- Document title:
- An object-oriented extension to RIF (Second Edition)
- Christian de Sainte Marie, IBM
This document, developed by the Rule Interchange Format (RIF) Working Group, specifies how RIF Core, and, followingly, RIF-BLD and RIF-PRD, are extended to cover object-oriented rule languages.
- Status of this Document
- @@update This is an automatically generated Mediawiki page, made from some sort of W3C-style spec.
RIF frames are, really, binary relations in disguise, and RIF is lacking a real notion of object, as it is used in object-oriented programming. In the following, we will use the term "frame object" to denote RIF frame objects, and "program object" to denote the kind of objects used in object-oriented programming languages.
Frame objects differ from program objects in a number of ways, that all come down to frame objects being characterised by an arbitrary collection of facts, whereas program objects are characterized by a fixed, predefined set of fact types that is characteristic of the object's class. Consequences are that:
- Program objects must be instances of a class, and that class determines the fixed set of facts that characterizes the object. On the other hand, a frame object may not verify any class membership formula, and still satisfy some frame formula;
- A program object that is an instance of a given class must have a value assigned for each of the fields that are defined for that class. On the other hand, the frame formulas that a frame object verifies bear no necessary relation to the class membership formulas that are verified by that object. A consequence is that a rule that implies that a program object has a given value for a given slot, implies ipso facto that the object has some value for all the fields defined by its class. Implying a frame formula does not have that consequence;
- Program object fields are single valued, whereas a frame object can verify frames assigning multiple values to the same field. A consequence is that a rule that implies that a program object has a given value for a given field, implies ipso facto that it is different from any program object having a different value for that same given field; that implication does not hold with respect to frame objects. Another consequence is that, in RIF active dialects, that allow assigning a value to a field in the conclusion of a rule, assigning a new value to a program object's field replaces the previous value, whereas asserting a new value for a frame object's attribute just adds the new value to the other values, if any.
Editor's Note: Does the fact that object fields are, usually, typed have any consequence, here? I do not think so.
It follows from these differences that rules that were written for program objects can be serialized using RIF frames, but frame formulas in a RIF document cannot be deserialized using program objects, in the general case, because the serialization of program objects into RIF frames is semantically lossy.
Therefore, RIF need be extended with a construct to represent program objects, if object-oriented rule languages are to be covered adequately.
This document specifies an object-oriented extension to RIF-Core, in the form of a single new construct. The next section specifies the syntax and the semantics of the extension.
Sections 3 and 4 specify how RIF-BLD and RIF-PRD, respectively, are extended to include the object-oriented extension of RIF-Core. and to take full advantage of that extension: in particular, the atomic actions specified for RIF-PRD are extended to apply to the new object construct.
This document does not specify how object models are defined or interchanged: this is orthogonal to the interchange of rules that use the object models, and, therefore, out of the scope of RIF.
An object-oriented extension to RIF Core
The abstract syntax of RIF Core is extended with an additional term construct , field value. A field value can occur anywhere a variable can occur.
Definition (Field value term). A field value has the form t1.t2, where t1 is a [ simple term], an [ externally defined term] or a field value, and t2 is a constant or an externally defined term.
The extension of the syntax of RIF Core with the field value does not affect the definition of formulas nor the well-formedness condition for formulas in RIF-Core or the definition of safeness.
Editor's Note: Or shall we allow membership relations for frame objects in the head of the extended RIF Core?
The EBNF grammar for the (non-normative) presentation syntax of RIF-Core is extended as follows:
TERM ::= IRIMETA? ( List | TERM_NOLIST ) TERM_NOLIST ::= (Const | Var | 'External' '(' Expr ')' | FieldValue) FieldValue ::= IRIMETA? TERM_NOLIST '.' (Const | Expr)
Example 2.1. Let Person be a class with three fields:
- an integer attribute, age;
- a Person attribute, spouse;
- and a method, childFromSpouse, that takes a Person argument, and returns an instance of Person, such that the returned Person is the other parent of the argument Person, who must be a child of the object instance (assume that the method returns in error if this is not the case).
CLASS Person Integer : age Person : spouse Person : childFromSpouse(Person : child)
?p.age, _John.spouse, ?p.childFromSpouse(_John) and ?p.spouse.age are four field values that represent, respectively, the value of the age attribute of an instance ?p of the class Person, the instance of the class Person that is the value of the spouse attribute of the object identified by the local constant _John, the instance of the class Person that represents the spouse with whom the Person represented by variable ?p had the child _John, and the value of the age attribute of the instance of Person that is the value of the spouse attribute of the instance of Person represented by the variable ?p.
The definition of a semantic structure, that is the basis for the model-theoretic semantics of RIF Core, is extended to include an additional mapping, IFV.
Definition (Semantic structure). A semantic structure, I, is a tuple of the form <TV, DTS, D, Dind, Dfunc, IC, IV, IF, IFV, Ilist, Itail, Iframe, Isub, Iisa, I=, Iexternal, Itruth>, where TV, DTS, D, Dind, Dfunc, IC, IV, IF, INF, Ilist, Itail, Iframe, Isub, Iisa, I=, Iexternal and Itruth are defined as in RIF Core, and IFV is a total mapping defined as follows:
- IFV maps Dind to partial function DC → Dind, where DC ⊆ Dind. This mapping interprets field value terms. An argument, o ∈ Dind, to IFV represents an object and the associated partial function maps each of that object's fields to its value: the domain, DC, of the function is the subset of Dind that interprets the identifiers of the fields that are defined by C, the most specific class to which o belongs. That is, C is the class such that all the following are true:
- o # C, and
- for all C', if o # C', then C ## C'.
Following the extension of the semantic structure I to include IFV, the convenience mapping I is extended as follows:
- I(o.f) = IFV(o)(I(f)).
Editor's Note: Do we need/want to add a special null value to Dind, to account for un-initialized objects fields?
Program objects can be represented using frame objects, although the reverse is not possible. As a consequence, RIF document using the object-oriented extension of RIF-Core can be transformed into (non-extended) RIF-Core documents. However, the transform is not semantically equivalent, since the information that the object satisfies the specific axioms of program objects is lost (each field has a value and that value is unique), and rule sets translated from the object-oriented extension into RIF Core must be reused (e.g. extended, imported) with care.
More specifically, if o denotes a program object of class C, and if f identifies a field that is defined for o, then the frame o [ f -> o.f ] is true. The transform can be expressed using the object-oriented extension of RIF Core, as follows:
Forall ?o, ?f ( ?o [ ?f -> ?o.?f ] :- Exists ?v (?o.?f = ?v) )
Example x.y. The OO extended RIF Core rule:
Forall ?x ( Adult(?x) :- External(pred:numeric-greater-or-equal(?x.age, 18)) )
can be translated into (pure) RIF Core as follows:
Forall ?x ( Adult(?x) :- External(pred:numeric-greater-or-equal(?x.age, 18)) )
Editor's Note: Transforming a statement about a field value into a statement about a frame's attribute value is more tricky when the field value results from a call to a method: it requires the introduction of a constant (e.g. a local one) for the name of the attribute, and of a new external function. For instance, the OO condition: ?x.childFromSpouse(_John) = _Jane could be translated into the pure RIF Core condition: Exists ?y ( And( ?x[_childFromSpouse -> ?y] External(my-childFromSpouse(?x, _John)) = _Jane)). Of course, the transform could be normalized: is it worth the burden?
XML serialization syntax
A field value is serialized using the FieldValue element.
The FieldValue element has two sub-elements, object and field:
- the object sub-element contains a Const element, a Var element, an External element, or a FieldValue element, that serializes the reference to the object identifier;
- the field sub-element contains
- a Const element, that serializes the name of an object attribute;
- or an Expr element, that serializes the call to an object method.
<FieldValue> <object> [ Const | Var | External | FieldValue] </object> <field> [ Const | Expr ] </field> </Fieldvalue>
Example 2.2. Continuing example 2.1, above, the field value ?p.age is serialized as follows:
<FieldValue> <object> ?p </object> <field> <Const type="XYZ"> age </Cons> </field> </Fieldvalue>
The field value ?p.childFromSpouse(_John) is serialized as:
<FieldValue> <object> ?p </object> <field> <Expr> <op> <Const type="XYZ"> chidlFromSpouse </Const> </op> <args ordered="yes"> <Const type="rif:local"> _John </Cons> </args> </Expr> </field> </Fieldvalue>
Object-oriented extension of RIF-BLD
RIF-BLD can be extended with the field value term exactly in the same way as RIF Core is.
The same restriction of the non-extended RIF-BLD that produces the non-extended RIF Core, produces the extended RIF Core, if applied to the thus extended RIF-BLD.
Editor's Note: I do not think that equality in the head is a problem, is it?
Object-oriented extension of RIF-PRD
In the same way, RIF-PRD can be extended with the field value term. In addition to the syntactic and semantic extensions inherited from the object-oriented extension of RIF Core, the object-oriented extension of RIF-PRD requires the extension of the RIF-PRD atomic actions.
Editor's Note: Proposed:
- extend Assert to assert program objects, with the effect that all the membership of the object to its class is asserted, along with all the equality facts for its fields;
- extend Retract to retract program objects with the effect that no fact involving that object is true anymore;
- add a new atomic action Modify(o.f v), where the field identifier f identifies an attribute (not a method), with the effect that the value of o.f is replaces by v. This is an atomic action, not a compound one, like the Modifying a frame: it cannot be replaced by any combination of Retract and Assert;
- extend New to take an object constructor as its argument: New(C(v1...vn)) (New(Expr)), where C is the name of a class, and v1...vn are valid values for a constructor of that class, returns a handle to a new object of class C, initialized according to the (external) semantics of the constructor.