This file is part of: AT&T Bell Laboratories and University of Pittsburgh CLASSIC Knowledge Representation System Tutorial Copyright AT&T and University of Pittsburgh 1994 ASG4.TXT PRELIMINARIES Open a new log file: >>> (dribble "your-file4.log") If you are continuing from asg3.txt in the same session type >>> (lload "Helper/just-wines.lisp") or type >>> (lload "Recover/after-just-wines.lisp") to recover state. Otherwise, if this is a new session, type: >>> (load "/Customize.lisp") >>> (lload "Recover/after-just-wines.lisp") These loading operations may take a bit of time because they are adding many wine individuals to the KB. REVIEW OF asg1.txt through asg3.txt In the first module of this assignment we covered: 1. How to create "disjoint-primitive" concepts. Using this construct we created the concepts WINE-PROPERTY, CONSUMABLE-THING, WINERY, and WINE-REGION. We also constructed the concepts EDIBLE-THING, POTABLE-LIQUID, WINE-COLOR, WINE-BODY, WINE-SUGAR, WINE-FLAVOR, WINE and MEAL-FOOD. 2. How to get verbose or laconic debugging information from Classic when concepts and individuals are defined. 3. Commands for inspecting and navigating the KB. 4. Definition of Roles and Attributes. 5. Creation of individuals and the effect of role restrictions on individuals. In the second module of this assignment we covered: 6. Adding concepts to the KB in such a way that existing concepts and instances get reclassified under them (we illustrated this with REGIONAL-WINERY and its children). 7. Use of the inverse of a role. In the third module of this assignment we covered: 8. Using rules in Classic: enhancing concepts via rules, adding and removing rules. The main use of rules, i.e. for adding non-definitional information to instances that get classified under a concept. You may want to review some of these. MORE USES OF RULES ------------------ Definitions can help to organize knowledge, but most useful domain information does not follow from concept definitions alone. Classic provides rules as a way to extend our knowledge of individuals, by adding information that can't be inferred from the definitions of the concepts under which the individual is classified, but that will nonetheless be expected or known. In the last module we saw how rules can be used for this purpose. In this module we will look at some other uses for rules. You might want to briefly review the end of asg3.txt before proceeding. RULES FOR CREATING PURELY DISJUNCTIVE CONCEPTS We have seen that the "ONE-OF" restriction construct can be used to define a concept as a disjunction of individual instances. The definition of WINE-FLAVOR in asg1.txt is an example. > (cl-define-concept 'WINE-FLAVOR '(AND WINE-PROPERTY (ONE-OF Delicate Moderate Strong))) However, there is no general way in Classic to define a concept as a disjunction of several other concepts. For instance, there is no direct way to define a concept of DELICATE-OR-WHITE-WINE. Disjunction is intentionally limited in Classic. Despite these limitations, we can often use rules to achieve some of the effects of disjunctive concepts. "Dirty tricks" of this sort are of course risky, but they can be useful. We will use an example to illustrate the use of rules to imitate disjunctive concepts. We know that in many cases, a concept is (implicitly) a disjunction of its children concepts. Suppose you want to define a primitive concept MY-FAVORITE-WINE whose only restrictions are that it must be either a CHARDONNAY or an ITALIAN-WINE. There is no straightforward way in Classic of expressing this restriction using the constructs for defining primitive concepts. But we can use rules to approximate the disjunctive concept that we want in the definition, as follows. 1. Create a primitive concept MY-FAVORITE-WINE under WINE. (The concept has to be primitive because there is nothing definitional distinguishing it from its parent concept WINE.) 2. Add rules to CHARDONNAY and ITALIAN-WINE asserting that any instance of each of these concepts should also be an instance of MY-FAVORITE-WINE. (Note that this information is certainly not definitional for either CHARDONNAY or ITALIAN-WINE.) This is only an approximation of true disjunction for several reasons. For instance, if we create an individual My-Wine and tell Classic that it is a MY-FAVORITE-WINE with its region filled by Sonoma, Classic will not infer that it is a CHARDONNAY. Moreover, if we create another individual, My-wine2, and tell Classic that it is MY-FAVORITE-WINE and a BORDEAUX-WINE, Classic will not detect the inconsistency. You can think of it this way: this trick will in general provide sufficient conditions for classifying something under MY-FAVORITE-WINE, but it won't provide necessary conditions. Try to implement the idea, in the following steps. 1. Create the concept MY-FAVORITE-WINE. 2. Show that there are no instances under the new concept. 3. Add the appropriate rules to CHARDONNAY and ITALIAN-WINE and show that the concepts now have them. You can use "cl-concept-rules" for this. 4. Show that MY-FAVORITE-WINE now has the appropriate instances. (To recover state here, use (lload "Recover/after-just-wines.lisp") ) USING RULES TO CREATE "QUERY TEMPLATES" This section introduces a use for rules that extends the type of reasoning you might think Classic is capable of doing. The definitions and rules are in file: "/Helper/food-wines.lisp". Look at the file, if you wish, then type: >> (lload "Helper/food-wines.lisp") The "food-wines.lisp" knowledge base contains examples like the following ones, which provide information about wines appropriate for spicy-red-meat food. Do NOT enter these commands; they were included in the file you just loaded. (cl-add-rule 'spicy-red-meat-wine-color @c{spicy-red-meat} '(all appropriate-drink (fills color red))) (cl-add-rule 'spicy-red-meat-wine-body @c{spicy-red-meat} '(all appropriate-drink (fills body full))) (cl-add-rule 'spicy-red-meat-wine-flavor @c{spicy-red-meat} '(all appropriate-drink (fills flavor moderate))) (cl-add-rule 'spicy-red-meat-wine-sugar @c{spicy-red-meat} '(all appropriate-drink (fills sugar dry))) Note that the rules associated with a food concept impose a number of restrictions on any wine that fills the appropriate-drink role of an instance of the concept. The rules concentrate on the appropriate-drink role because we are assuming that the knowledge base we are building would be used to give advice in selecting drinks to go with certain foods. If we were interested in other kinds of advice (suitability for certain sorts of diets, for instance), we would have to modify the food concept by adding appropriate roles, and would need to add rules constraining these roles. You'll see below how these rules are used. Suppose we want to find out what wines go with a SPICY-RED-MEAT food. We first create a meal course that is a SPICY-RED-MEAT. >>> (cl-create-ind 'My-Meal-Food '(AND SPICY-RED-MEAT (FILLS appropriate-drink Some-Wine))) Create My-Meal-Food using this definition, and use "cl-print-object" to inspect it. You will notice that the role "appropriate-drink" has restrictions associated with it, that were created by the rules for SPICY-RED-MEAT. These restrictions represent what we know about a wine, when we are told that it is appropriate with any instance of SPICY-RED-MEAT. Manually browse through the knowledge base for an individual wine that meets all these restrictions, and an individual instance of SPICY-RED-MEAT. Do you expect Classic to know that the wine is appropriate for the meat? Make your prediction, and then query Classic for the answer. Explain why Classic gives the result it does, and test your prediction, before reading the following paragraph. ************************************************** BLANK SPACE BLANK SPACE ************************************************** You should have discovered that Classic doesn't know that any wine at all is appropriate with my-meal-food, or Beef-Curry (which is also an instance of spicy-red-meat). In particular, it doesn't know that Mazocco-Zinfandel is appropriate with Beef-Curry, even though you can verify that Mazocco-Zinfandel in fact meets all of the restrictions we have placed on the color, body, flavor, and sugar of any filler of the appropriate-wine role of an instance of SPICY-RED-MEAT. And in fact, Classic is right to remain ignorant here. There are several reasons why the system shouldn't reach this conclusion, all of them connected with the design philosophy of Classic, which is intended to facilitate the representation of partial information about the objects that populate "open domains". (1) The role restrictions give necessary, not sufficient conditions. The fact that we have put these restrictions on what wines are appropriate with spicy red meats doesn't exclude the possibility of other restrictions that we haven't entered or aren't aware of. (2) The fact that Beef-Curry is a SPICY-RED-MEAT does not prevent it from being classified under some other concept, which might impose additional restrictions on the fillers of the appropriate-drink role. But even the most open domains can have parts that are closed; and it is often very useful in special cases to simulate closed-world reasoning. The case of SPICY-RED-MEAT is a good example. It is reasonable to expect here that we have listed all the conditions that make a wine appropriate for a spicy red meat, so that a wine that satisfies them will in fact be a good recommendation for a meal featuring SPICY-RED-MEAT. In fact, it is hard to see how we can use the knowledge we have put into the system to make useful meal-planning suggestions without making some assumption of this sort. To explore how to do this, let's return to the individual my-meal-food that we created above. Remember that the role "appropriate-drink" has only the restrictions that follow from assuming that a wine goes with SPICY-RED-MEAT. What we need to know now is, which individual wines in our knowledge base satisfy these restrictions. For this we can use the function "cl-object-subsumes" in the following way. (An explanation of this function is in the Classic Manual in the section entitled "Subsumption Retrieval Functions". It can be found in section D.5.1 in version 2.2 of the manual). >> (cl-object-subsumes @my-meal-food @appropriate-drink) The function "cl-object-subsumes" takes the ALL restriction on the appropriate-drink role of the individual and retrieves the wines that match this description. Enter the above command; Classic should return the following answer to your query: (@i{MAZOCCO-ZINFANDEL}) Mazocco-Zinfandel is in fact the only wine in our KB that we can recommend with a SPICY-RED-MEAT. You can see that techniques like this have to be used with care. We have to recognize the closed-world constraints that went into our recommendation: all we really know is that Mazocco-Zinfandel is not incompatible with SPICY-RED-MEAT. We are hoping that our constraints are complete enough so that any wine that is not incompatible with the constraints will in fact be appropriate. In the previous example the relationships between meal-foods and appropriate wines have been expressed through rules. And in fact we recommended a wine as appropriate for SPICY-RED-MEAT without ever actually filling the appropriate-drink role. (You might want to check at this point to verify that Mazocco-Zinfandel still does not fill the appropriate-drink role of Beef-Curry.) USE of TEST-C ============== The next concept we need to define is MEAL-COURSE. Intuitively, a meal-course is a part of a meal that may consist of one or more foods that one served at the same time. Usually a meal-course consists of foods that go together, such as beef curry, rice, and chutney in an entree, or strawberries and cream in a dessert course. We assume that a MEAL-COURSE will have exactly one associated drink that is served with it. Next you will try to define the Classic concept for MEAL-COURSE so that: 1) It is a CONSUMABLE-THING. 2) It consists of at-least 1 food MEAL-FOOD 3) It has exactly one course-drink, which is a WINE. In order to define this new concept, you need to create its two roles first. We can imagine a course being accompanied by more than one wine, but in our domain, where meals are supposed to be well coordinated, we can assume that this will never happen. Therefore it is worthwhile to treat the course-drink role as an attribute. Thus, you should create roles as follows. Do it now. 1. course-drink: an attribute (role with single filler) 2. food: a role (with possibly more than one filler) With the roles in place, you can now enter the definition of MEAL-COURSE. Note that in CLASSIC, you cannot put a restriction on only one of a set of unknown fillers of a role without putting the restriction on all of them. Be careful! Since concepts cannot be modified, you cannot undo an incorrect concept without clearing and reloading the whole KB. We said that a MEAL-COURSE can have more than one associated MEAL-FOOD, and we know that each MEAL-FOOD imposes restrictions over the kind of WINE that you can serve with it. Continuing, let's define two new concepts: 1) SINGLE-FOOD-MEAL-COURSE, which is a MEAL-COURSE that has AT-MOST 1 food. 2) APPROPRIATE-SINGLE-FOOD-MEAL-COURSE, a SINGLE-FOOD-MEAL-COURSE whose course-drink is an appropriate-drink for its food. (You will need to use a TEST-C description to express this condition. Its use is discussed in the section called "Procedural tests", in the Classic Manual which is section 2.1.4.1 in version 2.2). In writing the condition, assume that each MEAL-FOOD has its appropriate-drink role filled by all the wines that are appropriate with the food. Define the above concepts now. If you have trouble, you can find the above definitions in the file "Helper/single-food-meal-course.lisp". If you need to recover the knowledge base up to this point, load "Recover/after-single-meal-course.lisp". To test your definition, type the following: >>> (cl-create-ind 'My-Meal-Course1 '(and SINGLE-FOOD-MEAL-COURSE (fills food Lobster) (fills course-drink Forman-Chardonnay))) >>> (cl-create-ind 'My-Meal-Course2 '(and SINGLE-FOOD-MEAL-COURSE (fills food Lobster) (fills course-drink COTTURI-ZINFANDEL))) Since Forman-Chardonnay meets the specifications for an appropriate drink with lobster, My-Meal-Course1 should satisfy the concept APPROPRIATE-SINGLE-FOOD-MEAL-COURSE. However, Cottturi-Zinfandel is not a white wine and thus, is not appropriate with lobster. So, My-Meal-Course2 is not an APPROPRIATE-SINGLE-FOOD-MEAL-COURSE. Make sure that you get this result. Now define a LISP function, CHECK-MY-MEAL-COURSE, that accepts as input an individual MEAL-FOOD and another individual WINE and tells you whether or not the resulting individual SINGLE-FOOD-MEAL-COURSE is appropriate, and, if it is not, tells you what wines would make it appropriate. Show how your function works. THE SAME-AS RESTRICTION ====================== Now, let's define three subconcepts of MEAL-COURSE: APPETIZER-COURSE, ENTREE-COURSE, AND DESSERT-COURSE. An APPETIZER-COURSE is a course all of whose foods are APPETIZERs; the other sorts of courses are defined similarly. (Recall that APPETIZER, ENTREE and DESSERT were previously defined as primitive subconcepts of MEAL-FOOD. You can verify this by consulting the file "/Helper/meal-foods.lisp>" and the figure "/edible-thing.ps>".) Enter the definitions of these three concepts now. We can now define the concept of a MEAL. We will think of a MEAL as a CONSUMABLE-THING with attributes 1) main-course, which is restricted to ENTREE-COURSE; 2) appetizer-course, which is restricted to APPETIZER-COURSE; 3) dessert-course, which is restricted to DESSERT-COURSE. Define MEAL now. At this stage, we have created some highly structured concepts, involving multiple role paths. Roles can be used to restrict individuals or concepts. Here, we are using roles main-course, course-food, appropriate-drink and color to restrict the concepts MEAL, ENTREE-COURSE, MEAL-FOOD and WINE as follows. A MEAL's main-course is restricted to ENTREE-COURSE. An ENTREE-COURSE's course-food is restricted to MEAL-FOOD. A MEAL-FOOD's appropriate-drink is restricted to WINE. A WINE's color can be filled by any one of White, Rose, and Red. Thus, given an individual that satisfies MEAL, Classic should be capable of reasoning about its main-course's course-food's appropriate-drinks' colors. It should provide an error message, for instance, if you provide information that would require the filler along this role path to be anything but one of the three individuals White, Rose, or Red. It might be helpful for you at this point to diagram the concept MEAL and the concepts that restrict its roles. The next concepts that you have to add are 1) CHEAP-MEAL: a MEAL in which all three courses are SINGLE-FOOD-MEAL-COURSE; 2) ONE-WINE-MEAL: a MEAL in which the wine is the same for every course served (Use the SAME-AS function to add this concept. The SAME-AS function is discussed in two sections of the Classic Manual called "Equality Restrictions (SAME-AS); sections 2.1.3.4 section 2.2.1 in version 2.2; 3) REALLY-CHEAP-MEAL: a CHEAP-MEAL that is also a ONE-WINE-MEAL. To test what you have done, create a new individual Cheapo that is a REALLY-CHEAP-MEAL. Print Cheapo and verify that Classic returns the expected information. The above definitions can be found in "Helper/meals.lisp". Now, create a new individual Cheapo-Appetizer. Cheapo-Appetizer is an APPETIZER-COURSE whose course-drink is Forman-Chardonnay. Add Cheapo-Appetizer as the appetizer-course of Cheapo. Now reprint Cheapo-appetizer. What new information has Classic inferred? Go on to create a new individual Cheapo-Entree, which is an ENTREE-COURSE whose course-drink is a RED-WINE. What result do you expect if you assign Cheapo-Entree as the filler of the main-course role of Cheapo? Compare this with the result that Classic returns, and explain any discrepancy. We are nearly at the end of this part of the assignment, and will turn to a more open-ended task. The last experiments that you were doing with Classic should have suggested ways in which the knowledge base we have developed could be used to make suggestions and critique certain meal plans. You should now carry this a bit further by identifying several reasoning tasks that Classic could perform using the concepts we have defined up to now and others that you might want to add. (For example, you could explore how to have Classic give suggestions to someone who is planning a REALLY-CHEAP-MEAL and wants its courses to all be appropriate.) Implement a little demonstration of your reasoning tasks using appropriate LISP functions. ========================================================== USING RULES TO BREAK CIRCULAR DEFINITIONS The wines KB/domain doesn't really have much circularity. But suppose you were asked to define the following concepts: PERSON: a primitive CHILD: a PERSON with parents who are PARENTs PARENT: a PERSON with at least 1 children who are CHILDs CHILD would have to be defined before PARENT and viceversa. To break the loop, you could: 1. define PARENT as a person with at least one children and all of whose children are PERSONs; 2. define CHILD as a PERSON with a parents role all of whose fillers are PARENTs; 3. add a rule to PERSON that says that every instance of PERSON should also be classified as a CHILD. Try this. ===================================================================== Type: (dribble) to close your log file now. --------------------------------------------------------------------------- END OF asg4.txt YOU ARE DONE WITH THIS ASSIGNMENT