I prefer not to think in terms of undo, that lays itself to a particular
use case. Instead I prefer to model it on logical insertions, like
logical insertions when a rule is no longer true we retract the inserted
fact. A closure is an anonymous code block that will be executed using
the given state, think of it as a stateful callback. So in the same way
that a logical inssertion will execute an action that will retract the
fact it inserted a logical closure will execute the anonymous block
using hte previously supplied state - obviosly the onus is on the user
to provide state that would only be valid for execution at that time.
The main reason for this is rules are very good at telling you when
something happens, but not telling you when something stops happeneing
- 'not' CEs are not quite flexible enough for this.
Mark
James C. Owen wrote:
Greetings:
It's been interesting watching this thread develop. Originally, I
wasn't going to comment but then I threw caution to the four corners
of the globe and said, "Why not?"
Originally, rulebased systems were simple IF-THEN clauses in a
non-monotonic environment such the engine rules were evaluated as true
or false, those that were true were placed on the agenda to be fired,
which rule to fire next was then selected via some conflict resolution
strategy (such as MEA or LEX), the engine fired that rule, and the
process started all over until there were no more rules to fire.
Along the way, a rule might not be true until some other rule fired
that made it true. Conversely, if some rule fired that made another
rule false that the second rule was removed from the agenda table. A
rule is composed of its data and its logic. Originally, an OR
statement meant that another rule had to be written. Likewise, an
ELSE statement meant that DeMorgan's theorem was applied to the LHS of
the rule and a new rules was written.
Then came OPSJ that featured OR, ELSE and Conditional ELSE where the
ELSE (1) clause would only be evaluated if the first CE was false.
Very selective and very handy. Normally an ELSE fires if ANY of the
CEs are false on the LHS. It seems to me that the idea of "undo" and
"rollback" comes from the database world. If a rule no longer matches
that does not mean that one of the other rules might not change the
data of another CE in another rule so that it does, in fact, match
later. Refraction - a feature of almost all rulebased systems - will
remove a rule (logic+data) once it fires so I would not think that
this is not a matter under consideration.
Now, to the part that mystifies me: If there was a previous
"fireAllRules" and that rule did not match does not mean that the rule
would not match this time we run a "fireAllrules" unless the data and
the rule logic remained unchanged. if a rule never fires and never
will fire, why would it be in the system? Conversely, if the data
changes why would one want to "undo" the run from a previous match in
another run? You wouldn't. Obviously. But that seems to be what has
been promulgated in the foregoing discussion. "No longer matching"
does not mean that the rule will never match in the preset
"fireAllrules" run - you don't know that until all of the rules on the
Agenda (and the changes to the Agenda) have been processed completely.
And by that time it's way too late to consider an "undo" for those rules.
SDG
jco
/*"This above all: to thine own self be true,*/
/*And it must follow, as the night the day,*/
/*Thou canst not then be false to any man."*/
/*Hamlet, Act 1, Scene III*/
/*http://www-tech.mit.edu/Shakespeare/hamlet/hamlet.1.3.html*/
On Feb 19, 2009, at 8:45 AM, Mark Proctor wrote:
> Geoffrey De Smet wrote:
>> What would an "else clause" do?
>> Imagine a rule with matches on 5 different fact sets.
>> How many times would the else part match?
>> - none (because it matches at least one)
>> - a very lot (because it matches on any fact set that isn't that one
>> of those 5)
>>
>> The "undo-then" is another concept:
>> it matches when a rule that matched before (in a previous
>> fireAllRules), now no longer matches.
>> "undo-then" probably isn't the best name, so better suggestions are
>> welcome, but "else" isn't a good name for it as it's not about
"not
>> matching" but about "no longer matching".
> As I mentioned, i'd do it as a logical closure using an anonymous
> code block, in a similar manner that we do for logical insertions.
>
> Mark
>>
>>
>> Anyway, I 've been thinking and it wouldn't work for all use cases
>> in drools-solver:
>> rule
>> when
>> q1 : Queen()
>> q2 : Queen()
>> eval(q1.getY() - q2.getY() < 10)
>> then
>> a.add(q1.getY() - q2.getY());
>> undo-then
>> a.subtract(q1.getY() - q2.getY())
>> end
>> The y of a queen changes, so the subtract wouldn't subtract the
>> exact same number that was added.
>> Any way we could work around that, or is there no avoiding
>> insertLogical?
>>
>> With kind regards,
>> Geoffrey De Smet
>>
>> Mark Proctor schreef:
>>> Greg Barton wrote:
>>>> --- On Wed, 2/18/09, Geoffrey De Smet <ge0ffrey.spam(a)gmail.com
>>>> <mailto:ge0ffrey.spam@gmail.com>> wrote:
>>>>
>>>>
>>>>> The current workarounds [to undo-then] are clunky:
>>>>> - Writing an negative (opposite) rule isn't efficient:
>>>>> it means declaring the rule twice effectively. Also the
>>>>> negative rule is usually using lots of or's and
>>>>> not's which isn't fast.
>>>>>
>>>>
>>>> This would be made easier by...drum roll please...the else clause! :)
>>>>
>>> yes we want OPSJ style else statements, edson has an idea on how to
>>> do that, just a matter of time :(
>>>> Now, if there was the else clause plus undo-then/closures you
>>>> could probably write an entire complex ruleset in one rule. Might
>>>> as well just use perl, then. :P
>>> heh, that's true you would have potentially encapsulated 4 possible
>>> executions in a single rule.
>>>>
>>>> _______________________________________________
>>>> rules-dev mailing list
>>>> rules-dev(a)lists.jboss.org <mailto:rules-dev@lists.jboss.org>
>>>>
https://lists.jboss.org/mailman/listinfo/rules-dev
>>>>
>>>>
>>>>
>>>
>>>
>>> ------------------------------------------------------------------------
>>>
>>> _______________________________________________
>>> rules-dev mailing list
>>> rules-dev(a)lists.jboss.org <mailto:rules-dev@lists.jboss.org>
>>>
https://lists.jboss.org/mailman/listinfo/rules-dev
>>
>> _______________________________________________
>> rules-dev mailing list
>> rules-dev(a)lists.jboss.org <mailto:rules-dev@lists.jboss.org>
>>
https://lists.jboss.org/mailman/listinfo/rules-dev
>>
>>
>
>
> _______________________________________________
> rules-dev mailing list
> rules-dev(a)lists.jboss.org <mailto:rules-dev@lists.jboss.org>
>
https://lists.jboss.org/mailman/listinfo/rules-dev
------------------------------------------------------------------------
_______________________________________________
rules-dev mailing list
rules-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-dev