defineClass/1 — specify an ObjectPro class
:- defineClass(SpecEqns) .
Used as a directive to specify an ObjectPro class.
SpecEqns is a list of equations of the form
Keyword = Value
The acceptable keywords, together with their associated
Value types, are the following :
name - atom
subclassOf - atom (name of an existing class to serve as parent)
addl_slots - list of atoms (to serve as names of local slots)
defaults - list of default values for slots
constrs - list of constraint expressions for slots
export - yes [or] no
action - atom
The name equation and the subclassOf equation are both required. The single top-level pre-defined class is called
genericObjects. Atoms on the addl_slots list specify slots in the structure defining the state of objects which are instances of this class. These slot names must be distinct from slot names in any of the ancestor classes from which the new class inherits. The __state-schema__ of a class is the union of the local addl_slots of the class with the addl_slots of all classes of which the class is a subclass. An object which is instance of a class has a slot in its state structure corresponding to each entry in the state-schema for the class.
Class definitions can supply default values for slots using an equation of the type
defaults = [..., <SlotName> = <Value>, ...]
where each <
SlotName> is any one of the slot names from the complete state schema of the class, and <
Value> is any appropriate value for that slot. Omitting this keyword in a class definition is equivalent to including
defaults = 
export = yes equation appears on
SpecEqns, the class methods and other information concerning the class are exported from the module in which the directive is executed.
The constraints equation is used to impose constraints on the values of particular slots in the states of objects which instances of the class. The general form of a constraint specification is
constrs = list of constraint expressions
Three types of constraint expressions are supported:
slotName = value
slotName < valueList
slotName - Var^Condition
The left side of each of the the equations is the name of a slot occurring in the complete state-schema of the class being defined. The first two types of expressions are special cases of the third.
In the first constraint expression,
slotName = value,
value is any Prolog term, and specifies a fixed value for this slot.
The second constraint expression,
slotName < valueList, requires the values installed under
slotName to be among the Prolog terms appearing on the list
'<' is a short hand for ‘is an element of’.
The third constraint expression subsumes the first two.
Var is a Prolog variable, and
Condition is an arbitrary Prolog call in which
Var occurs. The test is imposed by binding the incoming candidate value to the variable
Var, and then calling the test
Conditon. Installation of the incoming value in the slot named
slotName takes place only if the test
If an equation
action = Name occurs on
Name is an atom, then methods of this class must be implemented by a binary predicate
Name/2. If this equation is absent, the methods predicate for this class will be
<className> is the name of the class(i.e.,
name = <className> occurs on
SpecEqns). The format of the calls to this predicate is
<className> Action(Message, State)
State is the state of an object of this class, and
Message is an arbitrary Prolog term.
The structure of a State is opaque. Access to the slots is provided by two predicates:
setObjStruct(SlotDescrip, State, Value) accessObjStruct(SlotDescrip, State, VarOrValue)
SlotDescrip is a slot description, which is either a slot name, or an expression of the form
The latter is used in cases of compound objects in which the value installed in a slot may be the state of another object. Thus,
<what>ObjStruct(Slot1^Slot2, State, Value)
is equivalent to
accessObjStruct(Slot1, State, Obj1), <what>ObjStruct(Slot2, Obj1, Value)
setObjStruct(SlotName, State, Value)
destructively updates the slot
State to contain
Value, provided that:
Valueis not an uninstantiated variable, and
- any constraints imposed on this slot by the class are satisfied by the incoming
However, note that
Value can be a term containing uninstantiated variables.
The second call
accessObjStruct(SlotName, State, ValueOrValue)
accesses the slot
State and unifies the value obtained with
VarOrValue. For compactness, the following syntactic sugar is provided:
State^SlotDescrip := Value
setObjStruct(SlotDescrip, State, Value)
VarOrValue := State^SlotDescrip
accessObjStruct(SlotDescrip, State, VarOrValue)
The bodies of clauses defining the action predicate of a class can contain calls on
send_self/2, and any other built-in or program-defined Prolog predicate.
:- defineClass( [ name = stacker, subclassOf = [genericObjects], addl_slots = [theStack, depth] ] ). stackerAction(push(Item), State) :- accessObjStruct(theStack, State, CurStack), setObjStruct(theStack, State, [Item | CurStack ]), accessObjStruct(depth, State, CurDepth), NewDepth is CurDepth + 1, setObjStruct(depth, State, NewDepth). stackerAction(pop(Item), State) :- accessObjStruct(theStack, State, [Item | RestStack ]), setObjStruct(theStack, State, RestStack), accessObjStruct(depth, State, CurDepth), NewDepth is CurDepth - 1, setObjStruct(depth, State, NewDepth). stackerAction(cur_stack(Stack), State) :- accessObjStruct(theStack, State, Stack). stackerAction(cur_depth(Depth), State) :- accessObjStruct(depth, State, Depth). ...create_object([name=stack, instanceOf=stacker, values=[theStack=, depth=0] ], Obj),...