How to read/use user input using CLIPS - clips

I'm working on a Clips project.
I am trying to firstly store facts (which is fine).
Then I am trying to ask the user to provide details about the gems that are stored as facts, and based on their answer, to provide them with the correct name of the gem.
(deftemplate gem
(slot name)
(slot hardness)
(slot density)
(multislot colors))
(deffacts gems
(gem (name diamond) (hardness 10) (density 3.52) (colors yellow, brown, green, blue, white, colorless))
(gem (name corundum) (hardness 9) (density 4) (colors red, pink, yellow, brown, green, blue, violet, black, white, colorless))
(gem (name chrysoberyl) (hardness 8.5) (density 3.72) (colors yellow,brown,green))
(gem (name spinel) (hardness 8) (density 3.6) (colors red, pink, yellow, brown, green, blue, violet, white, colorless)))
(defrule reading-input
=>
(printout t "Enter the hardness of the gem: " )
(assert (var(read)))
(printout t "Enter the density of the gem: " )
(assert (var(read)))
(printout t "Enter the color of the gem: " )
(assert (var(read))))
(defrule checking-input
(var ?hardness)
(var ?density)
(var ?colors)
(gem (name ?name1) (hardness ?hardness1) (density ?density1) (colors $?colors1))
(test (= ?hardness ?hardness1))
(test (= ?hardness ?hardness1))
(test (member$ ?hardness ?hardness1))
=>
(printout t "Gem is " ?name1 crlf))
I am a beginner in CLIPS and cannot figure out how to get the above code to work right despite spending hours on it. Any help would be appreciated.Thank you.

CLIPS (6.31 2/3/18)
CLIPS>
(deftemplate gem
(slot name)
(slot hardness)
(slot density)
(multislot colors))
CLIPS>
(deffacts gems
(gem (name diamond) (hardness 10) (density 3.52) (colors yellow brown green blue white colorless))
(gem (name corundum) (hardness 9) (density 4) (colors red pink yellow brown green blue violet black white colorless))
(gem (name chrysoberyl) (hardness 8.5) (density 3.72) (colors yellow brown green))
(gem (name spinel) (hardness 8) (density 3.6) (colors red pink yellow brown green blue violet white colorless)))
CLIPS>
(defrule reading-input
=>
(printout t "Enter the hardness of the gem: " )
(assert (hardness (read)))
(printout t "Enter the density of the gem: " )
(assert (density (read)))
(printout t "Enter the color of the gem: " )
(assert (color (read))))
CLIPS>
(defrule checking-input
(hardness ?hardness)
(density ?density)
(color ?color)
(gem (name ?name1) (hardness ?hardness1) (density ?density1) (colors $?colors1))
(test (= ?hardness ?hardness1))
(test (= ?density ?density1))
(test (member$ ?color ?colors1))
=>
(printout t "Gem is " ?name1 crlf))
CLIPS> (reset)
CLIPS> (run)
Enter the hardness of the gem: 9
Enter the density of the gem: 4
Enter the color of the gem: green
Gem is corundum
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 - How do I prompt a user until they enter a valid input

I'm having some trouble with this problem and would appreciate it if anyone could help me with it! My code asks the user for characteristics of a gem (hardness, density and colors) and returns its name. However, the user should be prompted until he or she responds with one of the colors listed here(red, pink, yellow, brown, green, blue, violet, black, white, colorless) and I don't know how to do that even after spending hours on this...
(deftemplate characteristics
(slot name)
(slot hardness)
(slot density)
(multislot colors)
(deffacts gems
(characteristics (name Diamond) (hardness 10) (density 3.52) (colors yellow brown green blue white colorless))
(characteristics (name Corundum) (hardness 9) (density 4) (colors red pink yellow brown green blue violet black white colorless))
(characteristics (name Chrysoberyl) (hardness 8.5) (density 3.72) (colors yellow brown green))
(characteristics (name Spinel) (hardness 8) (density 3.6) (colors red pink yellow brown green blue violet white colorless))
(characteristics (name Topaz) (hardness 8) (density 3.52) (colors red pink yellow brown blue violet white colorless))
(characteristics (name Beryl) (hardness 7.5) (density 2.7) (colors red pink yellow brown green blue white colorless))
(characteristics (name Zircon) (hardness 6) (density 4.7) (colors yellow brown green violet white colorless))
(characteristics (name Quartz) (hardness 7) (density 2.65) (colors yellow brown green blue violet white black colorless))
(characteristics (name Tourmaline) (hardness 7) (density 3.1) (colors red pink yellow brown green blue white black colorless))
(characteristics (name Peridot) (hardness 6.5) (density 3.3) (colors yellow brown green))
(characteristics (name Jadeite) (hardness 6.5) (density 3.3) (colors red pink yellow brown green blue violet white black colorless))
(characteristics (name Opal) (hardness 5.5) (density 2) (colors red pink yellow brown white black colorless))
(characteristics (name Nephrite) (hardness 5) (density 2.9) (colors green white black colorless))
(characteristics (name Turquoise) (hardness 5) (density 2.7) (colors blue)))
(defrule get-input
=>
(printout t "What is the hardness?")
(assert (hardness (read)))
(printout t "What is the density?")
(assert (density (read)))
(printout t "What is/are the color(s)?")
(assert (colors (read))))
(defrule what-gem-is-this
(hardness ?hardness)(density ?density)(colors ?colors)
(characteristics(name ?name1)(hardness ?hardness1)(density ?density1)(colors $?colors1))
(test (= ?hardness ?hardness1))
(test (= ?density ?density1))
(test (member$ ?colors ?colors1))
=>
(printout t "The gem described is a: " ?name1 crlf))
Define a function that you can pass a question and a set of allowed values:
CLIPS (6.31 4/1/19)
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 "What is the color? " yellow brown green blue white colorless red pink violet black)
What is the color? orange
What is the color? purple
What is the color? red
red
CLIPS>
Here's how you can check values using rules:
CLIPS>
(defrule get-color
(not (color ?))
=>
(printout t "What is the color? ")
(assert (color (read))))
CLIPS>
(defrule bad-color
?f <- (color ~yellow&~brown&~green&~blue&~white&~colorless&~red&~pink&~violet&~black)
=>
(retract ?f))
CLIPS>
(defrule get-hardness
(not (hardness ?))
=>
(printout t "What is the hardness? ")
(assert (hardness (read))))
CLIPS>
(defrule bad-hardness
?f <- (hardness ?h)
(test (or (not (numberp ?h))
(< ?h 1)
(> ?h 10)))
=>
(retract ?f))
CLIPS> (run)
What is the hardness? very
What is the hardness? 20
What is the hardness? 10
What is the color? orange
What is the color? blue
CLIPS>

