Frames provide a way of representing and manipulating complex
objects. There are two main features of frame systems:
Procedural Attachment |
Inference in a frame system is performed on an ad hoc basis by attaching procedures to the attributes of an object. These procedures are triggered depending on how the attribute is accessed. |
Inheritance |
Like all object-oriented systems, instance frames can inherit properties from generic frames in a hierarchy. iProlog supports multiple inheritance. |
In iProlog, frames are stored in Prolog's database and their contents can be queried and matched in the same way as other data. This section describes a front-end to iProlog that provides a convenient syntax for manipulating frames.
The structure of a generic frame is shown below
frame_name ako inheritance-list slot1: facet11 demon11 facet12 demon12; slot2: facet21 demon21 facet22 demon22!
cylinder ako object with height: range number(new value) and new value > 0 help print("Height must be a positive number") if_needed ask if_removed remove volume from this cylinder cache yes; radius: range number(new value) and new value > 0 help print("Radius must be a positive number") if_needed ask if_removed remove cross_section from this cylinder cache yes; cross_section: if_needed pi * radius of this cylinder ** 2 if_removed remove volume from this cylinder cache yes; volume: if_needed cross_section of this cylinder * height of this cylinder cache yes!
Generic frames describe generic objects, e.g. person, physical object, etc. A frame's attributes (slots) may be explicitly listed within the frame definition or they may be inherited from a generic frame. The value of "ako" contains a list of generic frame names from which slots can be inherited. In the example above, the "cylinder" frame can inherit attributes from the "object" frame.
A slot in a generic frame contains a list of facets and demons. Facets are labels which identify the type of demon. The allowable facets are described in the Reference Manual. Demons are procedures that are attached to slots and are triggered automatically by different kinds of accesses to the frame. They are written in Prolog.
The inheritance specification may be a single name such as object in the example above, or it may be a list. e.g.. [cylinder, container]. This means that the object would inherit all the properties of cylinder and container. The inheritance lists are searched left-to-right and depth-first. If there is more the one parent frame with the same slot name, the first one encountered is used.
frame-name isa inheritance-list with slot1: value1; slot2: value2; ................ slotN: valueN!
c isa cylinder with height: 2; radius: 4!
Instance frames describe instances of generic frames, i.e. cylinders, etc. The inheritance list, following the isa keyword contains a list of the names of the generic frame names from which the frame can inherit slots. Whenever a slot cannot be found within an instance frame, inheritance is applied. iProlog searches the inheritance hierarchy looking for a particular slot. However, instead of containing an actual value, the slot will contain a procedure for computing the corresponding value.
iProlog allows multiple inheritance, i.e. a frame may inherit attributes from more than one frame. The inheritance hierarchy is then searched in a depth-first, left-to-right manner.
Create a generic frame |
|
Create an instance frame |
|
Retrieve a slot value |
|
Add a new slot value |
|
Replace a slot value |
|
Remove a slot |
a predicate that checks a new value being added to slot |
|
a predicate that is invoked if range check fails |
|
a predicate invoked when instance frame is created |
|
a function that is invoked when a slot value needs to be computed |
|
a predicate that is invoked when a new value is added to a slot |
|
a predicate that is invoked when a slot value is replaced |
|
a predicate that is invoked when a slot is removed from an instance frame |
|
if the value if yes, the value computed by if_needed is stored in the instance frame |
|
if yes, allow a slot to contain a list of values |
|
Similar to if_needed, except that slot value is not evaluated |
if ... then ... else |
conditional expression which is a function (i.e.. returns a value) |
ask |
prompt the user to enter a value |
new value |
the new value being added to a slot |
old value |
the old value of the slot (prior to the current operation) |
X in List |
determinate list membership predicate (but as a user-friendly infix operator) |
Lo .. Hi |
a predicate that tests if |
must_be_a Generic |
a predicate that succeeds if new slot value is a Generic type |
yes |
a dummy value for the cache and multivalued slots |
make [GenericList] |
creates a new frame that is an instance of the list of generic frames specified in GenericList |
this GenericName |
refers to the current object |