Warning:
This wiki has been archived and is now read-only.

PRD Working Examples

From RIF
Jump to: navigation, search

Back to PRD Discussions Page

This page is dedicated to host examples for PRD.

We need more examples in our discussions to better illustrate and to improve our understanding of PRD's capability.

We need some examples of frames, of RDF / OWL, of simple rules and more complex rules. We should also agree on what to support and what not to support, and provide associated examples.

A "not" example by Changhai Ke

PRD needs to support the "not" condition, illustrated by the following example.

A customer is identified by an ID, and an account associated to a customer has the same ID (we have a join here). We want to write a rule "if there is a customer and there is no account associated to the customer, then create an account". The rule is expressed in JRules this way:

  when {
     Customer(?id: id)
     not Account(id == ?id);
  } then {
     assert Account() { id = ?id; }
  }

In this rule, the condition part expresses that in the working memory, there must not be any Account object such that its ID equals to the one of the customer.

If the working memory contains these objects:

  O1: Customer (id = 22);
  O2: Customer (id = 15);
  O3: Account (id = 30);
  O4: Account(id = 22);

Then the rule will be fireable on the object O2, because there is no account object with the ID 15.

Can this be expressed in PRD?

First attempt by csma

Forall ?customer ?id 
       (?customer#Customer)
       (?customer[id->?id)
    If Not(Exists ?account And(?account#Account) (?account[id->?id])))
    Then Do((?account New(?account)) Assert(?account#Account) Assert(?account[id->?id]))

According to the operational semantics, if the rule set contains only that rule:

  • Cycles
    1. the only matching instance that satisfies the condition: (O2/?customer 15/?id), is fired, and adds object O5: Account(id = 15) to the WM;
    2. Cycle 2: no matching instance satisfies the condition, the system stops. The resulting WM is:
  O1: Customer (id = 22);
  O2: Customer (id = 15);
  O3: Account (id = 30);
  O4: Account(id = 22);
  O5: Account(id = 15);

Comment from cke

Although this can be expressed, I notice the complexity of the syntax. Can we simplify it? Also the "forall" could be in conflict with the forall for aggregates. Here, "forall" means FOR EACH ONE that satisfies the conditions, the rule can be applied. The "forall" used in aggregation means "forall the objects determined by a scope qualifier, verify that all of them satisfy some conditions". The rule is then applied only once if the condition is true.

More on forall CE from Clips and Jess: