% Prolog code for implementing inheritance in semantic nets % Bill Wilson, April 2006 % Tested on SWI Prolog % Try the following queries: % ?- satisfies(hasname, e1, N). % check an unambiguous fact about e1 % ?- satisfies(legs, e1, N). % check e1 has 3 legs, not 4 % ?- satisfies(isa, e1, elephant). % check e1 isa elephant % ?- satisfies(legs, elephant, N). % normal elephants have 4 legs % ?- satisfies(skin, e1, Colour). % 2 steps: e1 isa elephant has grey skin % ?- satisfies(lactates, e1, Ans). % e1 isa elephant ako mammal lactates yes % e1 isa el... ako halluc... lact... no % Whether you get Ans = yes or Ans = no depends on which ako(elephant, ...) % fact appears first in the code below. Swap the order and check this. % It is an inherent problem of multiple inheritance that different nodes % of the inheritance graph might contain conflicting answers. This is a % feature when one node isa or ako the other (as with e1 and elephant) % but it's a problem with situations like mammal and hallucination having % conflicting values for "lactates". % ?- satisfies(worksat, e1, P). % e1 isa circusperformer worksat circus % ?- satisfies(material, e1, yes). % multi-step check ako(animate, realobject). ako(elephant, mammal). ako(elephant, hallucination). % if pink ako(mammal, animate). isa(e1, circusperformer). isa(e1, elephant). legs(e1, 3). legs(elephant, 4). hasname(e1, winifred). hobbies(e1, ballroomdancing). worksat(circusperformer, circus). alive(animate, yes). lactates(mammal, yes). lactates(hallucination, no). material(realobject, yes). skin(elephant, grey). tail(elephant, 1). trunk(elephant, 1). % You need to know about the =.. (Univ) predicate to understand % the next rule. =.. is an "infix" predicate. % An infix predicate name is written between its 2 arguments, not % in front of them. Other examples of infix predicates are ">" and "is". % % =.. converts between terms and lists: e.g. % % ?- Term =.. [likes, mary, pizza]. % Term = likes(mary, pizza) % % ?- likes(mary, pizza) =.. List. % List = [likes, mary, pizza] % first just check whether the Entity has the Property: satisfies(Property, Entity, Value) :- Goal =.. [Property, Entity, Value], Goal, !. % Stop after finding first answer. % Now let's see if Entity "isa" SomeType, and then check to see % if the Something has the Property: satisfies(Property, Entity, Value) :- isa(Entity, SomeType), satisfies(Property, SomeType, Value). % Now let's see if SomeType "ako" SuperType, and then check to see % if the SuperType has the Property: satisfies(Property, SomeType, Value) :- ako(SomeType, SuperType), satisfies(Property, SuperType, Value). % SuperSuperTypes further up the hierarchy will automatically be % checked recursively by the rule above.