What are the differences in creating the rules between CLIPS and PROLOG?
If I have a CLIPS rule, as in the example, what would be its translation in PROLOG?
(defrule Rule1
(declare (salience 1))
?a<-(factf (classfact agg|sost|nonst|scon)(valore ?x)(idstruttura ?id)(pos ?n) )
?canc<-(fn (inter[ ?sin)(componenti $?comp)(genere ?gen)(numero ?num)(]inter ?des) )
(not (fn (inter[ ?sin)(]inter ?n)))
(test (= ?n (+ 1 ?des)))
=>
(retract ?canc)
(bind ?*idstruct* (+ 1 ?*idstruct*))
(printout t crlf"********** Rule1 **********"crlf)
(assert (fn (inter[ ?sin)(componenti $?comp ?id)(genere ?gen)(numero ?num)(]inter ?n)(idstruttura ?*idstruct*)))
)
Related
I want to add a else part for below code as (assert (diabetes-assume false)). I glad if someone can help me to fix this issue.
(defrule diabetes-adult
(disease ?d)
(body-status ?b)
(age ?a&:(and (eq ?d none) (>= ?a 19) (< ?a 51) (or (eq ?b obesity) (eq ?b overweight) )))
=>
(assert (diabetes-assume true)))
You can assume as part of your initial state that diabetes is false and then define a higher salience rule (than the rules which rely on that assumption) to change the assumption to true:
(deffacts assumptions
(diabetes-assume false))
(defrule diabetes-adult-true
(declare (salience 10))
?f <- (diabetes-assume false)
(disease ?d)
(body-status ?b)
(age ?a&:(and (eq ?d none)
(>= ?a 19)
(< ?a 51)
(or (eq ?b obesity) (eq ?b overweight))))
=>
(retract ?f)
(assert (diabetes-assume true)))
I am trying to retract a deftemplate fact but when I do this CLIPS keeps saying I have to first declare the deffunction yet it is the appropriate deftemplate.What seems to be the problem?
I have attached the related code:
I get this error:
[EXPRNPSR3] Missing function declaration for Agriculture.
What seems to be the problem?
(deftemplate Agriculture
(slot weed
(type SYMBOL)
(allowed-symbols B G))
(slot crop
(type SYMBOL)
(allowed-symbols C S))
(slot organic-matter
(type INTEGER)
(allowed-values 1 2 3)))
(defrule Sencor-1
(and (Agriculture(weed B))
(Agriculture(crop C|S))
(Agriculture(organic-matter 1)))
=>
(printout t "Do not use Sencor!!"crlf))
(defrule Sencor-2
(and (Agriculture(weed B))
(Agriculture(crop C|S))
(Agriculture(organic-matter 2|3)))
=>
(printout t " " crlf "Use 3/4 pt/ac of Sencor" crlf ))
(defrule Lasso-1
(and (Agriculture(weed B|G))
(Agriculture(crop C|S))
(Agriculture(organic-matter 1)))
=>
(printout t crlf"Use 2 pt/ac of Lasso" crlf))
(defrule Lasso-2
(and (Agriculture(weed B|G))
(Agriculture(crop C|S))
(Agriculture(organic-matter 2)))
=>
(printout t crlf "Use 1 pt/ac of Lasso" crlf))
(defrule Lasso-3
(and (Agriculture(weed B|G))
(Agriculture(crop C|S))
(Agriculture(organic-matter 3)))
=>
(printout t crlf "Use 0.5 pt/ac of Lasso" crlf))
(defrule Bicep-1
(and (Agriculture(weed B|G))
(Agriculture(crop C))
(Agriculture(organic-matter 1)))
=>
(printout t crlf "Use 1.5 pt/ac of Bicep" crlf))
(defrule Bicep-2
(and (Agriculture(weed B|G))
(Agriculture(crop C))
(Agriculture(organic-matter 2)))
=>
(printout t crlf"Use 2.5 pt/ac of Bicep" crlf))
(defrule Bicep-3
(and (Agriculture(weed B|G))
(Agriculture(crop C))
(Agriculture(organic-matter 3)))
=>
(printout t crlf "Use 3 pt/ac of Bicep" crlf))
(defrule input
(initial-fact)
=>
(printout t crlf "What is the crop? (C:corn,S:soybean)")
(bind ?a (read))
(assert(Agriculture(crop ?a))) ;gets input from user
(printout t crlf "What is the weed problem? (B:broadleaf, G:grass)")
(bind ?b (read))
(assert(Agriculture(weed ?b)))
(printout t crlf "What is the % of organic matter content? (1:<2%,2:2-4%,3:>4%)")
(bind ?c (read))
(assert(Agriculture(organic-matter ?c)))
?d <- (Agriculture(crop ?a) (weed ?b) (organic-matter ?c))
(printout t ""crlf crlf "RECOMMENDATIONS:"crlf)
(retract ?d))
In the RHS of the input rule you state:
?d <- (Agriculture(crop ?a) (weed ?b) (organic-matter ?c))
This is interpreted as "Run function Agriculture and bind its results into ?d".
What you probably are trying to do is:
(bind ?d (assert (Agriculture (crop ?a) (weed ?b) (organic-matter ?c))))
I need to make complement and difference operations between two sets. I've a example, to do union between two sets, I can reuse this code to make these two other operations.
Thanks
The union example, that I've is:
(deffacts datos-iniciales
(conjunto B C A D E E B C E)
(conjunto E E B F D E))
(defrule inicio
=>
(assert (union)))
(defrule union
?h <- (union $?u)
(conjunto ? $? ?e $?)
(not (union $? ?e $?))
=>
(retract ?h)
(assert (union ?e $?u)))
Specifically, which part of the program should be changed? Thx
Here's how you can compute all three leaving the set-1 and set-2 facts unmodified, ignoring duplicate members, and sorting the results.
CLIPS (6.31 6/12/19)
CLIPS>
(deffacts datos-iniciales
(set-1 B C A D E E B C E)
(set-2 E E B F D E))
CLIPS>
(deffacts universe
(universe A B C D E F G H I J K))
CLIPS>
(deffunction str-sort (?a ?b)
(> (str-compare (sym-cat ?a) (sym-cat ?b)) 0))
CLIPS>
(defrule calcula
=>
(assert (union)
(complement)
(difference)))
CLIPS>
(defrule add-to-union
?union <- (union $?u)
(or (set-1 $? ?v $?)
(set-2 $? ?v $?))
(test (not (member$ ?v ?u)))
=>
(retract ?union)
(assert (union ?u ?v)))
CLIPS>
(defrule add-to-complement
?complement <- (complement $?c)
(universe $?u1 ?v $?u2)
(set-1 $?s)
(test (and (not (member$ ?v ?c))
(not (member$ ?v ?s))))
=>
(retract ?complement)
(assert (complement ?c ?v)))
CLIPS>
(defrule add-to-difference
?difference <- (difference $?d)
(set-1 $? ?v $?)
(set-2 $?set2)
(test (and (not (member$ ?v ?d))
(not (member$ ?v ?set2))))
=>
(retract ?difference)
(assert (difference ?d ?v)))
CLIPS>
(defrule write-union
(declare (salience -10))
(union $?u)
=>
(printout t "The union is " (sort str-sort ?u) crlf))
CLIPS>
(defrule write-complement
(declare (salience -10))
(complement $?c)
=>
(printout t "The complement is " (sort str-sort ?c) crlf))
CLIPS>
(defrule write-difference
(declare (salience -10))
(difference $?d)
=>
(printout t "The difference is " (sort str-sort ?d) crlf))
CLIPS> (reset)
CLIPS> (run)
The union is (A B C D E F)
The complement is (F G H I J K)
The difference is (A C)
CLIPS>
I'm trying to increment a defglobal variable (symcount) by 1 if the user defines that they have pain by using the (read) function
(defrule QPain
(initial-fact)
=>
(printout t "Are You In Pain? " crlf)
(bind (ans Answer) (read))
)
(defrule AnsInc
(Answ Answer = "y")
=>
(bind ?*symcount* (+ ?*symcount* 1)))
the increment must only happen of the user presses "y"
otherwise the increment must not happen.
CLIPS> (defglobal ?*symcount* = 0)
CLIPS>
(defrule QPain
=>
(printout t "Are You In Pain? ")
(bind ?answer (read))
(if (eq ?answer y)
then
(bind ?*symcount* (+ ?*symcount* 1))))
CLIPS> (reset)
CLIPS> (run)
Are You In Pain? y
CLIPS> ?*symcount*
1
CLIPS> (reset)
CLIPS> (run)
Are You In Pain? n
CLIPS> ?*symcount*
0
CLIPS>
Let's say that I have a rule like this:
(defrule get_next_N_poz
?id <- (get_next_poz $?)
(world (limit $?) (ball ?b1 ?b2) (men $? ?x ?y - $?) (id ?))
(and
(test (= ?x ?b1))
(test (= ?y (- ?b2 1))))
=>
(printout t "north ready position:" ?x ?y)
(modify ?id (get_next_poz 1)))
How do I add a new "and"?
Thank you.
It depends on what logic you're trying to implement. The existing and you have is redundant anyway, but if you wanted a second one, you'd just add it after the end of the last:
(and
(test (= ?x ?b1))
(test (= ?y (- ?b2 1))))
(and
(test (= ?x ?b2))
(test (= ?y (+ ?b1 1))))
If you wanted one or the other of these conditions you'd do this:
(or (and
(test (= ?x ?b1))
(test (= ?y (- ?b2 1))))
(and
(test (= ?x ?b2))
(test (= ?y (+ ?b1 1)))))
Rather than using and/or conditional elements, you could use the and/or boolean functions within a single test conditional element:
(test (or (and (= ?x ?b1)
(= ?y (- ?b2 1)))
(and (= ?x ?b2)
(= ?y (+ ?b1 1)))))