I think Ken Dornback wrote:
>
> Given a static list of recipes, I want to search a list of items in
> the pantry and see what recipes I can completely fulfill.
First -- the answer to your actual question:
The first step to writing a rule is usually to state, in English,
precisely what you want the rule to do. So, for example:
"I want to print a message if, for a given recipe, for every
ingredient, that ingredient appears somewhere in a pantry list."
The next step is to restate that in terms that can be logically
expressed. The "for every ingredient" clause is actually best
expressed as "there is no ingredient which doesn't appear in a pantry
list." i.e.,
"I want to print a message if, for a given recipe, there is no
ingredient that doesn't appear in a pantry list."
This version we can translate directly into a rule:
(defrule match-pantry-item-to-recipe
;; For a given recipe
(recipe (name ?name))
;; It is not true that...
(not
;; There is an ingredient in that recipe, and...
(and (recipe (name ?name) (ingredients $? ?item $?))
;; It's not in any pantry list
(not (pantry-list (listitems $? ?item $?)))))
=>
;; Print a message
(printout t "I can make " ?name crlf))
Now that I've given you an answer: the data structures you've chosen
are not the most efficient. It's actually going to perform much better
under load if you use templates like these:
(deftemplate recipe (slot name))
(deftemplate ingredient (slot recipe) (slot name))
(deftemplate pantry-list (slot name))
(deftemplate food (slot pantry-list) (slot name))
(This would also make it much easier to have amounts with each
ingredient in a recipe.) Then the rule would look like:
(defrule match-pantry-item-to-recipe
(recipe (name ?name))
(not (and (ingredient (recipe ?name) (name ?food))
(not (food (name ?food)))))
=>
(printout t "I can make " ?name crlf))
The changes we've made are exactly the same ones you'd make in putting
a database into "normal form."
---------------------------------------------------------
Ernest Friedman-Hill
Distributed Systems Research Phone: (925) 294-2154
Sandia National Labs FAX: (925) 294-2234
PO Box 969, MS 9012 [EMAIL PROTECTED]
Livermore, CA 94550 http://herzberg.ca.sandia.gov
--------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users [EMAIL PROTECTED]'
in the BODY of a message to [EMAIL PROTECTED], NOT to the list
(use your own address!) List problems? Notify [EMAIL PROTECTED]
--------------------------------------------------------------------