%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % Prolog programs from Chapter 4 of the book % % SIMPLY LOGICAL: Intelligent reasoning by example % % (c) Peter A. Flach/John Wiley & Sons, 1994. % % % % Predicates: term_tree/3 % % term_root/2 % % term_subtree/2 % % term_arc/2 % % term_path/2 % % term_write/1 % % arc/2 % % path/1 % % path_leaf/2 % % leaf/1 % % resolve/3 % % properties/2 % % properties_sn/2 % % inherit_sn/3 % % override/3 % % properties_fr/2 % % inherit_fr/3 % % % % NB. This file needs predicates defined in % % the file 'library'. % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% :-consult(library). %%% 4.1 Representing structured knowledge %%% % term_tree(T,R,S) <- term T represents a tree with root R % and list of subtrees S term_tree(Tree,Root,Subtrees):- Tree=..[Root|Subtrees]. % term_root(T,R) <- R is the root of tree T term_root(Tree,Root):- term_tree(Tree,Root,S). % term_subtree(T,S) <- S is a subtree of tree T term_subtree(Tree,Subtree):- term_tree(Tree,R,S), element(Subtree,S). % term_arc(T,A) <- T is a tree, and A is an arc in T term_arc(Tree,[Root,SR]):- % Arc from Root to Subtree term_root(Tree,Root), term_subtree(Tree,Subtree), term_root(Subtree,SR). term_arc(Tree,Arc):- % Arc in Subtree term_subtree(Tree,Subtree), term_arc(Subtree,Arc). % term_path(T,P) <- T is a tree, and P is a path in T term_path(Tree,Arc):- % consisting of one arc term_arc(Tree,Arc). term_path(Tree,[Node1,Node2|Nodes]):- % several arcs term_arc(Tree,[Node1,Node2]), term_path(Tree,[Node2|Nodes]). term_write(Tree):- term_write(0,Tree),nl. % write a Tree at position Pos term_write(Pos,Tree):- term_tree(Tree,Root,Subtrees), % decompose Tree term_write_node(Pos,Pos2,Root), % write Root term_writes(Pos2,Subtrees). % new position % write a list of trees at position Pos term_writes(Pos,[]). term_writes(Pos,[Tree]):-!, % no newline here term_write(Pos,Tree). term_writes(Pos,[Tree|Subtrees]):- term_write(Pos,Tree), nl,tab(Pos), % skip to position Pos term_writes(Pos,Subtrees). % write a Node from Begin to End term_write_node(Begin,End,Node):- name(Node,L),length(L,N), % N is length of Nodename End is Begin+10, N1 is End-Begin-N, % N1 is length of line write_line(N1), write(Node). % write a line of given length write_line(0). write_line(N):- N>0,N1 is N-1, write('-'), write_line(N1). %%% 4.2 Graphs generated by a predicate %%% /* arc(1,2). arc(1,3). arc(2,4). arc(2,5). arc(2,6). arc(5,7). arc(3,8). arc(3,9). arc(9,10). */ % path(P) <- P is a path in the graph given by arc/2 path([Node1,Node2]):- arc(Node1,Node2). path([Node1,Node2|Nodes]):- arc(Node1,Node2), path([Node2|Nodes]). % path_leaf(N,P) <- P is a path starting at node N, ending % in a leaf in the graph given by arc/2 path_leaf(Leaf,[Leaf]):- leaf(Leaf). path_leaf(Node1,[Node1|Nodes]):- arc(Node1,Node2), path_leaf(Node2,Nodes). leaf(Leaf):- not arc(Leaf,SomeNode). arc(A,B):- resolve(A,(br(X,Y):-[br(X,Z),br(Z,Y)]),B). arc(A,B):- resolve(A,(br(paul,peter):-[]),B). % resolve(G,C,NewG) <- the goal G (a list of atoms) % resolves with the clause C (body % is a list) to yield the goal NewG resolve([H1|T],(H2:-Body),B):- H1=H2, % literal in goal unifies with head of clause append(Body,T,B). resolve([H|T],Clause,[H|B]):- resolve(T,Clause,B). % try next literal %%% 4.3 Inheritance hierarchies %%% %% Logical representation %% % Classes instrument(X):-wind(X). instrument(X):-string(X). instrument(X):-percussion(X). wind(X):-woodwind(X). wind(X):-brass(X). string(X):-plucked(X). string(X):-bowed(X). string(X):-keyboard(X). percussion(X):-tuned(X). percussion(X):-untuned(X). % Instances woodwind(recorder). woodwind(flute). woodwind(oboe). woodwind(saxophone). brass(trumpet). brass(trombone). brass(horn). plucked(guitar). plucked(lute). plucked(harp). bowed(violin). bowed(cello). keyboard(harpsichord). keyboard(piano). tuned(triangle). tuned(kettledrum). untuned(cymbal). untuned(snaredrum). % Properties function(X,musical):-instrument(X). material(flute,metal). material(saxophone,metal). material(X,wood):-woodwind(X). material(X,metal):-brass(X). material(X,wood):-string(X). material(X,metal):-percussion(X). action(oboe,reed(double)). action(saxophone,reed(single)). action(harpsichord,plucked). action(piano,hammered). action(X,reed(lip)):-brass(X). action(X,plucked):-plucked(X). action(X,bowed):-bowed(X). action(X,hammered):-percussion(X). %%% Inference %%% properties(Inst,Props):- attributes(Attrs), properties(Attrs,Inst,Props). properties([],Inst,[]). properties([Attr|Attrs],Inst,[Attr=Value|Props]):- get_value(Attr,Inst,Value),!, % only first answer properties(Attrs,Inst,Props). attributes([function,material,action]). get_value(A,B,C):- Goal =.. [A,B,C], call(Goal). %% Semantic network %% % Classes isa(instrument,top). isa(wind,instrument). isa(string,instrument). isa(percussion,instrument). isa(woodwind,wind). isa(brass,wind). isa(plucked,string). isa(bowed,string). isa(keyboard,string). isa(tuned,percussion). isa(untuned,percussion). % Instances inst(recorder,woodwind). inst(flute,woodwind). inst(oboe,woodwind). inst(saxophone,woodwind). inst(trumpet,brass). inst(trombone,brass). inst(horn,brass). inst(guitar,plucked). inst(lute,plucked). inst(harp,plucked). inst(violin,bowed). inst(cello,bowed). inst(harpsichord,keyboard). inst(piano,keyboard). inst(triangle,tuned). inst(kettledrum,tuned). inst(cymbal,untuned). inst(snaredrum,untuned). % Class properties prop(instrument,function,musical). prop(string,material,wood). prop(percussion,material,metal). prop(percussion,action,hammered). prop(woodwind,material,wood). prop(brass,material,metal). prop(brass,action,reed(lip)). prop(plucked,action,plucked). prop(bowed,action,bowed). % Instance properties prop(flute,material,metal). prop(oboe,action,reed(double)). prop(saxophone,material,metal). prop(saxophone,action,reed(single)). prop(harpsichord,action,plucked). prop(piano,action,hammered). %%% Inference %%% properties_sn(Inst,Props):- props(Inst,InstProps), % properties of instance inst(Inst,Class), inherit_sn(Class,InstProps,Props). % inherit from (super)class inherit_sn(top,Props,Props). inherit_sn(Class,SpecificProps,AllProps):- props(Class,GeneralProps), % properties of this class override(SpecificProps,GeneralProps,Props), isa(Class,SuperClass), % climb hierarchy inherit_sn(SuperClass,Props,AllProps). % properties of superclasses override(Props,[],Props). override(Specific,[Attr=Value|General],Props):- element(Attr=V,Specific), % overriding override(Specific,General,Props). override(Specific,[Attr=Value|General],[Attr=Value|Props]):- not element(Attr=V,Specific), % no overriding override(Specific,General,Props). props(IC,Props):- findall(Attr=Value,prop(IC,Attr,Value),Props). %% Frames %% % Classes class(instrument,top,[]). class(wind,instrument,[function=musical]). class(string,instrument,[material=wood]). class(percussion,instrument,[material=metal,action=hammered]). class(woodwind,wind,[material=wood]). class(brass,wind,[material=metal,action=reed(lip)]). class(plucked,string,[action=plucked]). class(bowed,string,[action=bowed]). class(keyboard,string,[]). class(tuned,percussion,[]). class(untuned,percussion,[]). % Instances instance(recorder,woodwind,[]). instance(flute,woodwind,[material=metal]). instance(oboe,woodwind,[action=reed(double)]). instance(saxophone,woodwind,[material=metal,action=reed(single)]). instance(trumpet,brass,[]). instance(trombone,brass,[]). instance(horn,brass,[]). instance(guitar,plucked,[]). instance(lute,plucked,[]). instance(harp,plucked,[]). instance(violin,bowed,[]). instance(cello,bowed,[]). instance(harpsichord,keyboard,[action=plucked]). instance(piano,keyboard,[action=hammered]). instance(triangle,tuned,[]). instance(kettledrum,tuned,[]). instance(cymbal,untuned,[]). instance(snaredrum,untuned,[]). %%% Inference %%% properties_fr(Inst,Props):- instance(Inst,Class,InstProps), inherit_fr(Class,InstProps,Props). % inherit from (super)class inherit_fr(top,Props,Props). inherit_fr(Class,SpecificProps,AllProps):- class(Class,SuperClass,GeneralProps), % properties of this class override(SpecificProps,GeneralProps,Props), inherit_fr(SuperClass,Props,AllProps). % properties of superclasses