Re: [PRD] Refraction Semantics may be WRONG!

Hi all,

Gary wrote on 18/11/2009 22:50:41:
> 
> consider the rule:
> 
> Forall ?X (If Exists ?Y (_P(?X, ?Y)) THEN DO (Retract(_P(?X,?Y)), 
> Assert(_P(?Y, ?Y + 1))))
> 
> By rif semantics, this rule loops if given _P(0, 1) but does not loop if 

> given _P(0, 0).
> 
> In Jess, this rule either loops or does not loop, depending only on the 
> rule-level setting of loop/noloop. Any setting I pick will not always be 

> correct.

Ah! Would it be that, in Jess, actions are effective immediately?

Gary's example made me realize that there is an inconsistency in the 
specification of refraction currently in PRD. And resolving that 
inconsistency might help resolve Gary's problem (or maybe not).

By making the test of whether its condition has been continuously true 
since a rule instance fired (and, thus, whether it should be put back on 
the agenda or not) depend only on matching the instance at each cycle, the 
spec makes the implicit assumption that the actions in the RHS of the rule 
are effective, all together, only when all the actions in the actions 
block have been executed.

But atomic actions are effective immediately, according to the semantics 
of PRD. I think that we agreed on that, and this is what the spec says, 
anyway (by not saying anything on that subject).

And, so, in Gary's example, the condition of the rule becomes false, for 
the substitution ?X\0, when _P(0, 0) is retracted. It becomes true again 
when _P(0, 1) is asserted, so that, if the test is only wrt the state at 
the end of the cycle, there is no apparent breach in the continuity of 
matching, and, thus, the instance is refracted.

But if the test is that the condition has always been satisfied by the 
fact base, then the instance ?X\0 should be back on the agenda again, 
instead (since the fact base does not satisfy the condition after the 
retract is effective and before the assert is)... And, so the rule should 
loop in both cases (that is, with either _P(0, 0) or _P(0, 1) as the 
initial state of the fact base).

Another example, maybe closer to our object-oriented hearts, is

Forall ?X (
   IF Exists ?Y ((?X[_att-> ?Y] AND (?Y > 0))
   THEN DO ( Modify( ?X[_att-> -1] ) Modify( ?X[_att-> 1] )))

If the modifications are effective immediately, the rule will loop 
indefinitely, as soon as there is an object with a positive _att in the 
fact base. In the same condition, the rule will fire only once, if the 
modifications are effective as a block (and, thus, only the last Modify 
has an effect).

So, Gary was right, and there is something wrong in the semantics of 
refraction, indeed. If my understanding is correct, we have two ways to 
repair that:
1. either we keep actions being effective immediately upon execution, and 
we change the specification of refraction to say that an instance becomes 
fireable again, not only if it has been evaluated false (in a state of the 
PR system) since it was last fired, but, more generally, if there has been 
a state of the fact base, possibly an intermediate one, that it did not 
match since it was last executed. That change does not require a lot of 
modifications in the spec: see [1] for a diff between the modified spec 
and the CR one;
2. or we do keep the specification of refraction unchanged, but we change 
the spec to make the underlying assumption explicit with respect to when 
the actions are effective; that is, to make them effective all together as 
a block. That change is even easier than the previous one: we have, I 
think, to add only one sentence in the document.

There are other possibilities, of course, such as introducing an explicit 
mechanism to notify the engine when actions become effective, but that 
would be changing the design.

Whereas I believe that the above two solutions are not: they are only 
repairing an inconsistency in the current spec (and, therefore, making 
either one change does not send us back to LC).

I think that solution (1) is what we had in mind, when we agreed on the 
semantics of refraction. It is certainly easier to implement with a RETE. 
I am not sure whether it resolves Gary's problem, but it certainly does 
wrt the above examples. It preserves the difference between Modify and 
Retract-Assert, too.

On the other hand, we should prefer the solution that is closer to the 
default behaviour of most engines, I think (and I have no idea which one 
it is).

So, what do we do?

Gary, does solution (1) make your life easier? Or is it just a side 
effect, that this particular example happened to reveal the inconsistency 
in the spec?

[1] 
http://www.w3.org/2005/rules/wiki/index.php?title=PRD&diff=11831&oldid=11437

> I wanted to get a sense if I am the only one having trouble implementing 

> PRD refraction. (I didn't think it would be this hard until I tried to 
> actually do it :-)

I still have to check Chiheb's implementation wrt conflict resolution.

> Of course, I don't want to hold up the spec unless nobody can implement 
> it as-is.

+1

I hope that relieving the inconsistency in the spec will make things 
easier, no harder.

Cheers,

Christian

IBM
9 rue de Verdun
94253 - Gentilly cedex - FRANCE
Tel. +33 1 49 08 35 00
Fax +33 1 49 08 35 10



Sauf indication contraire ci-dessus:/ Unless stated otherwise above:
Compagnie IBM France
Siege Social : 17 avenue de l'Europe, 92275 Bois-Colombes Cedex
RCS Nanterre 552 118 465
Forme Sociale : S.A.S.
Capital Social : 611.451.766,20 ?
SIREN/SIRET : 552 118 465 03644

Received on Wednesday, 25 November 2009 15:12:18 UTC