CLIPSjni integrated JADE java - clips

I just started working with CLIPS integrated with Jade one agent.java, I have my facts and rules loaded in different .clp files, I already spent a lot of time trying to compare what I think are numbers but for some reason it doesn´t work, tried many different things nothing make it works:
Here part of my facts:
(deffacts products
(product (name "USB Memory") (category storage) (part-number 1234) (price 9.99))
(product (name Amplifier) (category electronics) (part-number 2341) (price 399.99))
(product (name Speakers) (category electronics) (part-number 23241) (price 19.99))
(product (name "iPhone 7") (category smartphone) (part-number 3412) (price 99))
(product (name "Samsung Edge 7") (category smartphone) (part-number 34412) (price 88))
)
And here I have the rules that are not working:
(defrule my-rule14
(not (product (category smartphone) **(price<50)**))
=>
(printout t "no smartphones cheaper than 50" crlf ))
;; Defining a rule for finding smartphones cheaper than 100 dlls
(defrule my-rule15
(product (category smartphone) (name ?nameb) **(price<100))**
=>
(printout t ?nameb " is cheaper than 100 dlls" crlf ))
None of the rules are working I tried changing comparison to {price<100}, (price< 100), (price < 100), (price ?pricea) (test(< ?pricea 100))
Thanks.

Sections 5.4.1.5 and 5.4.2 of the Basic Programming Guide contain the relevant information for the syntax needed:
CLIPS (6.4 2/9/21)
CLIPS>
(deftemplate product
(slot name)
(slot category)
(slot part-number)
(slot price))
CLIPS>
(deffacts products
(product (name "USB Memory") (category storage) (part-number 1234) (price 9.99))
(product (name Amplifier) (category electronics) (part-number 2341) (price 399.99))
(product (name Speakers) (category electronics) (part-number 23241) (price 19.99))
(product (name "iPhone 7") (category smartphone) (part-number 3412) (price 99))
(product (name "Samsung Edge 7") (category smartphone) (part-number 34412) (price 88)))
CLIPS>
(defrule my-rule14
(not (product (category smartphone) (price ?price&:(< ?price 50))))
=>
(printout t "no smartphones cheaper than 50" crlf))
CLIPS>
(defrule my-rule15
(product (category smartphone) (name ?nameb) (price ?price))
(test (< ?price 100))
=>
(printout t ?nameb " is cheaper than 100 dlls" crlf ))
CLIPS> (reset)
CLIPS> (agenda)
0 my-rule15: f-5
0 my-rule15: f-4
0 my-rule14: *
For a total of 3 activations.
CLIPS> (run)
Samsung Edge 7 is cheaper than 100 dlls
iPhone 7 is cheaper than 100 dlls
no smartphones cheaper than 50
CLIPS>

Related

Clips range find between 2 json inputs

I want to implemen a rule ;
Lets assume that ı have one input.json it consist a name value pair.Example;
{
"quality":"300"
}
I have another constant json ,Example
[{
"up":"100",
"down":"0",
"data":"xx"
},
{
"up":"200",
"down":"100",
"data":"yy"
},
,
{
"up":"300",
"down":"200",
"data":"zz"
}
]
I am trying to find propert value for data for which up and down range.
for this one ı, have to get zz because "quality":"300" is between 200-300.
how can ı success this one in clips rule.
CLIPS (6.31 6/12/19)
CLIPS>
(deftemplate pair
(slot name)
(slot value))
CLIPS>
(deffacts pairs
(pair (name "quality") (value 300)))
CLIPS>
(deftemplate data
(slot name)
(slot up)
(slot down))
CLIPS>
(deffacts data-values
(data (name "xx") (up 100) (down 0))
(data (name "yy") (up 200) (down 100))
(data (name "zz") (up 300) (down 200)))
CLIPS>
(defrule in-range
(pair (name "quality")
(value ?value))
(data (name ?name)
(up ?up)
(down ?down))
(test (and (> ?value ?down) (<= ?value ?up)))
=>
(printout t ?name " is in range." crlf))
CLIPS> (reset)
CLIPS> (facts)
f-0 (initial-fact)
f-1 (pair (name "quality") (value 300))
f-2 (data (name "xx") (up 100) (down 0))
f-3 (data (name "yy") (up 200) (down 100))
f-4 (data (name "zz") (up 300) (down 200))
For a total of 5 facts.
CLIPS> (agenda)
0 in-range: f-1,f-4
For a total of 1 activation.
CLIPS> (run)
zz is in range.
CLIPS>

Clips Expert System

