Pawel Biernacki - 2015-01-26

Perkun

perkun - an experimental AI language

perkun requires flex and bison to be built.

See the INSTALL file to learn how to build perkun.

Once installed run "make check" to perform the tests. Some tests are expected to fail (xfail tests). The tests expect the binary perkun to be installed in /usr/local/bin/perkun.

The usage of perkun is:
ṕerkun <file>

The perkun program consists of the following obligatory sections:
- values section
- variables section
- payoff section
- model section

After the model section any number of instructions follow.

The values section

The values section looks as follows:

~~~~~~
values
{
value v1, v2, v3;
}
~~~~~~

The above example declares three values v1,v2 and v3. The variables declared in the following section will be allowed to have these values.

The variables section

~~~~~~
variables
{
input variable x:{v1, v2}, y:{v2, v3};
output variable a:{v1,v2};
hidden variable s:{v1,v2,v3};
}
~~~~~~

The above example declares four variables. x and y are input variables, a is an output variable and s is a hidden variable. Each variable is followed by a list of values it may have. The list must not have duplicates. For example s may have one of three values: v1, v2 or v3.

Perkun considers the so called hidden variables, i.e. the variables that are necessary to take into account when describing the world, but not directly observable to the agent.

The payoff section

~~~~~~
payoff
{
set({x=>v1,y=>v2},0.0);
set({x=>v1,y=>v3},100.0);
set({x=>v2,y=>v2},250.0);
set({x=>v2,y=>v3},0.0); 
}
~~~~~~

The payoff section contains the so called payoff function defined as a float value for every single legal combination of the input variables values.

It is legal to omit some combinations, then the payoff function will have random values for them.

The model section

~~~~~~
model
{
set({x=>v1, y=>v2, s=>v1},{a=>v1},{x=>v1, y=>v2, s=>v1}, 0.2);
set({x=>v1, y=>v2, s=>v1},{a=>v1},{x=>v1, y=>v2, s=>v2}, 0.0);
set({x=>v1, y=>v2, s=>v1},{a=>v1},{x=>v1, y=>v2, s=>v3}, 0.0);
set({x=>v1, y=>v2, s=>v1},{a=>v1},{x=>v1, y=>v3, s=>v1}, 0.3);
set({x=>v1, y=>v2, s=>v1},{a=>v1},{x=>v1, y=>v3, s=>v2}, 0.1);
set({x=>v1, y=>v2, s=>v1},{a=>v1},{x=>v1, y=>v3, s=>v3}, 0.0);
set({x=>v1, y=>v2, s=>v1},{a=>v1},{x=>v2, y=>v2, s=>v1}, 0.0);
set({x=>v1, y=>v2, s=>v1},{a=>v1},{x=>v2, y=>v2, s=>v2}, 0.1);
set({x=>v1, y=>v2, s=>v1},{a=>v1},{x=>v2, y=>v2, s=>v3}, 0.2);
set({x=>v1, y=>v2, s=>v1},{a=>v1},{x=>v2, y=>v3, s=>v1}, 0.0);
set({x=>v1, y=>v2, s=>v1},{a=>v1},{x=>v2, y=>v3, s=>v2}, 0.1);
set({x=>v1, y=>v2, s=>v1},{a=>v1},{x=>v2, y=>v3, s=>v3}, 0.0);
...
}
~~~~~~

The set instructions in the model section have the following syntax:

set(INITIAL_STATE_QUERY, ACTION_QUERY, TERMINAL_STATE_QUERY, TRANSITION_PROBABILITY);

The queries contain pairs variable=>value separated by commas in {}.

The initial state query must contain all input and hidden variables. It must not contain any output variables.

The action query must contain all output variables. It must not contain any other variables.

The terminal state query must contain all input and hidden variables. It must not contain any output variables.

The sum of the probabilities over all terminal state queries must be 1.0 for each pair (initial_state_query, action_query).

It is legal to omit some set instructions (or even all of them). The model will be random.

The transition probability must be a float value within 0.0 and 1.0.

The instructions

In order to dump a model to the standard output one should use the instruction:

~~~~~~
cout << model << eol;
~~~~~~

This is the easiest way to create a new model once the values and variables are defined.
Simply insert the empty model section and use the above instruction to dump the model.
Example:

~~~~~~
# An example how to create a new model

values
{
value v1, v2, v3;
}

variables
{
input variable x:{v1, v2}, y:{v2, v3};
output variable a:{v1,v2};
hidden variable s:{v1,v2,v3};
}

payoff {}

model {}

cout << model << eol;
# end of example
~~~~~~

The model printed to the standard output can be copied and pasted into the Perkun code (cout << model << eol; produces a valid collection of set instructions).

The actual way to use Perkun is an interactive mode - after the model section type:

~~~~~~
loop(3);
~~~~~~

This instruction makes Perkun to enter the interactive mode. The parameter is the recursion depth used to select the optimal action. Don't make it too large
or the computation may take very long!

In the interactive mode it first prompts what variables values are expected to be entered and waits for your input. In the above example it will expect values of the variables x and y (all input variables in the declaration order).

After the prompt type for example:
perkun> v1 v2

The Perkun will calculate its belief and the optimal action, then it will print
both. The optimal action will be chosen so that according to the model it will maximize the payoff function. The maximization will concern the expected value of the payoff functions within the next n steps, with n being the parameter passed to the loop instruction.

What is the belief?

Belief is a probability distribution over all combinations of the hidden variable values.
In the beginning Perkun chooses a uniform belief, but after each input the belief will be updated to reflect the interpretation of the input given the model.

Prolog generators of Perkun code

The Perkun models tend to be big and Perkun is unfortunately too weak to express the model in a compact way. But there is somehing that can do it - Prolog!

In order to create a perkun model one can also use the "cout << prolog generator << eol;" instruction. It produces Prolog code that can be modified manually to create a valid model.

Look at the example src/t4.perkun. It only contains values and variables (the payoff and model sections are empty). Then it contains the instruction cout << prolog generator << eol;

It can be used to produce the Prolog code src/t4.prolog.

Compare it with the code src/t5.prolog. It is enhanced by certain rules which express complex model relationships for this particular example.

If you have Prolog (we use SWI Prolog) you can run the t5.prolog to produce something like t5.perkun. It is a valid Perkun code with a zeroed payoff function and a model enhanced with the rules we entered manually into src/t5.prolog. Remember to set the payoff function before actually playing with it!

Look at the "real life example" - src/t6.perkun. It is src/t5.perkun with added a payoff function.

Perkun as a library.

Since the version 0.0.3 perkun comes as a library. Use the class optimizer_with_all_data and optionally override its virtual functions to control the input/output.

Put the following line into your configure.ac:

~~~~~~
PKG_CHECK_MODULES([PERKUN], [libperkun >= 0.0.3])
~~~~~~

This will define PERKUN_LIBS and PERKUN_CFLAGS.

 

Last edit: Pawel Biernacki 2015-02-16