Recently, on this list, there was a question about how to find a pair
of facts ?a and ?b (of templates A, B) where multislot ?a.props
contains element ex and multislot ?a.props contains element ey.

The posting did not include sufficient information about the nature
of the values stored in the multislots, and therefore the choice
of using a multislot wasn't challenged. This, then, was the proposed
solution:

; implement a set as a multislot
;
(clear)

(deftemplate A (slot id)(multislot props))
(deftemplate B (slot id)(multislot props))

(deffacts ab
 (A (id a1)(props e1 e5))
 (A (id a2)(props e2 e5 e7))
 (A (id a3)(props e3 e4 e6 e8 e9))
 (B (id b1)(props e3 e7))
 (B (id b2)(props e4 e6 e7))
)

(defrule MatchAB
 ?a <- (A (props $? e3 $?))
 ?b <- (B (props $? e4 $?))
 =>
 (printout t "match a:" ?a.id " - b:" ?b.id crlf)
)

(reset)
(run)

Updates may be tricky, depending on the assumptions associated
with a list, which might be anything besides a set: a bag, a list, an
array or whatever.

Assuming that it is a set, this isn't the only way for implementation.
Comparing deftemplates and facts to relational database tables and
entities, and considering the guidelines for achieving some Normal Form,
multislots or lists aren't necessarily "best choice" for a deftemplate.

You might consider having an individual fact for each property.

; implement a set as a list of facts
;
(clear)

(deftemplate A (slot id)(slot prop))
(deftemplate B (slot id)(slot prop))

(deffacts ab
 (A (id a1)(prop e1))
 (A (id a1)(prop e5))
 (A (id a2)(prop e2))
 (A (id a2)(prop e5))
 (A (id a2)(prop e7))
 (A (id a3)(prop e3))
 (A (id a3)(prop e4))
 (A (id a3)(prop e6))
 (A (id a3)(prop e8))
 (A (id a3)(prop e9))
 (B (id b1)(prop e3))
 (B (id b1)(prop e7))
 (B (id b2)(prop e4))
 (B (id b2)(prop e6))
 (B (id b2)(prop e7))
)

(defrule MatchAB
 ?a <- (A (prop e3))
 ?b <- (B (prop e4))
 =>
 (printout t "match a:" ?a.id " - b:" ?b.id crlf)
)

(reset)
(run)

There are more facts, but handling these (including updates) is simpler,
in Jess as well as in Java. And the rule is simpler, too!

It is also quite simple to avoid a multislot by using a slot that
contains a POJO, using some Java Set implementation.

; implement a set as a Java Set
;
(clear)

(deftemplate A (slot id)(slot props))
(deftemplate B (slot id)(slot props))

(deffunction setOf ($?elems)
 (bind ?s (new java.util.HashSet))
 (foreach ?e $?elems (?s add ?e))
 (return ?s)
)

(deffacts ab
 (A (id a1)(props (setOf e1 e5)))
 (A (id a2)(props (setOf e2 e5 e7)))
 (A (id a3)(props (setOf e3 e4 e6 e8 e9)))
 (B (id b1)(props (setOf e3 e7)))
 (B (id b2)(props (setOf e4 e6 e7)))
)

(defrule MatchAB
 ?a <- (A (props ?pa &:(?pa contains e3)))
 ?b <- (B (props ?pb &:(?pb contains e4)))
 =>
 (printout t "match a:" ?a.id " - b:" ?b.id crlf)
)

(reset)
(run)

More code is required (the setOf deffunction), but we have a simple
deftemplate, and updates can rely on the methods of java.util.Set.
Similar solutions are possible with other classes from java.util.

I feel (and I freely admit that this is just a gut feeling) that the
single-slot solutions are, in general, to be preferred to the multislot
solution. Does anyone have data to confirm or contradict this?

Kind regards
Wolfgang


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