This question refers to the material in chapter 3 of the book: Programming in Prolog, Clocksin and Mellish, Ed 5
In page 72 of this book, a program using difference list is displayed:
partsOf(X,P):- partsacc(X,P,Hole) , Hole=[].
partsacc(X,[X|Hole],Hole):-basicpart(X).
partsacc(X,P,Hole):- assembly(X,Subparts), partsacclist(Subparts, P, Hole).
partsacclist([],Hole,Hole).
partsacclist([P|T], Total, Hole):- partsacc(P,Total,Hole1), partsacclist(T,Hole1,Hole).
In many tutorials online, the following format of using the "-" is used, for example::
append([ A , B , C | R1 ] – R1 , [ D , E | R2 ] – R2 , R3)
My questions are:
What is the difference between these two representations (Using - and not using it)
In which situations it is best to use each of them?
Thanks
Another implementation in the logic programming language Prolog uses unification variables. A difference list is a pair OpenList-Hole, where the first element OpenList is a list containing an unbound unification variable (hole) and the second element Hole is a reference to the hole.
In Prolog list elements are enclosed by brackets and separated by commas. Another way to represent a list is to use the head/tail notation [H|T]. Here the head of the list, H, is separated from the tail of the list, T, by a vertical bar. The tail of a list is the original list with its first element removed.
In prolog, lists have got only one operator, called pipe, denoted by |. This operator is used to append an element at the beginning of a list. The syntax of the pipe operator is as follows : [a | L] Here L is a list and a is a single element.
If you want to check if a list contains a member, use memberchk/2 . so memberchk(I/J, Item) succeeds if I/J is in the list Item . Your include/3 predicate has no base case, and attempt to ensure that every element of the given list is I/J , so it will always fail.
By all means: Do not use (-)/2
or (\)/2
or any other operator to represent "difference lists". The reason is that you will often have a predicate with one list argument and an internal predicate that uses a difference list. With both having the same arity and probably also the same name, things will get confusing. Even worse, it might work for "some cases". Also, that operator will incur some cost you can avoid with two separate arguments.
Try to stick to a clean naming convention. That is S0
, S1
... S
. In this manner the arguments representing the difference list will be easily visible. To better underline that those arguments belong together, some people do not use a space after the separating comma, whereas they use it for other arguments. Thus:
p(L+R, S0,S) :-
p(L, S0,S1),
p(R, S1,S).
Further, the (-)/2
has another meaning in Prolog. It is used to represent a pair Key-Value
, as in keysort/2
.
Any Prolog book I know suggesting an operator for difference lists comes from the 1980s.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With