I only posted an abstraction to figure out my problem, leaving out the
other details. What I'm doing is essentially modeling workflow which
manages to some target number of instances, so the fact in question is
further qualified by other attributes as you have indicated.
On Feb 20, 2008, at 6:29 AM, Jason Morris wrote:
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