1 / 49

PROgramming LOGic Continued

PROgramming LOGic Continued. A logic programming language is a notational system for writing logical statements together with specified algorithms for implementing inference rules. What will be covered. Lots of code. Another relation ?? Remember "is" breaks the logical model.

cpadro
Download Presentation

PROgramming LOGic Continued

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. PROgramming LOGicContinued A logic programming language is a notational system for writing logical statements together with specified algorithms for implementing inference rules. Head/Lander

  2. What will be covered • Lots of code Head/Lander

  3. Another relation ?? Remember "is" breaks the logical model. squares( [ ], [ ] ). squares( [N|T ], [S|ST ] ) :– S is N*N, squares( T, ST). ? – squares( [ 0, 2, 3, 1], X ). X = [ 0, 4, 9, 1] ? – squares( [ ], X ). X = [ ] ? – squares( [2, 4, 6], [4, 16, 36] ). yes Head/Lander

  4. More simple examples • Counts all the positive numbers in a list. (i.e. n >0) Your solution should allow only one correct solutions. positive( List, NumberOfPos). • Partition a list of numbers into a positive list and a negative list. selectpn( List, PositiveList, NegList ) Head/Lander

  5. positive( [ ], 0). positive( [ H | T ], Z ) :– H > 0, !, positive( T, Z1 ), Z is 1 + Z1. positive( [ _ | T ] , Z ) :– positive( T, Z ). ? – positive( [ 0, –1, –5, 5], X ). X = 1 ? – positive( [1, –2, 4, 2, 3], X ). X = 4 ? – positive( [ ], X ). X = 0 Head/Lander

  6. selectpn( [ ], [ ], [ ] ). selectpn( [ 0 | T ], X, Y ) :– selectpn( T, X, Y ), !. selectpn( [ H | T ], [ H|Z ], X ) :– H > 0, !, selectpn ( T, Z, X ). selectpn( [ H | T ], X, [ H|Z ] ) :– selectpn ( T, X, Z ). ? – selectpn( [ 0, –1, –5, 5], X, Y ). X = [5] Y = [–1, –5] ? – selectpn( [1, –2, 4, 2, 3], X, Y ). X = [1, 4, 2, 3] Y = [–2] Head/Lander

  7. permute( [ ], [ ] ). permute(L, [ X | Y ] ) :– select( L, X, T ), permute( T, Y ). select( [ X | Y ], X, Y ). select( [ X | Y ], Z, [ X | T ] ) :– select( Y, Z, T). ? – permute( [ 1, 4, 7 ], X ). X = [ 1, 4, 7 ]; X = [ 1, 7, 4 ]; X = [ 4, 1, 7 ]; X = [ 4, 7, 1 ]; X = [ 7, 1, 4 ]; X = [ 7, 4, 1 ]; no Head/Lander

  8. Try: callperm( X ):– permute( X ,Y ), write(Y ), nl, fail. ? – callperm( [1, 4, 7] ). [1, 4, 7] [1, 7, 4] [4, 1, 7] [4, 7, 1] [7, 1, 4] [7, 4, 1] no Head/Lander

  9. Recursion revisited fibonacci_1( X , 1) :– X =< 2. fibonacci_1( X , Y ) :– X > 2, X1 is X – 1, X2 is X – 2, fibonacci_1( X 1, Y1), fibonacci_1( X 2, Y2), Y is Y1 + Y2. Head/Lander

  10. Improvement: MemoizationUsing asserta to add facts to our program.(Need directive :-dynamic) fibonacci_2( 1, 1). fibonacci_2( 2, 1). fibonacci_2( X, Y ) :– X > 2, X1 is X – 1, X2 is X – 2, fibonacci_2( X1, Y1 ), fibonacci_2( X2, Y2 ), Y is Y1 + Y2, asserta(fibonacci_2( X,Y )). Head/Lander

  11. Dynamic ProgrammingUSING STATE VARIABLES (ACCUMULATORS) TO PASS VALUES FROM ONE ITERATION TO THE NEXT.(How would you simulate an array in Prolog?) fibonacci_3( N, Fib):– fib_aux( 2, N, 1, 1, Fib ). fib_aux ( N, N, F1, Fib, Fib ). fib_aux ( M, N, F1, F2, F ) :– M < N, NextM is M + 1, NextF2 is F1 + F2, fib_aux(NextM, N, F2, NextF2, F). Head/Lander

  12. Breaking the model • Another break of the logical model ... • Problems that can occur depending on the position of Variables in a predicate • Problems that can occur depending on the order of the predicates in a Query • The problem with NOT Head/Lander

  13. % Assume family.pl parent( X , Y ) :– mother( X , Y ). /* If mother( X ,Y ) then parent( X ,Y ) */ parent( X , Y ) :– father( X , Y ). grandparent( X , Z ) :– parent( X , Y ),parent(Y, Z ). mother(mary, ann). mother(mary, joe). mother(sue, marY ). father(mike, ann). father(mike, joe). grandparent(sue, ann). /* Redundant */ sibling( X , Y ) :– parent(P, X ), parent(P, Y ). ?- sibling( X, Y ). X = ann Y = ann Head/Lander

  14. sibling( X , Y ) :– parent(P, X ), parent(P, Y ), not( X = Y). both-parent-sibling( X , Y ) :– mother( M, X ), mother( M, Y ), father( F, X ), father( F, Y ), not( X = Y ). 1?- sibling( X, Y ). X = ann Y= joe 2?- both-parent-sibling( X , ann). X = joe Head/Lander

  15. Negation: not(P) :– call(P), !, fail. not(P). alternatively: not(P):– P, !, fail; true. alternatively: not(P):– P, !, fail. not(P):-true. Head/Lander

  16. The trouble with “not” test( S, T) :- S = T.1?- test( 3, 5). no 2?- test( 5, 5).yes 3?- not( test( 5,5)).no 4?- test( X,3), R is X+2.X=3R=5 5?- not( not( test( X,3))), R is X+2. warning unbounded variable in arithmetic expression fail ... /* When not(test(X,3)) fails the instantiation of X to 3 is released */ Head/Lander

  17. Another problem with not /* X instantiated to 0, then not( 0= 1) succeeds. */ 6?- X = 0, not( X=1). X=0 /* X instantiated to 1, not( X=1) fails, the goal X = 0 is never reached */ 7?- not( X=1 ), X=0. no Head/Lander

  18. append and reverse • Define append(L,M,Result)where Result is L appended to M. ?- append([1,2],[a,b],R). R = [1,2,a,b] • Pick the list to recur on: L or M. • BASE case? You only need one fact. • Recursive case? You only need one rule. M = L = 1, 2 a, b Result = 1, 2 a, b Head/Lander

  19. append continued • Using append to retrieve the prefix, suffix of a list append(Prefix,[e,e|Suffix],[a,b,c,d,e,e,f,g]). • Partitioning a list around an element. -- delete append (Before, [d|After], [a,b,c,d,e,e,f,g]). • Another definition of member member( E, L) :- append( L1,[E|L2], L). • What is big "O" of append? Head/Lander

  20. Reversing a list • Naive code using append. • Examine the recursion -- work done during the return. • Using a "helper" functor to have the work done before the call. • Faster Head/Lander

  21. Reverse- Slow rev([ ], [ ]). rev([Head|Tail],Result) :- rev(Tail, ReversedTail), append(ReversedTail,[Head],Result). • Without cuts ?- rev(X,[a,b])goes into a loop after “;” Head/Lander

  22. Reverse-Slow revA([ ], [ ]). revA([Head|Tail],Result) :- append(ReversedTail,[Head],Result), revA(Tail, ReversedTail). • Without cuts ?- revA([a,b], X)goes into a loop after “;” Head/Lander

  23. Reverse--Fast revEff(List,RList) :- revEff(List,[ ],RList). % Helper -- t.r. revEff([ ],RL,RL). revEff([Element|List],RevPrefix,RL) :- revEff(List,[Element|RevPrefix],RL). • Without cuts ?- revEff(X,[a,b])goes into a loop after “;” Head/Lander

  24. Difference lists • Represent a list segment as a list-pairs, separated by any symbol, typically the “-” sign • The second of the pair is the later part of the first list: [a,b| X] - X where L = [a,b | X](L - X) L X L [a, b | X] a b Head/Lander

  25. The “difference” is interpreted (by the reader ) as a list containing only the first part of the first of the pair;up to the beginning of the second list in the pair: [a,b,c,d | X] - [c,d | X] is interpreted as [a,b] • In fact, one of the best forms to work with is: [a,b,c,d | X ] - X which is interpreted as [a,b,c,d] Head/Lander

  26. Consider appendDL (L – M, M – N, L – N). compared to: append( [ ],X,X ). append( [X|Y],Z,[X|T ] ):– append(Y,Z,T). appendDL([a,b,c| A] -A, [d,e | B] - B, R - V) L M M N B A a d b e c Head/Lander

  27. appendDL([a,b,c|A] -A, [d,e |B] - B, R - V).appendDL (L – M, M – N, L – N). L M M N R V a d b e c Head/Lander

  28. appendDL (L – M, M – N, L – N). 1?–appendDL( [1,2,3|X]-X,[4,5]-[ ],Y – Z ). X = [4,5] Y = [1,2,3,4,5] Z = [ ] 2?–appendDL( [1,2,3|X]-X, [4,5|Y]-Y, W–Z ). X = [4,5| _n] Y = _n W = [1,2,3,4,5| _n] Z = _n Head/Lander

  29. Converting a Difference List to a list: simplify( X -Y,[] ):- X == Y. simplify( [X|Y]-Z,[X|W] ):- simplify(Y-Z,W). ?-simplify( [1,2,3|X]-X, Y ). Y = [1,2,3] Head/Lander

  30. Quick sort is very intuitive in Prolog: qsort( [P|L], Outlist):– partition( P ,L,Small,Large), qsort(Small,Localsmall), qsort(Large,Locallarge), append(Localsmall, [P|Locallarge], Outlist). qsort( [ ], [ ] ). partition( _,[ ],[ ],[ ] ). partition( P ,[Y|T],[Y|Sml],Lg) :– P > Y, !, partition(P, T, Sml,Lg). partition( P ,[Y|T],Sml,[Y|Lg] ):– partition(P, T, Sml,Lg). Head/Lander

  31. QuickSort using Difference Lists qsort1(Inlist, Outlist):– qsort2(Inlist,Outlist – [ ] ). qsort2( [X|Tl], A1–Z2):– partition( X ,Tl,Sm,Lg), qsort1(Sm,A1–[X|A2] ), qsort1(Lg,A2–Z2). qsort2( [ ], Z–Z ). Head/Lander

  32. Grammars and Prolog • Prolog is use in artificial intelligent processing especially for natural language processing. • Recognizers are easy to program in Prolog given a BNF grammar. • Converting the BNF grammar for anbn S-> a b | a S b where S is a non-terminal symbol and a,b terminal symbol s --> [a],[b]. s --> [a], s, [b]. where "[]" are used for terminal symbols and atoms for non-terminal symbols. Replace ->with -->, S with s and a, b with [a],[b] Head/Lander

  33. Under the Covers s --> [a],[b]. s --> [a], s, [b]. • Is syntactic sugar for s(A, B) :- 'C'(A, a, C), 'C'(C, b, B). s(A, B) :- 'C'(A, a, C), s(C, D), 'C'(D, b, B). 'C'([A|B], A, B). • Notice that 'C' is an atom and C is a variable • We represent the language as a list of a & b atoms. • To check if a string is recognized enter the following query: s([a,a,a,b,b,b], []). s([a,a,b,b,a,a,b,b,], []). Head/Lander

  34. Be careful with the Grammar • Because of the way Prolog executes it is a top down parser. • It behaviors like a recursive decent parser. • Left recursion must be removed to avoid "stack overflow". • So the grammar for balance "()" s -> ( ) | ( s ) | s s can not be used • However it can be transformed to : s -> ( ) | ( ) s | ( s ) | ( s ) s Head/Lander

  35. Additional Examples-- may not be discussed • Sum of Subset • Towers of Hanoi puzzle • Recursive data structures - trees • looping -- generate and test • Implementing repeat loop in Prolog • Implementing for loop in Prolog Head/Lander

  36. Naturally solved Problems using Prolog • Logic programming is a natural choice for problems that fit the database model and for algorithms that require the built-in backtracking search capability of logic programming. • Sum of subset decision problem. • What is the problem? • What is the code? • sumOfsubset(Set, Sum, SubSet). • What is the fact? • What are the rules? Head/Lander

  37. Sum of Subsets • Problem: Given n positive integers w1, ... wn and a positive integer W. Find all subsets of w1, ... wn that sum to W. • Similar to the 0-1 knapsack problem. When the benefit of each item is equal to its weight the 0/1 Knapsack problem becomes the sum of subsets problem. • Example: n=3, W=6, and w1=2, w2=4, w3=6 • Solutions: {2,4} and {6} Head/Lander

  38. Sum of subsets • We will assume a binary state space tree. • The nodes at level 1 are for including (yes, no) item 1, the nodes at level 2 are for item 2, etc. • The left branch includes wi, and the right branch excludes wi. • The nodes contain the weights included so far Head/Lander

  39. Sum of subset Problem: State SpaceTree for 3 items w1 = 2, w2 = 4, w3 = 6 and W = 6 0 yes no i1 2 0 yes no no yes 4 6 0 i2 2 no yes no yes yes yes no no 8 2 i3 6 10 0 12 6 4 The total weight up to the node is stored at the node. Head/Lander

  40. Towers of Hanoi puzzle: hanoi(N):– move(N,left,right,center). move(0, _ , _ , _ ) :– !. move(N,A,B,C):– M is N–1, move(M,A,C,B), inform(A,B), move(M, C, B, A). inform(X,Y):–write([move,a,disc,X,to,Y]),nl. ?-hanoi(3). move a disc left to rightmove a disc left to centermove a disc right to centermove a disc left to rightmove a disc center to leftmove a disc center to rightmove a disc left to right Head/Lander

  41. Recursive "data" structure: • Representing Binary Trees Binary tree structure: node(Self, Leftsubtree, Rightsubtree). binarytree(empty ). binarytree(node ( X , Y, Z )):– binarytree (Y ), binarytree (Z ). Head/Lander

  42. Searching the binary tree structure treeMember (E, node (E, _ , _ )):– !. /* cut off search after first time the element is found */ treeMember(E, node ( N , L, _ )):– E < N, !, treeMember (E, L). /* cut if E < N to avoid searching the right subtree */ treeMember(E, node ( _ , _ , R )):–treeMember(E, R). Head/Lander

  43. Repetition: Generate and test natural(1). natural(N) :- natural(M), N is M+1. loop(N) :-natural(Int), Int =< N, write(Int), nl, Int=N, !. Head/Lander

  44. Repetition Through BacktrackingBuilt-in: repeat repeat. repeat :- repeat. % repeat turns any predicate into a generator % Infinite number of “*” stars :- repeat, write(‘*’), fail. % repeat until “end of line” keyBoard :- repeat, get0(C), C = 0, !. Head/Lander

  45. Limitations of Repeat • Prolog’s repeat is quite different than a procedural language’s repeat because backtracking can take any subgoal that has an untried alternative. • The only way to pass information from one pass to another is to use assert to store data in the knowledge base. Head/Lander

  46. Repetition Through Backtrackingfor loop: for Index = Start to Finish for(I,I,I) :- !. %R1 for(I,I,_). %R2 for(Index,S,F) :- N is S+1, for(Index,N,F). %R3 printint(S,F) :- for(Ind,S,F), write(Ind), nl, fail. Head/Louden p457 ex 32

  47. % ForLoop: for(I,I,I) :- !. for(I,I,_). for(Index,S,F):- N is S+1,for(Index,N,F). printint(S,F):-for(Ind,S,F),write(Ind),nl, fail. ?- for(I, -1, 2). I = -1 ; I = 0 ; I = 1 ; I = 2 ; No ?- Head/Lander

  48. HOW? ?-printint(1,2). Pattern matching Unification printint(S,F) subgoal write(Ind),nl,fail. for(Ind,S, F) for(_v, 1, 2) write(1),nl,fail. for( 1, 1, 2). R2 fails try to redo for(_v, 1, 2) Succeeds Head

  49. for(_v, 1, 2) redone for(Ind,S, F) write(Ind),nl,fail. for(_v, 1,2) write(2),nl,fail. for(Index,S,F) R3subgoals fails Backtracking fails no more solutions for(Index,N,F) N is S+1 R1 _v2 is 1+1 for(_v,2,2) 2 is 1+1 for( 2,2,2) Head

More Related