1 / 21

Logic Programming – Part 2

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|[]].

ekrogman
Download Presentation

Logic Programming – Part 2

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. Logic Programming – Part 2 Lists Backtracking Optimization (via the cut operator) Meta-Circular Interpreters

  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|[]]

  3. Lists – CFG with Prolog Question: Which sentences can be constructed using this grammar? s -> npvp np -> det n vp -> v np| v det -> a | the n -> woman | man v -> shoots

  4. Lists – 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 vp np -> det n vp -> v np| v det -> a | the n -> woman | man v -> shoots

  5. Lists – CFG with Prolog • We 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]  …

  6. Lists – CFG with Prolog • Question: Add a few rules to the grammar What should we change in the code? • Answer: we add the following code s -> npvp np -> det n | detadj n vp -> v np| v det -> a | the n -> woman | man v -> shoots adj -> vicious | marvelous np(Z) :- det(X), adj(W), n(Y), append([X,W,Y],Z). adj([vicious]). adj([marvelous]).

  7. Lists – The date Relation • 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]).

  8. Lists – The date Relation • Q: How can we tell if hour 2 is before 9? • A: • A < relation isn’t really possible to implement.(More details in the PS document) • 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]).

  9. Lists – The date Relation 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). Example queries: ?- date([1,'Sun']). true dateLT(date([5,'Mon']), date([1,'Tue'])). true

  10. Lists – The date Relation • precedes is defined using append /2 precedes(X,Y,Z) :- append( [_,[X],_,[Y],_] , Z ). • Notice that the first argument is a list of lists • This version of append is a strong pattern matcher

  11. Lists – Merging date Lists • Merge 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'])]

  12. 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) Rule 1 – failure branch… Rule 2 – failure branch… dateLT(d2,d3), merge([d3,d5], [d3] ,Zs_2) merge([d3,d5], [d3] ,Zs_2) Rule 1 – failure branch… { X_3=d3,Xs_3=[d5],Ys_3=[], Zs_2=[d3,d3|Zs_3] } Rule 2 merge([d5], [] ,Zs_3) true { Xs_4=[d5], Zs_3=[d5] } Fact 4 Rule 3 – failure branch… Rule 2 – failure branch… { X_2=d3,Xs_2=[d5], Y_2=d2,Ys_2=[d3], Zs_1=[d2|Zs_2]} Rule 3 Rule 3 – failure branch…

  13. Backtracking Optimization - Cut The cut operator (denoted ‘!’) allows to prune trees from unwanted branches. • A cut prunes all the goals below it • A cut prunes all alternative solutions of goals to the left of it • A cut does not affect the goals to it’s right • The cut operator is a goal that always succeeds

  14. Backtracking Optimization - Cut

  15. merge([d1,d3,d5],[d2,d3],Xs) Rule 3 – failure branch… dateLT(d1,d2), !, merge([d3,d5], [d2,d3] ,Zs_1) Rule 2 – failure branch… !, merge([d3,d5], [d2,d3] ,Zs_1) merge([d3,d5], [d2,d3] ,Zs_1) Example - 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).

  16. Another Example • How many results does this query return? • Why does this happen? The query fits both rules 4 and 5 • How can we avoid this? Add cut to rule 4 ?- merge([],[],X) . X = []; X = []; No merge(Xs, [ ],Xs) :- !.

  17. Meta-Circular Interpreter Version 1 % 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 finds the first rule unifying with A with body 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)

  18. solve(ancestor(abraham, P)) {A_1 = ancestor(abraham, P)} Rule 3 solve clause(ancestor(abraham, P), B_1), solve(B_1) { B_1 = parent(abraham, P), X_2 = abraham, Y_2 = P } Rule 1 ancestor { B_1 = parent(abraham,Y_2), ancestor(Y_2, P) }Rule 2 ancestor solve(parent(abraham, P)) solve(parent(abraham,Y_2), ancestor(Y_2, P)) {A_3 = parent(abraham,Y_2) B_3 = ancestor(Y_2, P} Rule 2 solve {A_3 = parent(abraham, P)} Rule 3 solve solve( parent(abraham,Y_2)), solve(ancestor(Y_2, P)) clause(parent(abraham, P), B_3), solve(B_3). {P = issac, B_3 =true} Fact 1 parent {A_4 = parent(abraham,Y_2)} Rule 3 solve solve(true) clause(parent(abraham, Y_2), B_4), solve(B_4) solve(ancestor(Y_2, P)) Fact 1 solve ! {Y_2 = issac, B_4 =true} Fact 1 parent solve(true) , solve(ancestor(issac, P)) {P = issac} true

  19. Meta-Circular Interpreter Version 2 • In 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

  20. Meta-Circular Interpreter Version 2 % 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). Sample converted program: %rule (Head, BodyList)/21. rule( member(X, [X|_] ), [] ).2. rule( member(X, [_|Ys] ), [member(X, Ys)] ).

  21. solve(member(X, [a, b, c])) {Goal_1 = member(X, [a, b, c])} Rule 1 solve 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, []) { X_3=X,Ys_3=[b, c],B_2 = [member(X, [b,c])]}Rule 2 rule { X=a,X_3 = a, Xs_3=[b, c],B_2 = [] } Rule 1 rule solve([],[]) solve([member(X, [b,c])], []) Rule 1 solve { A_4= member(X, [b,c]), B_4=[], Goals_4=[] } Rule 3 rule true append([], [], Goals1_4), solve(member(X, [b,c]), Goals1_4). {X=a} { Goals1_4=[]} Rule of append solve(member(X, [b,c]), []). { A_5=member(X,[b,c]), Goals_5=[]} Rule 4 solve rule(member(X,[b,c]), B_5), solve(B_5, []) { X=b,X_6 = b,B_5 = [] } Rule 1 rule solve([],[]) Rule 1 solve true {X=b}

More Related