logic programming – part 2 lists backtracking optimization (via the cut operator) meta-circular...

21
Logic Programming – Logic Programming – Part 2 Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

Upload: amya-ventry

Post on 14-Dec-2015

223 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

Logic Programming – Part Logic Programming – Part 22• Lists• Backtracking Optimization (via the cut

operator)• Meta-Circular Interpreters

Page 2: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

Lists – Basic ExamplesLists – Basic Examples[] – The empty list[X,2,f(Y)] – A 3 element list[X|Xs] – A list starting with X. Xs

is a list as well.

Example - [3,5] may be written as [3|5|[]]

Page 3: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

Lists – CFG with PrologLists – CFG with Prolog

Question: Which sentences can be constructed using this grammar?

s -> np vpnp -> det nvp -> v np | vdet -> a | then -> woman | manv -> shoots

Page 4: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

Lists – CFG with PrologLists – CFG with Prolog

Lets make relations out of it:s(Z) :- np(X), vp(Y), append(X,Y,Z). np(Z) :- det(X), n(Y), append(X,Y,Z). vp(Z) :-  v(X), np(Y), append(X,Y,Z).vp(Z) :-  v(Z). det([the]).det([a]). n([woman]).n([man]). v([shoots]).

s -> np vpnp -> det nvp -> v np  | vdet -> a | then -> woman | manv -> shoots

Page 5: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

Lists – CFG with PrologLists – CFG with PrologWe can ask simple queries like:

Prolog generates entire sentences!

s([a,woman,shoots,a,man]).true

?-s(X). X = [a,woman,shoots,a,woman] ;X = [a,woman,shoots,a,man] ;X = [a,woman,shoots,the,woman] ;X = [a,woman,shoots,the,man] ;X = [a,woman,shoots] …

?-s([the,man|X]). X = [shoots,a,woman] ;X = [shoots,a,man] ;X = [shoots,the,woman] …

Page 6: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

Lists – CFG with PrologLists – CFG with PrologQuestion: Add a few rules to the grammar

What should we change in the code?Answer: we add the following code

s -> np vpnp -> det n | det adj nvp -> v np | vdet -> a | then -> woman | manv -> shootsadj -> vicious | marvelous

np(Z) :- det(X), adj(W), n(Y), append([X,W,Y],Z).adj([vicious]).adj([marvelous]).

Page 7: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

In this example we’ll work with dates

We assume, for simplicity that a date comprises of a week day and an hour

We define the possible week days and hours with lists:

week_day(['Sun', 'Mon', 'Tue','Wed','Thu','Fri','Sat']).

hour([0,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,

19, 20, 21, 22, 23]).

Lists – The date RelationLists – The date Relation

Page 8: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

Q: How can we tell if hour 2 is before 9?

A: 1.A < relation isn’t really possible to implement.

(More details in the PS document)

2.We can only do so by checking precedence in the lists above.

week_day(['Sun', 'Mon', 'Tue','Wed','Thu','Fri','Sat']).

hour([0,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,

19, 20, 21, 22, 23]).

Lists – The date RelationLists – The date Relation

Page 9: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

Lists – The date RelationLists – The date Relation

Example queries:

date([H,W]) :- hour(Hour_list), member(H, Hour_list), week_day(Weekday_list), member(W, Weekday_list). dateLT( date([_,W1]), date([_,W2]) ) :- week_day(Weekday_list), precedes(W1,W2,Weekday_list).dateLT( date([H1,W]), date([H2,W]) ) :- hour(Hour_list), precedes(H1,H2,Hour_list).

?- date([1,'Sun']).true dateLT(date([5,'Mon']), date([1,'Tue'])).true

Page 10: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

precedes is defined using append /2

precedes(X,Y,Z) :- append( [_,[X],_,[Y],_] , Z ).

Lists – The date RelationLists – The date Relation

Notice that the first argument is a list of lists

This version of append is a strong pattern matcher

Page 11: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

Lists – Merging date ListsLists – Merging date ListsMerge 2 ordered date-lists

% Signature: merge(Xs, Ys, Zs)/3% purpose: Zs is an ordered list of dates obtained% by merging the ordered lists of dates Xs and Ys.merge([X|Xs] , [Y|Ys] , [X|Zs]) :- dateLT(X,Y), merge(Xs, [Y|Ys] ,Zs).merge([X|Xs] , [X|Ys] , [X,X|Zs]) :- merge(Xs, Ys, Zs).merge([X|Xs],[Y|Ys],[Y|Zs]) :- dateLT(Y,X), merge( [X|Xs] ,Ys, Zs). merge(Xs,[ ], Xs). merge([ ],Ys, Ys).?- merge( [date([5,'Sun']), date([5,'Mon'])], X,

[date([2, 'Sun']), date([5,'Sun']), date([5, 'Mon'])]).X = [date([2, 'Sun'])]

Page 12: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

merge([d1,d3,d5],[d2,d3],Xs)

{X_1=d1,Xs_1=[d3,d5], Y_1=d2,Ys_1=[d3],Xs=[d1|Zs_1] } Rule 1 dateLT(d1,d2),

merge([d3,d5], [d2,d3] ,Zs_1)

merge([d3,d5], [d2,d3] ,Zs_1) 

true

merge([d3,d5], [d3] ,Zs_2)

dateLT(d2,d3), merge([d3,d5], [d3] ,Zs_2) 

Rule 2 – failure branch…Rule 1 – failure branch…

{ X_3=d3,Xs_3=[d5],Ys_3=[],Zs_2=[d3,d3|Zs_3] } Rule 2

Rule 1 – failure branch…

merge([d5], [] ,Zs_3) 

{ Xs_4=[d5], Zs_3=[d5] } Fact 4 

