Download Prolog Programming A First Course

Transcript
134
Advanced Features
difference append(OpenList1-Hole1,OpenList2-Hole2,OpenList1-Hole2):Hole1=OpenList2.
?- X=[a,b,c|Ho]-Ho,difference append(X,[d,e,f|Hole2]-Hole2,Ans).
Ans=[a,b,c,d,e,f|Hole2] - Hole2
Now we can recover the proper list we want this way:
?- X=[a,b,c|Ho]-Ho,difference append(X,[d,e,f|Hole2]-Hole2,Ans-[]).
Ans=[a,b,c,d,e,f]
One more transformation can be made: you will note that all we are saying
in the body of difference append/3 is that the hole of the first difference
list has to be the open list of the second difference list.
difference append(OpenList1-Hole1,Hole1-Hole2,OpenList1-Hole2).
We now have an extremely neat way of appending two difference lists together to get a difference list. Now, why bother?
Consider the question about how to add an element to the front of a list.
This is easy because you can, for example, add X=a to the list Y=[b,c,d] as
in [X|Y]. Now try to write a predicate add to back/3 to take an element
and add it to the end of a list. This does not work.
add to back(El,List,Ans):Ans=[List|El].
?- add to back(a,[b,c,d],X).
X=[[b,c,d]|a]
Not only is this not even a proper list (it does not end in []) but it is not
equal to [b,c,d,a]! What we have to do is something like:
add to back(El,[],[El]).
add to back(El,[Head|Tail],[Head|NewTail);add to back(El,Tail,NewTail).
This is an expensive procedure. We have to do many computations before
getting to the back of the list. We can, however, use difference lists to do
this:
?- difference append([b,c,d|Hole1]-Hole1,[a|Hole2]-Hole2,Ans-[]).
Ans=[b,c,d,a]
This is a cheap computation.
Now we could define a version of
add to back/3 for difference lists: