Language Reference/Properties

From wiki.visual-prolog.com

The properties section declares a set of object or class properties in the current scope.

Properties sections

A properties section declares a set of object or class properties in the current scope.

PropertiesSection :
   class-opt properties PropertyDeclaration-dot-term-list-opt

The keyword class can be used only inside class implementations, since:

  • properties declared in an interface are always object properties and
  • properties declared in a class declaration are always class properties.

Peoperty Declaration

PropertyDeclaration :
    PropertyName : PropertyType FlowPattern-list-opt
FlowPattern: one of
    (i)
    (o)

The properties are declared similar to single facts.

If flow patterns are skipped, both (i) and (o) are assumed.

For example:

interface ip
properties
   duration : integer.
   initialized : boolean.
   scale : string.
end interface

The properties are used exactly like single facts inside the implementation. It is possible to qualify properties for a scope name or object.

X is an object that supports the interface ip

X:duration := 5,
if X:initialized = true then ... else ... end if,
X:scale := "meter",
....

Inside an implementation of ip you access the properties as if they were facts.

duration := 5,
if initialized = true then ... else ... end if,
scale := "meter",
....

Implementation

You implement a property by defining a function for getting the value and an appropriate predicate to set it.

E.g.,

clauses
    duration() = duration_fact * scale.
    duration(D):- duration_fact := D/ scale.

Or as a fact with the same name as the property

facts
    initialized : boolean := false.

You cannot have set and get predicates and a fact with the same name. So if you want a fact, which stores the value of the property, which often is the case, you will have to give this fact another name e.g.:

properties
    duration : integer.
facts
    duration_fact : integer.
clauses
    duration() = duration_fact.
clauses
    duration(D) :-
        OldDuration = duration_fact,
        duration_fact := D,
        OldDuration <> D,
        !,
        sendChanged().
    duration(_D).

You cannot use the duration predicates as predicates (not surprisingly they are not declared as predicates, but as a property; it is just the way the get- and set-methods of the property are implemented).

But in the predicate names are taken - so you cannot declare a predicate duration\1 or duration\0->.

Implementation Detail

When you access a property declared in an interface, you cannot make any assumptions about how it is implemented; so you have to assume that it is implemented with predicates.

So if the programmer has defined the property as a fact, the compiler will have to generate the proper predicates. And use them, when accessing the property through an interface.

Inside the implementation, a property defined as a fact can be accessed simply as a fact.

Read or Write Restrictions

Sometimes you want to have a property, which can only be read or written to.

Assume we declare them with an i/o pattern as:

duration : integer (o).     % a read only property
duration : integer (i).     % a write only property
duration : integer (o) (i).     % a normal property, which can be both written to and read from. This is equivalent to not writing anything
duration : integer.     % equivalent to the declaration above.

If a property is declared as a read-only property, you only need to declare the get predicate and likewise if it is declared as write-only only the set predicate.

Of course if you implement the property as a fact then the fact can be used as a normal fact inside the implementation.

Properties from Interface

An interface can support a subset of another interface by stating the properties in a properties from section. The properties from section names the interface and all supported properties.

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 properties from section is that the mentioned properties retain their origin interface. Therefore:

  • there will be no support conflict with any properties from the origin interface;
  • they can be inherited as the properties from the origin interface.
PropertiesFromInterface :
    properties from InterfaceName PpropertyName-comma-sep-list-opt

PropertiesFromInterface can only be used in interface definitions.

Example
interface aaa
   properties
       pp : integer.
       qq : boolean.
end interface aaa
 
interface bbb
   properties from aaa
       pp
   properties
       rr : string.
end interface bbb
 
interface ccc supports aaa, bbb
end interface ccc

Even though aaa and bbb both declare a property pp, ccc can support them both without any conflicts, because pp has aaa as an origin interface in all cases.

Example
interface aaa
   properties
       pp : integer.
       qq : boolean.
end interface aaa
 
interface bbb
   properties from aaa
       pp
   properties
       rr : string.
end interface bbb
 
class aaa_class : aaa
end class aaa_class
 
class bbb_class : bbb
end class bbb_class
 
implement aaa_class inherits bbb_class
   facts
       pp_fact(): integer.
   clauses
       pp()= pp_fact-3.
   clauses
       pp(D):- pp_fact:=D+3.
end implement aaa_class

aaa_class can inherit pp from bbb_class, because pp in both classes has aaa as origin interface.