NeoClassic Knowledge Representation System Tutorial (Part 3)

Copyright AT&T 1996

Here is the text version

PRELIMINARIES

Open a new shell file (meta-X shell) and name it by saving it.

Whether you are continuing from Part 2 or starting this while starting up a fresh interpreter for NeoClassic, you should recover the state of the system by typing this command.

>>> (readFile "<topdir>/Recover/after-wineries.Neo ")

This will guarantee that there are no errors in the system.

You may want to skip down to the end of the review section if you are continuing from asg2.txt in the same session.

REVIEW OF Part 1 and Part 2

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. Commands for inspecting and navigating the KB.
  3. Definition of Roles and Attributes.
  4. Creation of individuals and the effect of role restrictions on individuals.

    In the second module of this assignment we covered:

  5. Adding concepts to the KB in such a way that existing concepts and individuals get reclassified under the new concepts (we illustrated this with REGIONAL-WINERY and its children).
You may want to review some of these topics.

Note that from this point in the tutorial, warnings will not be given before telling the user to do something that might cause an unexpected response. The user should now be familiar enough with NeoClassic and its error messages to realize when an error message or unexpected response is being used to make a point. If NeoClassic returns something unexpected, read it and read further in the tutorial to decipher whether it is making a point before trying to redo the command in order to get a "better" response.

PRACTICE WITH A FEW DEFINED CONCEPTS

We will now start developing the KB of wines. We'll begin with definitions of some generic wine subconcepts.

You should be able to define them yourself from the following specifications:

Try to define the concepts yourself first. If you can't or you want to check your definitions, look at ``
<topdir>/Recover/after-generic-wines.Neo.'' Make sure these concepts are defined before going on.

In the above definitions, you could have used "fills" or "oneOf". For instance, the alternative definitions are equivalent.

>>> (createConcept DELICATE-WINE1
	(and WINE (fills flavor Delicate)))

and

>>> (createConcept DELICATE-WINE2
	(and WINE (all flavor (oneOf Delicate))
	))
Enter the two definitions, and test for their equivalence. How can you tell that NeoClassic identifies these two concepts?

The equivalence of these two definitions depends on the fact that flavor is an attribute, and that WINEs were required by definition to have at least one flavor. To illustrate the difference between such definitions in general, recall the definition of MEAL-FOOD.

