I agree with the same, that adding a method to your Java class would make
the comparisons a lot easier. One thing you might not have noticed or
considered was that your getters/setters are not neccesary in the way you
designed your Java beans. Since your class members are public you can do a
direct comparison between the PO.customer.address & Customer.address
Strings. So as your code stands, it would suffice to just directly access
them.

For more of a proper "coding style" when using Java beans, make those class
members private, keep the getters/setters, and @Override your .equals method
in the class. By default it will accept Object obj and you can code in what
fields you want to use for a comparison. Since you know that customer and PO
both have the same address string inside of them, you can code the .equals
method to just compare those strings and it would make the comparison method
you call in your 'test' line a lot simpler; maybe something along the lines
of

(defrule rule
    ?c <- (Customer (address ?address))
    ?p <- (PO (customer ?customer))
    (test (?p (equals ?c)))

I could be wrong...might this should work with proper kung-fu in your Java
classes.

On Fri, Sep 4, 2009 at 7:24 PM, Michael Smith <[email protected]>wrote:

>
> (defrule rule
>     (Customer (address ?address))
>     (PO (customer ?customer))
>     (test (= 0 (str-compare ((?customer getAddress) getStreet) (?address
> getStreet))))
>     =>
>     (bind ?name (?customer getName))
>     (bind ?addr (?address getStreet))
>     (printout t ?addr ": customer: " ?name crlf)
> )
>
> Are there better, more elegant ways to accomplish the same?
>
> Beauty is in the eye of the beholder, of course, but I'll offer one
> alternative that might work and then a little commentary.
>
> I tried:
>
> ?po <-  (PO (customer ?customer))
> ?customer <-  (Customer (address ?address))
> (test (=  (((?po getCustomer) getAddress) getStreet)  ((?customer
> getAddress) getStreet)))
>
> But ?po and ?customer are facts (Jess.Fact) that have no getCustomer and
> getAddress methods.
>
>
> (defrule match-street-in-purchase-to-other-customers-for-some-reason
> (PO (customer ?poCustomer)) (Customer (OBJECT ?poCustomer)  (address
> ?poAddress))
> (Address (OBJECT ?poAddress) (street ?street))
> (Customer (OBJECT ?customer&~?poCustomer) (address ?customerAddress)) ;This
> assumes we aren't matching the PO customer
> (Address (OBJECT ?customerAddress) (street ?street)
> =>
> ;; do something here with something in purchase order unshown property
> (other than customer)?
> )
>
> It would also be possible to write methods on the classes that assist in
> this form of matching, to reduce the direct navigation through the object
> relationships.  Something like a streetEq method, or more directly a
> getCustomerStreet() method on the PO class to avoid navigating in the
> pattern matches across the Customer.
>
> There cam be real tension between object-oriented programming and
> rule-based programming.  Encapsulation of objects and avoiding breaking
> Demeter's law can take a lot of the classic OPS5 rule look out of
> rule-programming.  Adding properties (and accessors) to all the slots one
> might navigate through can add a burden to adding objects to the engine as
> the properties are shadowed, particularly if the properties are not easily
> computed/virtual.
>
> - Mike
>
>
>

Reply via email to