Main
About us
Members
Papers
Projects
Contact
Demo Podcasts and Posters
Using RIF to Interchange F-Logic Rules and Drools
F-Logic and Drools
The Negotiating eBusiness Contracts Across Rule Platforms Use Case illustrates the usage of RIF to supply a vendor-neutral representation of rules, so that rule-system developers can do their work without concern about a vendor-specific format and in particular without concern about the compatibility with the technology of its business partners.
Below are two rules from the use case:
- Rule R1: If an item is perishable and it is delivered more than 10 days after the scheduled delivery date then the item will be rejected.
- Rule R2: If an item is perishable and it is delivered more than 7 days after the scheduled delivery date but less than 14 days after the scheduled delivery date then a discount of 18.7% will be applied to this delivery.
Contents[hide] |
Rules are working on top of vocabularies
First we need to understand the vocabulary on which these rules act i.e. what is an item, scheduled delivery etc. Therefore first I have to develop the rules vocabulary.
Different developers may choose different vocabulary languages do do that. Some of them may choose RDFS, some others may choose OWL or UML. By consequence:
- RIF needs to deal with different vocabularies.
- RIF needs an uniform mechanism to address vocabulary elements. The usage of URI's may be such a mechanism.
- Vocabulary and rules are separate layers
In this document I will use RDFS to represent an excerpt from the entire use case vocabulary.
We assume that:
- Jane's e-commerce system uses Drools therefore the rules vocabulary is represented using Java beans and
- John uses an OWL vocabulary and its rules are represented in F-Logic.
Below is an excerpt from the John's OWL vocabulary:
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:owl="http://www.w3.org/2002/07/owl#" xmlns="http://www.example.org/JohnSystem/vocabulary"> <owl:Class rdf:ID="Item"/> <owl:DatatypeProperty rdf:ID="perishable"> <rdfs:domain rdf:resource="#Item"/> <rdfs:range rdf:resource="xs:boolean"/> </owl:DatatypeProperty> <owl:DatatypeProperty rdf:ID="actualDeliveryDate"> <rdfs:domain rdf:resource="#Item"/> <rdfs:range rdf:resource="xs:date"/> </owl:DatatypeProperty> <owl:DatatypeProperty rdf:ID="scheduledDeliveryDate"> <rdfs:domain rdf:resource="#Item"/> <rdfs:range rdf:resource="xs:date"/> </owl:DatatypeProperty> <owl:DatatypeProperty rdf:ID="status"> <rdfs:domain rdf:resource="#Item"/> <rdfs:range rdf:resource="Status"/> </owl:DatatypeProperty> <owl:DatatypeProperty rdf:ID="discount"> <rdfs:domain rdf:resource="#Item"/> <rdfs:range rdf:resource="xs:double"/> </owl:DatatypeProperty> <owl:Class rdf:ID="Delivery"/> <owl:Class rdf:ID="Status"> <owl:oneOf rdf:parseType="Collection"> <rdf:List> <rdf:first rdf:datatype="xs:string">rejected</rdf:first> <rdf:rest> <rdf:first rdf:datatype="xs:string">accepted</rdf:first> </rdf:rest> </rdf:List> </owl:oneOf> </owl:Class> </rdf:RDF>
Encoding of Rules
John Rules (F-Logic)
//If an item is perishable and it is delivered more than 10 days //after the scheduled delivery date then the item will be rejected RULE R1 I:item[status -> "rejected"] <- I:item[isPerishable -> true] AND I[actualDeliveryDate -> A] AND I[scheduledDeliveryDate -> S] AND R is (A - S) AND R > 10. //If an item is perishable and it is delivered more than 7 days after the scheduled delivery date //but less than 14 days after the scheduled delivery date //then a discount of 18.7% will be applied to this delivery. RULE R2 I:item[discount -> 18.7] <- D:delivery[hasItems->>Items] AND I:item[isPerishable -> true] AND I[actualDeliveryDate -> A] AND I[scheduledDeliveryDate-> S] AND member(I, Items) AND R is (A - S) AND R > 7.
Jane's Rules (Drools)
package com.sample import com.sample.Item; rule "R1" when i : Item(isPerishable==true, actualDeliveryDate : actualDeliveryDate, scheduledDeliveryDate : scheduledDeliveryDate ) eval( actualDeliveryDate.getDay() - scheduledDeliveryDate.getDay() > 10) then i.isRejected(true); modify(i); end rule "R2" when d:Delivery(hasItems: hasItems) i : Item(actualDeliveryDate : actualDeliveryDate, scheduledDeliveryDate : scheduledDeliveryDate ) eval( (actualDeliveryDate.getDay() - scheduledDeliveryDate.getDay() > 7) && hasItems.contains(i)) then i.setDiscount(18.7); modify(i); end
We assume that the function getDay()
is defined in a DeliveryDate
Java bean where all processing of time and dates is performed. This function is supposed to return an integer.
Interchanging of Rules
Importing Jane's Rules in the John's rule system
Translating from Drools into RIF
Since Jane's Rules are based on Java Beans all corresponding beans must be created from John's vocabulary. Therefore an interchange of vocabularies have to be performed.
We use the Presentation syntax provided by the RIF-BLD proposal. The reader may notice that Jane's Rules are Drools therefore production rules and RIF-BLD provides derivation rules therefore this translation has some limitations. Fortunately in the
use case the rules are quite simpler: for example, the action part of Jane's rule R1 is a simple assign action as in OMG PRR (beta 1 specification, 4 November 2007). Therefore in the future this translation must be modified according with the RIF-PRD specification.
Below is the translation of Jane's Drools Rules rules into RIF. This translation is one from probably many other solutions:
rule "R1" when i : Item(isPerishable==true, actualDeliveryDate : actualDeliveryDate, scheduledDeliveryDate : scheduledDeliveryDate ) eval( actualDeliveryDate.getDay() - scheduledDeliveryDate.getDay() > 10) then i.isRejected(true); modify(i); end // Translation to RIF Rule ("http://jane.com/R1" ?i#Item[(isRejected->"true"^^xs:boolean) :- And(?i#Item[(isPerishable->"true"^^xs:boolean) (actualDeliveryDate->?actualDeliveryDate ) (scheduledDeliveryDate ->?scheduledDeliveryDate)] op:numeric-greater-than( op:numeric-subtract( user-defined:getDay(?actualDeliveryDate), user-defined:getDay(?scheduledDeliveryDate) ), "10"^^xs:int ) ) )
While the usual Drools column (i.e i : Item(isPerishable==true,...)
) is straightforward to be translated into RIF-BLD frames the Drools eval()
is more complex to be implemented since actually the RIF Data Types and Built-Ins do not provide information about potential user-defined functions. Here we suppose the user-defined function
user-defined:getDay()
performing the same functionality as in Jane's Java Bean DeliveryDate
.
The Java constant true
is mapped into "true"^^xs:boolean
. Also the Java int 10
is mapped into the literal "10"^^xs:int
.
Therefore RIF have to solve the extensibility issue of user-defined functions.