Language Reference/Predicates

Predicates Sections
A predicates section declares a set of object or class predicates in the current scope.

 : class-opt predicates -dot-term-list-opt

The keyword class can be used only inside class implementations, since:
 * predicates declared in an interface are always object predicates and
 * predicates declared in a class declaration are always class predicates.

Predicate Declarations
The predicate declaration is used to declare the predicate in scopes in which the predicate declaration can be seen. When predicates are declared in an interface definition, this means that objects of the corresponding type must support these predicates. When predicates are declared in a class declaration, this means that the class publicly provides the declared predicates. And if predicates are declared in a class implementation, this means that the predicates are available locally. In all cases a corresponding definitions of the predicates must exist.

 :  :  -opt  :  -opt

 : as 

 : 

Here is the name of a predicate domain declared in the domains section.

A predicate declaration states the name of the predicate, its type, mode, flow (see ), and optionally a.

Only class predicates can have link names. If the link name is not stated then a link name is derived from the predicate name, the way this name is derived depends on the calling convention.

If the calling convention is then the link name stated in the as</vp> clause is decorated anyway. If this decoration is unintended, use instead.

Decorated
Sometimes a name must have the _...@N</vp> decoration, but the default from apicall</vp> is wrong. In such cases decorated</vp>, decoratedA</vp> and decoratedW</vp> can be used to control the decoration:

predicates myPredicate : (string X) language stdcall as decorated.

In this case the link name will be "_MyPredicate@4</vp>", where apicall would make it "_MyPredicate</vp> W @4</vp>".

predicates myPredicate : (pointer X) language stdcall as decoratedA.

In this case the link name will be "_MyPredicate</vp> A @4</vp>", where apicall would make it "_MyPredicate@4</vp>".

predicates myPredicate : (pointer X) language stdcall as decoratedW.

In this case the link name will be "_MyPredicate</vp> W @4</vp>", where apicall would make it "_MyPredicate@4</vp>".

All of them change the start of the name from xxxx</vp> to _Xxxx</vp> and all of them put <vp>@N</vp> behind. The first never uses a suffix; the second always uses A and the third always uses W. This means that the programmer is responsible for deciding which suffix is needed. But he needs not to worry about calculating argument size and initial "_X".

Constructors Sections
A <vp>constructors</vp> section declares a set of constructors. The constructors belong to the scope in which the <vp>constructors</vp> section occurs (see class declaration and class implementation).

<ConstructorsSection> : constructors <ConstructorDeclaration>-dot-term-list-opt

Constructor sections can only occur in declarations and implementations of classes that construct objects.

Constructor Declarations
A constructor declaration declares a named constructor of a class.

A constructor actually has two associated predicates:


 * A class function, which returns a new constructed object.
 * An object predicate, which is used when initializing inherited objects.

An associated constructor object predicate is used to perform an object initialization. This predicate can only be called from the constructor in the class itself and from a constructor in a class that inherits from the class (i.e. base class initialization).

<ConstructorDeclaration> : <ConstructorName> : <PredicateDomain>

It is illegal to state a predicate mode for constructors, constructors always have <vp>procedure</vp> mode.

Predicates from Interface
An interface can support a subset of another interface by stating the predicates in a predicates from section. The <vp>predicates</vp> <vp>from</vp> section names the interface and all supported predicates. The predicates are stated by name or by name and arity.

If an interface supports a subset of another interface it is neither subtype or super-type related to the other interface.

The important thing about the <vp>predicates</vp> <vp>from</vp> section is that the mentioned predicates retain their origin interface. Therefore:


 * there will be no support conflict with any predicates from the origin interface;
 * they can be inherited as the predicates from the origin interface.

<PredicatesFromInterface> : predicates from <InterfaceName> <PredicateNameWithArity>-comma-sep-list-opt

<PredicatesFromInterface> can only be used in interface definitions.

Extension Predicates
Extension predicates is a syntactic sugaring, which makes it possible use class predicates as if they were object predicates.

Extension predicates can also be used to give give a more natural code flow for binary operations:

