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

Logic Programming – Part 2

Feb 22, 2016

Download

Documents

Neo

Logic Programming – Part 2. Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters. Lists – 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|[]]. - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Logic Programming – Part 2

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

operator)• Meta-Circular Interpreters

Page 2: Logic Programming – Part 2

Lists – 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 – 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 – CFG with PrologLets 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 – CFG with PrologWe can ask simple queries like:

Prolog generates entire sentences!

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

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

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

Page 6: Logic Programming – Part 2

Lists – 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 – The date RelationIn this example we’ll work with

datesWe 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([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]).

Page 8: Logic Programming – Part 2

Lists – The date Relation

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

Answer: 1. We can only do so by checking

precedence in the lists above2. A < relation isn’t really possible to

implement(There’s a more detailed answer in the PS document)

week_day(['Sun', 'Mon', 'Tue','Wed','Thu','Fri','Sat']).hour([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]).

Page 9: Logic Programming – Part 2

Lists – The date Relation

Some 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 – The date Relationprecedes is defined using append

/2

Notice that the first argument is a list of lists

This version of append is a strong pattern matcher

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

Page 11: Logic Programming – Part 2

Lists – 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

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

Backtracking Optimization - 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
Page 15: Logic Programming – Part 2

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

rules can be true. There is no reason to try to 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

Another 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

Meta-Circular InterpretersWe have seen 3 different

interpreters in class

Version 1 is trivial

We can’t control the computation this way

solve( A ) :- A.

Page 18: Logic Programming – Part 2

Interpreter Version 2

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) :- A\=true, 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 19: Logic Programming – Part 2

{<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)

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))

Page 20: Logic Programming – Part 2

Interpreter Version 3In 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

Queries are checked against the new program

Page 21: Logic Programming – Part 2

Interpreter Version 3

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|Xs] ), [] ).2. rule( member(X, [Y|Ys] ), [member(X, Ys)] ).

Page 22: Logic Programming – Part 2

{ <X_3=X>,<Y_3= a>,<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>, <Xs_6=[c]>,<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 solvesolve([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