160 likes | 223 Views
What will be covered. Append -- A new way to think Difference Lists -- A way to understand how Prolog implements list. 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.
E N D
Head/Lander What will be covered • Append -- A new way to think • Difference Lists -- A way to understand how Prolog implements list.
Head/Lander 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 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 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 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 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 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 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 • 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 • 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 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 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| Z] Y = Z W = [1,2,3,4,5| Z]
Head/Lander 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 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 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 ).