Hi Alan:
To make a long story short: you need to call getIcon() on the Fact
instances you extract here, and use the new Facts returned by them. As
the Javadoc for getIcon() says
Return the canonical representation of this Fact object. For most
Facts, this returns "this", but for certain Facts -- in particular,
for Facts extracted from jess.Token
objects -- it may return another object. If you are examining a
jess.Token object and obtain a reference to a Fact from that Token,
then call getIcon() to "canonicalize"
that Fact before using it.
I should add a note about this issue to the Javadoc for
jess.Token.fact().
For those interested in the underlying explanation: the facts returned
from Token.fact() may -- in the case of a fact with a multifield that
is explicitly matched by the rule -- return not the "actual" fact, but
a sort of "view" of the fact, that describes how the multifield is
matched. The getIcon() method returns the "actual" fact associated
with the view.
On Jul 1, 2008, at 5:04 PM, Greenblatt, Alan wrote:
I have a series of rules which call a Java user function when they
fire which among other things, sometimes needs to get the list of
facts which caused the rule to fire and then modify a certain slot
in those facts.
Perhaps I have a misunderstanding of how the current activation
works ((engine) getThisAcivation), but I was under the impression
that if you get the Token from the Activation, you can get at the
Facts which contributed to the current rule firing.
I've simulated this with the following simple code, which produces
an exception:
(deftemplate Class1
(slot A)
(multislot B))
(defrule ModClass1
(Class1
(A ?a)
(B $? ?var1 $?))
=>
(bind ?token (((engine) getThisActivation) getToken))
(bind ?fact1 (?token fact 0))
(modify ?fact1 (A "123")))
(reset)
(assert
(Class1
(A "abc")
(B "def")))
(run)
When run this, I get the following exception: Fact object not in
working memory (MAIN::Class1 (A "abc") (B "def" )).
Evidently, this is because ?fact1 is not identical to the Fact
returned from:
(bind ?fact2 ((engine) findFactByID (?fact1 getFactId)))
It turns out that if I modify ?fact2 instead of ?fact1, I'm good to
go. Can someone please explain to me what is going on here? Why is
fact2 different from fact1?
Here's a version of the code from above that works just fine:
(deftemplate Class1
(slot A)
(multislot B))
(defrule ModClass1
(Class1
(A ?a)
(B $? ?var1 $?))
=>
(bind ?token (((engine) getThisActivation) getToken))
(bind ?fact1 (?token fact 0))
(bind ?fact2 ((engine) findFactByID (?fact1 getFactId)))
(modify ?fact2 (A "123")))
(reset)
(assert
(Class1
(A "abc")
(B "def")))
(run)
Thanks very much,
Alan
---------------------------------------------------------
Ernest Friedman-Hill
Informatics & Decision Sciences, Sandia National Laboratories
PO Box 969, MS 9012, Livermore, CA 94550
http://www.jessrules.com
--------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users [EMAIL PROTECTED]'
in the BODY of a message to [EMAIL PROTECTED], NOT to the list
(use your own address!) List problems? Notify [EMAIL PROTECTED]
--------------------------------------------------------------------