Darrel Davis wrote:

I am a real newbie having some difficulty understanding how I would test/access
nested Java objects from the LHS of a rule.

Given the following declarations:
(deftemplate AgreementVO  (declare (from-class AgreementVO)))
(deftemplate HostVO (declare (from-class HostVO)))

A HostVO is contained within an AgreementVO and has
firstName and lastName attributes.

I can do this:

(defrule hostvo
    (AgreementVO (host ?host&:(neq ?host nil)))
=> (bind ?ln (?host getLastName))
    (bind ?fn (?host getFirstName))
)

but this can be problematic if lastName or firstName is null,

Why? It'll bind nil to ?ln or ?fn, and you know how to compare
a variable with nil.

plus
I have some objects which are nested 3 deep.

I then found example code in the mailling list archives which
would define the rule as:

(defrule hostvo
    (AgreementVO (host ?host&:(neq ?host nil)))
    ?host <- (HostVO (lastName ?last)(firstName ?first))
    =>

Which doesn't fire at all.

First, you don't have to add another condition to get at the HostVO
contained within the AgreementVO. Accessing the HostVO's
attributes on the LHS or the RHS can be written as (?host getFirstName).
E.g.:

(defrule hostvo
  (AgreementVO (host ?host &: (neq ?host nil)))
  =>
  (printout t (?host getFirstName) crlf))

Or:

(defrule hostx
  (AgreementVO (host ?host &: (call "Smith" equals (?host getLastName))) )
   =>
  (printout t (?host getFirstName) " " (?host getFirstName) crlf)
)
Note that calling equals on "Smith" avoids the test for nil/null.

But, just to clarify the "doesn't fire", let's assume that you'll have to find
the embedded object by matching. The important thing to remember in
this situation is that any fact (and this includes shadow facts) is of class
jess.Fact. The corresponding Java object of some Java class is contained
within this jess.Fact object. - Assert or add some facts, and then do this:

Jess> (bind ?f (fact-id 1))
<Fact-1>
Jess> (printout t ((?f getClass) getName) crlf)
jess.Fact

The first condition in your rule is
 (AgreementVO (host ?host&:(neq ?host nil)))
which says "find me an AgreementVO with slot host not equal to nil and assign the
contents of this slot to ?host. This, then, will contain some Java object of
class HostVO.

The second condition tries to find a HostVO fact:
 ?host <- (HostVO (lastName ?last)(firstName ?first))
Since ?host is already bound, ?host <- (HostVO... means that the HostVO
fact(!) must be equal to whatever was stored in ?host. It should be clear
by now that a jess.Fact will never be equal in any sense to a HostVO object.

How can this be fixed? There are two ways. First, note that there is an
OBJECT slot in each shadow Fact, and this does contain the POJO.

(defrule hostvo
   (AgreementVO (host ?host&:(neq ?host nil)))
   ?hostfact <- (HostVO (OBJECT ?host)(lastName ?last)(firstName ?first))
   => ...

Now the second condition says "find me a HostVO fact whose
POJO is identical to the one we have in ?host". The fact is now
bound to ?hostfact.

The other way (not recommended) is this:
(defrule find1
   (AgreementVO(host ?host &:(neq ?host nil)))
   ?hFact  <- (HostVO (lastName ?last))
   (test (?hFact equals ((engine) getShadowFactForObject ?host)))
   =>

The jess.Rete method getShadowFactForObject returns a fact created
from some Java object. This may be compared to the fact found in
Jess' memory. Note that the result of getShadowFactForObject is
a *new* fact, and hence needs to be compared with equals. (The
identity comparison "eq" will not work.)

(I admit that even though I'm reading Jess In Action
as well as the printed manual, I'm having trouble understanding this syntax ).

You are not alone, there :-)

In some condition:
(SomeTemplate (aSlot ?aVar )...)
If variable ?aVar hasn't been bound before then
  assigns ("binds") the value of slot "aSlot" to variable "?aVar"
otherwise
  restricts matches to facts with slots equal to the contents of "?aVar".

(aSlot ?aVar & : (anExpressionReturningBoolean))
as before, and additionally, anExpressionReturningBoolean must return TRUE

The Jess Manual, section 6.3, contains more.

HTH
Wolfgang


So my question is: What is the correct method of accessing attributes of nested objects on the LHS of a rule? Maybe pointers to JIA chapters or manual chapters?

Thanks,
-
====================================
Darrel Davis [EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]> [EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]> ====================================


--------------------------------------------------------------------
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]
--------------------------------------------------------------------

Reply via email to