Extension predicates can also support a cascading data flow style:

An extension predicate is a class predicate whose first argument is marked with the attribute <vp>[this]</vp>.

Extension predicates can also be declared for non-object types.

It is illegal to declare an extension predicate on an interface type if that extension predicate is conflicting with a predicate that exist in the interface itself.

Extension predicates follows the visibility rules of class predicates.

Extension predicates can be qualified with namespace and class:

Several suitable extension predicates may be visible in a certain context, and thus cause ambiguity. Qualification can resolve such ambiguity.

Arity
A predicate that takes N arguments are said to be N-ary, or to have arity N. Predicates with different arity are always different predicates, even if they have the same name.

In most situations the arity of a predicate is obvious from the context in which the predicate is mentioned. But in, for example, sections and  the arity is not obvious.

In order to distinguish between different arities of predicates in <vp>predicates from</vp> sections and in, predicate names can (optionally) be stated with arity.

The following arities are possible:
 * Name/N meaning an ordinary predicate (i.e. not a function) Name of arity N.
 * Name/N-> meaning a function Name of arity N.
 * Name/N... meaning an ordinary predicate Name with N arguments followed by an <Ellipsis> argument (i.e. a varying number of arguments). ( <Ellipsis> "..." can be used in predicate and predicate domain declarations as the last formal argument. In this case it means that the declared predicate (predicate domain) can have a variable number of arguments. Ellipsis flow must match an ellipsis argument and can therefore be only the last flow in the flow pattern.)
 * Name/N...-> meaning a function Name with N arguments followed by an ellipsis argument.

<PredicateNameWithArity> : <PredicateName> <Arity>-opt

<Arity> : one of  / <IntegerLiteral> <Ellipsis>-opt / <IntegerLiteral> <Ellipsis>-opt ->

In Name/0... and Name/0...->. the zero is optional and can thus be written as Name/... and Name/...->, respectively.

programPoint
A <vp>programPoint</vp> is a value that represents a specific point in a clause. The <vp>programPoint</vp> contains the class name, the predicate name, the line number and position on the line. The <vp>programPoint</vp> domain is defined in the <vp>core</vp> class

<vp>programPoint</vp>'s are used by the exception mechanism to indicate where exceptions are raised and continued, but the usage is not limited to that purpose.

The compiler suppors <vp>programPoint</vp>'s in a special way by means of the attribute <vp>programPoint</vp>, which can be added to a predicate declaration like this:

predicates raiseAnException : (integer X) [programPoint].

Adding this attribute actually means that two predicates are declared, the one you have mentioned and an another one with name <vp>raiseAnException_explicit</vp> which in addition to the arguemnts of <vp>raiseAnException</vp> takes a <vp>programPoint</vp> as first argument:

predicates raiseAnException : (integer X). predicates raiseAnException_explicit : (programPoint ProgramPoint, integer X).

When you call raiseAnException the compiler will actually create a program point ans call raiseAnException_explicit instead.

If you have a programPoint you can directly call the explicit predicate with it.

Such code is treated in the usual way. I.e. when calling <vp>raiseAnException</vp> or <vp>raiseAnException_explicit</vp> will in both cases result in calling <vp>raiseAnException_explicit</vp>, so this is the only predicate that needs an implementation. In fact, it is illegal to state clauses for the non-explicit predicate that will never be called.

There is also a built-in predicate, <vp>programPoint/0-></vp>, which returns a <vp>programPoint</vp> corresponding to the place where it is called.

To summarize:
 * A predicate declaration with <vp>programPoint</vp> attribute actually declares two predicates. A non-explicit and an explicit predicate.
 * Calling the non-explicit predicate actually results in calling the explicit predicate with the call point as additional argument.
 * Only the explicit predicate should be implemented.

The introduction of the the <vp>programPoint</vp> feature simplifies the exception mechanism as known in Visual Prolog 7.3 and before. For example <vp>classInfo</vp> predicates are no longer needed (though they are still legal in Visual Prolog 7.4 and 7.5, but has been <vp>deprecated</vp> to ease transition).