I'm trying to create an expert system that decides whether or not you can buy a house. I want to know how to word a rule that allows the person to buy a house if they're over a certain age. For Example, if you type in that you're over 40 years old the system would come back and tell you that you're not allowed to buy a home.
I have tried this code below but it doesn't work
(defrule age-over-forty
(student yes)
(income low)
(credit excellent)
(age 40>)
=>
(printout t "You can not buy a house" crlf))
EDIT: What I mean by "it doesn't work" ; When I run it, you type in a age, lets just say I typed in 46. It would add it to the facts but it is supposed to print out "You can not buy a house" so it doesn't satisfy the (age 40>) part of the code.
Use the predicate constraint (section 5.4.1.5 of the CLIPS 6.3 Basic Programming Guide) or alternatively the test conditional element to perform a numeric comparison.
CLIPS (6.31 6/12/19)
CLIPS>
(defrule age-over-forty
(student yes)
(income low)
(credit excellent)
(age ?age&:(> ?age 40))
=>
(printout t "You can not buy a house" crlf))
CLIPS>
(assert (student yes)
(income low)
(credit excellent)
(age 46))
<Fact-4>
CLIPS> (agenda)
0 age-over-forty: f-1,f-2,f-3,f-4
For a total of 1 activation.
CLIPS> (run)
You can not buy a house
CLIPS>

How can I get the sum of items in a multislot

I have a template like the one shown bellow. How can I get the sum of items in the multislot grades?
(deftemplate student
(multislot name)
(multislot grades)
)
Here's one way to do it. In the reg6 rule, the + function is given two arguments of 0 in addition to the grades to insure that the + function allows has at least 2 arguments; otherwise, if there were zero or one grades for the student you'd get an error.
CLIPS (6.31 2/3/18)
CLIPS>
(deftemplate student
(multislot name)
(multislot grades))
CLIPS>
(deftemplate sum
(multislot name)
(slot grade))
CLIPS>
(defrule reg6
(student (name $?name)
(grades $?grades))
=>
(assert (sum (name ?name)
(grade (+ 0 0 (expand$ ?grades))))))
CLIPS>
(assert (student (name David Green) (grades))
(student (name Sue Brown) (grades 90))
(student (name Frank Black) (grades 85 75)))
<Fact-3>
CLIPS> (run)
CLIPS> (facts)
f-0 (initial-fact)
f-1 (student (name David Green) (grades))
f-2 (student (name Sue Brown) (grades 90))
f-3 (student (name Frank Black) (grades 85 75))
f-4 (sum (name Frank Black) (grade 160))
f-5 (sum (name Sue Brown) (grade 90))
f-6 (sum (name David Green) (grade 0))
For a total of 7 facts.
CLIPS>
You can use the expand$ function. Check in the Basic Programming Guide the Multifield Expansion Function chapter to know more.
(deftemplate student
(multislot name)
(multislot grades))
(defrule grades-sum
(student (grades $?grades))
=>
(printout t "Student grades sum is " (+ (expand$ ?grades))))
(assert (student (grades (create$ 1 2 3 4 5))))
(student (name) (grades 1 2 3 4 5))
(run)
Student grades sum is 15

Check multiple facts in 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>

How to printout all matches facts in a rule

I have a rule like below and I want to print all facts(here objct) that are compatible to this rule. I have a fact objct and there are some of these "objct"s that follow the rule. how I can do it? The printout below just prints the latest objct that player got. However I want to printout all of them. Any idea?
(defrule have_objcts
?input <- (input have|possession)
(objct (name ?n) (location player) (used 0))
=>
;WHAT SHOULD I WRITE HERE TO PRINTOUT those OBJCT's BELONG TO
PALYER???????????
(printout t crlf ?n)
(retract ?input))
Use the matches command:
CLIPS>
(deftemplate objct
(slot name)
(slot location)
(slot used))
CLIPS>
(deffacts initial
(objct (name x) (location player) (used 0))
(objct (name y) (location elsewhere) (used 1))
(objct (name z) (location player) (used 0))
(input have)
(input want)
(input possession)
(input thing))
CLIPS>
(defrule have_objcts
?input <- (input have|possession)
(objct (name ?n) (location player) (used 0))
=>
(retract ?input))
CLIPS> (reset)
CLIPS> (matches have_objcts)
Matches for Pattern 1
f-4
f-6
Matches for Pattern 2
f-1
f-3
Partial matches for CEs 1 - 2
f-6,f-3
f-6,f-1
f-4,f-3
f-4,f-1
Activations
f-6,f-3
f-6,f-1
f-4,f-3
f-4,f-1
(4 4 4)
CLIPS> (run)
CLIPS> (matches have_objcts)
Matches for Pattern 1
None
Matches for Pattern 2
f-1
f-3
Partial matches for CEs 1 - 2
None
Activations
None
(2 0 0)
CLIPS>

Resources