Hi Hal, Peter & Wolfgang,
>> The proposed solution does not compare a length with
foo.desired, and binding of a multislot vaue should use a variable
starting with $?.
Hal, since you said you were satisfied with Peter's solution, I
never posted my reply which anticipated Wolfgang's almost verbatim.
However, if you really want what Peter was advocating then there is
a bit more to it I think. You have to recall that Jess doesn't
allow multiple facts to have identical slot values -- that means
that no two foo facts could have the exact same multislot list and
desired value. You may need this in your application, so you'd
need some other slot like (slot id) to differentiate your facts.
Also, Peter's version would fire twice for each pair of foo facts
that had the same slot length, which is not what you want I'd think.
The implementation below addresses these issues.
Cheers,
Jason
;;;;;;;;;;;;;;;;;;
;; list-len.clp ;;
;;;;;;;;;;;;;;;;;;
(clear)
(watch all)
(deftemplate foo (slot id) (multislot my-list) (slot desired))
(deffacts init
(foo (id 1) (my-list 1 2 3 4))
(foo (id 2) (my-list a b c d))
(foo (id 3) (my-list 5 6 7 8))
(foo (id 4) (my-list e f g h)))
(defrule myrule
; Find a foo fact...
(foo (id ?id1) (my-list $?list1))
; ...and another fact of different id where the list lengths
are the same...
(foo (id ?id2&~?id1) (my-list $?list2&:(= (length$ ?list2)
(length$ ?list1))))
; ...such that we have not examined this pair of foo facts
before.
(not (has-fired ?id1 ?id2))
=>
; Assert that this pair has been processed with a little logic
trick.
(assert (has-fired ?id2 ?id1))
(printout t "Lists lengths in foo facts " ?id1 " and " ?id2 "
are equal!" crlf))
:: Program
(reset)
(run)
;MAIN::myrule: +1+1+1+2+1+1+2+t
; ==> Focus MAIN
; ==> f-0 (MAIN::initial-fact)
; ==> f-1 (MAIN::foo (id 1) (my-list 1 2 3 4) (desired nil))
; ==> f-2 (MAIN::foo (id 2) (my-list a b c d) (desired nil))
;==> Activation: MAIN::myrule : f-2, f-1,
;==> Activation: MAIN::myrule : f-1, f-2,
; ==> f-3 (MAIN::foo (id 3) (my-list 5 6 7 8) (desired nil))
;==> Activation: MAIN::myrule : f-3, f-1,
;==> Activation: MAIN::myrule : f-3, f-2,
;==> Activation: MAIN::myrule : f-1, f-3,
;==> Activation: MAIN::myrule : f-2, f-3,
; ==> f-4 (MAIN::foo (id 4) (my-list e f g h) (desired nil))
;==> Activation: MAIN::myrule : f-4, f-1,
;==> Activation: MAIN::myrule : f-4, f-2,
;==> Activation: MAIN::myrule : f-4, f-3,
;==> Activation: MAIN::myrule : f-1, f-4,
;==> Activation: MAIN::myrule : f-2, f-4,
;==> Activation: MAIN::myrule : f-3, f-4,
;FIRE 1 MAIN::myrule f-3, f-4,
; ==> f-5 (MAIN::has-fired 4 3)
;<== Activation: MAIN::myrule : f-4, f-3,
;Lists lengths in foo facts 3 and 4 are equal!
;FIRE 2 MAIN::myrule f-4, f-2,
; ==> f-6 (MAIN::has-fired 2 4)
;<== Activation: MAIN::myrule : f-2, f-4,
;Lists lengths in foo facts 4 and 2 are equal!
;FIRE 3 MAIN::myrule f-1, f-4,
; ==> f-7 (MAIN::has-fired 4 1)
;<== Activation: MAIN::myrule : f-4, f-1,
;Lists lengths in foo facts 1 and 4 are equal!
;FIRE 4 MAIN::myrule f-3, f-2,
; ==> f-8 (MAIN::has-fired 2 3)
;<== Activation: MAIN::myrule : f-2, f-3,
;Lists lengths in foo facts 3 and 2 are equal!
;FIRE 5 MAIN::myrule f-3, f-1,
; ==> f-9 (MAIN::has-fired 1 3)
;<== Activation: MAIN::myrule : f-1, f-3,
;Lists lengths in foo facts 3 and 1 are equal!
;FIRE 6 MAIN::myrule f-1, f-2,
; ==> f-10 (MAIN::has-fired 2 1)
;<== Activation: MAIN::myrule : f-2, f-1,
;Lists lengths in foo facts 1 and 2 are equal!
; <== Focus MAIN
--
-----------------------------------------------------------
Jason Morris
Morris Technical Solutions LLC
http://www.morris-technical-solutions.com