/* isa.pro - An example of reasoning using an isa hierarchy * * Copyright(c) 2006, 2008 - Russell C. Bjork * */ :- set_prolog_flag(enforce_directives, off). :- op(300, fy, ~). initialization(set_prolog_flag(unknown, fail)). /* **************************************************************************** * Facts of the form isa/2 relate an individual to a class or a class to a class * * Examples: isa(snoopy, beagle) records that snoopy belongs to the class beagle * isa(beagle, dog) records that a beagle is a kind of dog. * (This program does use different forms to distinguish between recording that * a specific individual belongs to a class or that a class is a subclass of * another class). * * Facts of the form individual/1 specify that a name is the name of an * individual, rather than the name of a class * * Facts of most other forms record a property of an individual or a class. The * fact may either have a single argument, indicating the individual or class to * which it applies, or may have two arguments, the first indicating the relevant * individual or class and the second the value of the property. * * Examples: bark(dog) records that dogs bark * owner(snoopy, brown) records that the owner of snoopy is brown * (Again, this program does use different forms to distinguish between * recording properties of a specific individual or of a class) * * Facts of the form ~any of the above are used to record that, in a specific * case, a property does _not_ hold. * * Class names always use the singular form of the noun naming the class * Properties and relationships always use the stem form of the relevant verb * *************************************************************************** */ /* Classification of individuals */ isa(snoopy, beagle). isa(nermal, cat). isa(garfield, cat). isa(mickey, mouse). isa(minnie, mouse). isa(rocky, squirrel). isa(chilly_willy, penguin). isa(tweety, canary). /* Hierarchy of classes */ isa(beagle, dog). isa(dog, carnivore). isa(cat, carnivore). isa(mouse, rodent). isa(squirrel, rodent). isa(carnivore, mammal). isa(rodent, mammal). isa(mammal, animal). isa(penguin, bird). isa(canary, bird). isa(bird, animal). isa(animal, earth_creature). isa(earth_creature, created_being). /* Specification of individuals */ individual(snoopy). individual(nermal). individual(garfield). individual(mickey). individual(minnie). individual(rocky). /* Properties of individuals */ owner(snoopy, brown). owner(garfield, john). owner(mickey, disney). ~purr(garfield). eat(garfield, lasagna). /* Default properties of classes */ roam(beagle). bark(dog). purr(cat). eat(carnivore, meat). fly(bird). ~fly(penguin). eat(mouse, cheese). /* **************************************************************************** * The inference engine is able to infer that an individual is an instance * of a class specified by an isa fact and of all superclasses of that * class; that a class is a subclass of a class specified by an isa fact and * all superclasses of that class; that an individual inherits all properties * of classes of which it is an instance unless blocked by an explicit * negation at a lower level; and that a class inherits all properties of * classes of which it is a subclass unless blocked by an explicit negation * at a lower level. * * The following is the entry point for the inference engine: * * infer/1 - make an inference - can instantiate variables if * present in goal. * *************************************************************************** */ infer(Fact) :- % Any fact recorded in the database is true. call(Fact). infer(Property) :- % Inheritance of class membership and properties Property =.. [ PropertyName, Who | Value ], isa(Who, Class), ClassProperty =.. [ PropertyName, Class | Value], infer(ClassProperty), not ~Property. % Inheritance can be blocked by an explicit negation