1 / 20

Prolog programming unification/matching programs as deductive databases resolution, goal reduction

Dave Reed. Prolog programming unification/matching programs as deductive databases resolution, goal reduction declarative vs. procedural readings code tracing lists. Prolog exercise. recall: a Prolog program is a collection of facts & rules that define relations about objects. 0. 1.

miller
Download Presentation

Prolog programming unification/matching programs as deductive databases resolution, goal reduction

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Dave Reed • Prolog programming • unification/matching programs as deductive databases • resolution, goal reduction declarative vs. procedural readings • code tracing • lists

  2. Prolog exercise • recall: a Prolog program is a collection of facts & rules that define relations about objects 0 1 • write Prolog facts & rules that capture the properties of these blocks • constants? predicates? 2 4 3 5 • use Prolog to show that • there is a small block on top of a large block • block 4 is above block 5 • there is a blue block above another blue block • there is nothing above a green block

  3. Prolog unification • when variables are present, inference requires finding appropriate matches between facts & rules • i.e., must Universally Instantiate variables so that facts & rules match mother(M, C) :- parent(M, C), female(M). ?- mother(laura, charlie).  requires instance mother(laura,charlie) :- parent(laura,charlie), female(laura). ?- mother(laura, jack).  requires instance mother(laura,jack) :- parent(laura,jack), female(laura). • unification is an algorithm for determining the variable instantiations needed to make expressions match • query: mother(laura, charlie) • rule conclusion: mother(M, C) • these expressions unify/match with the variable instantiations: • M = laura, C = charlie

  4. Prolog unification • Prolog's unification algorithm (for matching expressions t1 and t2) • if t1 and t2 are constants, then they match if they are the same object • if t1 is a variable, then they match with t1 instantiated to t2 (i.e., t1 = t2) • if t1 and t2 are function/predicate expressions, then they match if • they have the same function/predicate symbol, AND • all of their arguments match (simultaneously) foo(you) foo(you) match since identical foo(X) foo(you) match, with X = you foo(X) foo(Y) match, with X = Y bar(X,b) bar(a,Y) match, with X = a, Y = b bar(X,f(X)) bar(a,f(a)) match, with X = a foo(X) boo(X) no match, with foo  boo foo(X,X) foo(a,f(a)) no match, requires X = a & X = f(a)

  5. Prolog programs as databases • matching/unification alone can provide for computation • consider a database of facts about movies at a video store • %%% to see if Bull Durham is available • ?- movie(_,title('Bull Durham'),_,_,_). • Yes • %%% to find all comedies • ?- movie(type(comedy),title(T),_,_,_). • T = 'My Man Godfrey' ; • T = 'Bull Durham' ; • No • %%% to find movies starring costner • ?- movie(_,title(T),year(Y), • actors(kevinCostner,_),_). • T = 'Dances with Wolves' • Y = 1990 ; • T = 'Bull Durham' • Y = 1988 ; • No %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% movies.pro Dave Reed 1/25/02 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% movie(type(comedy), title('My Man Godfrey'), year(1936), actors(williamPowell,caroleLombard), director(gregoryLaCava)). movie(type(drama), title('Dances with Wolves'), year(1990), actors(kevinCostner,maryMcDonnell), director(kevinCostner)). movie(type(comedy), title('Bull Durham'), year(1988), actors(kevinCostner,susanSarandon), director(ronShelton)). '_' is the anonymous variable, matches anything (but not reported)

  6. Deductive databases • but Prolog databases also allow for deduction • can define new relations that require computation • ?- costars(M, F). • M = williamPowell • F = caroleLombard ; • M = kevinCostner • F = maryMcDonnell • Yes • ?- versatile(Who). • Who = kevinCostner • Yes • ?- modern(Who). • Who = kevinCostner ; • Who = maryMcDonnell ; • Who = kevinCostner ; • No %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% movies.pro Dave Reed 1/25/02 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% movie info as before costars(M,F) :- movie(_,_,_,actors(M,F),_). versatile(P) :- movie(_,_,_,actors(P,_),_), movie(_,_,_,_,director(P)). versatile(P) :- movie(_,_,_,actors(_,P),_), movie(_,_,_,_,director(P)). modern(P) :- movie(_,_,year(Y),actors(P,_),_), Y >= 1990. modern(P) :- movie(_,_,year(Y),actors(_,P),_), Y >= 1990. modern(P) :- movie(_,_,year(Y),_,director(P)), Y >= 1990.

  7. Resolution • the proof procedure for answering queries in Prolog is known as resolution, or goal reduction can think of a query as a goal (or sequence of goals) to be solved or proven can think of the rule H :- B1, B2. as saying • "to solve/prove goal H, solve/prove subgoal B1 and then subgoal B2 " • to solve/prove goals G1, …, Gn: if n = 0, then the answer is 'Yes' else • find a fact or rule whose conclusion matches G1 (searching top-to-bottom) if no match, the answer is 'No' • rename variables so there is no overlap with goal variables • replace G1 with the premises (rhs) of the rule if matched a fact, simply remove G1 from the goal list • instantiate all goals according to the above match • recursively solve the new goal list if successful, the answer is 'Yes' and report all variable bindings else BACKTRACK (go back to goals G1, …, Gn and try next fact/rule)

  8. Resolution example parent(dave, charlie). parent(dave, jack). parent(laura, charlie). parent(laura, jack). male(dave). male(charlie). male(jack). female(laura). father(F, C) :- parent(F, C), male(F). mother(M, C) :- parent(M, C), female(M). • ?- father(F, charlie). • matches the father rule • rename variables in the rule: F1, C1 • match binds: F = F1, C1 = charlie • replace goal with premises, apply binding •  • ?- parent(F1, charlie), male(F1). • first goal matches the top fact • match binds: F1 = dave • remove first goal, apply binding •  • ?- male(dave). • goal matches fact • remove goal •  • ?- • no goals, SUCCESS • answer is the variable binding: F = F1 = dave • F = dave • Yes

  9. Example with backtracking • ?- mother(M, charlie). • matches the mother rule • rename variables in the rule: M1, C1 • match binds: M = M1, C1 = charlie • replace goal with premises, apply binding •  • ?- parent(M1, charlie), female(M1). • first goal matches the top fact • match binds: M1 = dave • remove first goal, apply binding •  • ?- female(dave). • no match, FAILURE • BACKTRACK to previous goal list •  • ?- parent(M1, charlie), female(M1). • continue search after top fact, matches next fact • match binds: M1 = laura • remove first goal, apply binding •  • ?- female(laura). • matches fact, remove goal •  • ?- • no goals, SUCCESS • answer is the variable binding: M = M1 = laura • M = laura • Yes parent(dave, charlie). parent(dave, jack). parent(laura, charlie). parent(laura, jack). male(dave). male(charlie). male(jack). female(laura). father(F, C) :- parent(F, C), male(F). mother(M, C) :- parent(M, C), female(M).

  10. Dual readings • Prolog programs can be read procedurally H :- B1, B2. "to solve H, solve B1 and B2" • or declaratively: H :- B1, B2. B1  B2  H "H is true if B1 and B2 are true" • under the declarative view: • programming is defining relations using a subset of the predicate calculus • a goal G is true (follows logically from the program) if • there is a fact that matches G, or • there is an instance of a rule with conclusion G whose premises are all true (recursively) • in short, Prolog computation is logical inference logic programming

  11. Declarative vs. procedural • the declarative reading of programs is generally more intuitive • easier to reason with (centuries of research in logic) • static • however, must keep the procedural reading in mind • in reality, rule and premise ordering matters • ancestor(A,P) :- parent(A,P). • ancestor(A,P) :- parent(A,C), ancestor(C,P). is more efficient than • ancestor(A,P) :- parent(A,C), ancestor(C,P). • ancestor(A,P) :- parent(A,P). which is still better than • ancestor(A,P) :- ancestor(C,P), parent(A,C). • ancestor(A,P) :- parent(A,P). WHY?

  12. Ancestor tracing (1) • built-in predicates: • listing will display all facts & relations defining a predicate • trace will cause each inference step to be displayed • in this case, an answer is found quickly since the "simple" case is listed first ?- consult(family). % family compiled 0.16 sec, 72 bytes ?- listing(ancestor). ancestor(A, B) :- parent(A, B). ancestor(A, B) :- parent(A, C), ancestor(C, B). ?- trace. Yes [trace] ?- ancestor(Who, jack). Call: (6) ancestor(_G383, jack) ? creep Call: (7) parent(_G383, jack) ? creep Exit: (7) parent(dave, jack) ? creep Exit: (6) ancestor(dave, jack) ? creep Who = dave Yes

  13. ?- listing(ancestor). ancestor(A, B) :- parent(A, C), ancestor(C, B). ancestor(A, B) :- parent(A, B). Yes ?- trace. Yes [trace] ?- ancestor(Who, jack). Call: (7) ancestor(_G386, jack) ? creep Call: (8) parent(_G386, _G441) ? creep Exit: (8) parent(winnie, dave) ? creep Call: (8) ancestor(dave, jack) ? creep Call: (9) parent(dave, _G441) ? creep Exit: (9) parent(dave, charlie) ? creep Call: (9) ancestor(charlie, jack) ? creep Call: (10) parent(charlie, _G441) ? creep Fail: (10) parent(charlie, _G441) ? creep Redo: (9) ancestor(charlie, jack) ? creep Call: (10) parent(charlie, jack) ? creep Fail: (10) parent(charlie, jack) ? creep Fail: (9) ancestor(charlie, jack) ? creep Redo: (9) parent(dave, _G441) ? creep Exit: (9) parent(dave, jack) ? creep Call: (9) ancestor(jack, jack) ? creep Call: (10) parent(jack, _G441) ? creep Fail: (10) parent(jack, _G441) ? creep Redo: (9) ancestor(jack, jack) ? creep Call: (10) parent(jack, jack) ? creep Fail: (10) parent(jack, jack) ? creep Fail: (9) ancestor(jack, jack) ? creep Fail: (9) parent(dave, _G441) ? creep Redo: (8) ancestor(dave, jack) ? creep Call: (9) parent(dave, jack) ? creep Exit: (9) parent(dave, jack) ? creep Exit: (8) ancestor(dave, jack) ? creep Exit: (7) ancestor(winnie, jack) ? creep Who = winnie Yes Ancestor tracing (2) • in this case, finding an answer requires extensive backtracking • harder, recursive case is first • leads to many dead ends

  14. Ancestor tracing (3) • in this case, the initial recursive call leads to an infinite loop • GENERAL ADVICE: • put simpler cases first (e.g., facts before rules) • for recursive rules, put the recursive call last, after previous inferences have constrained variables ?- listing(ancestor). ancestor(A, B) :- ancestor(C, B), parent(A, C). ancestor(A, B) :- parent(A, B). Yes ?- trace. Yes [trace] ?- ancestor(Who, jack). Call: (7) ancestor(_G386, jack) ? creep Call: (8) ancestor(_G440, jack) ? creep Call: (9) ancestor(_G440, jack) ? creep Call: (10) ancestor(_G440, jack) ? creep Call: (11) ancestor(_G440, jack) ? creep Call: (12) ancestor(_G440, jack) ? creep Call: (13) ancestor(_G440, jack) ? creep Call: (14) ancestor(_G440, jack) ? creep Call: (15) ancestor(_G440, jack) ? creep Call: (16) ancestor(_G440, jack) ? creep Call: (17) ancestor(_G440, jack) ? creep . . .

  15. Another example %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% connect.pro Dave Reed 2/5/02 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% road(a, b). road(b, c). road(c, a). road(c, b). road(c, d). road(d, e). road(e, d). connected(City1, City2) :- road(City1, City2). connected(City1, City2) :- road(City1, City3), connected(City3, City2). ?- connected(a, c). Yes ?- connected(c, a). Yes ?- connected(b, d). Yes ?- connected(b, e). ERROR: Out of local stack

  16. Prolog lists • the most general data structure in Prolog is the list • a list is a (possibly empty) sequence of items, enclosed in [ ] [] [foo] [cityA, cityB, cityC] • for a non-empty list, • we say the first item is the HEAD and the rest of the list is the TAIL [foo]  HEAD = foo, TAIL = [] [cityA, cityB, cityC]  HEAD = cityA, TAIL = [cityB, cityC] • lists are useful & flexible structures (also central to LISP/Scheme)

  17. List notation • [ ] notation for lists is syntactic sugar for function expressions • the dot functor combines the HEAD and TAIL of a list [foo]  .(foo, []) [cityA, cityB, cityC]  .(cityA, .(cityB, .(cityC, []))) • the dot notation highlights the recursive nature of lists • a list is either • empty, OR • a structure with a HEAD (an item) and a TAIL (a list) • in Prolog, can use either notation ?- [a,b] = .(a, .(b, [])). Yes

  18. List matching • can match variables to specific list items • can match variables to the HEAD and TAIL using '|' • can match variables to multiple items at the front, then the TAIL since a list is really a function expression, can access via matching ?- [X,Y] = [foo, bar]. X = foo Y = bar Yes ?- [H|T] = [a, b, c]. H = a T = [b, c] Yes ?- [H1,H2|T] = [a, b, c]. H1 = a H2 = b T = [c] Yes

  19. List operations • there are numerous predefined predicates for operating on lists • member(X, L): X is a member of list L • recursive definition: X is a member of L if either • X is the HEAD of L, OR • X is a member of the TAIL of L ?- member(a, [a, b, c]). Yes ?- member(a, [b, a, c]). Yes ?- member(a, [b, c]). No member is predefined, but we could define it ourselves if we had to: member(X, [X|_]. member(X, [_|T) :- member(X, T).

  20. Example revisited %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% connect.pro Dave Reed 2/5/02 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% road(a, b). road(b, c). road(c, a). road(c, b). road(c, d). road(d, e). road(e, d). connected(City1, City2) :- pathConnected([City1], City2). pathConnected([City1|_], City2) :- road(City1, City2). pathConnected([CityX|Rest], City2) :- road(CityX, CityY), not(member(CityY,Rest)), pathConnected([CityY,CityX|Rest], City2). • can add loop checking to the connected relation • need to keep track of the path traveled so far • at each step, make sure a city hasn't been visited before adding it to path here, code utilizes a help function with (reversed) path so far as first arg makes use of member to test if visited, built-in not predicate to reverse ?- connected(b, e). Yes ?- connected(e, a). No

More Related