VIEWS: 74 PAGES: 7 CATEGORY: Technology POSTED ON: 1/19/2010
Outline • Prolog – Basic data types CSC326 Programming Languages – Lists (Week 13, Monday) – Unification – Prolog search tree – Negation as failure – Some small but useful things in Prolog Yilan Gu – Cut! guyilan@ecf.toronto.edu http://www.cs.toronto.edu/~yilan/326f09 Execution of Prolog Programs Cut ! • The goal “!”, pronounced “cut” always succeeds immediately. • Unification: variable bindings. • It has an important side effect: Once it is satisfied, it disallows • Backward Chaining/ either: Top-Down Reasoning/ – backtracking back over the cut, or Goal-Directed Reasoning: – backtracking and applying a different clause of the same Reduces a goal to one or more subgoals. predicate to satisfy the present goal. • Backtracking: • You can think of satisfying cut as making a commitment both Systematically searches for all possible solutions that can be obtained – to the variable bindings we’ve made during the application via unification and backchaining. of this rule, and – to this particular rule itself. Cut ! Use of Cut • The cut goal succeeds whenever it is the current goal, and the derivation • Cut can be used to improve the efficiency of search by reducing Prolog’s tree is trimmed of all other choices on the way back to and including the search space. E.g., point in the derivation tree where the cut was introduced into the sequence When two predicates are mutually exclusive. of goals. q(X) :- even(X), a(X). • Cut tells us: ”Do not pass back through this point when looking for alternative solutions. ! acts as a marker back beyond which Prolog will q(X) :- odd(X), b(X). not go. All the choices made prior to the cut are set, and are treated as With cut though they were the only possible choices. q(X) :- even(X), !, a(X). • You can think of Cut as telling the interpreter: ”Trust me – if you get this q(X) :- odd(X), b(X). far in the clause, there’s no need to backtrack and try another choice for proving this goal,or to try another way of satisfying any of the subgoals that were already proved for this goal.”The goal “!”, pronounced “cut” always succeeds immediately. Use of Cut Use of Cut • Cut can remove unwanted answers, but ... • Cut can remove unwanted answers. • Consider the Family Database: • Consider the Family Database: male(albert). male(albert). male(bob). male(bob). male(edward). male(edward). female(alice). female(alice). female(victoria). female(victoria). parent(albert,edward). parent(albert,edward). parent(victoria,edward). parent(victoria,edward). parent(albert,alice). parent(albert,alice). parent(victoria,alice). parent(victoria,alice). parent(albert,bob). parent(albert,bob). parent(victoria,bob). parent(victoria,bob). % son(?X) iff X is a son % son(?X) iff X is a son son(X):-parent(_,X),male(X), !. son(X):-parent(_,X),male(X). Use of Cut Use of Cut • Cut is dangerous Think: male(albert). any male is a potentially good answer, so we want to try all of them: can’t male(bob). put “cut” after “male” in the same rule. male(edward). • if a male has 2 parents, we only want to list him once as the answer: want to female(alice). put “cut” after “parent”. female(victoria). parent(albert,edward). Result: parent(victoria,edward). son(X):-male(X), isason(X). parent(albert,alice). isason(X):-parent(_,X),!. parent(victoria,alice). ?- son(X). parent(albert,bob). X = bob ; parent(victoria,bob). X = edward ; % son(?X) iff X is a son No son(X):-parent(_,X), !, male(X). Use of Cut Use of Cut • Try to use cut: sibling(X,Y):-parent(P,X),parent(P,Y). siblings(X,Y):-parent(P,X), !, parent(P,Y). ?- sibling(alice,Asib). ?- sibling(alice,Asib). Asib = edward ; Asib = edward ; Asib = alice ; Asib = alice ; Asib = bob ; Asib = bob ; Asib = edward ; No Asib = alice ; So far so good. Asib = bob ; • But if we ask: no. siblings(X,Y):-parent(P,X), !, parent(P,Y). ?- sibling(Asib,alice). Asib = edward ; No Not so good. Use of Cut Use of Cut Think: Finally, we don’t want X to be a sibling on X. • any two people in the database are potentially good answers, so we want to try all of them: can’t put “cut” in a rule after X and/or Y is instantiated • if 2 people share 2 parents, we only want to list them once as the answer: sibling(X,Y):-not(X=Y), person(X),person(Y), want to put “cut” after 2 “parent” rules. commmonparent(X,Y). Result: person(X):-male(X). sibling(X,Y):-person(X),person(Y), commonparent(X,Y). person(X):-female(X). person(X):-male(X). commonparent(X,Y):-parent(P,X),parent(P,Y),!. person(X):-female(X). ?- sibling(alice,Asib). commonparent(X,Y):-parent(P,X),parent(P,Y),!. No ?- sibling(alice,Asib). ?- sibling(Asib,alice). Asib = bob ; Asib = bob ; What went wrong? How to fix? (see next page) Asib = edward ; Asib = edward ; Asib = alice ; Asib = alice ; No No Use of Cut When to use cut? sibling(X,Y):- person(X),person(Y), not(X=Y), • Common uses of the !: commmonparent(X,Y). – Tell the Prolog system that it has found the right rule for a particular goal: person(X):-male(X). If you get this far, you have picked the correct rule for this goal. e.g., P(N,X):-odd(N), !, X is N+3. % assume that odd() is defined. person(X):-female(X). P(N,X):-even(N), X is N / 2. commonparent(X,Y):-parent(P,X),parent(P,Y),!. – Tell the Prolog system to fail a particular goal immediately without trying for alternate solutions: If you get to here, you should stop trying to satisfy the goal. ?- sibling(Asib,alice). e.g., not(G):- G,!, fail. Asib = bob ; not(G). Asib = edward ; – Terminate the generation of alternative solutions: No If you get to here, you have found the only solution to this problem, no point in looking for alternatives. ?- sibling(alice,Asib). e.g., factorial(N,X):- N>0, N1 is N-1, factorial(N1, X1), X is X1*N. Asib = bob ; factorial(0,1):-!. Asib = edward ; No Prolog: cut ! - examples Prolog: cut ! – example • Double-step function: • Double-step function - cont’d: if X < 3 then Y = 0 if X < 3 then Y = 0 if 3 =< X and X < 6 then Y = 2 if 3 =<X and X < 6 then Y = 2 if 6 =< X then Y = 4 if 6 =< X then Y = 4 What do we know about this function that Prolog doesn’t? % In Prolog f(X,0) :- X < 3. %rule 1 % same relations with ! f(X,2) :- 3 =< X, X < 6. %rule 2 f(X,0) :- X < 3,!. %rule 1 f(1,Y) 2<Y f(X,4) :- 6 =< X. %rule 3 f(1,Y) f(X,2) :- 3 =< X, X < 6,!. %rule 2 CUT 2<Y CUT f(X,4) :- 6 =< X. %rule 3 rule 1 rule 2 rule 3 ?- f(4,Y). %query rule 1 rule 2 rule 3 1<3 Y=2 ?- f(1,Y),2<Y. %query 1<3 3 =< 1, 6 =< 1 yes 1<6 no yes no no ?- f(1,Y),2<Y. %query 2<0 no 2<0 no no In this example, we changed the procedural meaning of the program, but not the declarative meaning Prolog: cut ! – example cut ! classification • Double-step cont’d: • Green cuts: % same relations with ! f(5,Y) f(X,0) :- X < 3,!. %rule1 – Affect procedural meaning of program but has no effect on the CUT f(X,2) :- 3 =< X, X < 6,!. %rule2 rule 1 rule 2 rule 3 declarative meaning. f(X,4) :- 6 =< X. %rule3 – Do not affect readability of programs. 5<3 3 =< 5 | ?- f(5,Y). %query 5<6 – Used mainly to avoid wasted computations. Y=2 no yes Can we come up with a more efficient version? f(5,Y) • Red cuts: f(X,0) :- X < 3,!. %rule1 – Affect declarative meaning of program as well as procedural meaning. CUT f(X,2) :- X < 6,!. %rule2 rule 1 rule 2 rule 3 – Affect readability: f(X,4). %rule3 • Similar to unconditional jump (goto) in imperative PLs 5<3 5<6 | ?- f(5,Y). %query – Used to avoid wasted computations and also introduce semantics Y=2 no yes – If not used cautiously, can affect result in arbitrary way. % What if we removed the cuts? | ?- f(1,Y).% query f(X,0) :- X < 3. %rule1 Y = 0; % right answer f(X,2) :- X < 6. %rule2 Y = 2; % wrong answer,why? f(X,4). %rule3 Y = 4; % wrong answer,why? Here, we changed the procedural and also the declarative meaning cut ! - examples cut ! – examples • Member function: • Bubble-sort without !: % Find 2 adjacent elements X and Y in List such that X > Y Bubblesort without ! member(Element, [Element | _]). (1) List=[10,3,1] member(Element, [_ | Rest]) :- member(Element, Rest). % and swap X and Y to get List1, then sort List1. If there is -------------------- % no pair of adjacent X and Y where X > Y, we are done. (3) List=[3,10,1] -------------------- Correct % What’s the problem in the above function? bubblesort(List,Sorted):-swap(List,List1), answer (8) List=[3,1,10] bubblesort(List1,Sorted). -------------------- member(Element, [Element | _]) :- !. bubblesort(Sorted,Sorted). (10) List=[1,3,10] Why didn’t -------------------- it stop? • Sum function: swap([X,Y | Rest],[Y,X | Rest]) :- X > Y. % rule 1 …(17) List=[3,1,10] – Without !: swap([Z|Rest],[Z|Rest1]) :- swap(Rest,Rest1). % rule 2 rule 1 rule 2 sum_to(1,1). ?- bubblesort([10,3,1],Res). %query swap swap sum_to(N, Res) :- N1 is N-1, sum_to(N1,TRes), Res is TRes + N. Res = [1,3,10]; (2) List=10,3,1 (5) List=3,10,1 …… % more output ? X=10,Y=3, Rest=1 Z=3, Rest=10,1 ?- sum_to(1,X). List1=3,10,1 ------------------- X=1; ------------------- (7) Rest1=1,10 %Infinite loop…………………. • Bubble-sort with !: (4) List=3,10,1 Z=3 bubblesort(List,Sorted):-swap(List,List1),!, X=3,Y=10,Rest=1 List1=3,1,10 bubblesort(List1,Sorted). ------------------ ------------------ – With !: (6) List=10,1 (12)Z=1,Rest=3,10 sum_to(1,1) :- !. bubblesort(Sorted,Sorted). X=10, Y=1,Rest= etc.. sum_to(N, Res) :- N1 is N-1, sum_to(N1,TRes), Res is TRes + N. swap([X,Y | Rest],[Y,X | Rest]) :- X > Y. List1=1,10 ?- sum_to(1,X). ------------------ swap([Z|Rest],[Z|Rest1]) :- swap(Rest,Rest1). (9) X=3,Y=1,Rest=10 X=1; ?- bubblesort([10,3,1],X). %query List1=1,3,10 X = [1,3,10]; ------------------ (11) X=1,Y=3,Rest=10 cut ! Pros & Cons Prolog: pros & cons • Pros: • Cons: – Horn clauses have limited expressive power – More efficient: interpreter will not process unnecessary branches in the – Closed world assumptions (anything not mentioned is false) unification tree – Ordering of clauses change the result – Save memory: interpreter will not allocate space for tree nodes that will not be unified. – Because horn clause is the basic construct, you must program carefully to avoid infinite loops and incorrect negation. • There is no 1-solution-fits-all for these problems… • Cons: – Creates side effects that change the way backtracking works (not really logic programming…) • Pros: – Makes the place markers of certain goals inaccessible. – Pattern matching – Backtracking – Unification – Rules and goals are also data (dynamic programming). Die the death of a thousand cuts… Richard O’Kaffe – Craft of Prolog – The logical model is powerful Logic vs. Imperative Languages ! " # $ # $ " % ! % ! & ! & / ' " ( ' ) * ) * + , (-((.( + , (-((.( ( ( ( ( 0 " 1 ,,2# 3 !" " ", ! " $ 4 5 5