CLIPS How to divide text into word?

I need to write a method of a function that does the following:
Divides the text into words;
Prints words that are different from the first word;
And before that converts each word according to the following rule:
If the word is odd, then removes its middle letter.
The result is displayed on the screen and in a text file.
Here's a function that will give you the list of different words:
CLIPS>
(deffunction munge (?text)
(bind ?w1 (explode$ ?text))
(bind ?w2 (create$))
(progn$ (?w ?w1)
(bind ?len (str-length ?w))
(if (oddp ?len)
then
(bind ?nw (str-cat (sub-string 1 (div ?len 2) ?w)
(sub-string (+ (div ?len 2) 2) ?len ?w)))
(bind ?w2 (create$ ?w2 ?nw))
else
(bind ?w2 (create$ ?w2 (str-cat ?w)))))
(bind ?first (nth$ 1 ?w2))
(bind ?rest (rest$ ?w2))
(bind ?w3 (create$))
(progn$ (?w ?w2)
(if (neq ?w ?first)
then
(bind ?w3 (create$ ?w3 ?w))))
?w3)
CLIPS> (munge "red green blue purple brown green white red black blue")
("gren" "blue" "purple" "brwn" "gren" "whte" "blck" "blue")
CLIPS>
I suggest you to start with some basic documentation.
An example:
http://www2.cs.siu.edu/~rahimi/cs537/slides/big-2.pdf
You should look at multi-field built-in functions.

Unable to generate output

When I run the below code, it doesn't give me any output. It prints Flag color (done to end)?. Not sure what I am missing. Any help is appreciated. Thank you
(deftemplate flag (slot country) (multislot colors))
(deffacts countries
(flag (country USA) (colors red white blue))
(flag (country Belgium) (colors black yellow red))
(flag (country Poland) (colors white red))
(flag (country Monaco) (colors white red))
(flag (country Sweden) (colors yellow blued))
(flag (country Panama) (colors red white blue))
(flag (country Jamaica) (colors black yellow green))
(flag (country Columbia) (colors yellow blue red))
(flag (country Italy) (colors green white red))
(flag (country Greece) (colors blue white))
(flag (country Botswana) (colors blue white black)))
(deffacts start
(get-color))
(defrule get-colors
?f <- (get-color)
=>
(retract ?f)
(printout t "Flag color (done to end)?")
(assert (new-color (read))))
(defrule find-matches
(find-flag)
(exists (color ?))
(flag (country ?country))
(forall (color ?color)
(flag (country ?country) (colors $? ?color $?)))
=>
(printout t ?country " 's flag contains the specified colors." crlf))
(defrule no-matches
(find-flag)
(not (and (flag (country ?country))
(forall (color ?color)
(flag (country ?country) (colors $? ?color $?)))))
=>
(printout t "No country's flag contains the specified colors." crlf))
(defrule all-flags-match
(find-flag)
(not (color ?))
=>
(printout t "No search colors were specified." crlf))
(defrule look-for-flags
?f <- (new-color done)
=>
(retract ?f)
(assert (find-flag)))
(defrule look-for-another-color
?f <- (new-color ?color&~done)
=>
(assert (color ?color))
(retract ?f)
(assert (get-color)))
The program is expecting you to enter one or more colors. When you've specified all of the colors, enter done at the prompt. It then prints the names of the countries that have flags containing those colors.
CLIPS> (reset)
CLIPS> (run)
Flag color (done to end)?red
Flag color (done to end)?done
Italy 's flag contains the specified colors.
Columbia 's flag contains the specified colors.
Panama 's flag contains the specified colors.
Monaco 's flag contains the specified colors.
Poland 's flag contains the specified colors.
Belgium 's flag contains the specified colors.
USA 's flag contains the specified colors.
CLIPS> (reset)
CLIPS> (run)
Flag color (done to end)?red
Flag color (done to end)?white
Flag color (done to end)?done
Italy 's flag contains the specified colors.
Panama 's flag contains the specified colors.
Monaco 's flag contains the specified colors.
Poland 's flag contains the specified colors.
USA 's flag contains the specified colors.
CLIPS> (reset)
CLIPS> (run)
Flag color (done to end)?red
Flag color (done to end)?white
Flag color (done to end)?blue
Flag color (done to end)?done
Panama 's flag contains the specified colors.
USA 's flag contains the specified colors.
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>

Resources