7. Functions¶
Functions are used as placeholders for specific CPTs of classes attributes. They replace the CPT declaration by a specific syntax depending on the type of function used. The first type is the set of functions called aggregators. These functions are used to quantify the information stored in multiple reference slots. The second kind contains deterministic functions and the third probabilistic functions. The last two kinds of functions are not part of the O3PRM specification and are implementation specific. All functions share the same syntax:
<aggregator> ::= ( "=" | "~" ) <word> "(" <parents>, <args> ")"
<parents> ::= ( <parent> | "[" <parent> (, <parent> )* "]" )
<args> ::= <word> ( "," <word> )*
The use of =
is reserved for deterministic functions and ~
for
probabilistic functions. There are only four built-in functions in the O3PRM
language that are deterministic functions called aggregators. There are five
built-in aggregators in the O3PRM language: min
, max
, exists
,
forall
and count
. Other deterministic functions such as median
and amplitude
are implemented in aGrUM but they can be implemented in
different ways, preventing us from adding them to the O3PRM specification.
7.1. Deterministic Functions¶
The min
and max
functions require a single parameter: a list of slot
chains pointing to attributes. The attributes must all be of the same type or
share some common supertype. If the common type is not an int, then the type’s
declaration order is used to compute the min and max values.
class Die {
type int (1, 6) result {["1/6", "1/6", "1/6", "1/6", "1/6", "1/6"]};
}
class GameOfDice {
Die[] dice;
type int (1, 6) snake_eyes = min( dice.result );
type int (1, 6) bingo = max( [ dice.result ] );
}
If there is only one element in the list of slot chains the []
are
optional.
The exists
and forall
require two parameters: a list of slot chains
and a value. As for min
and max
, all attributes referenced in the
slot chains list must share a common type or supertype. The value must be a
valid value of that common supertype. exists
and forall
attribute
type must always be a boolean
.
class BWPrinter {
boolean black { [ 0.2, 0.8 ] };
}
class ColorPrinter {
boolean magenta { [ 0.8, 0.2 ] };
boolean cyan { [ 0.8, 0.2 ] };
boolean yellow { [ 0.8, 0.2 ] };
boolean black { [ 0.8, 0.2 ] };
}
class PrinterMonitor {
BWPrinter[] bw;
ColorPrinter[] color;
boolean has_magenta = exists ([color.magenta], true);
boolean has_cyan = exists ([color.cyan], true);
boolean has_yellow = exists ([color.yellow], true);
boolean color = forall([color.black, color.magenta, color.cyan, color.yellow], true);
boolean black = exists( [ bw.black, color.black ] };
}
The count
aggregator counts how many times a given outcome occurred. Its
type must be of the form type int (0, N)
, where N
is a positive
integer. The outcome N
must be interpreted as “the outcome occurred
at least N
times”.
class Die {
type int (1, 6) result {["1/6", "1/6", "1/6", "1/6", "1/6", "1/6"]};
}
class GameOfDice {
Die[] dice;
type int (0, 4) four_six = count( dice.result, 6 );
}
7.2. Probabilistic Functions¶
Instead of generating CPTs filled with 0
and 1
, like deterministic
functions, probabilistic functions return conditional distributions
following a specific rule. A classic probabilistic function is the
noisy-or
, which is implemented in aGrUM as shown below:
class NoisyOr {
SomeIface iface;
SomeIface jface;
boolean state ~ noisy_or([iface.state, jface.state], [0.2, 0.1], 0.4);
}
As for deterministic functions, the first parameter must be a list of parents. For the noisy-or, the next parameter is a list of weights and the third the noise. These functions are not part of the O3PRM specification and you should check your interpreter documentation for their proper syntax.