(createConcept 
	MEAL-FOOD
	(and EDIBLE-THING
	(atLeast 1 appropriate-drink) (all appropriate-drink WINE) )
(You do not need to enter this definition!)

Now, suppose that we define FOOD-GOOD-WITH-FORMAN-CHARDONNAY to be any MEAL-FOOD whose appropriate-drink role is filled with Forman-Chardonnay. (Enter the definition.) And let's define FOOD-GOOD-ONLY-WITH-FORMAN-CHARDONNAY to be any MEAL-FOOD all of whose appropriate-drinks are oneOf Forman-Chardonnay. (Enter the definition.) Would you expect either of these concepts to be classified under the other? Does NeoClassic give the answer that you expect? Comment out your response.

If NeoClassic does not deduce that one of these concepts subsumes the other, it should be possible to create an individual that is subsumed by the first concept but not the second. Create such individuals now, and test them. (For instance, if NeoClassic does not classify FOOD-GOOD-ONLY-WITH-FORMAN-CHARDONNAY under FOOD-GOOD-WITH-FORMAN-CHARDONNAY, create a specific individual Food1 that has FOOD-GOOD-WITH-FORMAN-CHARDONNAY as an ancestor, but not FOOD-GOOD-ONLY-WITH-FORMAN-CHARDONNAY.)

USING RULES IN NeoClassic

In this section we will learn to use rules in NeoClassic and at the same time fill out the rest of the KB under WINE.

USING RULES TO ENHANCE CONCEPTS

In this section we will consider the use of rules in concept definitions.
Consider the following definition of the concept CHARDONNAY:
>>> (createConcept CHARDONNAY
		   (and WINE
		         (fills grape Chardonnay)  ))
This says that by definition, a CHARDONNAY is a wine with its grape role filled by Chardonnay. Since our simple definition of grape requires it to be an attribute, this means that a CHARDONNAY wine will have Chardonnay as its only grape.

But there's a lot more we know about CHARDONNAY wines, e.g., they are white, they usually have Full or Medium body, and they have Strong or Moderate flavor. However, these things are not part of the definition of CHARDONNAY, they are incidental properties of CHARDONNAY wines.

To specify such properties, we use rules like the following:

>>> (createRule chardonnay-color CHARDONNAY (fills color White))
   
>>> (createRule chardonnay-body
	        CHARDONNAY (all body (oneOf Full Medium)))

>>> (createRule chardonnay-flavor
	         CHARDONNAY (all flavor (oneOf Strong Moderate)))
Enter the concept definition of CHARDONNAY and then enter the rules. (The rules use the CHARDONNAY concept).

These rules say that any individual that gets classified as a CHARDONNAY will also be given certain constraints.

Rules can be added incrementally at any point in building a knowledge base and will affect both existing individuals and individuals created later.

You may have noticed that when we defined WINE, we were not able to place an appropriately specific restriction on the grape role. As a reminder, we repeat the role information from the definition of WINE.

You would have expected a restriction to GRAPE in the grape role, rather than to the less specific EDIBLE-THING. We had to be content with the definition that we used because NeoClassic will not tolerate circularities in definitions. GRAPE is defined in our KB in a way that classifies it under MEAL-FOOD; browse in the KB to determine the chain of parent concepts that lead from GRAPE to MEAL-FOOD. But in our KB, MEAL-FOOD is a defined concept, and part of the definition is a restriction of the appropriate-drink role to WINE! It was to avoid this circle that we used EDIBLE-THING rather than GRAPE.

We can repair this by adding a rule restricting the fillers of the grape role in WINE to GRAPE. Write this rule now.

We also expect each WINE to have a maker (which is a WINERY), and a region (which is a WINE-REGION). In this domain, we can expect each WINE to have exactly one region, and exactly one maker. So we can treat these roles as attributes. Use that function to add them now, and write rules that attach them to WINE.

Now, let's return to CHARDONNAY. Recall that we added rules to the definition of this wine, providing information about color, body, and flavor. Here is what the rule information looks like if you inspect the rules on the concept CHARDONNAY.

>>> (getRules CHARDONNAY)
{chardonnay-flavor, chardonnay-body, chardonnay-color}
>>> (printInfo chardonnay-flavor)
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Rule @@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:         chardonnay-flavor
@ Antecedent:   CHARDONNAY
@ Consequent:   (all flavor (oneOf Moderate Strong))
@ Inconsistent? false
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
>>> (printInfo chardonnay-body)
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Rule @@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:         chardonnay-body
@ Antecedent:   CHARDONNAY
@ Consequent:   (all body (oneOf Medium Full))
@ Inconsistent? false
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
>>> (printInfo chardonnay-color)
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Rule @@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Name:         chardonnay-color
@ Antecedent:   CHARDONNAY
@ Consequent:   (fills color White)
@ Inconsistent? false
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Notice that the only rules shown are those that are directly associated with the concept, i.e. those attached to ancestors are not shown. There is not as much information attached to the concept as you might expect, because rules are only used in NeoClassic to obtain information about individuals. We can use this fact to find out what NeoClassic knows about the concept, by creating a "generic individual". What makes this individual a generic CHARDONNAY is the fact that we will only attach information to it that is already included in the CHARDONNAY concept. Let's create the individual Generic-Chardonnay, and see what happens. (You can enter the following command line if you like, to see that NeoClassic in fact behaves as reported here. Or you can simply read the following few lines.)
>>>  (createIndividual Generic-Chardonnay CHARDONNAY)
Generic-Chardonnay
>>>  (printInfo Generic-Chardonnay)
********************* ClassicIndividual ********************
* Name:                   Generic-Chardonnay
* Ingredients:
*    Told Parents:        {CHARDONNAY}
*    Components:          {}
*    Closed Roles:        {}
*    Rules:               {
     <chardonnay-color -> (fills color White)>, 
     <chardonnay-body -> (all body (oneOf Medium Full))>, 
     <chardonnay-flavor -> (all flavor (oneOf Moderate Strong))>, 
     <wine-grape -> (all grape GRAPE)>, 
     <wine-maker -> (and (all maker WINERY) (atLeast 1 maker))>, 
     <wine-region -> (and (all region WINE-REGION) (atLeast 1 region))>}
*    In Propagations:     {}
* Parents:                {CHARDONNAY, WHITE-WINE}
* Inconsistent:           false
* Out Propagations:       {
   Propagation(Generic-Chardonnay Chardonnay 
            (and EDIBLE-THING GRAPE (oneOf Chardonnay))), 
   Propagation(Generic-Chardonnay White (and WINE-COLOR (oneOf White)))}
* Soup:
*    Primitive Ancestors: {POTABLE-LIQUID, CONSUMABLE-THING}
*    One of:              {}
*    RoleRestrictions:    {
     <maker 1-1 {} WINERY>, 
     <region 1-1 {} WINE-REGION>, 
     <color 1-1 {White} (and WINE-COLOR (oneOf White))>, 
     <body 1-1 {} (and WINE-BODY (oneOf Medium Full))>, 
     <flavor 1-1 {} (and WINE-FLAVOR (oneOf Moderate Strong))>, 
     <sugar 1-1 {} WINE-SUGAR>, 
     <grape 1-1 {Chardonnay} (and EDIBLE-THING GRAPE (oneOf Chardonnay))>}
*    Tests:               {}
* Comment:                
************************************************************
There are several points to be made here:

There is some fairly sophisticated classificational reasoning going on here. The role color has been filled with White by a rule. Thus, because Generic-Chardonnay has color White, the NeoClassic classifier can determine that Generic-Chardonnay is also a WHITE-WINE.

We can also see that the body and flavor roles have not been filled, since the restriction to one of two fillers for body and flavor does not allow NeoClassic to infer a single filler:

>>> (derivedFillers Generic-Chardonnay flavor)
{}
>>> (derivedFillers Generic-Chardonnay body)
{}

Instead, restrictions have been added to Generic-Chardonnay by the rules attached to the CHARDONNAY and the WINE concept:

 >>> (printInfo Generic-Chardonnay)
********************* ClassicIndividual ********************
* Name:                   Generic-Chardonnay
    ...
*    RoleRestrictions:    {
     <maker 1-1 {} WINERY>, 
     <region 1-1 {} WINE-REGION>, 
     <color 1-1 {White} (and WINE-COLOR (oneOf White))>, 
     <body 1-1 {} (and WINE-BODY (oneOf Medium Full))>, 
     <flavor 1-1 {} (and WINE-FLAVOR (oneOf Moderate Strong))>, 
     <sugar 1-1 {} WINE-SUGAR>, 
     <grape 1-1 {Chardonnay} (and EDIBLE-THING GRAPE (oneOf Chardonnay))>}
************************************************************
Be sure that you understand the sources of the information that are reported in the above printout; what definitions and rules are used?

To illustrate the incremental addition of information to individuals, let's create another individual, My-Chardonnay. My-Chardonnay will begin life as a generic CHARDONNAY, but we will add information to it using "addToldInformation" (which acts somewhat like a rule, but is restricted to a particular individual). At this point, you should create My-Chardonnay and print information about it. The printInfo command should show it just like Generic-Chardonnay.

With My-Chardonnay in the KB, first try to add information to it that conflicts with the rules associated with CHARDONNAY. Try the following: the attempt should create an error.

Add the fact that My-Chardonnay's flavor is Delicate.

Now, try the following. (Use one NeoClassic command to do this, rather than two.) This time, the attempt should work.

Add the fact that My-Chardonnay's flavor is Strong, and its body is Medium.

Here is what you should get at this point if you ask about My-Chardonnay.

>>> (printInfo My-Chardonnay)

********************* ClassicIndividual ********************
* Name:                   My-Chardonnay
* Ingredients:
*    Told Parents:        {CHARDONNAY}
*    Components:          {(fills flavor Strong), (fills body Medium)}
*    Closed Roles:        {}
*    Rules:               {
     <chardonnay-color -> (fills color White)>, 
     <chardonnay-body -> (all body (oneOf Medium Full))>, 
     <chardonnay-flavor -> (all flavor (oneOf Moderate Strong))>, 
     <wine-grape -> (all grape GRAPE)>,
     <wine-maker -> (and (all maker WINERY) (atLeast 1 maker))>, 
     <wine-region -> (and (all region WINE-REGION) (atLeast 1 region))>}
*    In Propagations:     {}
* Parents:                {CHARDONNAY, WHITE-WINE}
* Inconsistent:           false
* Out Propagations:       {
  Propagation(My-Chardonnay Strong 
           (and WINE-FLAVOR (oneOf Moderate Strong) (oneOf Strong))), 
  Propagation(My-Chardonnay Medium 
           (and WINE-BODY (oneOf Medium Full) (oneOf Medium))), 
  Propagation(My-Chardonnay Chardonnay 
           (and EDIBLE-THING GRAPE (oneOf Chardonnay))), 
  Propagation(My-Chardonnay White (and WINE-COLOR (oneOf White)))}
* Soup:
*    Primitive Ancestors: {POTABLE-LIQUID, CONSUMABLE-THING}
*    One of:              {}
*    RoleRestrictions:    {
     <maker 1-1 {} WINERY>, 
     <region 1-1 {} WINE-REGION>, 
     <color 1-1 {White} (and WINE-COLOR (oneOf White))>, 
     <body 1-1 {Medium} (and WINE-BODY (oneOf Medium Full) (oneOf Medium))>, 
     <flavor 1-1 {Strong} 
         (and WINE-FLAVOR (oneOf Moderate Strong) (oneOf Strong))>, 
     <sugar 1-1 {} WINE-SUGAR>, 
     <grape 1-1 {Chardonnay} (and EDIBLE-THING GRAPE (oneOf Chardonnay))>}
*    Tests:               {}
* Comment:                
************************************************************
Before you go on, type: >>> (readFile "
<topdir>/Recover/after-wine-varieties.Neo") You may get an error saying that CHARDONNAY has already been defined. Ignore it.

Because they add information to an individual classified under the concept that is the antecedent of the rule, rules may also cause further classification to occur. Consider the following individual. (Type it in).

 >>>  (createIndividual Chateau-Lafite-Rothschild-Pauillac
	         (and PAUILLAC 
                       (fills maker Chateau-Lafite-Rothschild)))
Then look at what its ancestors are. It was only asserted to be a PAUILLAC, but a PAUILLAC is a MEDOC and MEDOC has rules that set sugar to Dry, and color to Red. Therefore, Chateau-Lafite-Rothschild can be inferred to be a DRY-RED-WINE and a CABERNET-SAUVIGNON-WINE.

WHY ARE RULES BEING USED?

There are several reasons for using rules, but the reason they are being used here, in the definition of the wine varieties, is probably the most important one from a conceptual point of view.

Basically, rules are used to add to an individual information that is not definitional, i.e., you do not want to force an individual to have that information associated with it before you classify it as an instance of the concept. In the case of CHARDONNAY, above, the concept definition is saying that the color, body, and flavor information is not definitional for concept CHARDONNAY, although an individual that is classified as a CHARDONNAY will have these characteristics. The definitional characteristic of CHARDONNAY is the type of grape it is made from.

As another more familiar example, consider a concept PERSON. We know that PERSONs have a social security number, but it should not be necessary for a person to have a social security number in order to be classified as a PERSON. Instead we would want the system to infer that an instance of PERSON has a social security number and that, even if you didn't know what it was, it would have to have 9 digits. So you might add a rule to that effect.

INFORMATION THAT CAN BE ADDED WITH RULES

Rules, we said, are commonly used to add non-definitional information to instances of a concept. This information can be restrictions, fillers, or parents. Notice that rules do not need to be specified when a concept is defined. They can be added later.
  1. ADDING RESTRICTIONS. We have already seen, with CHARDONNAY and My-Chardonnay, an example of adding restrictions. Recall that body and flavor got their restrictions from rules.
  2. ADDING FILLERS. Here is an example of adding fillers explicitly (grape is filled by inheritance). The file `` <topdir>/Helper/wine-varieties.Neo'' defines CHENIN-BLANC as follows:
       (createConcept CHENIN-BLANC
    		   (and WINE
    		         (fills grape Chenin-Blanc)))
    
       (createRule chenin-blanc-color CHENIN-BLANC (fills color White))
       (createRule chenin-blanc-body
    	     CHENIN-BLANC (all body (oneOf Full Medium)))
       (createRule chenin-blanc-flavor CHENIN-BLANC (fills flavor Moderate))
       (createRule chenin-blanc-sugar
    	     CHENIN-BLANC (all sugar (oneOf Dry Off-Dry)))   
    
    Create an individual called Ventana-Chenin-Blanc that is a CHENIN-BLANC and has maker Ventana. Then print the object and verify that the roles color and flavor now each have a filler.
  3. ADDING PARENTS. Here is an example of explicitly classifying an individual under a different concept. Type the following definitions.
          (createConcept SPECIAL-RED-BORDEAUX
                             (and BORDEAUX-WINE RED-WINE))
    
          (createRule special-red-bordeaux-type
                       SPECIAL-RED-BORDEAUX CABERNET-SAUVIGNON-WINE)
    
    Any instance of SPECIAL-RED-BORDEAUX will become a CABERNET-SAUVIGNON-WINE as well. Create an individual called My-Red-Bordeaux and define it to be a BORDEAUX-WINE and a RED-WINE (these concepts were already defined). Verify that its ancestors are:
    1. A RED-BORDEAUX (because of the definition of RED-BORDEAUX)
    2. A CABERNET-SAUVIGNON-WINE (because of the rule above)
    3. A DRY-RED-WINE (because CABERNET-SAUVIGNON-WINEs are restricted to be Dry)

FILTERS ON RULES

A rule must contain a concept as the antecedent. This means that sometimes the user must create a named concept whose only purpose is to be the antecedent of a rule. (QUESTION: Why is it a good idea not to create named concepts that are unnecessary? Type your answer into the shell session in lines that begin with the comment symbol ";" so that your answer will appear in your log file.)

Make sure you read the manual to understand all about rules in NeoClassic.

Get into your shell buffer and type <meta-X> save file. to close your log file now.

YOU ARE DONE WITH PART THREE OF THIS ASSIGNMENT

You may now go to Part 4 or go back to the main NeoClassic Tutorial page.