Prolog: having true and false value - list

I am learning to use SWI Prolog, and I am learning to use lists. A small exercise is to check if an element is in a list. Here's what I got:
member(X,[X|_]).
member(X,[_|T]):-member[X|T].
The first case goes as intended:
?- member(a,[b,a]).
true.
But the second doesn't, as some backtracking seems to appear:
?- member(a,[a,b]).
true ;
false.
How could I prevent this from happening, i.e. to get Prolog return me only true? (I don't want to ignore false.)

member/2 is a standard Prolog predicate. You should name yours something else. The standard predicate has the same behavior that you show.
When you query:
?- member(a, [a,b]).
true ;
false.
Prolog finds that a matches the first element and succeeds. There's more in the list to check so it prompts you for more. Pressing ; says "yes, please, check for more". When it does, it finds no more a members so then yields false (in GNU Prolog, it would say no).
You can make it go away by either:
Not pressing ; but press Enter instead, OR
Use once/1: once(member(a, [a,b])), OR
You can change your predicate to include a cut in the first clause, but this is a bad idea since then it won't work in the general case: member(X, [a,b]) will only return X = a and then stop.

Using memberd/2 based on library(reif) available for SICStus|SWI, you get determinism in many cases:
?- memberd(a, [a,b]).
true.
?- memberd(a, [a,a]).
true.
?- memberd(a, [a,X]).
true.
?- memberd(a, [a|Xs]).
true.
Compare this to member/2:
?- member(a, [a,b]).
true
; false. % leftover choicepoint
?- member(a, [a,a]).
true
; true. % redundant solution
?- member(a, [a,X]).
true
; X = a. % redundant solution
?- member(a, [a|Xs]).
true
; Xs = [a|_A] % redundant answer
; Xs = [_A, a|_B] % redundant answer
; Xs = [_A, _B, a|_C] % redundant answer
; ... .
And still the implementation of memberd/2 produces different answers, when necessary
?- memberd(a, [X,Y]).
X = a
; Y = a, dif(X, a)
; false.
Even in this case, memberd/2 avoids the redundancy of member/2:
?- member(a, [X,Y]).
X = a
; Y = a. % partially redundant
These two answers are partially redundant: X = a, Y = a is described by both!
?- member(a, [X,Y]), X = a, Y = a.
X = Y, Y = a
; X = Y, Y = a. % redundant solution

Note that any query will unify with both clauses since member(X,[X|_]) unifies with member(X,[_|T]). You need mutually exclusive clauses. Since the prolog cut will break reversibility (as stated before), there is another option:
member(X,[X|_]).
member(X,[Y|T]):- X \== Y, member[X|T].

The other answer is good but maybe it is important to add that member/2 is in textbooks with this implementation exactly and because it uses pattern matchin and unification it can do more interesting things...
?- member(a(X), [a(1), b(2), c(3), a(4), b(5), a(6)]).
X = 1 ;
X = 4 ;
X = 6.
There is also memberchk/2 which is for testing for membership only. The other answer also explain how to implement.
It seems the two are on purpose not the same (why make both otherwise?)

Related

Get elements of arbitrary nested lists

I am looking for some predicate in SWI-Prolog to get the elements of some arbitrary nested list. Means, if I e.g. have the list:
L = [[a,b], c, [d, [e, f]]]
I get as result:
R = [a,b,c,d,e,f]
The SWI built-in predicate flatten/2 depends on the very instantiations of the first argument. It thus leads to quite non-relational behavior:
?- flatten(X,[]).
false.
?- X = [], flatten(X,[]).
X = [].
?- X = [[],[]], flatten(X,[]).
X = [[], []].
?- X = [[]|[]], flatten(X,[]).
X = [[]].
Note that there are infinitely many X to make flatten(X,[]) succeed. If you want this to be a relation, there are two choices either enumerate all such solutions, or produce an instantiation error, or just do not terminate (better than an incorrect answer), or delay goals appropriately, or produce some constraints, or produce a resource error. Oh, these have been now 6 choices... ...and lest I forget, you might also combine these options, like first producing some answer substitutions, then delayed goals, then constraints, and then loop quite some time to finally produce a resource error.
In most of such situations, the easiest way to go is to produce instantiation errors like so:
flattened(T) -->
{functor(T,_,_)}, % ensures instantiation
( {T = [E|Es]} -> flattened(E), flattened(Es)
; {T = []} -> []
; [T]
).
?- phrase(flattened([[]|[]]),Xs).
Xs = [].
?- phrase(flattened([[]|_]),Xs).
error(instantiation_error,functor/3).
As #brebs mentioned in his comment, Use predefined predicate flatten/2
% ?- flatten([[a,b], c, [d, [e, f]]], R).
% R = [a, b, c, d, e, f]
This user-defined implementation is similar to the predefined one [1]
my_flatten([],[]).
my_flatten([H|T], [H|Res]) :- \+ is_list(H), my_flatten(T, Res), !.
my_flatten([H|T], Res) :- my_flatten(H, Res). % H is list.
[1] except for cases of non-termination like my_flatten(X,non_list). and like my_flatten([X],[1,2,3,4]). thanks to #false comment

Determining if a list is empty or not

I want to do some if | else stuff in prolog. Below is my code, Prolog will return 'R = false' if my input list is not empty, it will return 'false' if my list is empty. What do I miss?
Code:
isEmpty([H|T],R) :-
length([H|T],L),
( L > 0 -> R = 'false'
;
L =:= 0 -> R = 'true'
).
Prolog Output:
1 ?- isEmpty([],R).
false.
2 ?- isEmpty([1],R).
R = false.
3 ?- isEmpty([1,2,3],R).
R = false.
One way to define this would be to use unification ("pattern matching"):
list_empty([], true).
list_empty([_|_], false).
If you insist on using an if-then-else, you need to pass the list without trying to match it in any way:
list_zerolength(List, Empty) :-
length(List, Len),
( Len == 0
-> Empty = true
; Empty = false
).
... but this is not optimal. The two predicates behave identically if the first argument is indeed a list:
?- list_empty([], R).
R = true.
?- list_empty([_], R).
R = false.
?- list_zerolength([], R).
R = true.
?- list_zerolength([_], R).
R = false.
However, something annoying happens if the first argument is not ground (that is, is not fully instantiated):
?- list_zerolength(L, true).
L = [] ;
ERROR: Out of global stack
So, we try to ask for an empty list, and we get it; however, Prolog insists there might be another answer. When we try to get it, we get an error.
(Extra credit: figure out what happens!)
The predicate list_empty/2 is not perfect, either. Consider:
?- list_empty([_|a], R).
R = false.
This succeeds, and we could interpret the answer as: "The list [_|a] is not empty". However, this is not ever a proper list!
?- is_list([_|a]).
false.
Using length/2 is not at all a bad idea. We can use it to write a predicate that is arguably a bit more useful than list_empty/2. I call it list_nonempty/2 to confuse the situation:
list_nonempty([], false).
list_nonempty([_|T], true) :-
length(T, _).
length/2 does a lot more than just finding the length of a list. It can be used to generate lists of increasing length, or check whether its first argument is a proper list:
?- list_nonempty(L, NE).
L = [],
NE = false ;
L = [_G904],
NE = true ;
L = [_G904, _G907],
NE = true . % and so on
?- list_nonempty(L, false).
L = [].
?- list_nonempty([], true).
false.
?- list_nonempty([_|a], true).
ERROR: length/2: Type error: `list' expected, found `a' (an atom)
SWI-Prolog throws an error when length/2 is not given a list. Implementations that are more committed to ISO-compliance should fail instead. With GNU Prolog:
?- list_nonempty([_|a], true).
no
I know it's old thread but still this might be useful for those using SWI-Prolog. Instead of defining their own rules, you can try:
nth0(0, List, _).
It is used to return the first element on the list, which in case of empty list simply fails.
Since you are only dealing with lists of the form [H|T] your clauses will only match for lists that have at least one list element. In other words, you get the answer false for the empty list because there is not a matching clause - not because the length is 0.

Print list of lists, Prolog

I got this grid:
tab([[s,f,f,f,s,f,f,f,s],
[f,s,f,f,f,f,f,s,f],
[f,f,s,f,f,f,s,f,f],
[f,f,f,f,f,f,f,f,f],
[s,f,f,f,m,f,f,f,s],
[f,f,f,f,f,f,f,f,f],
[f,f,s,f,f,f,s,f,f],
[f,s,f,f,f,f,f,s,f],
[s,f,f,f,s,f,f,f,s]]).
I want to print in the screen without brackets and commas.
By the way I can't print it right with or without them.
These are the print rules:
viewTab([]).
viewTab([H|T]) :-
printList(H),
viewTab(T).
printList([]) :-
nl.
printList([H|T]) :-
write(H),
write(' | '),
printList(T).
I call it in the Prolog's terminal like:
?- viewTab(X), tab(X).
I can't print a thing, and I get an infinite loop at:
printList([]) :-
nl.
Can you help me find my mistake?
Or some tips to make the code easier to work with.
Your viewTab/1 is not a purely logical predicate: it has a side effect, and it does not terminate for if its argument is a variable.
For example:
?- listing(foo).
foo([]).
foo([_|A]) :-
foo(A).
true.
?- foo(X).
X = [] ;
X = [_G256] ;
X = [_G256, _G259] ;
X = [_G256, _G259, _G262] ;
X = [_G256, _G259, _G262, _G265] ;
X = [_G256, _G259, _G262, _G265, _G268] . % and so on
So this:
?- viewTab(X), tab(X).
Puts a list in X, then tab(X) fails, and you are back at viewTab(X), ad infinitum.
You should try:
?- tab(X), viewTab(X).
Use dcg!
Definite clause grammars are a versatile, logical way of processing input/output.
For a start, read this well-written DCG primer by Markus Triska, also known as #mat on SO!
Right now, as a quick fix, use the built-in predicate format/2 like this:
?- X = [a,b,c], format('~s~n',[X]).
abc % output via side-effect
X = [a, b, c]. % query succeeds

Add two more occurrences using prolog

I have a list [a, b, a, a, a, c, c]
and I need to add two more occurrences of each element.
The end result should look like this:
[a, a, a, b, b, b, a, a, a, a, a, c, c, c, c]
If I have an item on the list that is the same as the next item, then it keeps going until there is a new item, when it finds the new item, it adds two occurrences of the previous item then moves on.
This is my code so far, but I can't figure out how to add two...
dbl([], []).
dbl([X], [X,X]).
dbl([H|T], [H,H|T], [H,H|R]) :- dbl(T, R).
Your code looks a bit strange because the last rule takes three parameters. You only call the binary version, so no recursion will ever try to derive it.
You already had a good idea to look at the parts of the list, where elements change. So there are 4 cases:
1) Your list is empty.
2) You have exactly one element.
3) Your list starts with two equal elements.
4) Your list starts with two different elements.
Case 1 is not specified, so you might need to find a sensible choice for that. Case 2 is somehow similar to case 4, since the end of the list can be seen as a change in elements, where you need to append two copies, but then you are done. Case 3 is quite simple, we can just keep the element and recurse on the rest. Case 4 is where you need to insert the two copies again.
This means your code will look something like this:
% Case 1
dbl([],[]).
% Case 2
dbl([X],[X,X,X]).
% Case 3
dbl([X,X|Xs], [X|Ys]) :-
% [...] recursion skipping the leading X
% Case 4
dbl([X,Y|Xs], [X,X,X|Ys]) :-
dif(X,Y),
% [...] we inserted the copies, so recursion on [Y|Xs] and Ys
Case 3 should be easy to finish, we just drop the first X from both lists and recurse on dbl([X|Xs],Ys). Note that we implicitly made the first two elements equal (i.e. we unified them) by writing the same variable twice.
If you look at the head of case 4, you can directly imitate the pattern you described: supposed the list starts with X, then Y and they are different (dif(X,Y)), the X is repeated 3 times instead of just copied and we then continue with the recursion on the rest starting with Y: dbl([Y|Xs],Ys).
So let's try out the predicate:
?- dbl([a,b,a,a,a,c,c],[a,a,a,b,b,b,a,a,a,a,a,c,c,c,c]).
true ;
false.
Our test case is accepted (true) and we don't find more than one solution (false).
Let's see if we find a wrong solution:
?- dif(Xs,[a,a,a,b,b,b,a,a,a,a,a,c,c,c,c]), dbl([a,b,a,a,a,c,c],Xs).
false.
No, that's also good. What happens, if we have variables in our list?
?- dbl([a,X,a],Ys).
X = a,
Ys = [a, a, a, a, a] ;
Ys = [a, a, a, X, X, X, a, a, a],
dif(X, a),
dif(X, a) ;
false.
Either X = a, then Ys is single run of 5 as; or X is not equal to a, then we need to append the copies in all three runs. Looks also fine. (*)
Now lets see, what happens if we only specify the solution:
?- dbl(X,[a,a,a,b,b]).
false.
Right, a list with a run of only two bs can not be a result of our specification. So lets try to add one:
?- dbl(X,[a,a,a,b,b,b]).
X = [a, b] ;
false.
Hooray, it worked! So lets as a last test look what happens, if we just call our predicate with two variables:
?- dbl(Xs,Ys).
Xs = Ys, Ys = [] ;
Xs = [_G15],
Ys = [_G15, _G15, _G15] ;
Xs = [_G15, _G15],
Ys = [_G15, _G15, _G15, _G15] ;
Xs = [_G15, _G15, _G15],
Ys = [_G15, _G15, _G15, _G15, _G15] ;
Xs = [_G15, _G15, _G15, _G15],
Ys = [_G15, _G15, _G15, _G15, _G15, _G15] ;
[...]
It seems we get the correct answers, but we see only cases for a single run. This is a result of prolog's search strategy(which i will not explain in here). But if we look at shorter lists before we generate longer ones, we can see all the solutions:
?- length(Xs,_), dbl(Xs,Ys).
Xs = Ys, Ys = [] ;
Xs = [_G16],
Ys = [_G16, _G16, _G16] ;
Xs = [_G16, _G16],
Ys = [_G16, _G16, _G16, _G16] ;
Xs = [_G86, _G89],
Ys = [_G86, _G86, _G86, _G89, _G89, _G89],
dif(_G86, _G89) ;
Xs = [_G16, _G16, _G16],
Ys = [_G16, _G16, _G16, _G16, _G16] ;
Xs = [_G188, _G188, _G194],
Ys = [_G188, _G188, _G188, _G188, _G194, _G194, _G194],
dif(_G188, _G194) ;
[...]
So it seems we have a working predicate (**), supposed you filled in the missing goals from the text :)
(*) A remark here: this case only works because we are using dif. The first predicates with equality, one usually encounters are =, == and their respective negations \= and \==. The = stands for unifyability (substituting variables in the arguments s.t. they become equal) and the == stands for syntactic equality (terms being exactly equal). E.g.:
?- f(X) = f(a).
X = a.
?- f(X) \= f(a).
false.
?- f(X) == f(a).
false.
?- f(X) \== f(a).
true.
This means, we can make f(X) equal to f(a), if we substitute X by a. This means if we ask if they can not be made equal (\=), we get the answer false. On the other hand, the two terms are not equal, so == returns false, and its negation \== answers true.
What this also means is that X \== Y is always true, so we can not use \== in our code. In contrast to that, dif waits until it can decide wether its arguments are equal or not. If this is still undecided after finding an answer, the "dif(X,a)" statements are printed.
(**) One last remark here: There is also a solution with the if-then-else construct (test -> goals_if_true; goals_if_false, which merges cases 3 and 4. Since i prefer this solution, you might need to look into the other version yourself.
TL;DR:
From a declarative point of view, the code sketched by #lambda.xy.x is perfect.
Its determinacy can be improved without sacrificing logical-purity.
Code variant #0: #lambda.xy.x's code
Here's the code we want to improve:
dbl0([], []).
dbl0([X], [X,X,X]).
dbl0([X,X|Xs], [X|Ys]) :-
dbl0([X|Xs], Ys).
dbl0([X,Y|Xs], [X,X,X|Ys]) :-
dif(X, Y),
dbl0([Y|Xs], Ys).
Consider the following query and the answer SWI-Prolog gives us:
?- dbl0([a],Xs).
Xs = [a,a,a] ;
false.
With ; false the SWI prolog-toplevel
indicates a choicepoint was left when proving the goal.
For the first answer, Prolog did not search the entire proof tree.
Instead, it replied "here's an answer, there may be more".
Then, when asked for more solutions, Prolog traversed the remaining branches of the proof tree but finds no more answers.
In other words: Prolog needs to think twice to prove something we knew all along!
So, how can we give determinacy hints to Prolog?
By utilizing:
control constructs !/0 and / or (->)/2 (potentially impure)
first argument indexing on the principal functor (never impure)
The code presented in the earlier answer by #CapelliC—which is based on !/0, (->)/2, and the meta-logical predicate (\=)/2—runs well if all arguments are sufficiently instantiated. If not, erratic answers may result—as #lambda.xy.x's comment shows.
Code variant #1: indexing
Indexing can improve determinacy without ever rendering the code non-monotonic. While different Prolog processors have distinct advanced indexing capabilities, the "first-argument principal-functor" indexing variant is widely available.
Principal? This is why executing the goal dbl0([a],Xs) leaves a choicepoint behind: Yes, the goal only matches one clause—dbl0([X],[X,X,X]).—but looking no deeper than the principal functor Prolog assumes that any of the last three clauses could eventually get used. Of course, we know better...
To tell Prolog we utilize principal-functor first-argument indexing:
dbl1([], []).
dbl1([E|Es], Xs) :-
dbl1_(Es, Xs, E).
dbl1_([], [E,E,E], E).
dbl1_([E|Es], [E|Xs], E) :-
dbl1_(Es, Xs, E).
dbl1_([E|Es], [E0,E0,E0|Xs], E0) :-
dif(E0, E),
dbl1_(Es, Xs, E).
Better? Somewhat, but determinacy could be better still...
Code variant #2: indexing on reified term equality
To make Prolog see that the two recursive clauses of dbl1_/3 are mutually exclusive (in certain cases), we reify the truth value of
term equality and then index on that value:
This is where reified term equality (=)/3 comes into play:
dbl2([], []).
dbl2([E|Es], Xs) :-
dbl2_(Es, Xs, E).
dbl2_([], [E,E,E], E).
dbl2_([E|Es], Xs, E0) :-
=(E0, E, T),
t_dbl2_(T, Xs, E0, E, Es).
t_dbl2_(true, [E|Xs], _, E, Es) :-
dbl2_(Es, Xs, E).
t_dbl2_(false, [E0,E0,E0|Xs], E0, E, Es) :-
dbl2_(Es, Xs, E).
Sample queries using SWI-Prolog:
?- dbl0([a],Xs).
Xs = [a, a, a] ;
false.
?- dbl1([a],Xs).
Xs = [a, a, a].
?- dbl2([a],Xs).
Xs = [a, a, a].
?- dbl0([a,b,b],Xs).
Xs = [a, a, a, b, b, b, b] ;
false.
?- dbl1([a,b,b],Xs).
Xs = [a, a, a, b, b, b, b] ;
false.
?- dbl2([a,b,b],Xs).
Xs = [a, a, a, b, b, b, b].
To make above code more compact, use control construct if_/3 .
I was just about to throw this version with if_/3 and (=)/3 in the hat when I saw #repeat already suggested it. So this is essentially the more compact version as outlined by #repeat:
list_dbl([],[]).
list_dbl([X],[X,X,X]).
list_dbl([A,B|Xs],DBL) :-
if_(A=B,DBL=[A,B|Ys],DBL=[A,A,A,B|Ys]),
list_dbl([B|Xs],[B|Ys]).
It yields the same results as dbl2/2 by #repeat:
?- list_dbl([a],DBL).
DBL = [a,a,a]
?- list_dbl([a,b,b],DBL).
DBL = [a,a,a,b,b,b,b]
The example query by the OP works as expected:
?- list_dbl([a,b,a,a,a,c,c],DBL).
DBL = [a,a,a,b,b,b,a,a,a,a,a,c,c,c,c]
Plus here are some of the example queries provided by #lambda.xy.x. They yield the same results as #repeat's dbl/2 and #lambda.xy.x's dbl/2:
?- dif(Xs,[a,a,a,b,b,b,a,a,a,a,a,c,c,c,c]), list_dbl([a,b,a,a,a,c,c],Xs).
no
?- list_dbl(X,[a,a,a,b,b]).
no
?- list_dbl(L,[a,a,a,b,b,b]).
L = [a,b] ? ;
no
?- list_dbl(L,DBL).
DBL = L = [] ? ;
DBL = [_A,_A,_A],
L = [_A] ? ;
DBL = [_A,_A,_A,_A],
L = [_A,_A] ? ;
DBL = [_A,_A,_A,_A,_A],
L = [_A,_A,_A] ? ;
...
?- list_dbl([a,X,a],DBL).
DBL = [a,a,a,a,a],
X = a ? ;
DBL = [a,a,a,X,X,X,a,a,a],
dif(X,a),
dif(a,X)
?- length(L,_), list_dbl(L,DBL).
DBL = L = [] ? ;
DBL = [_A,_A,_A],
L = [_A] ? ;
DBL = [_A,_A,_A,_A],
L = [_A,_A] ? ;
DBL = [_A,_A,_A,_B,_B,_B],
L = [_A,_B],
dif(_A,_B) ? ;
DBL = [_A,_A,_A,_A,_A],
L = [_A,_A,_A] ?
dbl([X,Y|T], [X,X,X|R]) :- X \= Y, !, dbl([Y|T], R).
dbl([H|T], R) :-
T = []
-> R = [H,H,H]
; R = [H|Q], dbl(T, Q).
The first clause handles the basic requirement, adding two elements on sequence change.
The second one handles list termination as a sequence change, otherwise, does a plain copy.

Even sized list in Prolog

I've been trying to write a predicate which would evaluate the size of a list to be even or not and this has to be done without computing the length of the list or any arithmetic operations. It's supposedly easier than computing the length but I'm having trouble thinking of how to do it without that. I'm guessing a sort of recursive technique but if anyone is able to help it would be great.
Yes, you want recursion. The base cases would be the smallest odd/even lists you can have, and then all you need is to figure out how to construct the recursive call so that it will boil down to the base case. You could start out by imagining a list of length 3 that's supposed to return true for "oddList". If it's not the base case, what's the next logical step? How does an odd list differ from an even one?
Preserve logical-purity! Simply proceed like this:
evenlength([]). % smallest list with even length is [] (length=0)
evenlength([_|Xs]) :-
oddlength(Xs).
oddlength([_|Xs]) :- % smallest list with odd length is [_] (length=1)
evenlength(Xs).
Some simple ground queries for evenlength/1 and oddlength/1:
?- evenlength([]).
true.
?- oddlength([]).
false.
?- evenlength([1]).
false.
?- oddlength([1]).
true.
?- evenlength([1,2]).
true.
?- oddlength([1,2]).
false.
?- evenlength([1,2,3]).
false.
?- oddlength([1,2,3]).
true.
Note that these predicates can not only test candidate lists, but also generate them:
?- evenlength(Xs).
Xs = []
; Xs = [_A,_B]
; Xs = [_A,_B,_C,_D]
; Xs = [_A,_B,_C,_D,_E,_F]
...
?- oddlength(Xs).
Xs = [_A]
; Xs = [_A,_B,_C]
; Xs = [_A,_B,_C,_D,_E]
; Xs = [_A,_B,_C,_D,_E,_F,_G]
...
Using meta-predicate foldl/4 and Prolog lambdas all we need to do is:
evenlength(Xs) :-
foldl(\_^E^O^(O is \E),Xs,1,1). % each item in `Xs` flips the "evenness flag"
Sample uses:
?- evenlength([]).
true.
?- evenlength([_]).
false.
?- evenlength([_,_]).
true.
?- evenlength([_,_,_]).
false.
?- evenlength([_,_,_,_]).
true.
Let's not forget about the most general query!
?- evenlength(Xs).
Xs = []
; Xs = [_A,_B]
; Xs = [_A,_B,_C,_D]
; Xs = [_A,_B,_C,_D,_E,_F]
...
I know it is too late to answer your question, but hopefully this will help:
To find list has odd length:
oddlength([_]).
oddlength([_,_|R]) :- oddlength(R),!.
To find list has even length:
evenlength([]).
evenlength([_,_|R]) :- evenlength(R),!.