Language Reference/Facts

Facts Sections
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.

 : class-opt facts -opt -dot-term-list-opt

 : - 

Fact Declarations
A fact declaration declares a fact of a fact database. A fact declaration is either a fact variable, or a functor fact.

 : <FactVariableDeclaration> <FactFunctorDeclaration>

<FactFunctorDeclaration> : <FactName> : ( <Argument>-comma-sep-list-opt ) <FactMode>-opt

<FactName> : <LowerCaseIdentifier>

A fact functor declaration has nondeterm</vp> 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</vp>, 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</vp>, then the fact can have zero, one, or any other number of values. If mode is determ</vp>, 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</vp> functor fact. However, syntactically it is used as a mutable variable (i.e. with assignment).

<FactVariableDeclaration> : <FactVariableName> : <Domain> <InitialValue>-opt

<InitialValue> : := <Term> := erroneous

<FactVariableName> : <LowerCaseIdentifier>

The initialization expression <InitialValue> must evaluate to a value of <Domain> type.

The initialization expression can be omitted (only) if the fact variable is initialized in a constructor. Class fact variables should always have an initialization expression.

The keyword erroneous</vp> 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</vp> value is to give clear runtime error if some code uses uninitialized fact variable by mistake.

Visual Prolog has late initialization of fact variables, meaning that the initialization code for a fact variable is not execute before and unless it is needed.

If the initialization expression can be evaluated to a constant at compile time then the fact is initialized immediately, rather than late.

Late initialization of facts is threadsafe in the following way: if two or more threads are reading a late fact simultaneously, they will/may potentially all execute the initialization code. But only one of the results will be used as the initial value, and all the threads will receive that value; all the other calculated initialization values will be discarded.

The attribute immediate</vp> can be used to enforce immediate initialization of a fact variable.

Facts
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.

Constant fact variable
A constant fact variable is a fact variable that never changes value after it has been initialized. It can for example be a global "table" that initialized at some point and then used for lookup afterwards. Or an "id" in an object identifying what the object represents.

A fact variable is a constant fact variable if it is market with the attribute [constant]</vp>.

A constant class fact variable can only be assigned:
 * Directly in the declaration
 * Or in a predicate

A constant object fact variable can only be assigned:
 * Directly in the declaration
 * Or in a constructor