The RIF-PRD action language determines what can appear in the action part in a rule supported by RIF-PRD.
In the first part of this section, the syntax of RIF-PRD action language is specified non-normatively: the normative reference for the XML syntax is the [ XML schema].
In the second part, the normative semantics of RIF-PRD action language is specified.
*** Difference wrt RIF-BLD: all the constructs in this section are specific to RIF-PRD. ***
*** What about truth maintenance capabilities in many PR systems ***
Syntax
The overall structure of the syntax used in the RIF-PRD action language is depicted on the following diagram.
*** Except for the different names, the missing abstract class that groups the Assert, Remove and Update actions, and the possibility to Assign a value to a (ruleset) variable (which are not defined in this draft), the ACTION abstract class is copied from the ImperativeExp abstract class that specifies the actions in the OMG [ PRR OCL] specification. ***
RIF-PRD defines one single abstract class for actions: ACTION, that is realised by five concrete constructs:
the Assert, Remove and Update constructs are associated with an ATOMIC that represents the target of the eponym actions;
the Execute construct is associated with a TERM that identifies the operation to be executed, and zero or more TERMs that represent the arguments with which the operation is to be executed;
the Assign construct is associated with a Frame that represents the target object and slot, as well as the new value to be assigned.
*** Should other actions be considered in RIF-PRD? Esp., do we need some basic programatic constructs, such as a loop? ***
The following sections specify each construct separately, grouped by abstract syntactic classes. Each element is given an XML syntax, in the form of a BNF pseudo schema; a presentation syntax, in the form of an EBNF production; and an informal semantics. None of these is normative: the normative XML syntax is given in the [ RIF-PRD XML schema] and the normative semantics is given in the section [ Operational semantics].
ACTION
The ACTION class of constructs is used to represent the actions that are intended as a consequence of firing a production rule.
This version of RIF-PRD covers five ACTIONs: Assert, Remove, Update, Execute and Assign.
XML Syntax. As an abstract class, ACTION is not associated with specific XML markup in RIF-PRD instance documents. It is specified in the normative schema as a substitution group.
*** ...Substitution group or another construct, depending on how we handle extensibility in the XML schema. ***
[ Assert | Remove | Update | Execute | Assign ]
Presentation syntax.
ACTION ::= Assert | Remove | Update | Execute | Assign
Assert
The Assert construct is used to represent actions that result in asserting an atomic statement.
XML Syntax. The Assert element has one target sub-element that contains a construct from the ATOMIC group, which represents the atomic statement to be asserted on implementing the action.
*** Are there any restriction on the kind of ATOMIC that can be Assert-ed? E.g. what would it mean to Assert an Equal or an ExtTerm? Shall we allow Member and Subclass ATOMICs to be Assert-ed?***
*** Issues: ATOMIC might not be the right way to represent the target anyway: what about the case where a new individual has to be created? Use, by convention, the assertion of an anonymous frame (that is, a frame where the object is the name of a class, not an individual)? ***
*** Or remove the Assert construct and interpret an ATOMIC as an ACTION as an assert? That would improve PRD/BLD/Core compatibility at the synatctic level. What would be the drawbacks? ***
<Assert> <target> ATOMIC </target> </Assert>
Presentation syntax.
Assert ::= ' ASSERT ( ' ATOMIC ' ) '
Informal semantics. The Assert contruct is used to represent actions that result is an atomic statement, represented by the ATOMIC content of the Assert's target sub-element, being true; and that have no effect if that atomic statement was already true before the action.
*** What about nested Frames, if they are allowed as a target ATOMIC? ***
Remove
The Remove construct is used to represent actions that result in negating an atomic statement.
XML Syntax. The Remove element has one target sub-element that contains a construct from the ATOMIC group that represents the atomic statement to be removed on implementing the action.
*** Are there any restriction on the kind of ATOMIC that can be removed? E.g. what would it mean to remove an Equal or an ExtTerm? Should we allow a Member or a Subclass ATOMIC to be Remove-ed? ***
*** Issue: ATOMIC might not be the right way to represent the target anyway: e.g. how to Remove an individual (if empty Frames are not allowed)? ***
<Remove> <target> ATOMIC </target> </Remove>
Presentation syntax.
Remove ::= ' REMOVE ( ' ATOMIC ' ) '
Informal semantics. The Remove contruct is used to represent actions that result is an atomic statement, represented by the ATOMIC content of the Remove's target sub-element, not being true anymore; and that have no effect if that atomic statement was not true before the action.
*** Issue: How to remove multiple facts at once? E.g. Remove-ing an individual: use empty frames (if allowed) as a convention? ***
*** What about nested Frames, if they are allowed as a target ATOMIC? ***
Update
The Update construct is used to represent actions that result in updating an atomic statement.
XML Syntax. The Update element has one target sub-element that contains a construct from the ATOMIC group that represents the atomic statement to be updated on implementing the action.
<Update> <target> ATOMIC </target> </Update>
Presentation syntax.
Update ::= ' UPDATE ( ' ATOMIC ' ) '
Informal semantics. From the specification of OMG PRR-OCL [ PRR]: "Some operations modify the state of objects and others do not. If the modified objects are in the scope of the engine, the engine must be notified that the objects state has been modified to be able to compute the list of eligible rules. It is not possible from the operation call to determine automatically what objects will be modified so it may be necessary in the rule to explicitly notify the engine."
*** Issues: The Update as an action is specific to some rule engine technologies or implementations (e.g. RETE-based). Since it is required by such implementations only because of the opaque nature of the Execute actions with respect to the modification of ATOMICs, and since the specification of the procedural attachments to be Execute-ed requires a specific interchange channel anyway (as builtins or depending on an out-of-band agreement), should not the information relevant to any ATOMIC impacted by an Execute-ed procedure, and thus to required updates for engines that use them, rather be interchanged as part of the specification of said procedures? And Update not be covered by RIF-PRD, as a consequence? ***
*** What about nested Frames, if they are allowed as a target ATOMIC? ***
Execute
The Execute is used to represent actions that result in the execution of a procedural attachment.
XML Syntax. The Execute element has one op sub-element that represents the symbol of the procedural attachement to be executed on implementing the action, followed by zero or more arg sub-elements that represent its arguments:
The content of the op element must be a construct of the TERM abstract class;
*** Or should the op element be restricted to a Const instead? ***
The content of the arg elements must be constructs from the TERM abstract class. The order of the arg elements is significant and MUST be preserved.
*** Or use the ExtTerm construct instead (AdrianP)? But how about (i) the amiguity with fixed interprestation predicates; (ii) asserted ATOMICs if we remove the Assert construct? ***
<Execute> <op> TERM </op> <arg> TERM </arg>* </Execute>
Presentation syntax.
Execute ::= ' EXECUTE { ' op ' ( ' arg* ' ) } '
Builtin operations. TBD
*** Should RIF-PRD have builtin executable operations (e.g. print etc) or should they be left to be the application specific? ***
Informal semantics. The Execute contruct is used to represent actions that result in the execution a procedural attachement, identified by the TERM content if the Execute's op sub-element and applied to the arguments represented by the TERM content of its arg sub-elements, if any. The value that results from executing the procedural attachment, if any, is lost, so that only the possible side-effects have an impact. Resulting changes may or may not impact the truth value of other statements.
The semantics of the procedural attachments is always specified outside of a RIF instance document where they appear.
The op TERM must represent a constant symbol of type rif:iri that must uniquely identify the operation to be applied to the arg TERMs. It can be one of the builtin operations specified for RIF-PRD, or it can be application specific. In the latter case, it is up to the producers and consumers of RIF-PRD rulesets that reference non-builtin operationsto agree on their semantics.
Arguments out of the domain of definition. An operation can be successfully executed only if its arguments are within the operation's domain of definition. For arguments out of its domain of definition, the result of executing an operation is not defined.
RIF-PRD does not specify any expected behaviour for that case: it is the responsibility of the consummer of a RIF-PRD ruleset to know the expected behaviour or to handle the error.
Assign
The Assign construct is used to represent actions that result in a value being assigned to a property of an individual.
XML Syntax. The Assign element has one target sub-element that contains a Frame that represents an object-attribute-value, where the "value" has to be assigned to the "attribute" of the "object" on implementing the action.
*** Only basic frames should be allowed, right? ***
*** Or reuse the Equal construct (AdranP)? But that would be with a different semantics ***
*** How will values be assigned to parameters (if and once we add them)? ***
<Assign> <target> Frame </target> </Assign>
Presentation syntax.
Assign ::= ' SET ( ' Frame ' ] ) '
Informal semantics. The Assign contruct is used to represent actions that result in assigning a value to a given property of a given individual, as represented by the Frame content of the Assign's target sub-element, replacing the previous one, if any; and that have no effect otherwise.
In other terms, the represented action results in the atomic statement represented by the Frame content of the Assign's target sub-element being true, and in any conflicting atomic statement about the value of the same property for the same individual not being true anymore.
*** Assign is equivalent to Remove-ing the Frame with the previous value and Assert-ing the target Frame instead, except that you do not have to care about representing the previous value, right? ***
*** What if the individual does not exist? Is the Assign-ement equivalent to Assert-ing the target Frame, or is it a no-op? ***
*** What if the individual has several values for the property? ***
Operational semantics
Data sources
The operational semantics of the ACTION constructs is specified with respect to the state of the specified data sources (or fact base) after the actions they represent have been implemented.
For the purpose of specifying the operational semantics of RIF-PRD, the data sources are considered collectively to be a collection of ground ATOMICs named WM: as specified in section [ operational semantics of CONDITIONs], the WM is assumed to represent explicitely, in the form of ground ATOMICs, all the relevant information and knowledge that is available to the consumer of a RIF-PRD instance document.
In particular, the WM is assumed to contain a special Executable element, defined, for the purpose of specifying the operational semantics of the RIF-PRD action language only, to contain the set of ground Execute statements, where the Const content of the op and args sub-elements represent a (ground) procedural attachments that has a semantics.
*** How do we reference data sources? At what level: ATOMIC? CONDITION/ACTION? RULE? RuleSet? RIF instance document? ***
Implementors are responsible for making sure that the RIF-PRD translation of action statements preserves their native semantics, according to the operational semantics for RIF-PRD ACTIONs that is specified below, and subject to a consistent translation of the specified data sources.
Conformant implementations MUST translate ACTIONs retrieved from RIF-PRD in such a way that their native evaluation against the specified data sources preserves their semantics, according to the operational semantics for RIF-PRD ACTIONs that is specified below, and subject to a consistent translation of the specified data sources.
The following sections specify the normative operational semantics of each construct separately, grouped by abstract syntactic classes.
ACTION
The sections below specifies the operational semantics of the constructs of the ACTION class, where they have one.
An ACTION does not have an operational semantics in RIF-PRD if any of its sub-element does not have an operational semantics in RIF-PRD.
*** What happens when a ACTION "does not have an operational semantics in RIF-PRD"? ***
An ACTION that does not have an operational semantics in RIF-PRD cannot be successfully implemented.
Assert
The successful implementation of an Assert ACTION results in the ATOMIC content of its target sub-element being true.
Remove
The successful implementation of a Remove ACTION results the ATOMIC content of its target sub-element not being true.
Update
The successful implementation of an Update ACTION results in TBD
Execute
An Execute element E matches a ground Execute sub-element E_g in the Executable element of the WM iff:
the TERM content of the op sub-element of E matches any Const that matches the Const content of the op sub-element of E_g;
and the TERM content of each of the arg sub-elements of E matches any Const that matches the Const content of the same position arg sub-element of E_g.
An Execute element that does not match a ground Execute sub-element in the Executable element of the WM does not have an operational semantics in RIF-PRD.
The successful implementation of an Execute ACTION results in the operation executed by the Const content of op sub-element of the ground Execute sub-element of the Executable element of the WM that the Execute ACTION matches being executed with the arguments represented by the TERM content of its arg sub-elements.
*** ...that is, if the ACTION has a semantics, of course: should that be said explicitely again? ***
The successful implementation of an Execute ACTION may or may not have side-effects that may or may not result in changes in the WM: the effects that are intended from the execution of RIF-PRD builtin opérations are specified in [ the section where the are specified]. It is the responsibility of the consumer of a RIF-PRD instance document to know what are the intended effects of executing application-specific operations.
Assign
The successful implementation of an Assign ACTION results in:
the Frame contained in its target sub-element being true; and
any Frame being false, if the content of its object and slotKey sub-elements match, respectively, Consts that match the same Consts as the content of the object and slotKey sub-elements of the Frame content of the Assign's target, and the content of its slotValue sub-element matches a Const that the slotValue sub-element of the Frame content of the Assign's target does not match.
*** The option taken here is that, if the object of the target Frame does not exist, the Assign functions as an Assert: is that the usual interpretation? ***
*** The second bullet must be removed if Frames are allowed multiple slotValues for the same slotKey. ***