Clips: comparing facts between each other

530 views Asked by At

I'm trying to create an expert system which each time the user responds a question it creates a new fact (for example):

assert(like accion yes)
assert(like multi yes)

And once its done, it shows the name of every game that has those facts in their description:

(deffacts gaming (game Call_of_Duty multi accion)
(game BattleField multi strategy))

I tried using this rule, where I check if every "like-fact" is located inside an especific "game-fact", but it doesn't work:

(defrule conclusion
   (like $?x yes)
   (game ?y $?x2)
   (test(member$ ?x ?x2))
   =>
   (printout t "You like the game: " ?y crlf))
1

There are 1 answers

1
Gary Riley On BEST ANSWER

Here's three different ways you can write the rule. Your original rule, conclusion-1, will print a message for each like that is matched by a game so you can get multiple prints for each game. Rule conclusion-2 prints a game if there is at least one like that matches the game. At most you will see a game printed once. Rule conclusion-3 will print a game only if it matches every like for that game.

CLIPS> 
(deffacts gaming 
   (like accion yes)
   (like multi yes)
   (game Call_of_Duty multi accion)
   (game BattleField multi strategy))
CLIPS>    
(defrule conclusion-1
   (like $?x yes)
   (game ?y $?x2)
   (test(member$ ?x ?x2))
   =>
   (printout t "1 You like the game: " ?y crlf))
CLIPS>    
(defrule conclusion-2
   (game ?y $?x2)
   (exists (like $?x yes)
           (test (member$ ?x ?x2)))
   =>
   (printout t "2 You like the game: " ?y crlf))
CLIPS>    
(defrule conclusion-3
   (game ?y $?x2)
   (forall (like $?x yes)
           (test (member$ ?x ?x2)))
   =>
   (printout t "3 You like the game: " ?y crlf))
CLIPS> (reset)
CLIPS> (run)
1 You like the game: BattleField
2 You like the game: BattleField
1 You like the game: Call_of_Duty
1 You like the game: Call_of_Duty
2 You like the game: Call_of_Duty
3 You like the game: Call_of_Duty
CLIPS>