I want this Clips program to compare 4 symptoms of disease using if then(the symptoms are ows, yhp, sda and dgb) - clips

I want this Clips program to compare 4 symptoms of a disease Bacterial fruit blotch of watermelon using if then rules of Clips (the symptoms are ows, yhp, sda and dgb). the issue is when I run the code it does not display anything.
below is the sample code. I need your help please.
(defrule bacterial-fruit-blotch-of-watermelon
(initial-fact)
(printout t "is the plant showing a symptom of Oily and water-soaked cotyledons" crlf)
(printout t "is the plant showing a symptom of Yellow halo paralleling veins " crlf)
(printout t "is the plant showing a symptom of Small dark and angled lesion on leaves " crlf)
(printout t "is the plant showing a symptom of Dark green blotch on the upper surface of developing fruit " crlf)
=>
(assert (OWS (read)))
(assert (YHP (read)))
(assert (SDA (read)))
(assert (DGB (read))))
CLIPS>
(defrule check
(ows ?OWS)
(yhp ?YHP)
(sda ?SDA)
(dgb ?DGB)
=>
(if (and (eq ?OWS yes)
(and (eq ?YHP yes)
(and (eq ?SDA yes)
(eq ?DGB yes))))
then
(printout t "The plant is showing a symptom of bacterial fruit blotch of watermelon disease " crlf)
clips>(run)

Don't use the initial-fact pattern in rules.
The printout statements should be in the actions of the rule, not the conditions.
If you're printing to standard output, you can use the print and println functions rather than printout.
Matching is case sensitive, so OWS will not match ows.
Checking for yes in the conditions of the rule, rather than the actions, simplifies the rule and prevents it from being activated if any of the responses is not yes.
With these changes the rule will execute:
CLIPS (6.4 2/9/21)
CLIPS>
(defrule bacterial-fruit-blotch-of-watermelon
=>
(print "Is the plant showing a symptom of Oily and water-soaked cotyledons? ")
(assert (OWS (read)))
(print "Is the plant showing a symptom of Yellow halo paralleling veins? ")
(assert (YHP (read)))
(print "Is the plant showing a symptom of Small dark and angled lesion on leaves? ")
(assert (SDA (read)))
(print "Is the plant showing a symptom of Dark green blotch on the upper surface of developing fruit? ")
(assert (DGB (read))))
CLIPS>
(defrule check
(OWS yes)
(YHP yes)
(SDA yes)
(DGB yes)
=>
(println "The plant is showing a symptom of bacterial fruit blotch of watermelon disease."))
CLIPS> (reset)
CLIPS> (run)
Is the plant showing a symptom of Oily and water-soaked cotyledons? yes
Is the plant showing a symptom of Yellow halo paralleling veins? yes
Is the plant showing a symptom of Small dark and angled lesion on leaves? yes
Is the plant showing a symptom of Dark green blotch on the upper surface of developing fruit? yes
The plant is showing a symptom of bacterial fruit blotch of watermelon disease.
CLIPS>

Related

CLIPS - compare 2 facts if are equal, with wildcard in rule

I am trying to create rule which compares in this way:
CLIPS> (assert (flower red yellow))
CLIPS> (assert (flower blue yellow))
CLIPS> (assert (isflower yellow))
CLIPS> (defrule has_color2
(isflower ?x)
(eq flower red ?x flower red ?)
=>
(printout t "has property" ?x crlf))
CLIPS> (run)
So my question is this ; How to compare a variable against a set of facts to check if theres any match ? The alone ? mark on the 6th line is where I want to insert a wildcard in a way it's done. Whole line is inaccurate probably.
CLIPS> (assert (flower red yellow))
<Fact-1>
CLIPS> (assert (flower blue yellow))
<Fact-2>
CLIPS> (assert (isflower yellow))
<Fact-3>
CLIPS>
(defrule has_color2
(isflower ?x)
(flower ? ?x)
=>
(printout t "has property " ?x crlf))
CLIPS> (agenda)
0 has_color2: f-3,f-2
0 has_color2: f-3,f-1
For a total of 2 activations.
CLIPS> (facts)
f-1 (flower red yellow)
f-2 (flower blue yellow)
f-3 (isflower yellow)
For a total of 3 facts.
CLIPS> (run)
has property yellow
has property yellow
CLIPS>

Clips: comparing facts between each other

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

Clips Not Equals To

Using the Clips programming language, what is the correct "not equals" syntax?
This is the not symbol ~
Clips Documentation
The ~ constraint is part of the pattern matching language. The neq function is for use within expressions. Both can be used with values of any type. The != and <> functions can only be used with numeric arguments.
CLIPS> (clear)
CLIPS>
(defrule rule-1
(color ?color&~red&~blue)
=>
(printout t "rule-1: " ?color crlf))
CLIPS>
(defrule rule-2
(color ?color)
(test (and (neq ?color red) (neq ?color blue)))
=>
(printout t "rule-2: " ?color crlf))
CLIPS> (assert (color green) (color blue) (color yellow) (color red))
<Fact-4>
CLIPS> (run)
rule-1: yellow
rule-2: yellow
rule-1: green
rule-2: green
CLIPS> (neq 2 3)
TRUE
CLIPS> (neq a b)
TRUE
CLIPS> (!= 2 3)
TRUE
CLIPS> (!= a b)
[ARGACCES5] Function != expected argument #1 to be of type integer or float
CLIPS>

CLIPS Validate Text Entry

Morning, Excuse the silly question but I am busy building a expert system much like the "21 Questions" game that uses questions asked to the user in order to determine the right dog for them. The expert system is coded in CLIPS / .CPS language and one of the requirements I am looking to include is that when the user is asked a yes/no question they are required to input "y" or "n".
In all the resources we have been taught we have only been tough number validation and not a specific character validation and I cannot find any resources that do this either.
This is an example of the number validation I did in order to ensure they input a valid number on one of my questions
(defrule test-integer
(number-in ?number&:(integerp ?number))
=>
(printout t ?number "is valid"
(defrule test-non-int
?number-address <- (number-in ?number&:(not (integerp ?number)))
=>
(printout t ?number " not valid int" crlf)
(retract ?number-address))
This is how you'd do it using rules:
CLIPS>
(defrule test-response
(response-in ?response&y|n)
=>
(printout t ?response " is valid" crlf))
CLIPS>
(defrule test-non-response
?response-address <- (response-in ?response&~y&~n)
=>
(printout t ?response " not valid response" crlf)
(retract ?response-address))
CLIPS> (assert (response-in xyz))
<Fact-1>
CLIPS> (run)
xyz not valid response
CLIPS> (assert (response-in n))
<Fact-2>
CLIPS> (run)
n is valid
CLIPS>
I'd suggest using a function that only accepts correct responses:
CLIPS>
(deffunction ask-question (?question $?allowed-values)
(printout t ?question)
(bind ?answer (read))
(if (lexemep ?answer)
then (bind ?answer (lowcase ?answer)))
(while (not (member ?answer ?allowed-values)) do
(printout t ?question)
(bind ?answer (read))
(if (lexemep ?answer)
then (bind ?answer (lowcase ?answer))))
?answer)
CLIPS> (ask-question "Continue? " y n yes no)
Continue? k
Continue? l
Continue? ye
Continue? YeS
yes
CLIPS>
What i figured out was to link the answer from the one defrule to that of another defrule first to check if the answer was valid and then again if that answer was valid to link it to the correct defrule then that will proceed with the next question.
Code is from my own Expert System:
(defrule Small-CoatType-Full
(Small-Coat f)
(person (name ?name))
=>
(open "result.txt" result "a")
(printout result ?name " Likes Smaller, Fury Dogs" crlf)
(close result)
(printout t "Would you like a low energetic(l) or high energetic(h) breed?" crlf)
(assert (Small-Energy-Level(lowcase(read)))))
(defrule Small-Energy-Level-Wrong
(Small-Energy-Level ?var &~l&~h)
=>
(printout t crlf "Plesae Only Choose (l) or (h)")
(assert (Small-Energy-Level (lowcase(read)))))`

Obtain ID of fact I just asserted

Is there a way for me to get the fact ID of a fact that I just asserted in the RHS of a rule? Something along the lines of
?f <- (assert (new-fact))
CLIPS>
(defrule example
=>
(bind ?f (assert (new-fact)))
(bind ?i (fact-index ?f))
(printout t "The fact index is " ?i crlf))
CLIPS> (reset)
CLIPS> (run)
The fact index is 1
CLIPS> (facts)
f-0 (initial-fact)
f-1 (new-fact)
For a total of 2 facts.
CLIPS>

Resources