Documentos de Académico
Documentos de Profesional
Documentos de Cultura
© ©
CS 538 Spring 2006 412 CS 538 Spring 2006 413
© ©
CS 538 Spring 2006 414 CS 538 Spring 2006 415
The rule in line 2 says that if you take Inverting Inputs and Outputs
a list that begins with H and has T1 as
the rest of the list and append it to a In Prolog the division between
list L then the resulting appended list “inputs” and “outputs” is
will begin with H. intentionally vague. We can exploit
this. It is often possible to “invert” a
Moreover, the rest of the resulting
query and ask what inputs would
list, T3, is the result of appending T1
compute a given output. Few other
(the rest of the first list) with L2 (the
languages allow this level of
second input list).
flexibility.
The query
Consider the query
| ?- append([1],[2,3],[1,2,3]).
answers append([1],X,[1,2,3]).
Yes
This asks Prolog to find a list X such
that if we append [1] to X we will
because with H=1, T1=[], L2 =[2,3] get [1,2,3].
and T3=[2,3] it must be the case
that append([],[2,3],[2,3]) is Prolog answers
true and fact (1) says that this is so. X = [2,3]
© ©
CS 538 Spring 2006 416 CS 538 Spring 2006 417
© ©
CS 538 Spring 2006 418 CS 538 Spring 2006 419
Note that we don’t have to “tell” If we want to know if any member of
Prolog that X can’t be a member of an a list L satisfies a predicate p, we can
empty list—if we don’t tell Prolog simply write:
that something is true, it member(X,L),p(X).
automatically assumes that it must be
false. There is no explicit iteration or
searching. We simply ask Prolog to
Thus saying nothing about find an X such that member(X,L) is
membership in an empty list is the true (X is in L) and p(X) is true.
same as saying that membership in an Backtracking will find the “right”
empty list is impossible. value for X (if any such X exists).
Since inputs and outputs in a relation This is sometimes called the “guess
are blurred, we can use member in an and verify” technique.
unexpected way—to iterate through a
list of values. Thus we can query
member(X,[3,-3,0,10,-10]),
(X > 0).
This asks for an X in the list
[3,-3,0,10,-10] which is greater
than 0.
© ©
CS 538 Spring 2006 420 CS 538 Spring 2006 421
© ©
CS 538 Spring 2006 422 CS 538 Spring 2006 423
Sorting Algorithms We can implement this concept of a
sort directly in Prolog. We
Sorting algorithms are good examples (a) permute an input list
of Prolog’s definitional capabilities. In (b) check if it is in sorted order
a Prolog definition the “logic” of a
sorting algorithm is apparent, (c) repeat (a) & (b) until a sorting is
stripped of the cumbersome details of found.
data structures and control structures
that dominate algorithms in other
programming languages.
Consider the simplest possible sort
imaginable, which we’ll call the
“naive sort.”
At the simplest level a sorting of a list
L requires just two things:
• The sorting is a permutation (a
reordering) of the values in L.
• The values are “in order” (ascending
or descending).
© ©
CS 538 Spring 2006 424 CS 538 Spring 2006 425
© ©
CS 538 Spring 2006 426 CS 538 Spring 2006 427
Let’s see perm in action: One solution to this goal is
| ?- perm([1,2,3],X). V = [], H = 1, U = [2,3]
X = [1,2,3] ;
We next solve append(V,U,W) which
X = [1,3,2] ; simplifies to append([],[2,3],W).
X = [2,1,3] ;
The only solution for this is W=[2,3].
X = [2,3,1] ;
X = [3,1,2] ; Finally, we solve perm(W,T), which
X = [3,2,1] ; simplifies to perm([2,3],T).
no One solution to this is T=[2,3].
We’ll trace how the first few answers This gives us our first solution:
are computed. Note though that all [H|T]=[1,2,3].
permutations are generated, and with To get our next solution we backtrack.
no apparent data structures or Where is the most recent place we
control structures. made a choice of how to solve a goal?
We start with L=[1,2,3] and It was at perm([2,3],T). We chose
X=[H|T].
T=[2,3], but T=[3,2] is another
We first solve append(V,[H|U],L), solution. Using this solution, we get
which simplifies to out next answer [H|T]=[1,3,2].
append(V,[H|U],[1,2,3]).
© ©
CS 538 Spring 2006 428 CS 538 Spring 2006 429
© ©
CS 538 Spring 2006 430 CS 538 Spring 2006 431
Now our naive permutation sort is Though this sort works, it is
only one line long: hopelessly inefficient—it repeatedly
naiveSort(L1,L2) :- “shuffles” the input until it happens
perm(L1,L2), inOrder(L2). to find an ordering that is sorted. The
And the definition works too! process is largely undirected. We
| ?- don’t “aim” toward a correct ordering,
naiveSort([1,2,3],[3,2,1]). but just search until we get lucky.
no
?- naiveSort([3,2,1],L).
L = [1,2,3] ;
no
| ?-
naiveSort([7,3,88,2,1,6,77,
-23,5],L).
L = [-23,1,2,3,5,6,7,77,88]
© ©
CS 538 Spring 2006 432 CS 538 Spring 2006 433