Unformatted text preview:

412CS 538 Spring 2006©List Processing in PrologProlog has a notation similar to “conscells” of Lisp and Scheme.The “.” functor (predicate name) actslike cons.Hence.(a,b) in Prolog is essentiallythe same as(a . b) in Scheme.Lists in Prolog are formed much thesame way as in Scheme and ML:[] is the empty list[1,2,3] is an abbreviation for.(1, .(2, .(3,[])))just as(1,2,3) in Scheme is an abbreviationfor(cons 1 (cons 2 (cons 3 () )))413CS 538 Spring 2006©The notation [H|T] represents a listwithH matching the head of the listandT matching the rest of the list.Thus[1,2,3] ≡ [1| [2,3]] ≡[1,2| [3]] ≡ [1,2,3| [] ]As in ML, “_” (underscore) can beused as a wildcard or “don’t care”symbol in matches.Given the fact p([1,2,3,4]).The query | ?- p([X|Y]).answersX = 1,Y = [2,3,4]414CS 538 Spring 2006©The queryp([_,_,X|Y]).answersX = 3,Y = [4]415CS 538 Spring 2006©List Operations in PrologList operations are defined using rulesand facts. The definitions are similarto those used in Scheme or ML, butthey are non-procedural.That is, you don’t given an executionorder. Instead, you give recursive rulesand non-recursive “base cases” thatcharacterize the operation you aredefining.Considerappend: append([],L,L). append([H|T1],L2,[H|T3]) :- append(T1,L2,T3).The first fact says that an empty list(argument 1) appended to any listL(argument 2) gives L (argument 3) asits answer.416CS 538 Spring 2006©The rule in line 2 says that if you takea list that begins withH and has T1 asthe rest of the list and append it to alistL then the resulting appended listwill begin withH.Moreover, the rest of the resultinglist,T3, is the result of appending T1(the rest of the first list) with L2 (thesecond input list).The query | ?- append([1],[2,3],[1,2,3]).answersYesbecause with H=1, T1=[], L2 =[2,3]and T3=[2,3] it must be the casethatappend([],[2,3],[2,3]) istrue and fact (1) says that this is so.417CS 538 Spring 2006©Inverting Inputs and OutputsIn Prolog the division between“inputs” and “outputs” isintentionally vague. We can exploitthis. It is often possible to “invert” aquery and ask what inputs wouldcompute a given output. Few otherlanguages allow this level offlexibility. Consider the queryappend([1],X,[1,2,3]).This asks Prolog to find a list X suchthat if we append[1] to X we willget[1,2,3]. Prolog answersX = [2,3]418CS 538 Spring 2006©How does it choose this answer?First Prolog tries to match the queryagainst fact (1) or rule (2).Fact (1) doesn’t match (the firstarguments differ) so we match rule(2).This gives usH=1, T1=[], L2=X andT3 = [2,3].We next have to solve the body ofrule (2) which isappend([],L2,[2,3]).Fact (1) matches this, and tells usthatL2=[2,3]=X, and that’s ouranswer!419CS 538 Spring 2006©The Member RelationA common predicate whenmanipulating lists is a membershiptest—is a given value a member of alist?An “obvious” definition is a recursiveone similar to what we mightprogram in Scheme or ML:member(X,[X|_]).member(X,[_|Y]):- member(X,Y).This definition states that the firstargument,X, is a member of thesecond argument (a list) ifX matchesthe head of the list or ifX is(recursively) a member of the rest ofthe list.420CS 538 Spring 2006©Note that we don’t have to “tell”Prolog thatX can’t be a member of anempty list—if we don’t tell Prologthat something is true, itautomatically assumes that it must befalse.Thus saying nothing aboutmembership in an empty list is thesame as saying that membership in anempty list is impossible.Since inputs and outputs in a relationare blurred, we can usemember in anunexpected way—to iterate through alist of values.421CS 538 Spring 2006©If we want to know if any member ofa listL satisfies a predicate p, we cansimply write:member(X,L),p(X).There is no explicit iteration orsearching. We simply ask Prolog tofind anX such that member(X,L) istrue (X is in L) and p(X) is true.Backtracking will find the “right”value forX (if any such X exists).This is sometimes called the “guessand verify” technique.Thus we can querymember(X,[3,-3,0,10,-10]), (X > 0).This asks for an X in the list[3,-3,0,10,-10] which is greaterthan0.422CS 538 Spring 2006©Prolog answersX = 3 ;X = 10 ;Note too that our “obvious”definition of member is not the onlyone possible.An alternative definition (which is farless obvious) ismember(X,L) :- append(_,[X|_],L).This definition says X is a member ofL if I can take some list (whose valueI don’t care about) and append it to alist that begins withX (and whichends with values I don’t care about)and get a list equal toL.Said more clearly,X is a member of Lif X is anywhere in the “middle” of L.423CS 538 Spring 2006©Prolog solves a query involvingmember by partitioning the list L inall possible ways, and checking to seeifX ever is the head of the secondlist. Thus formember(X,[1,2,3]),ittries the partition[] and [1,2,3](exposing 1 as a possible X), then [1]and [2,3] (exposing 2) and finally[1,2] and [3] (exposing 3).424CS 538 Spring 2006©Sorting AlgorithmsSorting algorithms are good examplesof Prolog’s definitional capabilities. Ina Prolog definition the “logic” of asorting algorithm is apparent,stripped of the cumbersome details ofdata structures and control structuresthat dominate algorithms in otherprogramming languages.Consider the simplest possible sortimaginable, which we’ll call the“naive sort.”At the simplest level a sorting of a listL requires just two things:• The sorting is a permutation (areordering) of the values inL.• The values are “in order” (ascendingor descending).425CS 538 Spring 2006©We can implement this concept of asort directly in Prolog. We(a) permute an input list(b) check if it is in sorted order(c) repeat (a) & (b) until a sorting is found.426CS 538 Spring 2006©PermutationsLet’s first look at how permutationsare defined in Prolog. In mostlanguages generating permutations isnon-trivial—you need data structuresto store the permutations you aregenerating and control structures tovisit all permutations in some order.In Prolog, permutations are definedquite concisely, though with a bit ofsubtlety:perm(X,Y) will be true if list Y is apermutation of listX.Only two definitions are needed:perm([],[]).perm(L,[H|T]) :- append(V,[H|U],L), append(V,U,W), perm(W,T).427CS 538 Spring 2006©The first definition,perm([],[]).is trivial. An empty list may only bepermuted into another empty list.The second definition is rather


View Full Document

UW-Madison COMPSCI 538 - Lecture 28 Notes

Download Lecture 28 Notes
Our administrator received your request to download this document. We will send you the file to your email shortly.
Loading Unlocking...
Login

Join to view Lecture 28 Notes and access 3M+ class-specific study document.

or
We will never post anything without your permission.
Don't have an account?
Sign Up

Join to view Lecture 28 Notes 2 2 and access 3M+ class-specific study document.

or

By creating an account you agree to our Privacy Policy and Terms Of Use

Already a member?