Rule 2 – failure branch…

Rule 3 – failure branch…

Rule 3 – failure branch…

{ X_2=d3,Xs_2=[d5],Y_2=d2,Ys_2=[d3],Zs_1=[d2|Zs_2]} Rule 3

Page 13: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

Backtracking Optimization Backtracking Optimization - Cut- CutThe cut operator (denoted ‘!’) allows to prune trees from unwanted branches.

A cut prunes all the goals below itA cut prunes all alternative solutions of goals to the left of itA cut does not affect the goals to it’s right

The cut operator is a goal that always succeeds

Page 14: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

Backtracking Optimization Backtracking Optimization - Cut- Cut

Page 15: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

Example - Merge with CutExample - Merge with Cut In the merge example, only 1 of the 3 first

rules can be true. There is no reason to try the others.

Modify rule 1:merge([X|Xs] ,[Y|Ys], [X|Zs]) :- dateLT(X,Y), !, merge (Xs, [Y |Ys],Zs).

merge([d1,d3,d5],[d2,d3],Xs)

dateLT(d1,d2),!, merge([d3,d5], [d2,d3] ,Zs_1)

merge([d3,d5], [d2,d3] ,Zs_1) 

!, merge([d3,d5], [d2,d3] ,Zs_1)

Rule 2 – failure branch…

Rule 3 – failure branch…

Page 16: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

Another ExampleAnother ExampleHow many results does this query

return?

Why does this happen?The query fits both rules 4 and 5How can we avoid this?Add cut to rule 4

?- merge([],[],X) .

merge(Xs, [ ],Xs) :- !.

X = [];X = [];No

Page 17: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

Meta-Circular Interpreter Meta-Circular Interpreter Version 1Version 1

clause finds the first rule unifying with A with body B

% Signature: solve(Goal)/1% Purpose: Goal is true if it is true when posed to the original program P.

solve(true) :- !.solve( (A, B) ) :- solve(A), solve(B).solve(A) :- clause(A, B), solve(B).

?- clause( parent(X,isaac),Body).X = abraham Body = true

?- clause(ancestor(abraham, P),Body).P = Y, Body = parent(abraham, Y) ;P = Z, Body = parent(abraham, Y), ancestor(Y, Z)

Page 18: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

{A_1 = ancestor(abraham, P)}Rule 3 solve

solve(ancestor(abraham, P))

clause(ancestor(abraham, P), B_1), solve(B_1) 

{ B_1 = parent(abraham, P), X_2 = abraham, Y_2 = P }Rule 1 ancestor

solve(parent(abraham, P))

{A_3  =  parent(abraham, P)}Rule 3 solve  

{P = issac, B_3 =true}Fact 1 parent  

solve(parent(abraham,Y_2), ancestor(Y_2, P))

{ B_1 = parent(abraham,Y_2), ancestor(Y_2, P) }Rule 2 ancestor 

{A_3 = parent(abraham,Y_2)B_3 = ancestor(Y_2, P}Rule 2 solve 

clause(parent(abraham, P), B_3), solve(B_3).

 

solve(true)

!

solve( parent(abraham,Y_2)), solve(ancestor(Y_2, P))

clause(parent(abraham, Y_2), B_4), solve(B_4)

solve(ancestor(Y_2, P))Fact 1 solve

  

{P = issac}

 

 

{A_4 = parent(abraham,Y_2)}Rule 3 solve 

{Y_2 = issac, B_4 =true}Fact 1 parent  solve(true) ,

solve(ancestor(issac, P))

true

Page 19: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

Meta-Circular Interpreter Meta-Circular Interpreter Version 2Version 2In this version we control the

goal selection order by using a stack of goals

Preprocessing – The given program is converted into a program with a single predicate rule containing only facts

Queries are checked against the new program

Page 20: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

Meta-Circular Interpreter Meta-Circular Interpreter Version 2Version 2

Sample converted program:

% Signature: solve(Goal)/1% Purpose: Goal is true if it is true when posed to the original program P.1. solve(Goal) :- solve(Goal, []). % Signature: solve(Goal, Rest_of_goals)/21. solve([],[]).2. solve([],[G | Goals]):- solve(G, Goals).3. solve([A|B],Goals):- append(B, Goals, Goals1), solve(A, Goals1).4. solve( A, Goals) :- rule(A, B), solve(B, Goals).

%rule (Head, BodyList)/21. rule( member(X, [X|_] ), [] ).2. rule( member(X, [_|Ys] ), [member(X, Ys)] ).

Page 21: Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

{ X_3=X,Ys_3=[b, c],B_2 = [member(X, [b,c])]} Rule 2 rule

{ A_4= member(X, [b,c]), B_4=[], Goals_4=[] }  Rule 3 rule

{ Goals1_4=[]}Rule of append

{ A_5=member(X,[b,c]), Goals_5=[]}Rule 4 solve

{ X=b,X_6 = b,B_5 = [] }  Rule 1 rule

{Goal_1 = member(X, [a, b, c])}Rule 1 solve

solve(member(X, [a, b, c]))

solve(member(X, [a, b, c]), [])

{ A_2 = member(X, [a, b, c], Goals_1 = [] }Rule 4 solve

rule(member(X, [a, b, c], B_2), solve(B_2, [])

solve([],[])

{ X=a,X_3 = a, Xs_3=[b, c],B_2 = [] }Rule 1 rule

true

{X=a}

Rule 1 solve

solve([member(X, [b,c])], [])

append([], [], Goals1_4), solve(member(X, [b,c]), Goals1_4).

solve(member(X, [b,c]), []).

rule(member(X,[b,c]), B_5), solve(B_5, [])

solve([],[])

true

{X=b}

Rule 1 solve