Sunday, September 27, 2015

Perkun 0.0.9 released!

Perkun (http://sourceforge.net/projects/perkun/) 0.0.9 has been released! It contains multiple classes mentioned previously that facilitate applying heuristics. It contains also a new class - dump_controller, inherited by the optimizer_with_all_data, which controls dumping the data in the verbose mode. It is possible to redirect various data to the XML or text files, to stdout, stderr or a single file. Take a look at the constructor dump_controller::dump_controller in the file dump_controller.cc.

Monday, September 21, 2015

JPerkun

There is a Perkun (http://sourceforge.net/projects/perkun/) port in Java. You can download it from http://www.pawelbiernacki.net/software/perkun/jperkun.jsp. There are two JARs there:
  • JPerkun.jar - the Perkun port to Java (a library)
  • Perkun.jar - a Java application based on JPerkun
They both contain the source code. In order to run an example execute:

java -jar Perkun.jar example.perkun

Multiple features are not yet implemented though. The primary functionality should be there.

Sunday, September 13, 2015

Action iteration controller - Perkun 0.0.9.

You may have noticed that the feature described recently in Perkun (http://sourceforge.net/projects/perkun/) 0.0.9 allows breaking the computation in any moment. This ability is not so great, though, if we process the actions in a strict, a-priori defined order. A new class has been introduced to relax this order. It is called action_iteration_controller. It is derived from class_with_tracking, and so can benefit of its stack of trackers. It contains three virtual functions:

virtual std::list<action*>::const_iterator get_action_iteration_begin() const;

virtual void action_iteration_increment(std::list<action*>::const_iterator & target) const;

virtual bool get_action_iteration_terminated(const std::list<action*>::const_iterator & i) const;

It is inherited by the class optimizer. Whenever the get_optimal_action iterates over the actions it uses these three functions. In your own programs you are free to override them providing a new (possibly random) order of the action iteration. And you can base these new orders (permutations of actions) on the knowledge stored in the stack of trackers!



Saturday, September 12, 2015

Heuristics in Perkun 0.0.9

In (yet unreleased) Perkun (http://sourceforge.net/projects/perkun/) 0.0.9 there will be a new mechanism to control the loop in the function get_optimal_action.

The optimizer will be inherited from a class called "class_with_tracking" which (as an attribute) will contain a stack of trackers. Each tracker will have access to the currently best action, current action, current best result. Based on the stack of trackers the program will decide how to proceed in the loop. There are three possible decisions:
  • NONE
  • BREAK
  • CONTINUE
NONE means we are proceeding with the current action. BREAK means we are terminating the execution (we are happy with the current best action) and CONTINUE means we skip the current action, but proceed with the loop.

The user embedding Perkun in his own programs will be free to override the virtual function:

class_with_tracking::decision class_with_tracking::make_decision(const std::list<tracker*> & s)

The decision returned by it will be precisely NONE,BREAK or CONTINUE. In the default implementation it is NONE, meaning exhaustive search of the game tree.

Friday, September 11, 2015

Perkun API. The variables.

In Perkun (http://sourceforge.net/projects/perkun/) there are three classes representing variables:


It is:
  • perkun::hidden_variable
  • perkun::input_variable
  • perkun::output_variable
They are all inherited from the class perkun::variable. Each variable has a list of allowed values. You might need to use these classes when you embed Perkun in your own programs.


Thursday, September 10, 2015

Perkun interactive commands.

While executing Perkun (http://sourceforge.net/projects/perkun/) loop instruction (in the interactive mode) it is possible to give a special command rather than the list of input variable values. There are three such commands:
  • verbose
  • silent
  • reset
Verbose switches Perkun to verbose mode and silent does the reverse. In the verbose mode the Perkun's decision is "explained", i.e. the expected values of the payoff are given for all decisions being considered. The reset command destroys the current belief, so that it will be replaced by an apriori (uniform) belief.

If you are curious how the commands work take a look at the function optimizer_with_all_data::get_input. This function is virtual and is likely to be replaced in your own programs based on Perkun.

Wednesday, September 9, 2015

Perkun 0.0.8

A new Perkun (http://sourceforge.net/projects/perkun/) has been released. It is version 0.0.8. It contains a man page.  Just install it and type:

$ man perkun

Apart from that there is an important enhancement in the API:

void perkun::optimizer_with_all_data::set_apriori_belief(belief * b) const;

It can be overridden to fill the belief with an a-priori distribution (it is useful in programs based on Perkun).

Monday, September 7, 2015

Perkun. The Haskell generators.

Try using in Perkun (http://sourceforge.net/projects/perkun/) the instruction "cout << haskell generator << eol;". For example:

values
{
value false;
value true;
value place_Wyzima;
value place_Novigrad;
value place_Shadizar;
value do_nothing;
value attack_vampire;
}
variables
{
input variable do_I_see_vampire:{false,true};
input variable where_am_I:{place_Wyzima,place_Novigrad,place_Shadizar};
hidden variable where_is_vampire:{place_Wyzima,place_Novigrad,place_Shadizar};
output variable action:{do_nothing,attack_vampire};
}
payoff
{
}
model
{
}
cout << haskell generator << eol;


It will print out a Haskell code generating the model. The idea is similar like the Prolog generators described previously. You may enhance the generated code to create actual model.

Sunday, September 6, 2015

Perkun API. Optimizer classes.

Perkun (http://sourceforge.net/projects/perkun/) provides an API allowing to extend it in your own programs. The central class containing the Perkun algorithm is perkun::optimizer:

It is possible to use Perkun just by instantiating the perkun::optimizer. However this would be not very convenient. The Perkun parser requires an instance of the class perkun::optimizer_with_all_data, which contains:
  • perkun::collection_of_values
  • perkun::collection_of_variables
  • perkun::collection_of_visible_states
  • perkun::collection_of_actions
Its base class relies only on the references to these classes instances. It is recommended to instantiate a class inherited from perkun::optimizer_with_all_data and redefine the virtual functions in it. The most important are two functions:

virtual void get_input(std::map<variable*, value*> & m, bool & eof);
virtual void execute(const action * a);

get_input fills the map with the pairs: (variable*,value*) and eventually sets the boolean flag eof, while execute executes the optimal action chosen by the Perkun algorithm. See the Perkun Wars project (http://sourceforge.net/projects/perkunwars/) to learn how these function work in the class npc. They use pipes to communicate with the parent process.


Friday, September 4, 2015

Avoiding surprises with embedded Perkun.

I have already mentioned that in some cases it may happen that Perkun (http://sourceforge.net/projects/perkun/) gets "surprised". This happens when the model says that some input values are impossible. See the code:

values
{
        value false, true;
        value hello;
}

variables
{
        input variable what_I_can_see:{false, true};
        output variable action:{hello};
}

payoff
{
        set({what_I_can_see=>false},0.0);
        set({what_I_can_see=>true},1.0);
}

model
{

set({what_I_can_see=>false },{action=>hello },{what_I_can_see=>false },0.0);
set({what_I_can_see=>false },{action=>hello },{what_I_can_see=>true },1.0);
set({what_I_can_see=>true },{action=>hello },{what_I_can_see=>false },1.0);
set({what_I_can_see=>true },{action=>hello },{what_I_can_see=>true },0.0);

}

loop(1);


The input values must be false, true, false, true,... interchangeably. If you tell Perkun it gets "false" twice it gets surprised. You probably want to avoid this situation when you embed Perkun in your own programs. In order to do that you should redefine the virtual function:

void optimizer::on_error_in_populate_belief_for_consequence(const belief & b1, const action & a, const visible_state & vs, belief & target) const;

You must do it in the new class inherited from perkun::optimizer_with_all_data (see the previous post). In Perkun Wars I redefine it in the class npc. Instead of throwing an error I call on the target belief "make_uniform". This makes Perkun to assume a reasonable belief distribution once it gets "surprised".

Another way is to make the model without zeros in the set instructions. You could replace them for example with 0.01. Then nothing is impossible.

Thursday, September 3, 2015

Perkun as a library.

Imagine you would like to use Perkun (http://sourceforge.net/projects/perkun/) as a library in your own project. It is possible! Take a look at my game: Perkun Wars (http://sourceforge.net/projects/perkunwars/).

In your configure.ac you have to add the line:

PKG_CHECK_MODULES([PERKUN], [libperkun >= 0.0.7])

In src/Makefile.am you will add the flags defined by this macro - PERKUN_CFLAGS to AM_CXXFLAGS and PERKUN_LIBS to your LDADD. For example:

AM_CXXFLAGS = @CXXFLAGS@ \
    -I.. -I../inc \
    @XML_CFLAGS@ @GTK_CFLAGS@ @PERKUN_CFLAGS@ \
    -DDATADIR=\"$(datadir)\"


perkun_wars_LDADD = \
    @LIBS@ @GTK_LIBS@ @PERKUN_LIBS@ @XML_LIBS@


In your header file you need to include <perkun.h>. See the file inc/perkun_wars.h.

Define a new class inheriting perkun::optimizer_with_all_data, In Perkun Wars it is the class npc.

Instantiate the class and run the perkun interpreter (see the file src/perkun_wars.cc, function main_perkun). You run the interpreter calling the function "parse".

This function main_perkun runs in a separate process, because in Perkun specification we use the loop. But there are pipes in place and the redefined virtual functions of the class npc communicate with the main process through the pipes. In fact there are three extra processes in Perkun Wars. They are named after the heros:
  • Dorban
  • Pregor
  • Thragos

Wednesday, September 2, 2015

Perkun and XML.

Perkun (http://sourceforge.net/projects/perkun/) can produce an XML file containing its specification. Write a Perkun specification (i.e. the four mandatory sections) and terminate it with an instruction:

cout << xml << eol;

When you execute the code with Perkun it will write an XML document to the standard output.

Now look at the file perkun.xslt. It is written in an XML-like language called XSLT. You may use it to convert the XML produced by Perkun into a HTML document. This can be done with any XSLT processor, we use here xsltproc:

xsltproc perkun.xslt document.xml > document.html


Tuesday, September 1, 2015

Perkun. Payoff generated in Prolog.

Let us begin with an easy example. In Perkun (http://sourceforge.net/projects/perkun/) you have to provide the payoff section and model section. The payoff in dorban_general.perkun looks as follows:

payoff
{
set({where_is_Dorban=>place_Wyzima, do_I_see_vampire=>false}, 0.0);
set({where_is_Dorban=>place_Wyzima, do_I_see_vampire=>true}, 100.0);
set({where_is_Dorban=>place_Shadizar, do_I_see_vampire=>false}, 0.0);
set({where_is_Dorban=>place_Shadizar, do_I_see_vampire=>true}, 100.0);
set({where_is_Dorban=>place_Novigrad, do_I_see_vampire=>false}, 0.0);
set({where_is_Dorban=>place_Novigrad, do_I_see_vampire=>true}, 100.0);
}


Do we notice any rule, any regularity here? Of course no matter where we are the payoff depends on the variable do_I_see_vampire only. In dorban_general_final.prolog we needed to add the fact:

% get_payoff(INPUT_where_is_Dorban,INPUT_do_I_see_vampire, PAYOFF).
 

get_payoff(_,true, 100.0). % Dorban is hunting the vampires



The comment above the fact was generated by Perkun. That is it! The payoff for do_I_see_vampire=false will be provided by the fallback rule (also generated by Perkun):

get_payoff(_,_, 0.0).

By the way, I did not mention yet, that in order to use Prolog generators it is better to avoid in Perkun the identifiers beginning with a capital letter. Lower case letters are better. Needless to say, the underscore character ("_") is also a bad candidate for an identifier.

Monday, August 31, 2015

Perkun. The Prolog generators.

You have identified an optimization problem that Perkun (http://sourceforge.net/projects/perkun/) could solve for you? Excellent. Then you need to write a Perkun code yourself. When you look at the files like dorban_general.perkun you probably wonder how I created them. I did not write all this manually. Instead I used a Prolog generator.  Do you know Prolog? It would be very helpful to learn it. This is the file I started with:

values
{
    value false, true; # logical values
    value place_Wyzima,place_Shadizar,place_Novigrad;
    value do_nothing,escape,fight,goto_Wyzima,goto_Shadizar,goto_Novigrad;

}

variables
{
    input variable where_is_Dorban:{place_Wyzima,place_Shadizar,place_Novigrad}; # where am I
    input variable do_I_see_vampire:{false, true};
    output variable action:{do_nothing,goto_Wyzima,goto_Shadizar,goto_Novigrad}; # actions
    hidden variable where_is_vampire:{place_Wyzima,place_Shadizar,place_Novigrad};
}

payoff {}
model {}

cout << prolog generator << eol;


As you can see the model section is followed by a new instruction:

cout << prolog generator << eol;

It produces a program in Prolog. You can download the result - dorban_general.prolog. If you look at the code you will find the comments:

% PLEASE INSERT YOUR CODE HERE-get_probability
% PLEASE INSERT YOUR CODE HERE-write_model_impossible_if_necessary
% PLEASE INSERT YOUR CODE HERE-write_model_action_illegal_if_necessary
% PLEASE INSERT YOUR CODE HERE-get_payoff


If you execute dorban_general.prolog directly (for example with SWI Prolog) you will get a Perkun code with zeros in the model. Instead you should write the Prolog code, insert it in the locations indicated by the comments and make something like the file dorban_general_final.prolog. That is it! When you execute dorban_general_final.prolog with Prolog you will get dorban_final.perkun.

What Prolog code has been added? I think I will discuss it in the next post.


Sunday, August 30, 2015

Perkun. Pregor.

I have one more example for Perkun (http://sourceforge.net/projects/perkun/) coming from Perkun Wars (a simple Perkun based fantasy game). The hero's name is Pregor. Download the file pregor_general.perkun. The variables are similar to those known from dorban_general.perkun:

input variable where_is_Pregor:{place_Wyzima,place_Shadizar,place_Novigrad};
input variable do_I_see_vampire:{false,true};
output variable action:{do_nothing,goto_Wyzima,goto_Shadizar,goto_Novigrad};
hidden variable where_is_vampire:{place_Wyzima,place_Shadizar,place_Novigrad};


But the payoff function is different. Pregor does not want to see the vampire:

payoff
{
set({where_is_Pregor=>place_Wyzima, do_I_see_vampire=>false}, 100.0);
set({where_is_Pregor=>place_Wyzima, do_I_see_vampire=>true}, 0.0);
set({where_is_Pregor=>place_Shadizar, do_I_see_vampire=>false}, 100.0);
set({where_is_Pregor=>place_Shadizar, do_I_see_vampire=>true}, 0.0);
set({where_is_Pregor=>place_Novigrad, do_I_see_vampire=>false}, 100.0);
set({where_is_Pregor=>place_Novigrad, do_I_see_vampire=>true}, 0.0);
}


Let us begin a perkun session:
$ perkun pregor_general.perkun
loop with depth 3
I expect the values of the variables: where_is_Pregor do_I_see_vampire
perkun> 


Let us begin in Novigrad and assume we do see the vampire.
perkun> place_Novigrad true
belief:
where_is_vampire=place_Wyzima where_is_Pregor=place_Novigrad do_I_see_vampire=true 0
where_is_vampire=place_Shadizar where_is_Pregor=place_Novigrad do_I_see_vampire=true 0
where_is_vampire=place_Novigrad where_is_Pregor=place_Novigrad do_I_see_vampire=true 1
optimal action:
action=goto_Wyzima
perkun> 


Of course, the belief is that the vampire is in Novigrad. And the decision is to escape, to go to Wyzima. Let us do it:

perkun> place_Wyzima false
belief:
where_is_vampire=place_Wyzima where_is_Pregor=place_Wyzima do_I_see_vampire=false 0
where_is_vampire=place_Shadizar where_is_Pregor=place_Wyzima do_I_see_vampire=false 0
where_is_vampire=place_Novigrad where_is_Pregor=place_Wyzima do_I_see_vampire=false 1
optimal action:
action=do_nothing
perkun>


Now Pregor still thinks the vampire is in Novigrad, but he cannot see him, so he is satisfied. The decision is to do nothing!

Saturday, August 29, 2015

Perkun. The impossible states.

I hope you remember that a Perkun (http://sourceforge.net/projects/perkun/) model can be represented as a collection of directed graphs, each graph for one action (fixed values of the output variables). It may happen that in these graphs certain states cannot be achieved. It is the case in the file dorban_general.perkun. It contains the following variables:

input variable where_is_Dorban:{place_Wyzima,place_Shadizar,place_Novigrad};
input variable do_I_see_vampire:{false,true};
output variable action:{do_nothing,goto_Wyzima,goto_Shadizar,goto_Novigrad};
hidden variable where_is_vampire:{place_Wyzima,place_Shadizar,place_Novigrad};


Obviously Dorban cannot see the vampire if it is in a different town. What does it mean? For example that the following state is impossible:

where_is_Dorban=>place_Wyzima
do_I_see_vampire=>true
where_is_vampire=>place_Shadizar

There is an instruction for the model section that denotes that. It is called "impossible". Grep the file dorban_general.perkun for this instruction.


$ grep "impossible" dorban_general.perkun
impossible({where_is_Dorban=>place_Wyzima, do_I_see_vampire=>false, where_is_vampire=>place_Wyzima}); # Dorban must see vampire
impossible({where_is_Dorban=>place_Wyzima, do_I_see_vampire=>true, where_is_vampire=>place_Shadizar}); # Dorban cannot see vampire
impossible({where_is_Dorban=>place_Wyzima, do_I_see_vampire=>true, where_is_vampire=>place_Novigrad}); # Dorban cannot see vampire
impossible({where_is_Dorban=>place_Shadizar, do_I_see_vampire=>false, where_is_vampire=>place_Shadizar}); # Dorban must see vampire
impossible({where_is_Dorban=>place_Shadizar, do_I_see_vampire=>true, where_is_vampire=>place_Wyzima}); # Dorban cannot see vampire
impossible({where_is_Dorban=>place_Shadizar, do_I_see_vampire=>true, where_is_vampire=>place_Novigrad}); # Dorban cannot see vampire
impossible({where_is_Dorban=>place_Novigrad, do_I_see_vampire=>false, where_is_vampire=>place_Novigrad}); # Dorban must see vampire
impossible({where_is_Dorban=>place_Novigrad, do_I_see_vampire=>true, where_is_vampire=>place_Wyzima}); # Dorban cannot see vampire
impossible({where_is_Dorban=>place_Novigrad, do_I_see_vampire=>true, where_is_vampire=>place_Shadizar}); # Dorban cannot see vampire


Its syntax is:
impossible(STATE_QUERY);

The STATE_QUERY contains values of the input and hidden variables.

OK. Now you know enough to execute the file dorban_general.perkun with perkun. Just one more word about the payoff. Dorban is a witcher and will try to find the vampire. In other words, he likes to see the vampire. Let us start:

$ perkun dorban_general.perkun
loop with depth 3
I expect the values of the variables: where_is_Dorban do_I_see_vampire
perkun>


We need to enter the values for where_is_Dorban and do_I_see_vampire. Let us assume Dorban is in Shadizar and the vampire is in Novigrad. This implies that Dorban cannot see the vampire.

perkun> place_Shadizar false
belief:
where_is_vampire=place_Wyzima where_is_Dorban=place_Shadizar do_I_see_vampire=false 0.5
where_is_vampire=place_Shadizar where_is_Dorban=place_Shadizar do_I_see_vampire=false 0
where_is_vampire=place_Novigrad where_is_Dorban=place_Shadizar do_I_see_vampire=false 0.5
optimal action:
action=goto_Wyzima
perkun>


There is something interesting about the belief. Perkun assumes with 50% that the vampire is in Wyzima and 50% that he is in Novigrad. Quite correct! The vampire is not in Shadizar, because Dorban cannot see him. The decision is goto_Wyzima. Let us do it:

perkun> place_Wyzima false
belief:
where_is_vampire=place_Wyzima where_is_Dorban=place_Wyzima do_I_see_vampire=false 0
where_is_vampire=place_Shadizar where_is_Dorban=place_Wyzima do_I_see_vampire=false 0
where_is_vampire=place_Novigrad where_is_Dorban=place_Wyzima do_I_see_vampire=false 1
optimal action:
action=goto_Novigrad
perkun> 


Now Dorban is sure that the vampire is in Novigrad! And he wants to go there! Correct.


Friday, August 28, 2015

Perkun. Illegal actions.

You may be wondering how to prevent some actions to be chosen by Perkun (http://sourceforge.net/projects/perkun/) in some situations. Download the file dorban_general.perkun. Take a look at the beginning. There are two input variables:

input variable where_is_Dorban:{place_Wyzima,place_Shadizar,place_Novigrad};
input variable do_I_see_vampire:{false,true};


There are three places (Shadizar, Wyzima and Novigrad). I have borrowed the names from the fantasy literature, two from Sapkowski and one from Howard. There are also three corresponding actions plus do_nothing:

output variable action:{do_nothing,goto_Wyzima,goto_Shadizar,goto_Novigrad};

How do we tell Perkun that while being in Wyzima it is no point to use the action goto_Wyzima? There is a special instruction for that used in the model section. It is called "illegal". Grep the file dorban_general.perkun for it:

$ grep "illegal" dorban_general.perkun
illegal({where_is_Dorban=>place_Wyzima, do_I_see_vampire=>false},{action=>goto_Wyzima});
illegal({where_is_Dorban=>place_Wyzima, do_I_see_vampire=>true},{action=>goto_Wyzima});
illegal({where_is_Dorban=>place_Shadizar, do_I_see_vampire=>false},{action=>goto_Shadizar});
illegal({where_is_Dorban=>place_Shadizar, do_I_see_vampire=>true},{action=>goto_Shadizar});
illegal({where_is_Dorban=>place_Novigrad, do_I_see_vampire=>false},{action=>goto_Novigrad});
illegal({where_is_Dorban=>place_Novigrad, do_I_see_vampire=>true},{action=>goto_Novigrad});


The syntax is:
illegal(VISIBLE_STATE_QUERY,ACTION_QUERY);

The VISIBLE_STATE_QUERY contains the input variable values, while the ACTION_QUERY contains the output variable values. That is it, Perkun won't try to use these actions when these situations occur!

Thursday, August 27, 2015

Perkun. An example with hidden variables.

You are probably curious how Perkun (http://sourceforge.net/projects/perkun/) deals with the variables it cannot perceive. The hidden variables are, after all, something that differs Perkun from the other programming languages. Let us build an example.

Download the file abcd.perkun. It begins with the following code:

values
{
    value a,b,c,d;
    value do_nothing, switch;
}
variables
{
    input variable alpha:{a,b};
    hidden variable beta:{c,d};
    output variable gamma:{do_nothing, switch};
}
payoff
{
    set({alpha=>a},0.0);
    set({alpha=>b},100.0);
}


As you can see there are three variables: the input variable alpha, hidden variable beta and output variable gamma. For each fixed value of gamma we can show the model as a directed graph, because we still have a deterministic model (probabilities 0.0 or 1.0). Let us show the directed graph for gamma=do_nothing:

This was easy, each state (alpha/beta) remains as it was. Let us introduce the directed graph for gamma=switch:


Now it is slightly more complex. Let us see how Perkun deals with the file. Run:

$ perkun abcd.perkun

It responds with:

loop with depth 1
I expect the values of the variables: alpha
perkun> 


Enter a. If you look at the graphs you would not know whether we mean the state "a,c" or "a,d". That is the point - the variable beta is hidden!

perkun> a
belief:
beta=c alpha=a 0.5
beta=d alpha=a 0.5
optimal action:
gamma=switch
perkun>


Now there is something interesting. Perkun chooses the output variable gamma value to be switch, but does not know precisely in which state it is! There is 50% probability for both "a,c" and "a,d"! That is correct. Now enter a again.

perkun> a
belief:
beta=c alpha=a 0
beta=d alpha=a 1
optimal action:
gamma=switch

perkun>

Look at the "belief" in the response. Now Perkun is sure it is in "a,d" state! This is implied by the model. So we have in some cases the certainty about hidden variables. Anyway Perkun deals with them in terms of probability, so the decision making can be biased by what it believes. But isn't it the case also for ourselves? Let us now enter b:

perkun> b
belief:
beta=c alpha=b 0
beta=d alpha=b 1
optimal action:
gamma=do_nothing
perkun> 


Again the Perkun is sure about the hidden variable! It knows it is in the state "b,d". It chooses "do_nothing" because the payoff says it "likes" to see alpha=b.

Terminate the session now and restart it entering b:

loop with depth 1
I expect the values of the variables: alpha
perkun> b
belief:
beta=c alpha=b 0.5
beta=d alpha=b 0.5
optimal action:
gamma=do_nothing
perkun>


Note that Perkun now is not sure whether it is in the state "b,c" or "b,d"! But it does not care. Alpha is b, that is what it likes, so it chooses do_nothing! Sometimes we just do not need to know the hidden variables to make proper decisions!



Wednesday, August 26, 2015

Perkun. The loop command.

So you want to learn finally what Perkun (http://sourceforge.net/projects/perkun/) can do for you? As you remember the four sections in the Perkun code may be followed by instructions, and now is the time to learn another one: loop. It takes one argument - an integer constant, which denotes how deep Perkun should look into the game tree. Try the following code:

values
{
    value false, true, do_nothing, switch;
}
variables
{
    input variable alpha:{false, true};
    output variable beta:{do_nothing, switch};
}
payoff
{
    set({alpha=>false},0.0);
    set({alpha=>true},100.0);
}
model
{
    set({alpha=>false},{beta=>do_nothing},{alpha=>false},1.0);
    set({alpha=>false},{beta=>do_nothing},{alpha=>true},0.0);
    set({alpha=>true},{beta=>do_nothing},{alpha=>false},0.0);
    set({alpha=>true},{beta=>do_nothing},{alpha=>true},1.0);

    set({alpha=>false},{beta=>switch},{alpha=>false},0.0);
    set({alpha=>false},{beta=>switch},{alpha=>true},1.0);
    set({alpha=>true},{beta=>switch},{alpha=>false},1.0);
    set({alpha=>true},{beta=>switch},{alpha=>true},0.0);
}

loop(1);


As you see we used the model from the former post. The Perkun will respond with the message and a prompt:

loop with depth 1
I expect the values of the variables: alpha
perkun>


Now it is your turn. You can enter one of the two values that the input variable alpha may have, i.e. false or true. Let us first try false:

perkun> false
belief:
alpha=false 1
optimal action:
beta=switch
perkun>


As the optimal action the beta=switch was chosen! Why? Because Perkun can see alpha=false, it does not like it (see the payoff) and knows that if it uses switch the alpha will change its value to not alpha. How does it know it? From the model (see the previous post). That is it, this is how Perkun works. OK. Let us continue. Let us now enter true:

perkun> true
belief:
alpha=true 1
optimal action:
beta=do_nothing
perkun> 


Again Perkun chooses an optimal action, but this time it is beta=do_nothing! Why? Because it can see alpha=true, it likes it (see the payoff) and knows that do_nothing will keep the value of alpha unmodified. The last fact, again, is known from the model.

Just for fun let us lie to Perkun and enter now "false". This is impossible, because the model says that alpha after beta=do_nothing is unmodified. But let us do it:

perkun> false
result
alpha=false its probability was 0
exception caught
line 28 at T_INT_LITERAL: syntax error
error


What happened? Perkun has thrown an exception and stated that alpha=false was impossible! Quite correct. The bad news is that it terminated the session. But if you use Perkun as a library there is a way to overcome it and continue the session, so that you do not have to worry that using Perkun would break your programs.







Tuesday, August 25, 2015

Perkun model.

The time has come to learn the last part of the Perkun (http://sourceforge.net/projects/perkun/) program: the model. We know already how to declare the variables (input,output or hidden ones) and how to define the payoff, i.e. tell Perkun which input variable values are good and which are not so good. In order to do its job Perkun needs to know how its decisions will affect the world, i.e. how the world state in the future depends on its state now and the Perkun's choices.

Imagine a world where we have only one variable - input variable alpha. Its value can be either false or true. Let us introduce an output variable beta which can control two actions:
  • do_nothing - alpha remains as it is now
  • switch - alpha switches to not alpha
Let us further assume that Perkun "likes" alpha=true, and "dislikes" alpha=false. For this simple world our Perkun program will look as follows:

values
{
    value false, true, do_nothing, switch;
}
variables
{
    input variable alpha:{false, true};
    output variable beta:{do_nothing, switch};
}
payoff
{
    set({alpha=>false},0.0);
    set({alpha=>true},100.0);
}
model
{
    set({alpha=>false},{beta=>do_nothing},{alpha=>false},1.0);
    set({alpha=>false},{beta=>do_nothing},{alpha=>true},0.0);
    set({alpha=>true},{beta=>do_nothing},{alpha=>false},0.0);
    set({alpha=>true},{beta=>do_nothing},{alpha=>true},1.0);

    set({alpha=>false},{beta=>switch},{alpha=>false},0.0);
    set({alpha=>false},{beta=>switch},{alpha=>true},1.0);
    set({alpha=>true},{beta=>switch},{alpha=>false},1.0);
    set({alpha=>true},{beta=>switch},{alpha=>true},0.0);
}

cout << model << eol;

The model section is filled with the set instructions, but they have slightly different syntax than the set instructions we know from the payoff section. Each set instruction in the model section has syntax:

set(INITIAL_STATE_QUERY,ACTION_QUERY,TERMINAL_STATE_QUERY,VALUE);

The INITIAL_STATE_QUERY and TERMINAL_STATE_QUERY are regular queries containing all input and hidden variables.

The ACTION_QUERY is a regular query containing all output variables.

The VALUE is a probability value.

In short set(A,B,C,D) means "if A and you do B then the probability to jump to C is D".

When you put the above Perkun code in a file and execute it with perkun it will write down:

# model
# {beta=>do_nothing}
set({alpha=>false },{beta=>do_nothing },{alpha=>false },1.00000);
set({alpha=>false },{beta=>do_nothing },{alpha=>true },0.00000);

# {beta=>switch}
set({alpha=>false },{beta=>switch },{alpha=>false },0.00000);
set({alpha=>false },{beta=>switch },{alpha=>true },1.00000);

# {beta=>do_nothing}
set({alpha=>true },{beta=>do_nothing },{alpha=>false },0.00000);
set({alpha=>true },{beta=>do_nothing },{alpha=>true },1.00000);

# {beta=>switch}
set({alpha=>true },{beta=>switch },{alpha=>false },1.00000);
set({alpha=>true },{beta=>switch },{alpha=>true },0.00000);


It will be done by the command "cout << model << eol;".

Note that the sum of the probabilities over the terminal state queries equals 1.0 for each initial state query and each action query. Perkun checks this with a certain tolerance (and shows a warning on models that violate this rule).

Creating the Perkun models is difficult. The difficulty is of the quantitative nature - they tend to be very big. If you skip the set instructions in the model section the model will be random. Try running with perkun the following code:

values { value false,true; }
variables {
input variable a:{false,true},b:{false,true},c:{false,true},d:{false,true},e:{false,true};
output variable f:{false,true},g:{false,true},h:{false,true};
}
payoff {}
model {}
cout << model << eol;


The model printed out will likely be bigger than 1MB of code. Remember, the models "explode" with the number of variables.

Congratulations, now you know everything what you have to tell Perkun. Values, variables, payoff, model. The time has come to see what Perkun can do for you given this information. It will attempt to maximize the expected value of the payoff function by appropriate choosing the actions. First you give it current values of the input variables, then it responds with the optimal action chosen (the values of the output variables). As you can see we will interact with Perkun and this interaction will involve both input and output. But this will be discussed in the next post.

Monday, August 24, 2015

Perkun hidden variables.

We do not perceive directly everything that is happening in the world. Or to say it otherwise - in order to understand the world it is useful to imagine that some facts about it remain hidden. Likewise - in Perkun (http://sourceforge.net/projects/perkun/) it is assumed that the world has a state described by the visible variables (so called input variables) and by the invisible variables (so called hidden variables). How to declare them in Perkun?

values { value false, true; }
variables 
{
    input variable a:{false, true}, b:{false, true};
    hidden variable c:{false, true}, d:{false, true};
}
payoff {}
model {}
cout << variables << eol;

The above Perkun code defines two input variables (a and b) and two hidden variables (c and d). All of them may have either value false or true. When you run it with perkun it will write out:

# variables
input variable a:{false,true};
input variable b:{false,true};
hidden variable c:{false,true};
hidden variable d:{false,true};


But how can we use the hidden variables? What is it good for, to take into account the variables we do not perceive? Well, in order to understand this we need to learn how to use the model section of the Perkun program. It will be described in the next post.


Sunday, August 23, 2015

Perkun. Payoff.

We know already how to declare Perkun (http://sourceforge.net/projects/perkun/) values and variables (see the previous posts). We know that the agent i.e. Perkun program can see the input variables and can control the output variables. The question is how to control the output variables. What do we want to achieve? What is "good" for the agent and what is not?

In order to define it we use the payoff section of the Perkun program. The most simple Perkun program contains four following sections:

values {}
variables {}
payoff {}
model {}

When you place the above text in a file and run perkun it will do nothing. Try replacing it with the following code:

values
{
        value false, true;
        value move, do_nothing;
}

variables
{
        input variable what_I_can_see:{false, true};
        output variable action:{move, do_nothing};
}

payoff
{
        set({what_I_can_see=>false},0.0);
        set({what_I_can_see=>true},1.0);
}


model {}

cout << payoff << eol;

It will print out the contents of the payoff section:

# payoff
what_I_can_see=false payoff 0
what_I_can_see=true payoff 1


The payoff section contains the commands "set" with two arguments:
  1. input state query
  2. payoff value (a real number)
The query contains all input variables followed by "=>" and the corresponding value, separated by commas, enclosed in curly brackets. In short it is an expression:

{INPUT_VARIABLE1=>VALUE,INPUT_VARIABLE2=>VALUE,...}

Note that the query must contain all the input variables.

What does the payoff value mean? It is a value representing "how good" the payoff function is (for the respective combination of the input variable values). The higher the payoff value the "better" it is. In the example above the agent "likes" to see the value "true" on its input (variable what_I_can_see), while it dislikes the value "false", because for "true" the payoff value equals 1.0, while for "false" it equals 0.0.


You already know three different instructions that can follow the model section:
  • cout << values << eol;
  • cout << variables << eol;
  • cout << payoff << eol;

What happens if you fail to specify payoff for some or all input variables values combinations? It will be random. Try:

values {}
variables {}
payoff {}
model {}
cout << payoff << eol;

Anyway it does not make much sense since in this case the payoff function is constant (there are no input variables).

Try:
values
{
        value false, true;
        value move, do_nothing;
}

variables
{
        input variable what_I_can_see:{false, true};
        output variable action:{move, do_nothing};
}

payoff {}

model {}
cout << payoff << eol;

After running the above code with perkun you will see random values for both "false" and "true" of the input variable what_I_can_see.



Saturday, August 22, 2015

Perkun variables.

Perkun (http://sourceforge.net/projects/perkun/) allows three kinds of variables:
  • input variables
  • hidden variables
  • output variables
On the picture above the time axis is shown. We can see two sets of the input and hidden variables (NOW and LATER) and one set of the output variables. The yellow arrow denotes an agent (Perkun program) which chooses the values of the output variables given the current values of the input variables (and its memory). Note that the world is an automaton whose state LATER depends both on its state NOW and the agent's decision (output variables values).

The hidden variables are essential for the machine learning. They represent the state variables of the world that are not directly visible to the agent. Yet they do affect the state of the world.

Let us forget for now the hidden variables though, and introduce a simple Perkun code with one input variable and one output variable:

 
values
{
        value false, true;
        value move, do_nothing;
}

variables
{
        input variable what_I_can_see:{false, true};
        output variable action:{move, do_nothing};
}


payoff {}
model {}

As you can see the variables section contains now two variables:
  • what_I_can_see
  • action
Unlike many other programming languages Perkun does not have the concept of a variable type. Instead each variable declaration is followed by a colon and a list of possible values in curly brackets, separated by comas. For example what_I_can_see may have value false or true.

Try using the command "cout << variables << eol;":


values
{
        value false, true;
        value move, do_nothing;
}

variables
{
        input variable what_I_can_see:{false, true};
        output variable action:{move, do_nothing};
}


payoff {}
model {}
cout << variables << eol;

When you put the above text in a file and call Perkun it will respond:
# variables
input variable what_I_can_see:{false,true};
output variable action:{move,do_nothing};



By the way you have learned another command. You know currently:
  • cout << values << eol;
  • cout << variables << eol;




Friday, August 21, 2015

Perkun. Values. Keywords.

The values section of the Perkun (http://sourceforge.net/projects/perkun/) code contains the keyword "value" followed by the valid identifiers.

values
{
        value false, true;
        value move, do_nothing;
}

variables {}
payoff {}
model {}

The above code declares four new values: false, true, move and do_nothing. You might ask what a valid identifier is. It is any sequence of letters/digits beginning with a letter that is not a keyword. Below is the list of all Perkun keywords (version 0.0.7):
  • value
  • variable
  • hidden
  • input
  • output
  • visible
  • state
  • model
  • cout
  • variables
  • eol
  • values
  • actions
  • states
  • beliefs
  • payoff
  • set
  • loop
  • generator
  • xml
  • impossible
  • illegal
  • prolog
  • haskell 
The values are used to denote the possible values of the variables. The Perkun variables is a complex topic and will be discussed later. You can print out all the values with the command "cout << values << eol;". For example:

values
{
        value false, true;
        value move, do_nothing;
}

variables {}
payoff {}
model {}
cout << values << eol;
 
The above Perkun code will print out:
 # values
false
true
move
do_nothing



There are many other commands apart from "cout << values << eol;". They can all be placed directly after the model section.

One-line comments begin in Perkun with a hashtag "#".  

Thursday, August 20, 2015

Artificial Intelligence. Your first Perkun program.

Perkun (to obtain from http://sourceforge.net/projects/perkun/) is a strict form programming language. A program in Perkun consists of four sections and any number of commands:
  • values section
  • variables section
  • payoff section
  • model section
  • commands
The simplest Perkun program is:
values {}
variables {}
payoff {}
model {} 

When you place the above text in a file (for example test.perkun) and run:
$ perkun test.perkun

it will do nothing. That is correct. But if you remove any of the sections you will get an error. Also correct.

Take a look at the Perkun wiki: http://sourceforge.net/p/perkun/wiki/Home/.
It describes the Perkun specifications in more details.

Wednesday, August 19, 2015

How to build perkun

In order to build Perkun one has to install first bison and flex. On my Fedora Core 21 it requires following instructions:

$ yum install bison.x86_64

and

$ yum install flex.x86_64 

Both these commands need to be given as the root user. Then one has to download the perkun-0.0.7.tar.gz from http://sourceforge.net/projects/perkun/. The tarball has to be unpacked and untared (as any user):

$ gunzip perkun-0.0.7.tar.gz 
$ tar -xvf perkun-0.0.7.tar 

This will create a directory perkun-0.0.7. Let us enter into it:

$ cd perkun-0.0.7

Let us first configure the project:

$ ./configure 

The "configure" script will create the makefiles. Then we need to compile the project:

$ make 

If no errors were encountered then we can install the project (as the root user):

$ make install

After it is installed we can optionally run the tests:

$ make check 

Once the Perkun is installed it should be possible to call it:

$ perkun
usage: perkun <file>

In order to use it we should create a file containing a valid Perkun specification.

Perkun - experimental language for AI

Take a look at my AI project:
http://sourceforge.net/projects/perkun/

It is an experimental language and a library. I have also written a simple game using it: http://sourceforge.net/projects/perkunwars/.

Both projects are Open Source, on the license GPL3.0.

I will change the blog's profile a bit. Now I intend to write more about Artificial Intelligence and Perkun.