A length/2 predicate that works with constraints [duplicate] - list

Here is the problem:
$ swipl
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.6-5-g5aeabd5)
Copyright (c) 1990-2015 University of Amsterdam, VU Amsterdam
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
Please visit http://www.swi-prolog.org for details.
For help, use ?- help(Topic). or ?- apropos(Word).
?- use_module(library(clpfd)).
true.
?- N in 1..3, length(L, N).
N = 1,
L = [_G1580] ;
N = 2,
L = [_G1580, _G1583] ;
N = 3,
L = [_G1580, _G1583, _G1586] ;
ERROR: Out of global stack % after a while
(I can switch the order of the subqueries, the result is the same).
I guess I need to label N before I can use it, but I wonder what the problem is? I have not managed to choke up length/2 before.

What's probably more useful than a slightly less nondeterministic length/2 is a proper list-length constraint. You can find an ECLiPSe implementation of it here, called len/2. With this you get the following behaviour:
?- N :: 1..3, len(Xs, N).
N = N{1 .. 3}
Xs = [_431|_482] % note it must contain at least one element!
There is 1 delayed goal.
Yes (0.00s cpu)
You can then enumerate the valid lists either by enumerating N:
?- N :: 1..3, len(Xs, N), indomain(N).
N = 1
Xs = [_478]
Yes (0.00s cpu, solution 1, maybe more)
N = 2
Xs = [_478, _557]
Yes (0.02s cpu, solution 2, maybe more)
N = 3
Xs = [_478, _557, _561]
Yes (0.02s cpu, solution 3)
or by generating lists with good old standard length/2:
?- N :: 1..3, len(Xs, N), length(Xs, _).
N = 1
Xs = [_488]
Yes (0.00s cpu, solution 1, maybe more)
N = 2
Xs = [_488, _555]
Yes (0.02s cpu, solution 2, maybe more)
N = 3
Xs = [_488, _555, _636]
Yes (0.02s cpu, solution 3)

Let's start with the most obvious one. If you switch the goals, you have:
?- length(L, N), N in 1..3.
which has the same termination properties as:
?- length(L, N), false, N in 1..3.
So obviously, this must not terminate with Prolog's execution mechanism.
However, if you put N in 1..3 in front, this might affect termination. To do so, it must be possible with finite means to prove that there is no N from 4 on. How can you prove this in a system without constraints - that is, only with syntactic unification present? Well, you can't. And length/2 is commonly defined just without constraints present.
With library(clpfd) things are trivial, for N #>= 4, N in 1..3 simply fails1. Note also that library(clpfd) does not collaborate much with library(clpq) which might be an interesting candidate, too.
As a consequence you would need to define your own length — for each constraint package you are interested in. That's a bit of a pity, but currently there is no generic way to do so in sight. ((That is, if you are interested and think a bit about it, you might come up with a nice API that every constraint system should adhere to. Alas, this will take some more decades, I suspect. Currently, there is much too much divergence.))
So here is a first naive way for fd_length/2:
fd_length([], N) :-
N #= 0.
fd_length([_|L], N0) :-
N0 #>= 1,
N1 #= N0-1,
fd_length(L, N1).
OK, this could be optimized to avoid the superfluous choicepoint. But there is a more fundamental problem: If you are determining the length of a list of length N, this will create N constraint variables! But we do need only one.
fd_length(L, N) :-
N #>= 0,
fd_length(L, N, 0).
fd_length([], N, N0) :-
N #= N0.
fd_length([_|L], N, N0) :-
N1 is N0+1,
N #>= N1,
fd_length(L, N, N1).
Again, this is not perfect for so many reasons: It could use Brent's algorithm like current systems do ; and combine it with all the fd properties. Also, arithmetic expressions are probably not a good idea to permit ; but I would have to wait for (#)/1 in SWI...
1: Strictly speaking, this "simply fails" only for SICStus, SWI, and YAP. For in those systems, there is no accidental failure due to exhaustion of the current representation. That is, their failure can always be taken as an honest no.

How about the following baroque work-around based on clpfd and meta-predicate tcount/3?
:- use_module([library(clpfd), library(lambda)]).
list_FDlen(Xs, N) :-
tcount(\_^ =(true), Xs, N).
Let's query!
?- N in 1..3, list_FDlen(Xs, N).
N = 1, Xs = [_A]
; N = 2, Xs = [_A,_B]
; N = 3, Xs = [_A,_B,_C]
; false. % terminates universally
?- N in inf..2, list_FDlen(Xs, N).
N = 0, Xs = []
; N = 1, Xs = [_A]
; N = 2, Xs = [_A,_B]
; false. % terminates universally, too
What about this particular query?
?- N in 2..sup, list_FDlen(Xs, N).
N = 2, Xs = [_A,_B]
; N = 3, Xs = [_A,_B,_C]
; N = 4, Xs = [_A,_B,_C,_D]
... % does not terminate (as expected)

