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>
Related
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>
I'm trying to define some rules with CLIPS for searching pieces of text in paragraphs or documents (e.g. filter the words that contain the letter 'a' or search for words that appear more than once), but I cannot find any example. Where can I find some examples for my problem?
Within your rule patterns you'd place constraints either on multiple words from your paragraph (such as to see if the same words appears more than once):
CLIPS>
(deftemplate paragraph
(multislot words))
CLIPS>
(defrule more-than-once
(paragraph (words $? ?w $? ?w $?))
=>
(assert (more-than-once ?w)))
CLIPS>
(defrule print-more-than-once
(more-than-once ?w)
=>
(printout t "'" ?w "' appears more than once." crlf))
CLIPS>
(assert (paragraph (words the quick brown fox jumped over the lazy dogs)))
<Fact-1>
CLIPS> (run)
'the' appears more than once.
CLIPS>
Or you'd place them on a single word:
CLIPS>
(defrule contains-e
(paragraph (words $? ?w&:(str-index "e" ?w) $?))
=>
(assert (contains ?w e)))
CLIPS>
(defrule print-contains
(contains ?w ?l)
=>
(printout t "'" ?l "' is contained in '" ?w "'." crlf))
CLIPS> (run)
'e' is contained in 'the'.
'e' is contained in 'jumped'.
'e' is contained in 'over'.
CLIPS>
Let's say I have some facts (I do not know how many there are) like this: lamp x is off. With a defrule I proggressively turn all lamps on so every fact will be: lamp x is on. How do I check every lamp that is on. I know that if there were three lamps I could write:
(defrule checkAllLamps
(lamp 1 is on)
(lamp 2 is on)
(lamp 3 is on)
=>
(printout t "All lamps are on now")
)
But for x lamps?
Thank you!
You can use fact-set query functions for that (chapter 12.9.12 of the Basic Programming Guide).
(deftemplate lamp
(slot id (type INTEGER))
(slot state (type SYMBOL)))
(defrule all-lamps-are-on
(lamp (state on))
(test (>= (length$ (find-all-facts ((?l lamp)) (eq ?l:state on))) 3))
=>
(printout t "All lamps are on" crlf))
Here's how you can check whether all of the lamps are on. The checkAllLamps rule treats the case where there are no lamps at all as all lamps being on, whereas the checkAllLampsAtLeastOne rule requires that there is at least one lamp that is on.
CLIPS (6.31 2/3/18)
CLIPS>
(defrule checkAllLamps
(not (lamp ? is off))
=>
(printout t "All lamps are on now" crlf))
CLIPS>
(defrule checkAllLampsAtLeastOne
(exists (lamp ? is on))
(not (lamp ? is off))
=>
(printout t "All lamps are on now" crlf))
CLIPS> (agenda)
0 checkAllLamps: *
For a total of 1 activation.
CLIPS> (assert (lamp 1 is on))
<Fact-1>
CLIPS> (agenda)
0 checkAllLampsAtLeastOne: *,*
0 checkAllLamps: *
For a total of 2 activations.
CLIPS> (assert (lamp 2 is off))
<Fact-2>
CLIPS> (agenda)
CLIPS> (retract 2)
CLIPS> (assert (lamp 2 is on))
<Fact-3>
CLIPS> (agenda)
0 checkAllLampsAtLeastOne: *,*
0 checkAllLamps: *
For a total of 2 activations.
CLIPS>
In my system the user inputs a Y or N to answer simple questions. I call this rule after every question to increment a counter. There are some general problems with my code but i can't see where
(defrule QPain
(initial-fact)
=>
(printout t "Are You In Pain? " crlf)
(bind ?*Answer* (read))
)
(defrule IncSym
(test(=(str-compare (?*Answer*) "y")0))
=>
(bind ?*symcount* (+ ?*symcount* 1))
)
Thanks
The syntactic errors can be corrected as follows:
CLIPS> (clear)
CLIPS> (defglobal ?*Answer* = nil)
CLIPS> (defglobal ?*symcount* = 0)
CLIPS>
(defrule QPain
=>
(printout t "Are you in pain? ")
(bind ?*Answer* (read)))
CLIPS>
(defrule IncSym
(test (eq ?*Answer* y))
=>
(bind ?*symcount* (+ ?*symcount* 1)))
CLIPS> (reset)
CLIPS> (run)
Are you in pain? y
CLIPS> (show-defglobals)
?*Answer* = y
?*symcount* = 0
CLIPS>
This won't produce the behavior you're expecting, however, since ?*symcount* will not be incremented. The behavior of global variables and why you should not be using them in the manner you're attempting has been discussed previously:
How exactly (refresh) works in the clips?
CLIPS: forcing a rule to re-evaluate the value of a global variable?
Number equality test fails in CLIPS pattern matching?
CLIPS constant compiler directive
How can I run the clips with out reset the fact when using CLIPS
Instead of using global variables to track responses and symptoms, you should use facts or instances. Here's one approach:
CLIPS> (clear)
CLIPS>
(deftemplate symptom
(slot id)
(slot response))
CLIPS>
(deftemplate symptom-list
(multislot values))
CLIPS>
(deffacts initial
(symptom-list))
CLIPS>
(defrule QPain
=>
(printout t "Are you in pain? ")
(assert (symptom (id in-pain) (response (read)))))
CLIPS>
(defrule IncSym
(symptom (id ?id) (response y))
?f <- (symptom-list (values $?list))
(test (not (member$ ?id ?list)))
=>
(modify ?f (values ?list ?id)))
CLIPS>
(defrule symptoms-found
(declare (salience -10))
(symptom-list (values $?list))
=>
(printout t "Symptom count: " (length$ ?list) crlf))
CLIPS> (reset)
CLIPS> (run)
Are you in pain? y
Symptom count: 1
CLIPS> (reset)
CLIPS> (run)
Are you in pain? n
Symptom count: 0
CLIPS>
And another:
CLIPS> (clear)
CLIPS>
(deftemplate symptom
(slot id)
(slot response))
CLIPS>
(defrule QPain
=>
(printout t "Are you in pain? ")
(assert (symptom (id in-pain) (response (read)))))
CLIPS>
(defrule symptoms-found
(declare (salience -10))
=>
(bind ?count (find-all-facts ((?f symptom)) (eq ?f:response y)))
(printout t "Symptom count: " (length$ ?count) crlf))
CLIPS> (reset)
CLIPS> (run)
Are you in pain? y
Symptom count: 1
CLIPS> (reset)
CLIPS> (run)
Are you in pain? n
Symptom count: 0
CLIPS>
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>