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 ASG2.TXT PRELIMINARIES Open a new log file: >>> (dribble "your-file2.log") If you are continuing from lab-asg1.txt in the same session, type: >>> (lload "Helper/meal-foods.lisp") otherwise type: >>> (load "/Customize.lisp") >>> (lload "Recover/after-meal-food.lisp") REVIEW OF asg1.txt In the previous 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 set the level of debugging information that CLASSIC will supply when concepts and individuals are defined. 3. Commands for inspecting and navigating the KB. 4. How to define roles and attributes. 5. How to create individuals, and when role restrictions will make the description of an individual inconsistent. USEFUL REMINDER --------------- When a CLASSIC description is not called for and you need to refer to a concept, individual or role use the @ in front of the symbol name. When a CLASSIC description is called for, do NOT use the @ inside of the description, just use the symbol name. For instance, (cl-create-ind 'temp-wine '(AND WINE (FILL color red))) (cl-ind-remove @temp-wine 'WINE). Thus the @ was needed in cl-ind-remove to get the individual with the name temp-wine, but no @ was needed in the expression which defines temp-wine. Notice that a quote is needed in front of both the symbol and the description required in cl-create-ind. The quote is needed when you are creating an object and giving it its name or when you are entering a CLASSIC description. MORE INDIVIDUAL CREATION ------------------------ The next parts of the KB we will start fleshing out are the WINE-REGIONs and the WINERYs, as represented in "/wine-region.ps" and "/wineries.ps". The two concepts are structurally very simple: WINE-REGIONs and WINERYs are simply individuals that belong to WINE-REGION or WINERY, respectively. The following is typical of the definitions of WINE-REGIONs: >>> (cl-create-ind 'Medoc 'WINE-REGION) Type this in. Now, create another WINE-REGION called Bordeaux. And another one called Napa-Valley. The WINERYs are created in a similar way. Create a WINERY called Kalin-Cellars and one called Forman. You can verify that the above individuals are in the KB using the CLASSIC function "cl-print-all-inds". Do it. Remember, you can never delete an individual from the KB, unless you decide to remove all the existing individuals using the function (cl-clear-kb) or you may remove all objects from the KB via the function "cl-startup." -- don't enter this command, unless you want to remove all the individuals that you have created so far. On the other hand, you can remove some information from selected individuals using the general function "cl-ind-remove", or more specific functions listed in the "Retraction" section in appendix "CLASSIC Function Variable Descriptions") of the CLASSIC Manual (section D.7.4 in version 2.2). Also refer to the "Retraction" section under the "Updates" section in the CLASSIC Manual (section 5.2 in version 2.2) for further explanation of the use of these functions. Whenever an individual is modified through deletion or addition of information, CLASSIC will reclassify it using the new definition. For instance, print the information that CLASSIC knows about the individual Medoc. Now, try to retract the fact that Medoc is a WINE-REGION. Once you are done, print Medoc again. You will see that its direct parent is now CLASSIC-THING instead of WINE-REGION. We will not go through the definition of all the instances of WINE-REGION, WINERY and MEAL-FOOD. They are in separate files which you will need to load; but you needn't look at the files unless you want to. Load the files now. >>> (lload "Helper/wineries-and-regions.lisp") >>> (lload "Helper/meal-food-instances.lisp") You can verify that the instances of WINERY and WINE-REGION have been created properly by using the "cl-concept-instances" command on WINERY and WINE-REGION. Try it. ADDING INTERMEDIATE CONCEPTS ---------------------------- Suppose we are not satisfied with the very flat classification of wineries that we now have, and would like them to be organized by region. We are going to do this in 3 steps: 1. We will first create subclasses of WINE-REGION. 2. Using these, we will create subclasses of WINERY. 3. Finally we will add some information to the individual wineries that will allow them to be classified by region. 1. SUBCLASSES OF WINE-REGION The goal is to refine the concept WINE-REGION into 3 subclasses: FRENCH-WINE-REGION, AMERICAN-WINE-REGION and OTHER-EUROPEAN-WINE-REGION. We want FRENCH-WINE-REGION to be a WINE-REGION that is one of Bordeaux, Bourgogne, Beaujolais, Loire, and Medoc. Try to define this new concept, using the "ONE-OF" construct. Now examine the instances of FRENCH-WINE-REGION. You should find the five regions listed. Let's pause for a moment to examine how enumerative definitions work. First, verify using "cl-classic-ind?" that there is no individual Charlie in your CLASSIC KB. Now, define a concept C1 using a slightly different version of the definition for the FRENCH-WINE-REGION concept, which contains Charlie as another member of the list of WINE-REGIONs. Notice that CLASSIC does not complain about your definition! Check the KB again with "cl-print-ind". What has CLASSIC done? (Put a brief commented answer in your file.) Evidently, CLASSIC can be accommodating about some definitions that invoke as-yet undefined individuals. Second, examine the instances of C1. Explain why Charlie is not an instance of C1. (Comment out your answer.) Third, define a new concept C2: C2 is a CLASSIC-THING that is one of Bordeaux, Bourgogne, Beaujolais, Loire, and Medoc. Examine this concept; note that CLASSIC knows that every possible instance of C2 is a WINE-REGION, but doesn't seem to know that C2 is a WINE-REGION. Can you give an account of what is going on here? (Comment out your answer.) Can you explain why CLASSIC doesn't classify C2 under WINE-REGION? (If you have trouble answering this, consult "Living with CLASSIC," Section 4.3, "Concepts and Individual Processing".) Now, let's continue building the knowledge base. AMERICAN-WINE-REGION is defined in a similar way to FRENCH-WINE-REGION, with the instances Napa-valley, Sonoma, Santa-Cruz-Mountains, and Santa-Barbara. Define this concept before you go on. OTHER-EUROPEAN-WINE-REGION includes the regions that are not part of the other classifications. Since CLASSIC doesn't have a "NOT" construct, we will have to use exhaustive enumeration to capture the other regions, i.e. Alsace, Chianti, Piemonte. Define the concept before going on. (If you haven't been able to define these concepts by yourself, look at file "/Recover/until-regional-winery.lisp".) Check that the non-French wine region instances were correctly classified under the newly created concepts. 2. SUBCLASSES OF WINERYs Next you'll create a concept REGIONAL-WINERY which is defined to be a WINERY with a region role filled by exactly one WINE-REGION. Declare the region role so that an inverse role wineries is available; and decide whether or not in this domain the role should be an attribute. (Remember that you need to define roles before you can use them and that CLASSIC provides a construct for declaring the inverse of a role within the definition of the role itself.) See the role section of the CLASSIC Manual (Section 2.5 in version 2.2) for further explanation of roles and how to define them. Also remember that WINERY is a primitive, so REGIONAL-WINERY will have to be explicitly asserted to be a WINERY. Create REGIONAL-WINERY now. (If you are really lost about how to do it, see the file "/Recover/after-regional-winery.lisp".) Check that everything worked as it should by using the function cl-print-concept. The description that you get should look exactly like this. @c{REGIONAL-WINERY} -> Derived Information: Primitive ancestors: (@c{WINERY} @c{CLASSIC-THING}) Parents: (@c{WINERY}) Ancestors: (@c{THING} @c{CLASSIC-THING}) Role Restrictions: Region![1 ; 1] => @c{WINE-REGION} @c{REGIONAL-WINERY} Remember that there are two ways for imposing the required "exactly one" number restriction on the role region of REGIONAL-WINERY. 1) You can define region as an attribute. This will automatically set up an "AT-MOST 1" restriction for each concept that has region as a role. Thus, when you define a concept like REGIONAL-WINERY that should have one and only one region, you will only need to declare an "AT-LEAST 1" restriction in the definition; CLASSIC will automatically infer the "AT-MOST 1" restriction from the fact that region is an attribute. 2) You can define region as a role. This will require you to add appropriate "AT-MOST" restrictions in the definitions of concepts that have region as a role, as these definitions come up. The decision between the above alternatives depends upon whether different concepts may vary in the "AT-MOST" restrictions they impose on the role. In general, a certain role may function as an attribute for all concepts in the domain, or it may function as an attribute only for some. In our example, if we are sure that we will never add any multi-regional wineries (wineries that operate in more than one wine region) to the domain, we could safely declare the role region to be an attribute. But we have to be careful about such decisions; we do need to be very sure that we will never want to include multi-regional wineries in our knowledge base. If we ever decide to retract our decision to make region an attribute, we will have to go through the knowledge base by hand and rebuild it so that the desirable consequences that followed from making region an attribute are preserved in the new KB, while the undesirable ones are discarded. This may well be a complicated procedure if the KB is at all large, and we are liable to make mistakes. Other factors to take into consideration are: a) Whether the role must be inserted in a role hierarchy. (In CLASSIC, attributes cannot be part of role hierarchies.) b) Whether a "SAME-AS" restriction must be imposed on the role. (In CLASSIC, the "SAME-AS" construct is restricted to attributes.) In our KB, we are, in fact, very sure that all the wineries will have at most one associated region, and we will not use the role region for non-wineries. Therefore, we can define region as an attribute in order to avoid including the "AT-MOST 1" restriction in the definition of WINERY. You can check whether you made region an attribute typing >>> (cl-attribute? @r{region}). If you did not make region an attribute, you should change it, since the definitions supplied in our Helper files will assume that it is an attribute. To do this, you can type >>> (lload "Recover/after-regional-winery.lisp") You might want to look at the file "/Recover/until-wineries.lisp" to see what you would have needed to do if region had not been an attribute. CLASSIC will automatically infer that an instance of WINERY is a regional winery as long as it is able to show that the instance has at least one region. To illustrate this, first create an individual My-Winery, which is a WINERY with the region role filled by Chianti. Test that in fact CLASSIC classifies My-Winery as a regional winery. Second, try to create an individual Impossible-Winery that is a REGIONAL-WINERY and yet has no regions. Note the response that you get from CLASSIC when you try to do this. Now that we have the concept of REGIONAL-WINERY, let's use it. First, we will create several child concepts of REGIONAL-WINERY, namely FRENCH-WINERY, AMERICAN-WINERY and OTHER-EUROPEAN-WINERY, so that we can eventually classify all the wineries under these concepts. 1. A FRENCH-WINERY is a REGIONAL-WINERY with all its regions FRENCH-WINE-REGIONs. 2. An AMERICAN-WINERY is a REGIONAL-WINERY with all its regions AMERICAN-WINE-REGIONs. 3. An OTHER-EUROPEAN-WINERY is a REGIONAL-WINERY with all its regions OTHER-EUROPEAN-WINE-REGIONs. Define the three concepts now. (If you are really confused at this point, look at file "/Recover/until-wineries.lisp".) Once the concepts are defined, print one of them to make sure that CLASSIC is understanding you properly. In common sense language and reasoning, we often presuppose the existence of role fillers; if I tell you that all Jack's children are in college, for instance, you will assume that Jack has at least one child. But in logic, and in many logic-based KR systems, including CLASSIC, these so-called "existential presuppositions" will not be made by the system unless they are declared explicitly. (Recall that in First-Order Logic, "All Jack's children are in college" will be true if Jack has no children.) Because of this discrepancy between common sense and First-Order Logic, it's easy to forget to declare explicitly that an attribute must have some fillers. To drive this point home, create a temporary individual No-Regions that is a WINERY with at most 0 regions. Print the ancestors of this regionless winery. Briefly explain why CLASSIC returns the information that it does; in particular, why doesn't CLASSIC treat No-Regions as a REGIONAL-WINERY? Comment out your answer. You should now be able to tell why we defined FRENCH-WINERY as we did, rather than saying that a FRENCH-WINERY is a WINERY with all its regions FRENCH-WINE-REGIONs. CLASSIC would then not have classified FRENCH-WINERY under REGIONAL-WINERY. To test this, define a concept C3 to be a WINERY with all its regions FRENCH-WINE-REGIONs. Does CLASSIC place C3 under REGIONAL-WINERY? Verify this using CLASSIC. You shouldn't be surprised that it doesn't; explain why CLASSIC doesn't think that C3s are REGIONAL-WINERIES, commenting out your answer. (Hint: print the ancestors of No-Regions.) 3. CLASSIFYING THE WINERIES Now we have all the concepts we need to properly classify the instances of WINERY by region. In order to do this we will need to add region information to each instance of WINERY. Since there are lots of wineries, we'll only ask you to do this for a couple of them. There are a number of functions for adding information to an individual. The CLASSIC Manual shows these in the "Addition" sections under sections "Updates" and "Individuals" (sections 5.1, D.7.3. in version 2.2). Since we will need to add both a role and its filler, the correct one to use is either "cl-ind-add" or "cl-ind-add-fillers." Let's take the winery Forman as an example. We want to add the information that its region is Napa-Valley. Look at the documentation for cl-ind-add and try that now. (Hint: use FILLS.) If you absolutely can't do it by yourself, look at the file "/Helper/winery-region-info.lisp". After you have added the information to Forman, check that the system classifies it as an AMERICAN-WINERY. IMPORTANT: remember, you can always add information to or remove information from individuals, but you can never delete an individual from the KB or modify an existing concept, other than by reloading the knowledge base. For this reason, you have to be cautious when adding concepts to the CLASSIC KB. WHEN a ROLE has an INVERSE ============================ Now, print the individual Bordeaux, that we created as a FRENCH-WINE-REGION. As you can see, the printed information about Bordeaux does not contain any role restriction, since no roles were contained in the definition of Bordeaux, or any of its ancestors. Now, add to the winery Chateau-D-Ychem the filler Bordeaux for the role region. (Use either "cl-ind-add" or "cl-ind-add-fillers"). Print Chateau-D-Ychem and Bordeaux. As you can see, now the role wineries is attached to Bordeaux, and the role is filled with Chateau-D-Ychem. CLASSIC has derived this information from the fact that we have declared the role region to have inverse wineries. Print the concept FRENCH-WINE-REGION. You will notice that it does not contain any information about the role wineries, since the descriptions of classes don't change with the changes to individuals. Therefore, the definition of the inverse of a role affects only the individuals that become fillers of that role, not the concepts they belong to. The inverse of a role is a regular CLASSIC role and all the CLASSIC functions defined to inspect roles work on it. Try "cl-print-role" and "cl-role-inverse" on the wineries role. The same information about the inverse role was derived for the region Napa-Valley when it was added as the region of the Forman winery. Check this by printing Napa-Valley. Now, add Napa-Valley as the region of the winery Kalin-Cellars and use the function "cl-fillers" to inspect the content of Napa-Valley's role wineries. You will see that now Napa-Valley has two fillers for the role wineries. ---------------------------------------------------------------- We won't make you go through all the wineries. But you might look at the file "/Helper/winery-region-info.lisp" to see what's in it. Then type: >>> (lload "Helper/winery-region-info.lisp") Use CLASSIC functions to determine the instances of FRENCH-WINERY and of OTHER-EUROPEAN-WINERY. Write a lisp function that takes as input a WINE-REGION and returns all the individual WINERYs in that region. (If things get messed up and you want to recover the state up to this point, type: >>> (lload "Recover/after-wineries.lisp") ) Type: (dribble) to close your log file now. --------------------------------------------------------------------------- END OF asg2.txt If you are going on, open the file "/asg3.txt"