We present a clpfd-ish variant of
length/2 that's tailored to #mat's clpfd implementation.
:- use_module(library(clpfd)).
:- use_module(library(dialect/sicstus)).
:- multifile clpfd:run_propagator/2.
The "exported" predicate lazy_len/2 is defined like this:
lazy_len(Es, N) :-
N in 0..sup, % lengths are always non-negative integers
lazylist_acc_len(Es, 0, N),
create_mutable(Es+0, State),
clpfd:make_propagator(list_FD_size(State,N), Propagator),
clpfd:init_propagator(N, Propagator),
clpfd:trigger_once(Propagator).
The global constraint handler list_FD_size/3 incrementally modifies its internal state as constraint propagation occurs. All modifications are trailed and are un-done upon backtracking.
clpfd:run_propagator(list_FD_size(State,N), _MState) :-
get_mutable(Es0+Min0, State),
fd_inf(N, Min),
Diff is Min - Min0,
length(Delta, Diff),
append(Delta, Es, Es0),
( integer(N)
-> Es = []
; Delta = []
-> true % unchanged
; update_mutable(Es+Min, State)
).
lazy_len/2 tackles the problem from two sides; the clpfd constraint part of it was shown above. The tree side uses prolog-coroutining to walk down the list as far as the partial instantiation allows1:
lazylist_acc_len(_, _, N) :-
integer(N),
!.
lazylist_acc_len(Es, N0, N) :-
var(Es),
!,
when((nonvar(N);nonvar(Es)), lazylist_acc_len(Es,N0,N)).
lazylist_acc_len([], N, N).
lazylist_acc_len([_|Es], N0, N) :-
N1 is N0+1,
N in N1..sup,
lazylist_acc_len(Es, N1, N).
Sample queries:
?- lazy_len(Xs, N).
when((nonvar(N);nonvar(Xs)), lazylist_acc_len(Xs,0,N)),
N in 0..sup,
list_FD_size(Xs+0, N).
?- lazy_len(Xs, 3).
Xs = [_A,_B,_C].
?- lazy_len([_,_], L).
L = 2.
?- lazy_len(Xs, L), L #> 0.
Xs = [_A|_B],
when((nonvar(L);nonvar(_B)), lazylist_acc_len(_B,1,L)),
L in 1..sup,
list_FD_size(_B+1, L).
?- lazy_len(Xs, L), L #> 2.
Xs = [_A,_B,_C|_D],
when((nonvar(L);nonvar(_D)), lazylist_acc_len(_D,3,L)),
L in 3..sup,
list_FD_size(_D+3, L).
?- lazy_len(Xs, L), L #> 0, L #> 2.
Xs = [_A,_B,_C|_D],
when((nonvar(L);nonvar(_D)), lazylist_acc_len(_D,3,L)),
L in 3..sup,
list_FD_size(_D+3, L).
And, at long last, one more query... well, actually two more: one going up—the other going down.
?- L in 1..4, lazy_len(Xs, L), labeling([up], [L]).
L = 1, Xs = [_A]
; L = 2, Xs = [_A,_B]
; L = 3, Xs = [_A,_B,_C]
; L = 4, Xs = [_A,_B,_C,_D].
?- L in 1..4, lazy_len(Xs, L), labeling([down], [L]).
L = 4, Xs = [_A,_B,_C,_D]
; L = 3, Xs = [_A,_B,_C]
; L = 2, Xs = [_A,_B]
; L = 1, Xs = [_A].
Footnote 1:
Here, we focus on preserving determinism (avoid the creation of choice-points) by using delayed goals.

Related

Numbers in a list smaller than a given number

