5. Class Declaration¶
Classes are the placeholder of attributes and references in the O3PRM language. You can see them as fragments of Bayesian Networks.
<class> ::= class <word> [ extends <word> ] "{" <class_elt>* "}"
<class_elt> ::= <reference_slot> | <attribute> | <parameter>
Classes contain three different elements: attributes, reference slots and parameters.
5.1. Attributes¶
Attributes are a generic definition of random variables. They are not random variables: only their instances after instantiating the class are random variables. Attributes are defined by a type, a name, a set of parents and a CPT.
<attribute> ::= <attribute_type> <attribute_name> <attribute_cpt> ";"
<attribute_type> ::= <anonymous_type> | <word>
<anonymous_type> ::= <labelized_type> | <integer_type> | <real_type>
<attribute_name> ::= <word> [ <dependency> ]
<attribute_cpt> ::= ( <CPT> | <aggregator> )
<dependency> ::= dependson <parent> ( "," <parent> )*
<CPT> ::= "{" ( <raw_CPT> | <rule_CPT> ) "}"
<raw_CPT> ::= "[" <cpt_cell> ( "," <cpt_cell> )+ "]"
<rule_CPT> ::= ( <word> ("," <word>)* ":" <cpt_cell> ";" )+
<cpt_cell> ::= <float> | """ <formula> """
<formula> ::= <real> | <function> | <formula> <operator> <formula>
<function> ::= <function_name> "(" <formula> ")"
<function_name> ::= exp | log | ln | pow | sqrt
5.1.1. Tabular Declaration¶
When declaring a CPT in tabular form, the probability values for all the possible values of the attribute and its parents must be specified. In addition, the order in which the values are specified is important. The O3PRM language uses a declaration by column, i.e., in each column of the CPT, the values must sum to one because the rows of the CPT correspond the domain of the attribute for which the CPT is specified (please, note that the terms column and row are used loosely since the table is only one-dimensional). The following example illustrates the reason why we say that the columns sum to one:
class Example {
boolean Y {[0.2, 0.8]};
boolean Z {[0.5, 0.5]};
boolean X dependson Y, Z {[
// Y==false | Y==true
// Z==false | Z=true | Z==false | Z==true
0.2, 0.3, 0.7, 0.9, // X == false
0.8, 0.7, 0.3, 0.1 // X == true
]};
}
In this example, we can see that the first value is the probability
P(X=false|Y=false,Z=false)
, the second value
P(X=false|Y=false,Z=true)
, the third P(X=false|Y=true,Z=false)
and so
on.
5.1.2. Rule-based CPT declaration¶
Rule-based declarations exploit the *
wildcard symbol to reduce the number of
parameters needed to specify the CPT.
class Example {
boolean Y {[0.2, 0.8]};
boolean Z {[0.5, 0.5]};
boolean X dependson Y, Z {
// Y, Z: X=false, X=true
*, false: 1.0, 0.0;
true, true: 0.01, 0.99;
false, true: 0.3, 0.7;
};
The first line uses the wildcard *
for Y
’s outcomes. This defines in
one line the set of probabilities P(X|Y=y,Z=false)
for y
in
{false,true}
. There is no limit in the number of rules and, when two
rules overlap, the last one takes precedence.
5.2. Reference Slots¶
Reference slots can either be simple (defining a one to one relation, or a unary relation) or complex (defining a one to N relation, or n-ary relation).
<reference_slot> ::= [internal] <word> [ "[" "]" ] <word> ";"
5.2.1. Simple Reference Slots¶
Simple reference slots are used to define a one to one relation between two classes. They are used in slot chains to add parents from other classes to an attribute.
class SomeClass {
boolean Y {[0.2, 0.8]};
boolean Z {[0.5, 0.5]};
}
class AnotherClass {
SomeClass myClass;
boolean X dependson myClass.Y, myClass.Z {
// Y, Z: X=false, X=true
*, false: 1.0, 0.0;
true, true: 0.01, 0.99;
false, true: 0.3, 0.7;
};
Class AnotherClass
defines the reference slot myClass
of type
SomeClass
and its attribute X
uses two slot chains, myClass.Y
and
myClass.Z
, to reference its parents.
Note that if reference cycles are allowed, you must be careful to not create cycles between attributes. Indeed, if there exists a cycle between two attributes, this implies that the CPT of the first one is conditional given the second attribute and the CPT of the second attribute is conditional given the first attribute. As a consequence, it is not possible to define a joint probability distribution using these two CPTs. The problem is exactly the same for regular Bayesian Networks and it explains why directed cycles are forbidden in BNs.
5.2.2. Complex Reference Slots¶
Complex reference slots are used to define n-ary relations between classes. They can be used in slot chains when declaring aggregators, special attributes described in section 5.
class SomeClass {
boolean Y {[0.2, 0.8]};
boolean Z {[0.5, 0.5]};
}
class AnotherClass {
SomeClass[] myClass;
boolean X = or([myClass.Y, myClass.Z]);
}
To declare a complex reference slots we use []
as a suffix to the
reference slot type. In the above example, we declared an or
aggregator
referencing attributes Y
and Z
accessed though the complex reference
myClass
. Since myClass
is a complex reference slot, we will be able to
reference more than instance of SomeClass
. Since we do not know how many
parents there is for attribute X
, we need to use an aggregator to
generate the attribute’s CPT when instantiating the class containing the
attribute.
5.3. Parameters¶
Parameters are used to define constants used in the CPT generation. For
example, if we define two parameters such as lambda
and t
, we will be
able to write the following formula in a CPT: 1-exp(-lambda*t)
.
class ClassWithParams {
param real lambda default 0.003;
param int t default 8760;
boolean state {
["exp(-lambda*t)", "1-exp(-lambda*t)" ]
};
}
The default
keyword is mandatory to provide a default value to
parameters, since they can be changed when declaring an instance of a class
with parameters.