I'm having a slight difficulty in understanding how the not function interacts with pattern matching. I'd like to write a pattern match that goes "such a fact doesn't exist".
Namely, what I want is:
(defrule init-count
(not (highest-debt ?))
(catherines ?debt)
=>
(assert (highest-debt ?debt))
)
and then:
(defrule continue-count
?debt-fact <- (highest-debt ?h-debt)
(? ?a-debt)
(test (> ?a-debt ?h-debt))
=>
(retract ?debt-fact)
(assert (highest-debt ?a-debt))
)
But for some reason not doesn't work for me here. Replacing not with (not (exists /*pattern*/)) doesn't seem to work either.
Is there something I'm missing and/or a nice way to implement finding the highest number with rules like that?
Update
The answer that I have just discovered is this: the not pattern shouldn't be the first one ((declare (salience 0)) doesn't count either). So, the following code works correctly:
(defrule init-count
(catherines ?debt)
(not (highest-debt ?))
=>
(assert (highest-debt ?debt))
)
Sorry for bothering :(
In versions 6.24 and earlier, when the not conditional element was the first pattern in a rule, the pattern (initial-fact) was added before it (this is described in section 5.4.9, Automatic Addition and Reordering of LHS CEs, in the Basic Programming Guide). The (initial-fact) fact is asserted when a (reset) command is performed. I think this is the cause of your problem. Your original rule would have worked if you'd performed a (reset) before asserting your other facts.
Related
The question seems to be slight open-ended. I am in the process of handling rules (mostly production rules) with arithmetic operators. I also have an ontology which defines relationships between elements of these rules (This is atleast the inital setup). E.g.
Trivial Example
Facts
NoOfItems('100')
BaseRental('300')
Production Rule
Profit = (NoOfUnits * ProductionCostPerUnit) + TransportationCost - (NoOfUnits * SellingPricePerUnit)
TransportationCost = (FuelCost/Litre * FuelUsedInLitre) + DriverCost
Ontology:
Profit owl:sameAs ProfitPerQuarter
NoOfUnits owl:sameAs NoOfItems
I have handled these independently before i.e. Used Prolog (SWI-Prolog) for handling production type of rules or Even a Drools to handle them on a different occasion. To query RDF/OWL, I have used Apache Jena. including writing rules on the Triple Store.
But, can you guys suggest a framework which can handle both, like in this situation. I have heard of Prova, which can handle these. But, can Jena or Drools have reasoner which can handle both.
I am also new to Apache Jena/ Reasoners etc. I have done similar arithmetic operations using Apache Jena reasoners. There are many built-in functions available in Jena inferencing model.
As you have not mentioned how the RDF triples look like I am assuming the following format.
:production :hasunits "100"^^xsd:int
:production :costperunit "20"^^xsd:int
:production :sellingprice "25"^^xsd:int
:production :fuelcostlitre "20"^^xsd:int
:production :fuelused "10"^^xsd:int
:production :drivercost "100"^^xsd:int
Rules for the above mentioned RDF looks like
[r1: (?p :fuelcostlitre ?f)
(?p :fuelused ?l) (?p :drivercost ?d) product(?f ?l ?m) sum(?m ?d ?s)
-> (?p :transportation ?s)]
[r2: (?p :hasunits ?n) (?p :costperunit ?c) (?p :sellingprice ?m)
(?p :transportation ?t) product(?n ?c ?a) product(?n ?m ?b)
sum(?a ?t ?e) difference(?e ?b ?d)
-> (?p :profit ?d)
]
More about Jena built-in you can refer here.
https://jena.apache.org/documentation/inference/#RULEbuiltins
This is the Clips code that i am trying to arrange. I have some vector in de BH and I want to search among them, those which ?P is common between them. Moreover in the second vector to search the restriction is that ?E can only be that types. Please help me.
(defrule padre
(es-padre ?P ?H)
(?E & :(tigre | leopardo | jirafa | cebra | avestruz | pinguino | albatros) ?P)
=>
(assert (?E ?H))
)
Is there any solution implementing a Switch case, or the unique solution is making more rules?
You have multiple syntax errors, so it's hard to tell what you're trying to do. To start, the first field of a pattern or fact you're asserting can't be a variable. If you include examples in your question (such as the facts you're asserting and what should happen when your rule executes) it will make it easier to answer your question.
I am new to CLIPS development and I need to retrieve a rule body and store it in string in order to parse it. I tried to redirect the defrule stream but without success.
Is there any way to do it like that or does it exist a special command that I would have forgotten.
(defrule one
(fact a)
=>
(assert (fact b)))
(bind ?str (ppdefrule one))
one rule displaying but ?str is empty
Thank you for your time and consideration.
There's not a clean way to do this out of the box, but there's a C API for retrieving the text, so you could extend CLIPS with a user-defined function to allow you to do this. The alternative would be to use dribble-on/dribble-off to capture the output in a file, but this would also display the output to the screen each time you retrieved the rule text.
I wonder if it is somehow possible to have a construct, such that a user can modify a rule without triggering a rule. So my minimal example:
(defrule A-has-B
(A B)
=>
(assert (A-has-B)
)
(assert (A A))
f-1 (A A)
Now, I would like to modify (A A) to (A B) without triggering the rule "A-has-B".
First I thought about something like:
(defrule A-has-B
(A B)
(not (exists (usercontrol on)))
=>
(assert (A-has-B)
)
But after retracting '(usercontrol on)' the rule fires.
Maybe, somebody can tell me whether it's possible or not.
It is not possible to disable a pattern from being matched by a fact.
So, I'm trying to make a "golf club recommendation system" for a 18 hole course. Now, after having defined the basic templates for the golfcourse, golf club and the golf player, I'm stuck due to the large search space this particular problem presents. So currently I have:
(defrule teeoff
?g <- (golfer (position "tee"))
=>
(retract ?g)
(assert (golfer (position "fairway") (Current_club "driver") (Yardage 650))
After this, the ball is on fairway and can have a combination of factors say, it can be on sand, it can be on rough or it could be on a normal green. My question is instead of making a rule for every possibility can I have one or two rules like:
(defrule makemove
?m <- (golfer (position ?x))
?go <- (golfcourse (obstacles ?$y)
=>
(assert (golfer (Current_club ?c)))
If not, then what alternatives do I have?
I suggest to you to design an object or attribute to manage the ground_material (sand, green, ...) and include it inside the rule.
You can write rule for each ground or use IF-THEN condition inside a single rule.
Hope this helps you.
bye
Nic