A facts section declares a fact database, consisting of a number of facts. The fact database and the facts belong to the current scope.
Fact databases can exist on a class level as well as on an object level.
Facts sections can be declared only in class implementations.
If the fact database is named, an additional compound domain is implicitly defined. This domain has the same name as the fact section and has functors corresponding to the facts in the fact section.
If the facts section is named, the name denotes a value of the build-in domain factDB. The save and consult predicates accept values of this domain.
FactsSection : class-opt facts FactsSectionName-opt FactDeclaration-dot-term-list-opt
FactsSectionName : - LowerCaseIdentifier
A fact declaration declares a fact of a fact database. A fact declaration is either a fact variable, or a functor fact.
FactDeclaration : FactVariableDeclaration FactFunctorDeclaration
FactFunctorDeclaration : FactName : ( Argument-comma-sep-list-opt ) FfactMode-opt
FactName : LowerCaseIdentifier
A fact functor declaration has nondeterm fact mode by default.
A fact functor can have initialization via clauses section. In such case values in the clauses should be expressions, which can be evaluated at compile time.
FactMode : one of determ nondeterm single
If mode is single, then a fact always has one and only one value and the assert predicate overwrites old value with a new one. Predicate retract cannot be applied to single facts.
If mode is nondeterm, then the fact can have zero, one, or any other number of values. If mode is determ, then the fact can have zero or one value. If fact has zero values, then any read access to it gives fail.
Fact Variable Declarations
A fact variable is similar to a one-argument single functor fact. However, syntactically it is used as a mutable variable (i.e. with assignment).
FactVariableDeclaration : FactVariableName : Domain InitialValue-opt
InitialValue : := ConstantValue := erroneous
FactVariableName : LowerCaseIdentifier
A constant value ConstantValue should be a term (of the Domain type), which can be evaluated at compile time.
The constant value can be omitted only if the fact variable is initialized in a constructor. Class fact variables should always have an initial constant value.
Notice that the keyword erroneous can be used as value to be assigned to fact variables. That is both lines below are valid:
facts thisWin : vpiDomains::windowHandle := erroneous. clauses p() :- thisWin := erroneous.
The idea of assigning erroneous value is to give clear runtime error if some code uses uninitialized fact variable by mistake.
Facts can only be declared in a class implementation and subsequently they can only be referenced from this implementation. So the scope of facts is the implementation in which they are declared. But the lifetime of object facts is the lifetime of the object to which they belong. Likewise the lifetime of class facts are from program start to program termination.
implement aaa_class facts objectFact : (integer Value) determ. class facts classFact : (integer Value) determ. ... end implement aaa_class