xMenores(_,[],[]).
xMenores(X,[H|T],[R|Z]) :-
xMenores(X,T,Z),
X > H,
R is H.
xMenores takes three parameters:
The first one is a number.
The second is a list of numbers.
The third is a list and is the variable that will contain the result.
The objective of the rule xMenores is obtain a list with the numbers of the list (Second parameter) that are smaller than the value on the first parameter. For example:
?- xMenores(3,[1,2,3],X).
X = [1,2]. % expected result
The problem is that xMenores returns false when X > H is false and my programming skills are almost null at prolog. So:
?- xMenores(4,[1,2,3],X).
X = [1,2,3]. % Perfect.
?- xMenores(2,[1,2,3],X).
false. % Wrong! "X = [1]" would be perfect.
I consider X > H, R is H. because I need that whenever X is bigger than H, R takes the value of H. But I don't know a control structure like an if or something in Prolog to handle this.
Please, any solution? Thanks.
Using ( if -> then ; else )
The control structure you might be looking for is ( if -> then ; else ).
Warning: you should probably swap the order of the first two arguments:
lessthan_if([], _, []).
lessthan_if([X|Xs], Y, Zs) :-
( X < Y
-> Zs = [X|Zs1]
; Zs = Zs1
),
lessthan_if(Xs, Y, Zs1).
However, if you are writing real code, you should almost certainly go with one of the predicates in library(apply), for example include/3, as suggested by #CapelliC:
?- include(>(3), [1,2,3], R).
R = [1, 2].
?- include(>(4), [1,2,3], R).
R = [1, 2, 3].
?- include(<(2), [1,2,3], R).
R = [3].
See the implementation of include/3 if you want to know how this kind of problems are solved. You will notice that lessthan/3 above is nothing but a specialization of the more general include/3 in library(apply): include/3 will reorder the arguments and use the ( if -> then ; else ).
"Declarative" solution
Alternatively, a less "procedural" and more "declarative" predicate:
lessthan_decl([], _, []).
lessthan_decl([X|Xs], Y, [X|Zs]) :- X < Y,
lessthan_decl(Xs, Y, Zs).
lessthan_decl([X|Xs], Y, Zs) :- X >= Y,
lessthan_decl(Xs, Y, Zs).
(lessthan_if/3 and lessthan_decl/3 are nearly identical to the solutions by Nicholas Carey, except for the order of arguments.)
On the downside, lessthan_decl/3 leaves behind choice points. However, it is a good starting point for a general, readable solution. We need two code transformations:
Replace the arithmetic comparisons < and >= with CLP(FD) constraints: #< and #>=;
Use a DCG rule to get rid of arguments in the definition.
You will arrive at the solution by lurker.
A different approach
The most general comparison predicate in Prolog is compare/3. A common pattern using it is to explicitly enumerate the three possible values for Order:
lessthan_compare([], _, []).
lessthan_compare([H|T], X, R) :-
compare(Order, H, X),
lessthan_compare_1(Order, H, T, X, R).
lessthan_compare_1(<, H, T, X, [H|R]) :-
lessthan_compare(T, X, R).
lessthan_compare_1(=, _, T, X, R) :-
lessthan_compare(T, X, R).
lessthan_compare_1(>, _, T, X, R) :-
lessthan_compare(T, X, R).
(Compared to any of the other solutions, this one would work with any terms, not just integers or arithmetic expressions.)
Replacing compare/3 with zcompare/3:
:- use_module(library(clpfd)).
lessthan_clpfd([], _, []).
lessthan_clpfd([H|T], X, R) :-
zcompare(ZOrder, H, X),
lessthan_clpfd_1(ZOrder, H, T, X, R).
lessthan_clpfd_1(<, H, T, X, [H|R]) :-
lessthan_clpfd(T, X, R).
lessthan_clpfd_1(=, _, T, X, R) :-
lessthan_clpfd(T, X, R).
lessthan_clpfd_1(>, _, T, X, R) :-
lessthan_clpfd(T, X, R).
This is definitely more code than any of the other solutions, but it does not leave behind unnecessary choice points:
?- lessthan_clpfd(3, [1,3,2], Xs).
Xs = [1, 2]. % no dangling choice points!
In the other cases, it behaves just as the DCG solution by lurker:
?- lessthan_clpfd(X, [1,3,2], Xs).
Xs = [1, 3, 2],
X in 4..sup ;
X = 3,
Xs = [1, 2] ;
X = 2,
Xs = [1] ;
X = 1,
Xs = [] .
?- lessthan_clpfd(X, [1,3,2], Xs), X = 3. %
X = 3,
Xs = [1, 2] ; % no error!
false.
?- lessthan_clpfd([1,3,2], X, R), R = [1, 2].
X = 3,
R = [1, 2] ;
false.
Unless you need such a general approach, include(>(X), List, Result) is good enough.
This can also be done using a DCG:
less_than([], _) --> [].
less_than([H|T], N) --> [H], { H #< N }, less_than(T, N).
less_than(L, N) --> [H], { H #>= N }, less_than(L, N).
| ?- phrase(less_than(R, 4), [1,2,3,4,5,6]).
R = [1,2,3] ? ;
You can write your predicate as:
xMenores(N, NumberList, Result) :- phrase(less_than(Result, N), NumberList).
You could write it as a one-liner using findall\3:
filter( N , Xs , Zs ) :- findall( X, ( member(X,Xs), X < N ) , Zs ) .
However, I suspect that the point of the exercise is to learn about recursion, so something like this would work:
filter( _ , [] , [] ) .
filter( N , [X|Xs] , [X|Zs] ) :- X < N , filter(N,Xs,Zs) .
filter( N , [X|Xs] , Zs ) :- X >= N , filter(N,Xs,Zs) .
It does, however, unpack the list twice on backtracking. An optimization here would be to combine the 2nd and 3rd clauses by introducing a soft cut like so:
filter( _ , [] , [] ) .
filter( N , [X|Xs] , [X|Zs] ) :-
( X < N -> Zs = [X|Z1] ; Zs = Z1 ) ,
filter(N,Xs,Zs)
.
(This is more like a comment than an answer, but too long for a comment.)
Some previous answers and comments have suggested using "if-then-else" (->)/2 or using library(apply) meta-predicate include/3. Both methods work alright, as long as only plain-old Prolog arithmetics—is/2, (>)/2, and the like—are used ...
?- X = 3, include(>(X),[1,3,2,5,4],Xs).
X = 3, Xs = [1,2].
?- include(>(X),[1,3,2,5,4],Xs), X = 3.
ERROR: >/2: Arguments are not sufficiently instantiated
% This is OK. When instantiation is insufficient, an exception is raised.
..., but when doing the seemingly benign switch from (>)/2 to (#>)/2, we lose soundness!
?- X = 3, include(#>(X),[1,3,2,5,4],Xs).
X = 3, Xs = [1,2].
?- include(#>(X),[1,3,2,5,4],Xs), X = 3.
false.
% This is BAD! Expected success with answer substitutions `X = 3, Xs = [1,2]`.
No new code is presented in this answer.
In the following we take a detailed look at different revisions of this answer by #lurker.
Revision #1, renamed to less_than_ver1//2. By using dcg and clpfd, the code is both very readable and versatile:
less_than_ver1(_, []) --> [].
less_than_ver1(N, [H|T]) --> [H], { H #< N }, less_than_ver1(N, T).
less_than_ver1(N, L) --> [H], { H #>= N }, less_than_ver1(N, L).
Let's query!
?- phrase(less_than_ver1(N,Zs),[1,2,3,4,5]).
N in 6..sup, Zs = [1,2,3,4,5]
; N = 5 , Zs = [1,2,3,4]
; N = 4 , Zs = [1,2,3]
; N = 3 , Zs = [1,2]
; N = 2 , Zs = [1]
; N in inf..1, Zs = []
; false.
?- N = 3, phrase(less_than_ver1(N,Zs),[1,2,3,4,5]).
N = 3, Zs = [1,2] % succeeds, but leaves useless choicepoint
; false.
?- phrase(less_than_ver1(N,Zs),[1,2,3,4,5]), N = 3.
N = 3, Zs = [1,2]
; false.
As a small imperfection, less_than_ver1//2 leaves some useless choicepoints.
Let's see how things went with the newer revision...
Revision #3, renamed to less_than_ver3//2:
less_than_ver3([],_) --> [].
less_than_ver3(L,N) --> [X], { X #< N -> L=[X|T] ; L=T }, less_than_ver3(L,N).
This code uses the if-then-else ((->)/2 + (;)/2) in order to improve determinism.
Let's simply re-run the above queries!
?- phrase(less_than_ver3(Zs,N),[1,2,3,4,5]).
N in 6..sup, Zs = [1,2,3,4,5]
; false. % all other solutions are missing!
?- N = 3, phrase(less_than_ver3(Zs,N),[1,2,3,4,5]).
N = 3, Zs = [1,2] % works as before, but no better.
; false. % we still got the useless choicepoint
?- phrase(less_than_ver3(Zs,N),[1,2,3,4,5]), N = 3.
false. % no solution!
% we got one with revision #1!
Surprise! Two cases that worked before are now (somewhat) broken, and the determinism in the ground case is no better... Why?
The vanilla if-then-else often cuts too much too soon, which is particularly problematic with code which uses coroutining and/or constraints.
Note that (*->)/2 (a.k.a. "soft-cut" or if/3), fares only a bit better, not a lot!
As if_/3 never ever cuts more (often than) the vanilla if-then-else (->)/2, it cannot be used in above code to improve determinism.
If you want to use if_/3 in combination with constraints, take a step back and write code that is non-dcg as the first shot.
If you're lazy like me, consider using a meta-predicate like tfilter/3 and (#>)/3.
This answer by #Boris presented a logically pure solution which utilizes clpfd:zcompare/3 to help improve determinism in certain (ground) cases.
In this answer we will explore different ways of coding logically pure Prolog while trying to avoid the creation of useless choicepoints.
Let's get started with zcompare/3 and (#<)/3!
zcompare/3 implements three-way comparison of finite domain variables and reifies the trichotomy into one of <, =, or >.
As the inclusion criterion used by the OP was a arithmetic less-than test, we propose using
(#<)/3 for reifying the dichotomy into one of true or false.
Consider the answers of the following queries:
?- zcompare(Ord,1,5), #<(1,5,B).
Ord = (<), B = true.
?- zcompare(Ord,5,5), #<(5,5,B).
Ord = (=), B = false.
?- zcompare(Ord,9,5), #<(9,5,B).
Ord = (>), B = false.
Note that for all items to be selected both Ord = (<) and B = true holds.
Here's a side-by-side comparison of three non-dcg solutions based on clpfd:
The left one uses zcompare/3 and first-argument indexing on the three cases <, =, and >.
The middle one uses (#<)/3 and first-argument indexing on the two cases true and false.
The right one uses (#<)/3 in combination with if_/3.
Note that we do not need to define auxiliary predicates in the right column!
less_than([],[],_). % less_than([],[],_). % less_than([],[],_).
less_than([Z|Zs],Ls,X) :- % less_than([Z|Zs],Ls,X) :- % less_than([Z|Zs],Ls,X) :-
zcompare(Ord,Z,X), % #<(Z,X,B), % if_(Z #< X,
ord_lt_(Ord,Z,Ls,Rs), % incl_lt_(B,Z,Ls,Rs), % Ls = [Z|Rs],
less_than(Zs,Rs,X). % less_than(Zs,Rs,X). % Ls = Rs),
% % less_than(Zs,Rs,X).
ord_lt_(<,Z,[Z|Ls],Ls). % incl_lt_(true ,Z,[Z|Ls],Ls). %
ord_lt_(=,_, Ls ,Ls). % incl_lt_(false,_, Ls ,Ls). %
ord_lt_(>,_, Ls ,Ls). % %
Next, let's use dcg!
In the right column we use if_//3 instead of if_/3.
Note the different argument orders of dcg and non-dcg solutions: less_than([1,2,3],Zs,3) vs phrase(less_than([1,2,3],3),Zs).
The following dcg implementations correspond to above non-dcg codes:
less_than([],_) --> []. % less_than([],_) --> []. % less_than([],_) --> [].
less_than([Z|Zs],X) --> % less_than([Z|Zs],X) --> % less_than([Z|Zs],X) -->
{ zcompare(Ord,Z,X) }, % { #<(Z,X,B) }, % if_(Z #< X,[Z],[]),
ord_lt_(Ord,Z), % incl_lt_(B,Z), % less_than(Zs,X).
less_than(Zs,X). % less_than(Zs,X). %
% %
ord_lt_(<,Z) --> [Z]. % incl_lt_(true ,Z) --> [Z]. %
ord_lt_(=,_) --> []. % incl_lt_(false,_) --> []. %
ord_lt_(>,_) --> []. % %
OK! Saving the best for last... Simply use meta-predicate tfilter/3 together with (#>)/3!
less_than(Xs,Zs,P) :-
tfilter(#>(P),Xs,Zs).
The dcg variant in this previous answer is our starting point.
Consider the auxiliary non-terminal ord_lt_//2:
ord_lt_(<,Z) --> [Z].
ord_lt_(=,_) --> [].
ord_lt_(>,_) --> [].
These three clauses can be covered using two conditions:
Ord = (<): the item should be included.
dif(Ord, (<)): it should not be included.
We can express this "either-or choice" using if_//3:
less_than([],_) --> [].
less_than([Z|Zs],X) -->
{ zcompare(Ord,Z,X) },
if_(Ord = (<), [Z], []),
less_than(Zs,X).
Thus ord_lt_//2 becomes redundant.
Net gain? 3 lines-of-code !-)

Create list of pair of values 0 to n-1 in lexicographical order

I'm doing a program with Result is a pair of values [X,Y] between 0 and N-1 in lexicographic order
I have this right now:
pairs(N,R) :-
pairsHelp(N,R,0,0).
pairsHelp(N,[],N,N) :- !.
pairsHelp(N,[],N,0) :- !.
pairsHelp(N,[[X,Y]|List],X,Y) :-
Y is N-1,
X < N,
X1 is X + 1,
pairsHelp(N,List,X1,0).
pairsHelp(N,[[X,Y]|List],X,Y) :-
Y < N,
Y1 is Y + 1,
pairsHelp(N,List,X,Y1).
I'm getting what I want the first iteration but Prolog keeps going and then gives me a second answer.
?-pairs(2,R).
R = [[0,0],[0,1],[1,0],[1,1]] ;
false.
I don't want the second answer (false), just the first. I want it to stop after it finds the answer. Any ideas?
Keep in mind that there is a much easier way to get what you are after. If indeed both X and Y are supposed to be integers, use between/3 to enumerate integers ("lexicographical" here is the same as the order of natural numbers: 0, 1, 2, .... This is the order in which between/3 will enumerate possible solutions if the third argument is a variable):
pairs(N, R) :-
succ(N0, N),
bagof(P, pair(N0, P), R).
pair(N0, X-Y) :-
between(0, N0, X),
between(0, N0, Y).
And then:
?- pairs(2, R).
R = [0-0, 0-1, 1-0, 1-1].
?- pairs(3, R).
R = [0-0, 0-1, 0-2, 1-0, 1-1, 1-2, 2-0, 2-1, ... - ...].
I am using the conventional Prolog way of representing a pair, X-Y (in canonical form: -(X, Y)) instead of [X,Y] (canonical form: .(X, .(Y, []))).
The good thing about this program is that you can easily re-write it to work with another "alphabet" of your choosing.
?- between(0, Upper, X).
is semantically equivalent to:
x(0).
x(1).
% ...
x(Upper).
?- x(X).
For example, if we had an alphabet that consists of b, a, and c (in that order!):
foo(b).
foo(a).
foo(c).
foo_pairs(Ps) :-
bagof(X-Y, ( foo(X), foo(Y) ), Ps).
and then:
?- foo_pairs(R).
R = [b-b, b-a, b-c, a-b, a-a, a-c, c-b, c-a, ... - ...].
The order of the clauses of foo/1 defines the order of your alphabet. The conjunction foo(X), foo(Y) together with the order of X-Y in the pair defines the order of pairs in the list. Try writing for example bagof(X-Y, ( foo(Y), foo(X) ), Ps) to see what will be the order of pairs in Ps.
Use dcg in combination with lambda!
?- use_module(library(lambda)).
In combination with meta-predicate init0/3 and
xproduct//2 ("cross product") simply write:
?- init0(=,3,Xs), phrase(xproduct(\X^Y^phrase([X-Y]),Xs),Pss).
Xs = [0,1,2], Pss = [0-0,0-1,0-2,1-0,1-1,1-2,2-0,2-1,2-2].
How about something a little more general? What about other values of N?
?- init0(=,N,Xs), phrase(xproduct(\X^Y^phrase([X-Y]),Xs),Pss).
N = 0, Xs = [], Pss = []
; N = 1, Xs = [0], Pss = [0-0]
; N = 2, Xs = [0,1], Pss = [0-0,0-1,
1-0,1-1]
; N = 3, Xs = [0,1,2], Pss = [0-0,0-1,0-2,
1-0,1-1,1-2,
2-0,2-1,2-2]
; N = 4, Xs = [0,1,2,3], Pss = [0-0,0-1,0-2,0-3,
1-0,1-1,1-2,1-3,
2-0,2-1,2-2,2-3,
3-0,3-1,3-2,3-3]
; N = 5, Xs = [0,1,2,3,4], Pss = [0-0,0-1,0-2,0-3,0-4,
1-0,1-1,1-2,1-3,1-4,
2-0,2-1,2-2,2-3,2-4,
3-0,3-1,3-2,3-3,3-4,
4-0,4-1,4-2,4-3,4-4]
...
Does it work for other terms, too? What about order? Consider a case #Boris used in his answer:
?- phrase(xproduct(\X^Y^phrase([X-Y]),[b,a,c]),Pss).
Pss = [b-b,b-a,b-c,a-b,a-a,a-c,c-b,c-a,c-c]. % succeeds deterministically

prolog list of how many times an element occurs in a list?

Well, I have a list, say [a,b,c,c,d], and I want to generate a list [[a,1],[b,1],[c,2],[d,1]]. But I'm having trouble with generating my list. I can count how many times the element occur but not add it into a list:
% count how much the element occurs in the list.
count([], _, 0).
count([A|Tail], A, K) :-
count(Tail, A, K1),
K is K1 + 1.
count([_|Tail], X, K) :-
count(Tail, X, K1),
K is K1 + 0.
% Give back a list with each element and how many times is occur
count_list(L, [], _).
count_list(L, [A|Tail], Out) :-
count(L, A, K),
write(K),
count_list(L, Tail, [K|Out]).
I'm trying to learn Prolog but having some difficulties... Some help will be much appreciated... Thanks in advance!
Let me first refer to a related question "How to count number of element occurrences in a list in Prolog" and to my answer in particular.
In said answer I presented a logically-pure monotone implementation of a predicate named list_counts/2, which basically does what you want. Consider the following query:
?- list_counts([a,b,c,c,d], Xs).
Xs = [a-1,b-1,c-2,d-1]. % succeeds deterministically
?- list_counts([a,b,a,d,a], Xs). % 'a' is spread over the list
Xs = [a-3,b-1,d-1]. % succeeds deterministically
Note that the implementation is monotone and gives logically sound answers even for very general queries like the following one:
?- Xs = [_,_,_,_],list_counts(Xs,[a-N,b-M]).
Xs = [a,a,a,b], N = 3, M = 1 ;
Xs = [a,a,b,a], N = 3, M = 1 ;
Xs = [a,a,b,b], N = M, M = 2 ;
Xs = [a,b,a,a], N = 3, M = 1 ;
Xs = [a,b,a,b], N = M, M = 2 ;
Xs = [a,b,b,a], N = M, M = 2 ;
Xs = [a,b,b,b], N = 1, M = 3 ;
false.
I cannot follow your logic. The easy way would be to use library(aggregate), but here is a recursive definition
count_list([], []).
count_list([H|T], R) :-
count_list(T, C),
update(H, C, R).
update(H, [], [[H,1]]).
update(H, [[H,N]|T], [[H,M]|T]) :- !, M is N+1.
update(H, [S|T], [S|U]) :- update(H, T, U).
the quirk: it build the result in reverse order. Your code, since it uses an accumulator, would give the chance to build in direct order....

Prolog program that deletes every n-th element from a list

Could you help me solve the following?
Write a ternary predicate delete_nth that deletes every n-th element from a list.
Sample runs:
?‐ delete_nth([a,b,c,d,e,f],2,L).
L = [a, c, e] ;
false
?‐ delete_nth([a,b,c,d,e,f],1,L).
L = [] ;
false
?‐ delete_nth([a,b,c,d,e,f],0,L).
false
I tried this:
listnum([],0).
listnum([_|L],N) :-
listnum(L,N1),
N is N1+1.
delete_nth([],_,_).
delete_nth([X|L],C,L1) :-
listnum(L,S),
Num is S+1,
( C>0
-> Y is round(Num/C),Y=0
-> delete_nth(L,C,L1)
; delete_nth(L,C,[X|L1])
).
My slightly extravagant variant:
delete_nth(L, N, R) :-
N > 0, % Added to conform "?‐ delete_nth([a,b,c,d,e,f],0,L). false"
( N1 is N - 1, length(Begin, N1), append(Begin, [_|Rest], L) ->
delete_nth(Rest, N, RestNew), append(Begin, RestNew, R)
;
R = L
).
Let's use clpfd! For the sake of versatility and tons of other good reasons:
:- use_module(library(clpfd)).
We define delete_nth/3 based on if_/3 and (#>=)/3:
delete_nth(Xs,N,Ys) :-
N #> 0,
every_tmp_nth_deleted(Xs,0,N,Ys).
every_tmp_nth_deleted([] ,_ ,_,[] ). % internal auxiliary predicate
every_tmp_nth_deleted([X|Xs],N0,N,Ys0) :-
N1 is N0+1,
if_(N1 #>= N,
(N2 = 0, Ys0 = Ys ),
(N2 = N1, Ys0 = [X|Ys])),
every_tmp_nth_deleted(Xs,N2,N,Ys).
Sample query:
?- delete_nth([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],2,Ys).
Ys = [1,3,5,7,9,11,13,15] % succeeds deterministically
Ok, how about something a little more general?
?- delete_nth([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],N,Ys).
N = 1 , Ys = []
; N = 2 , Ys = [1, 3, 5, 7, 9, 11, 13, 15]
; N = 3 , Ys = [1,2, 4,5, 7,8, 10,11, 13,14 ]
; N = 4 , Ys = [1,2,3, 5,6,7, 9,10,11, 13,14,15]
; N = 5 , Ys = [1,2,3,4, 6,7,8,9, 11,12,13,14 ]
; N = 6 , Ys = [1,2,3,4,5, 7,8,9,10,11, 13,14,15]
; N = 7 , Ys = [1,2,3,4,5,6, 8,9,10,11,12,13, 15]
; N = 8 , Ys = [1,2,3,4,5,6,7, 9,10,11,12,13,14,15]
; N = 9 , Ys = [1,2,3,4,5,6,7,8, 10,11,12,13,14,15]
; N = 10 , Ys = [1,2,3,4,5,6,7,8,9, 11,12,13,14,15]
; N = 11 , Ys = [1,2,3,4,5,6,7,8,9,10, 12,13,14,15]
; N = 12 , Ys = [1,2,3,4,5,6,7,8,9,10,11, 13,14,15]
; N = 13 , Ys = [1,2,3,4,5,6,7,8,9,10,11,12, 14,15]
; N = 14 , Ys = [1,2,3,4,5,6,7,8,9,10,11,12,13, 15]
; N = 15 , Ys = [1,2,3,4,5,6,7,8,9,10,11,12,13,14 ]
; N in 16..sup, Ys = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15].
Please follow aBathologist instructive answer and explanation (+1). I just post my own bet at solution since there is a problem in ditto solution for ?‐ delete_nth([a,b,c,d,e,f],0,L)..
delete_nth(L,C,R) :-
delete_nth(L,C,1,R).
delete_nth([],_,_,[]).
delete_nth([_|T],C,C,T1) :- !, delete_nth(T,C,1,T1).
delete_nth([H|T],N,C,[H|T1]) :- C<N, C1 is C+1, delete_nth(T,N,C1,T1).
yields
1 ?- delete_nth([a,b,c,d,e,f],2,L).
L = [a, c, e].
2 ?- delete_nth([a,b,c,d,e,f],1,L).
L = [].
3 ?- delete_nth([a,b,c,d,e,f],0,L).
false.
A minor (?) problem: this code is deterministic, while the samples posted apparently are not (you have to input ';' to get a false at end). Removing the cut will yield the same behaviour.
An interesting - imho - one liner variant:
delete_nth(L,C,R) :- findall(E, (nth1(I,L,E),I mod C =\= 0), R).
but the C==0 must be ruled out, to avoid
ERROR: mod/2: Arithmetic: evaluation error: `zero_divisor'
Edited, correcting the mistake pointed out by #CapelliC, where predicate would succeed on N = 0.
I can see where you're headed with your solution, but you needn't bother with so much arithmetic in this case. We can delete the Nth element by counting down from N repeatedly until the list is empty. First, a quick note about style:
If you use spaces, line breaks, and proper placement of parenthesis you can help your readers parse your code. Your last clause is much more readable in this form:
delete_nth([X|L], C, L1):-
listnum(L, S),
Num is S+1,
C>0 -> Y is round(Num/C),
Y=0 -> delete_nth(L, C, L1)
; delete_nth(L, C, [X|L1]).
Viewing your code now, I'm not sure whether you meant to write
( C>0 -> ( Y is round(Num/C),
Y=0 -> delete_nth(L, C, L1) )
; delete_nth(L, C, [X|L1])
).
or if you meant
C>0 -> Y is round(Num/C),
( Y=0 -> delete_nth(L, C, L1)
; delete_nth(L, C, [X|L1])
).
or perhaps you're missing a ; before the second conditional? In any case, I suggest another approach...
This looks like a job for auxiliary predicates!
Often, we only need a simple relationship in order to pose a query, but the computational process necessary to resolve the query and arrive at an answer calls for a more complex relation. These are cases where it is "easier said than done".
My solution to this problem works as follows: In order to delete every nth element, we start at N and count down to 1. Each time we decrement the value from N, we move an element from the original list to the list of elements we're keeping. When we arrive at 1, we discard the element from our original list, and start counting down from N again. As you can see, in order to ask the question "What is the list Kept resulting from dropping every Nth element of List?" we only need three variables. But my answer the question, also requires another variable to track the count-down from N to 1, because each time we take the head off of List, we need to ask "What is the Count?" and once we've reached 1, we need to be able to remember the original value of N.
Thus, the solution I offer relies on an auxiliary, 4-place predicate to do the computation, with a 3-place predicate as the "front end", i.e., as the predicate used for posing the question.
delete_nth(List, N, Kept) :-
N > 0, %% Will fail if N < 0.
delete_nth(List, N, N, Kept), !. %% The first N will be our our counter, the second our target value. I cut because there's only one way to generate `Kept` and we don't need alternate solutions.
delete_nth([], _, _, []). %% An empty list has nothing to delete.
delete_nth([_|Xs], 1, N, Kept) :- %% When counter reaches 1, the head is discarded.
delete_nth(Xs, N, N, Kept). %% Reset the counter to N.
delete_nth([X|Xs], Counter, N, [X|Kept]) :- %% Keep X if counter is still counting down.
NextCount is Counter - 1, %% Decrement the counter.
delete_nth(Xs, NextCount, N, Kept). %% Keep deleting elements from Xs...
Yet another approach, following up on #user3598120 initial impulse to calculate the undesirable Nth elements away and inspired by #Sergey Dymchenko playfulness. It uses exclude/3 to remove all elements at a 1-based index that is multiple of N
delete_nth(List, N, Kept) :-
N > 0,
exclude(index_multiple_of(N, List), List, Kept).
index_multiple_of(N, List, Element) :-
nth1(Index, List, Element),
0 is Index mod N.

Count only numbers in list of numbers and letters

I'm new to Prolog and I can't seem to get the answer to this on my own.
What I want is, that Prolog counts ever Number in a list, NOT every element. So for example:
getnumbers([1, 2, c, h, 4], X).
Should give me:
X=3
getnumbers([], 0).
getnumbers([_ | T], N) :- getnumbers(T, N1), N is N1+1.
Is what I've got, but it obviously gives me every element in a list. I don't know how and where to put a "only count numbers".
As usual, when you work with lists (and SWI-Prolog), you can use module lambda.pl found there : http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl
:- use_module(library(lambda)).
getnumbers(L, N) :-
foldl(\X^Y^Z^(number(X)
-> Z is Y+1
; Z = Y),
L, 0, N).
Consider using the built-in predicates (for example in SWI-Prolog), and checking their implementations if you are interested in how to do it yourself:
include(number, List, Ns), length(Ns, N)
Stay logically pure, it's easy: Use the meta-predicate
tcount/3 in tandem with the reified type test predicate number_t/2 (short for number_truth/2):
number_t(X,Truth) :- number(X), !, Truth = true.
number_t(X,Truth) :- nonvar(X), !, Truth = false.
number_t(X,true) :- freeze(X, number(X)).
number_t(X,false) :- freeze(X,\+number(X)).
Let's run the query the OP suggested:
?- tcount(number_t,[1,2,c,h,4],N).
N = 3. % succeeds deterministically
Note that this is monotone: delaying variable binding is always logically sound. Consider:
?- tcount(number_t,[A,B,C,D,E],N), A=1, B=2, C=c, D=h, E=4.
N = 3, A = 1, B = 2, C = c, D = h, E = 4 ; % succeeds, but leaves choice point
false.
At last, let us peek at some of the answers of the following quite general query:
?- tcount(number_t,[A,B,C],N).
N = 3, freeze(A, number(A)), freeze(B, number(B)), freeze(C, number(C)) ;
N = 2, freeze(A, number(A)), freeze(B, number(B)), freeze(C,\+number(C)) ;
N = 2, freeze(A, number(A)), freeze(B,\+number(B)), freeze(C, number(C)) ;
N = 1, freeze(A, number(A)), freeze(B,\+number(B)), freeze(C,\+number(C)) ;
N = 2, freeze(A,\+number(A)), freeze(B, number(B)), freeze(C, number(C)) ;
N = 1, freeze(A,\+number(A)), freeze(B, number(B)), freeze(C,\+number(C)) ;
N = 1, freeze(A,\+number(A)), freeze(B,\+number(B)), freeze(C, number(C)) ;
N = 0, freeze(A,\+number(A)), freeze(B,\+number(B)), freeze(C,\+number(C)).
of course, you must check the type of an element to see if it satisfies the condition.
number/1 it's the predicate you're looking for.
See also if/then/else construct, to use in the recursive clause.
This uses Prolog's natural pattern matching with number/1, and an additional clause (3 below) to handle cases that are not numbers.
% 1 - base recursion
getnumbers([], 0).
% 2 - will pass ONLY if H is a number
getnumbers([H | T], N) :-
number(H),
getnumbers(T, N1),
N is N1+1.
% 3 - if got here, H CANNOT be a number, ignore head, N is unchanged, recurse tail
getnumbers([_ | T], N) :-
getnumbers(T, N).
A common prolog idiom with this sort of problem is to first define your predicate for public consumption, and have it invoke a 'worker' predicate. Often it will use some sort of accumulator. For your problem, the public consumption predicate is something like:
count_numbers( Xs , N ) :-
count_numbers_in_list( Xs , 0 , N ) .
count_numbers_in_list( [] , N , N ) .
count_numbers_in_list( [X|Xs] , T , N ) :-
number(X) ,
T1 is T+1 ,
count_numbers_in_list( Xs , T1 , N )
.
You'll want to structure the recursive bit so that it is tail recursive as well, meaning that the recursive call depends on nothing but data in the argument list. This allows the compiler to reuse the existing stack frame on each call, so the predicate becomes, in effect, iterative instead of recursive. A properly tail-recursive predicate can process a list of infinite length; one that is not will allocate a new stack frame on every recursion and eventually blow its stack. The above count_numbers_in_list/3 is tail recursive. This is not:
getnumbers([H | T], N) :-
number(H),
getnumbers(T, N1),
N is N1+1.