How to compare symbols between 2 multifield-variable in CLIPS

The problem is to compare between two multifield-variable of type SYMBOL. Here an example of the code I try to develop.

CLIPS>(defrule r       
=>
(printout t "Input A: ")
(bind $?A (explode$ (readline)))

(printout t "Input B: ")
(bind $?B (explode$ (readline)))

(if (member$ $?A $?B) then (printout t " Something ..." crlf)))
CLIPS> (run)
Input A: 1 2 3 4 5
Input B: 7 3 2 1 6
CLIPS> 

I want to compare each argument (or value) of $?A with each argument of $?B and if at least one argument of both is in the $?A or $?B, the if test becomes TRUE.

Upvotes: 0

Views: 756

Answers (1)

Gary Riley
Gary Riley

Reputation: 10757

You can write a function to test for the intersection of two multifield values:

CLIPS> 
(deffunction intersectionp (?m1 ?m2)
   (foreach ?i1 ?m1
      (foreach ?i2 ?m2
         (if (eq ?i1 ?i2)
            then (return TRUE))))
   (return FALSE))
CLIPS> 
(defrule r       
   =>
   (printout t "Input A: ")
   (bind ?A (explode$ (readline)))

   (printout t "Input B: ")
   (bind ?B (explode$ (readline)))

   (if (intersectionp ?A ?B) then (printout t " Something ..." crlf)))
CLIPS> (run)
Input A: 1 2 3 4 5
Input B: 7 3 2 1 6
 Something ...
CLIPS> (reset)
CLIPS> (run)
Input A: 1 2 3
Input B: 4 5 6
CLIPS> 

Alternately you can use pattern matching to test for an intersection:

CLIPS> (clear)
CLIPS>    
(defrule r       
   =>
   (printout t "Input A: ")
   (bind ?A (explode$ (readline)))
   (assert (A ?A))

   (printout t "Input B: ")
   (bind ?B (explode$ (readline)))
   (assert (B ?B)))
CLIPS> 
(defrule intersect
   (exists (A $? ?v $?)
           (B $? ?v $?))
   =>
   (printout t " Something ..." crlf))
CLIPS> (reset)
CLIPS> (run)
Input A: 1 2 3 4 5
Input B: 7 3 2 1 6
 Something ...
CLIPS> (reset)
CLIPS> (run)
Input A: 1 2 3
Input B: 4 5 6
CLIPS> 

Upvotes: 2

Related Questions