Difference between revisions of "Language Reference/Properties"

From wiki.visual-prolog.com
m (header levels)
m (spell & grammar)
Line 21: Line 21:
properties
properties
   duration : integer.
   duration : integer.
   initialised : boolean.
   initialized : boolean.
   scale : string.
   scale : string.
end interface</vip>
end interface</vip>
Line 30: Line 30:


<vip>X:duration := 5,
<vip>X:duration := 5,
if X:initialised = true then ... else ... end if,
if X:initialized = true then ... else ... end if,
X:scale := "meter",
X:scale := "meter",
....</vip>
....</vip>
Line 37: Line 37:


<vip>duration := 5,
<vip>duration := 5,
if initialised = true then ... else ... end if,
if initialized = true then ... else ... end if,
scale := "meter",
scale := "meter",
....</vip>
....</vip>
Line 54: Line 54:


<vip>facts
<vip>facts
     initialised : boolean := false.</vip>
     initialized : boolean := false.</vip>


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.:
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.:
Line 73: Line 73:
     duration(_D).</vip>
     duration(_D).</vip>


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).
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->.
But in the predicate names are taken - so you cannot declare a predicate duration\1 or duration\0->.

Revision as of 12:32, 21 October 2008

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

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.