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>
Related
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>
I have certain template defined as follows:
(deftemplate action
(slot name)
(slot field)
(slot value))
I have other rules which will use other facts to assert the action fact.
Now I want to retrieve only the fact with template action.
For now, I am using find-fact to retrieve, but here I have to use query which I do not want to provide.
(find-fact ((?fact action)) (= (str-compare ?fact:name 'Action1') 0))
I want all facts with template action and do not want to write a loop over all names with Action1, Action2 etc..
Thank you in advance.
CLIPS (6.31 4/1/19)
CLIPS>
(deftemplate action
(slot name)
(slot field)
(slot value))
CLIPS>
(deffacts actions
(action (name Action1) (field x) (value 3))
(action (name Action2) (field y) (value 4))
(action (name Action3) (field z) (value 5)))
CLIPS>
(defrule find-Action1
(action (name Action1))
=>)
CLIPS> (reset)
CLIPS> (agenda)
0 find-Action1: f-1
For a total of 1 activation.
CLIPS> (facts)
f-0 (initial-fact)
f-1 (action (name Action1) (field x) (value 3))
f-2 (action (name Action2) (field y) (value 4))
f-3 (action (name Action3) (field z) (value 5))
For a total of 4 facts.
CLIPS>
I want to build an expert system in which in a case of emergency at a building with some floors (it needs to work for any amount of floors) the elevator should take the people into the ground.
The thing is, that the defrule to send the elevator at any floor never makes it in the agenda, so the system just does nothing. The correct action should be to fire the rule and then another rule that takes the people from the floor.
The code for the defrule is this:
(defrule move_to_floor "elevator moves to any floor "
?i <- (elevator is_at floor ?x has ?y adults and ?z minors)
(floor ?fl&~?x has ?n adult and ?m minor people)
(test (> (+ ?n ?m) 0))
=>
(retract ?i)
(assert (elevator is_at floor ?fl has ?y adults and ?z minors))
)
The facts as they have been initialized from the user in another defrule above are these:
f-0 (initial-fact)
f-1 (elevator is_at 0 has 0 adults and 0 minors)
f-3 (capacity 4)
f-4 (floors 3)
f-5 (initCanEnter 0) ;At 0 this prevents from entering the init_defrule again
f-6 (floor 3 has 2 adult and 1 minor people)
f-7 (floor 2 has 4 adult and 5 minor people)
f-8 (floor 1 has 1 adult and 2 minor people)
I can't seem to find the solution. Also, I'm using deffacts and not deftemplate as I have seen many people using on the internet.
You can use the matches command to see which patterns in a rule are matched.
CLIPS (6.31 2/3/18)
CLIPS>
(defrule move_to_floor "elevator moves to any floor "
?i <- (elevator is_at floor ?x has ?y adults and ?z minors)
(floor ?fl&~?x has ?n adult and ?m minor people)
(test (> (+ ?n ?m) 0))
=>
(retract ?i)
(assert (elevator is_at floor ?fl has ?y adults and ?z minors)))
CLIPS>
(deffacts initial
(elevator is_at 0 has 0 adults and 0 minors)
(capacity 4)
(floors 3)
(initCanEnter 0) ;At 0 this prevents from entering the init_defrule again
(floor 3 has 2 adult and 1 minor people)
(floor 2 has 4 adult and 5 minor people)
(floor 1 has 1 adult and 2 minor people))
CLIPS> (reset)
CLIPS> (matches move_to_floor)
Matches for Pattern 1
None
Matches for Pattern 2
f-5
f-6
f-7
Partial matches for CEs 1 - 2
None
Activations
None
(3 0 0)
CLIPS>
In this case, the first pattern is not matched. That's because your pattern expects is_at floor ?x but your fact contains is_at 0 (the symbol floor is missing in your fact). If you correct this issue, the rule will be placed on the agenda.
CLIPS>
(deffacts initial
(elevator is_at floor 0 has 0 adults and 0 minors)
(capacity 4)
(floors 3)
(initCanEnter 0) ;At 0 this prevents from entering the init_defrule again
(floor 3 has 2 adult and 1 minor people)
(floor 2 has 4 adult and 5 minor people)
(floor 1 has 1 adult and 2 minor people))
CLIPS> (reset)
CLIPS> (agenda)
0 move_to_floor: f-1,f-7
0 move_to_floor: f-1,f-6
0 move_to_floor: f-1,f-5
For a total of 3 activations.
CLIPS>
If you issue a (run) command at this point, the rules will endlessly fire in a loop moving from floor to floor, so that's something you'll need to address next.
If you use deftemplate facts rather than ordered facts, you'll get an error if you misspell slot names, so it's better to use these if you have a fact with multiple attributes.
CLIPS> (clear)
CLIPS>
(deftemplate elevator
(slot at_floor (type INTEGER))
(slot adults (type INTEGER))
(slot minors (type INTEGER)))
CLIPS>
(deftemplate floor
(slot # (type INTEGER))
(slot adults (type INTEGER))
(slot minors (type INTEGER)))
CLIPS>
(deffacts initial
(elevator (at_floor 0))
(capacity 4)
(floors 3)
(initCanEnter 0)
(floor (# 3) (adults 2) (minors 1))
(floor (# 2) (adults 4) (minors 5))
(floor (# 1) (adults 1) (minors 2)))
CLIPS>
(defrule move_to_floor
?i <- (elevator (at_floor ?x))
(floor (# ?fl&~?x) (adults ?n) (minors ?m))
(test (> (+ ?n ?m) 0))
=>
(modify ?i (at_floor ?fl)))
CLIPS> (reset)
CLIPS> (facts)
f-0 (initial-fact)
f-1 (elevator (at_floor 0) (adults 0) (minors 0))
f-2 (capacity 4)
f-3 (floors 3)
f-4 (initCanEnter 0)
f-5 (floor (# 3) (adults 2) (minors 1))
f-6 (floor (# 2) (adults 4) (minors 5))
f-7 (floor (# 1) (adults 1) (minors 2))
For a total of 8 facts.
CLIPS> (agenda)
0 move_to_floor: f-1,f-7
0 move_to_floor: f-1,f-6
0 move_to_floor: f-1,f-5
For a total of 3 activations.
CLIPS>
I'm asking if there is a possibility of accessing a get the index of fact in RHS of defrule ?
It gives me that undefined every time I try to index a fact in a RHS of defrule.
because I have a while loop , I want to be able to modify elevator fact depending on my input data.
(deftemplate elevator
(slot goal))
(deffacts elevator
(elevator (goal 0)))
(defrule read-data
=>
?f1 <- (elevator)
(modify ?f2 (goal 1))
)
this an example of my code , since I can't put all online :
(deftemplate data
(slot data)
)
(deffacts data
(data (data 1))
)
(defrule rule1
?f1 <-(data)
=>
(bind ?value (readline input) )
(while (neq ?value EOF)
do
(bind ?data (fact-slot-value ?f1 data))
(printout t "data " ?data crlf )
(retract ?f1)
(modify ?f1 (data ?value))
(bind ?value (readline input)
)
)
)
this is my input file :
2
3
4
5
6
7
this is what I'm getting :
CLIPS> (run)
data 1
data FALSE
data FALSE
data FALSE
data FALSE
data FALSE
CLIPS>
I want it to print out
data 2
data 3
data 4 ..ect
You can do it this way from the RHS of a rule, but if your rule actually has no LHS conditions, it's pointless to use a rule to change the value of the fact. Just use a function.
CLIPS>
(deftemplate elevator
(slot goal))
CLIPS>
(deffacts elevator
(elevator (goal 0)))
CLIPS>
(defrule read-data
=>
(do-for-fact ((?f elevator)) TRUE
(modify ?f (goal 1))))
CLIPS> (watch facts)
CLIPS> (reset)
<== f-0 (initial-fact)
==> f-0 (initial-fact)
==> f-1 (elevator (goal 0))
CLIPS> (run)
<== f-1 (elevator (goal 0))
==> f-2 (elevator (goal 1))
CLIPS>
Alternately, you can bind the fact you want to modify in the conditions of the rule:
CLIPS> (clear)
CLIPS>
(deftemplate elevator
(slot goal))
CLIPS>
(deffacts elevator
(elevator (goal 0)))
CLIPS>
(defrule read-data
?f <- (elevator (goal 0))
=>
(modify ?f (goal 1)))
CLIPS> (watch facts)
CLIPS> (reset)
<== f-0 (initial-fact)
==> f-0 (initial-fact)
==> f-1 (elevator (goal 0))
CLIPS> (run)
<== f-1 (elevator (goal 0))
==> f-2 (elevator (goal 1))
CLIPS>
Updated:
You can get your original rule to "work" by removing the retract and rebinding ?f1 to the value returned by modify:
CLIPS> (clear)
CLIPS>
(deftemplate data
(slot data))
CLIPS>
(deffacts data
(data (data 1)))
CLIPS>
(defrule rule1
?f1 <- (data)
=>
(bind ?value (readline input))
(while (neq ?value EOF)
(bind ?data (fact-slot-value ?f1 data))
(printout t "data " ?data crlf )
(bind ?f1 (modify ?f1 (data ?value)))
(bind ?value (readline input))))
CLIPS> (reset)
CLIPS> (open input.txt input)
TRUE
CLIPS> (run)
data 1
data 2
data 3
data 4
data 5
data 6
CLIPS> (close input)
TRUE
CLIPS>
It's still suspiciously complicated to be modifying the same fact multiple times on the RHS.
i have deftemplate for url that contains url itself and integer counter :
(deftemplate url_t
(slot counter
(type INTEGER)
(default 0))
(slot url
(type STRING)
(default "")))
and i am trying to define the rule to print url string if counter value >0
(defrule print-url
(url_t (counter ?counter) (url ?url))
(test (> ?counter 0))
=>
(printout t "url is " ?url crlf)
)
But when i try to change the values of url_t:
(assert url_t (counter 2) (url "hello hello"))
The rule is not executed. Where's my error?
If the assert statement in your description is exactly what you entered, then that's your problem because the syntax is invalid. Other than that, there's nothing wrong with the syntax of your deftemplate or defrule:
CLIPS> (clear)
CLIPS> (unwatch all)
CLIPS>
(deftemplate url_t
(slot counter
(type INTEGER)
(default 0))
(slot url
(type STRING)
(default "")))
CLIPS>
(defrule print-url
(url_t (counter ?counter) (url ?url))
(test (> ?counter 0))
=>
(printout t "url is " ?url crlf))
CLIPS> (assert (url_t (counter 2) (url "hello hello")))
<Fact-1>
CLIPS> (facts)
f-0 (initial-fact)
f-1 (url_t (counter 2) (url "hello hello"))
For a total of 2 facts.
CLIPS> (agenda)
0 print-url: f-1
For a total of 1 activation.
CLIPS> (run)
url is hello hello
CLIPS> (modify 1 (counter 3) (url "goodbye goodbye"))
<Fact-2>
CLIPS> (agenda)
0 print-url: f-2
For a total of 1 activation.
CLIPS> (run 1)
url is goodbye goodbye
CLIPS> (modify 2 (counter 0) (url "won't fire"))
<Fact-3>
CLIPS> (agenda)
CLIPS>