W3C home > Mailing lists > Public > public-rif-wg@w3.org > July 2008

Re: [PRD] Default conflict resolution strategy (ISSUE-64) (Was; Re: [Fwd: Re: PRD Review])

From: Gary Hallmark <gary.hallmark@oracle.com>
Date: Tue, 29 Jul 2008 21:25:09 -0700
Message-ID: <488FED25.6010609@oracle.com>
To: Mark Proctor <mproctor@redhat.com>
CC: Christian de Sainte Marie <csma@ilog.fr>, RIF WG <public-rif-wg@w3.org>

I don't think Jess no-loop is easily simulated because I don't think it 
is easy to express in the PRD semantic framework.  I'm not overly 
concerned about no-loop because I think the Jess no-loop declaration is 
somewhat ill-conceived. I am more concerned that one of the reasons that 
no-loop seems hard to express is that the agenda and working memory are 
updated after a picked sequence of actions is run to completion, rather 
than the more usual semantics that the agenda and working memory are 
updated after each action.  This could be problematic if we have actions 
that internally access the agenda or WM (e.g. a print-agenda builtin or 
a counter increment builtin)

Mark Proctor wrote:
> (deftemplate person (slot age) )
> (defrule rule1 (declare (no-loop TRUE)) (person (age ?a) ) => (assert 
> (person (age (+ ?a 1) ) ) ) (printout t fire " " rule1) )
> (assert (person (age 200) ) )
> (run)
> I made the above example to test our Jess. What do we do about clips? 
> I guess no-loop can be simulated with objects acting as semaphores on 
> the LHS pattern constraints.
> Mark
> Gary Hallmark wrote:
>> Christian de Sainte Marie wrote:
>>> Gary Hallmark wrote:
>>>>> Mark Proctor wrote:
>>>>>> Refaction in JRules is the same as jess/clips/drools no-loop. 
>>>> I'd be surprised if it is exactly the same.   What do you expect 
>>>> from the following ruleset:
>>>> p(1)
>>>> q(1)
>>>> q(2)
>>>> (* rule1[loop->false] *)
>>>> Do(external(print("rule1 fired, ?x=" ?x))) :- q(?x)
>>>> (* rule2[loop->false] *)
>>>> Do(Retract(p(1)) p(1) external(print("rule2 fired, ?x=" ?x))) :- 
>>>> And(p(1) q(?x))
>>> I guess you mean:
>>> rule1: if q(?x) then print("rule1 fired, ?x=" ?x)
>>> rule2: if p(1) and q(?x) then Retract(p(1)), Assert(p(1)), print 
>>> ("rule2 fired, ?x=" ?x)
>>> Hey, Gary, this is not in the spec, you can write them rules in a 
>>> way that makes sense :-)
>> I think we'll need to speak somewhat formally here to be sure we 
>> understand each other.
>>>> With Oracle/Jess, you get
>>>> rule2 fired, ?x=2
>>>> rule1 fired, ?x=2
>>>> rule1 fired, ?x=1
>>> With JRules, you bind only objects, so, the example does not really 
>>> work.
>>> But if you could bind primitive data types, (I have to check, but I 
>>> think) 
>> I think you'd better check.
>>> that you would fire rule2 with ?x=1 as well. 
>> Do you mean rule2 fires twice, once with ?x=1 and once with ?x=2?  
>> That demonstrates a difference in semantics.  As I said, with Oracle 
>> and Jess, rule2 fires once with ?x=2 (because ?x=2 is the more recent 
>> binding)
>>> And that is certainly what you would get with the semantics that was 
>>> described in PRD.
>> Please clarify whether you mean rule2 fires once or twice, and then 
>> please "prove" it using the PRD semantics.  I don't see how PRD can 
>> give the Oracle/Jess semantics without some substantial changes.  PRD 
>> assumes that mergeInstances is not called between actions of the same 
>> rule; yet in Oracle/Jess (and most engines, I think) the agenda is 
>> modified by individual actions and this is why when the (actions of 
>> the) first instance of rule2 is executed, the second instance is 
>> removed.  But when the first instance of rule1 is executed, nothing 
>> happens to the second instance of rule1 and so rule1 is executed twice.
>>>> The semantics of Oracle/Jess is that a rule's actions cannot 
>>>> re-activate that rule.  Initially, because of the input data, rule1 
>>>> and rule2 each have 2 activations.  When rule2 fires, the 
>>>> retraction removes the other rule2 activation.  The assert action 
>>>> cannot reactivate rule2 because of the no-loop property.
>>> I do not understand that. I mean, I do not understand the intended 
>>> behaviour: do you mean that p(1) after rule2 has been fired is 
>>> distinct from p(1) before, and that, somehow, the engine recognizes 
>>> the difference? Does this have to do with the assertion being 
>>> logical (and the engine tracing the origin of it)? I mean, as in a 
>>> TMS: Jess has a TMS facility, right? I have to check how we handle 
>>> refraction (or equivalent) wrt logical statements in JRules...
>> No, it has to do with the fact that even though the initial and final 
>> states of the sequence of actions Do(Retract(p(1)) p(1)) are the same 
>> (assuming p(1) exists in the initial state), this sequence of actions 
>> is different from Do().  And this difference is not accounted for in 
>> the semantics.  This difference is needed to explain the Oracle/Jess 
>> no-loop semantics.
>>>> We need to carefully specify these strategies to be sure we agree 
>>>> what they are, and then we need to see what the intersection is, 
>>>> and if it is  >= 1, give it an explicit name(s) (and probably not 
>>>> in the metadata as my example does).
>>> Absolutely agree.
>> BTW, Oracle/Jess does not support all-at-once rule firing, other than 
>> by aggregation.  Nor do they support random firing. I think these are 
>> rare features, and do not merit standardization. 
> I'm ok with that. These are mostly hacks to get over the overhead of a 
> single agenda, I think more research needs to be done here that more 
> strongly supports parallelisation techniques for PR systems.
Received on Wednesday, 30 July 2008 04:28:47 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 6 January 2015 21:47:51 UTC