Related
How to change string to atoms using maplist.
This does not work :
?- maplist(atom_string,["a","b","c"]).
first because atom_string/2 has arity of two (How do you do partial-function//currying in prolog).
But even if partial-fun worked the complication is that the first argument of atom_string is the unknown i.e. the call is :
atom_string(A,"atom")
not :
atom_string("atom",A)
this worked :
?- use_module(library(lambda)).
?- F = \Y^X^(atom_string(X,Y)), maplist(F,["a","b","c"],L).
F = \Y^X^atom_string(X, Y),
L = [a, b, c].
This works as intended:
?- maplist(atom_string, Atoms, ["a","b","c"]).
Atoms = [a, b, c].
If this is not what you are after, please explain.
Use a helper predicate.
string_atom(String,Atom) :-
atom_string(Atom,String).
Then run using
?- maplist(string_atom,["a","b","c"],Atoms).
Atoms = [a, b, c].
I'm working on Problem 26 from 99 Prolog Problems:
P26 (**) Generate the combinations of K distinct objects chosen from
the N elements of a list
Example:
?- combination(3,[a,b,c,d,e,f],L).
L = [a,b,c] ;
L = [a,b,d] ;
L = [a,b,e] ;
So my program is:
:- use_module(library(clpfd)).
combination(0, _, []).
combination(Tot, List, [H|T]) :-
length(List, Length), Tot in 1..Length,
append(Prefix, [H], Stem),
append(Stem, Suffix, List),
append(Prefix, Suffix, SubList),
SubTot #= Tot-1,
combination(SubTot, SubList, T).
My query result starts fine but then returns a Global out of stack error:
?- combination(3,[a,b,c,d,e,f],L).
L = [a, b, c] ;
L = [a, b, d] ;
L = [a, b, e] ;
L = [a, b, f] ;
Out of global stack
I can't understand why it works at first, but then hangs until it gives Out of global stack error. Happens on both SWISH and swi-prolog in the terminal.
if you try to input, at the console prompt, this line of your code, and ask for backtracking:
?- append(Prefix, [H], Stem).
Prefix = [],
Stem = [H] ;
Prefix = [_6442],
Stem = [_6442, H] ;
Prefix = [_6442, _6454],
Stem = [_6442, _6454, H] ;
...
maybe you have a clue about the (main) problem. All 3 vars are free, then Prolog keeps on generating longer and longer lists on backtracking. As Boris already suggested, you should keep your program far simpler... for instance
combination(0, _, []).
combination(Tot, List, [H|T]) :-
Tot #> 0,
select(H, List, SubList),
SubTot #= Tot-1,
combination(SubTot, SubList, T).
that yields
?- aggregate(count,L^combination(3,[a,b,c,d,e],L),N).
N = 60.
IMHO, library(clpfd) isn't going to make your life simpler while you're moving your first steps into Prolog. Modelling and debugging plain Prolog is already difficult with the basic constructs available, and CLP(FD) is an advanced feature...
I can't understand why it works at first, but then hangs until it gives Out of global stack error.
The answers Prolog produces for a specific query are shown incrementally. That is, the actual answers are produced lazily on demand. First, there were some answers you expected, then a loop was encountered. To be sure that a query terminates completely you have to go through all of them, hitting SPACE/or ; all the time. But there is a simpler way:
Simply add false at the end of your query. Now, all the answers are suppressed:
?- combination(3,[a,b,c,d,e,f],L), false.
ERROR: Out of global stack
By adding further false goals into your program, you can localize the actual culprit. See below all my attempts: I started with the first attempt, and then added further false until I found a terminating fragment (failure-slice).
combination(0, _, []) :- false. % 1st
combination(Tot, List, [H|T]) :-
length(List, Length), Tot in 1..Length, % 4th terminating
append(Prefix, [H], Stem), false, % 3rd loops
append(Stem, Suffix, List), false, % 2nd loops
append(Prefix, Suffix, SubList),
SubTot #= Tot-1, false, % 1st loops
combination(SubTot, SubList, T).
To remove the problem with non-termination you have to modify something in the remaining visible part. Evidently, both Prefix and Stem occur here for the first time.
The use of library(clpfd) in this case is very suspicious. After length(List, Length), Length is definitely bound to a non-negative integer, so why the constraint? And your Tot in 1..Length is weird, too, since you keep on making a new constrained variable in every step of the recursion, and you try to unify it with 0. I am not sure I understand your logic overall :-(
If I understand what the exercise is asking for, I would suggest the following somewhat simpler approach. First, make sure your K is not larger than the total number of elements. Then, just pick one element at a time until you have enough. It could go something like this:
k_comb(K, L, C) :-
length(L, N),
length(C, K),
K =< N,
k_comb_1(C, L).
k_comb_1([], _).
k_comb_1([X|Xs], L) :-
select(X, L, L0),
k_comb_1(Xs, L0).
The important message here is that it is the list itself that defines the recursion, and you really don't need a counter, let alone one with constraints on it.
select/3 is a textbook predicate, I guess you should find it in standard libraries too; anyway, see here for an implementation.
This does the following:
?- k_comb(2, [a,b,c], C).
C = [a, b] ;
C = [a, c] ;
C = [b, a] ;
C = [b, c] ;
C = [c, a] ;
C = [c, b] ;
false.
And with your example:
?- k_comb(3, [a,b,c,d,e,f], C).
C = [a, b, c] ;
C = [a, b, d] ;
C = [a, b, e] ;
C = [a, b, f] ;
C = [a, c, b] ;
C = [a, c, d] ;
C = [a, c, e] ;
C = [a, c, f] ;
C = [a, d, b] ;
C = [a, d, c] ;
C = [a, d, e] ;
C = [a, d, f] ;
C = [a, e, b] ;
C = [a, e, c] . % and so on
Note that this does not check that the elements of the list in the second argument are indeed unique; it just takes elements from distinct positions.
This solution still has problems with termination but I don't know if this is relevant for you.
The thing I wanted to do was generate all combinations of elements from a given list. E.g.: From [a,b,c], I might want:
[]
[a]
[b]
[c]
[a,a]
[a,b]
[a,c]
[b,a]
...
And so on. Perhaps there is a magical prolog one-liner that does this. If so, I would love to hear it.
However, my question is less about solving this particular problem and more of a request that someone explain some subtleties of Prolog's search algorithm for me.
So here's what I did first to solve the above problem:
members([], _).
members([X|Xs], List) :-
member(X,List),
members(Xs, List).
This works great but returns all possible results, and not in a great order:
[]
[a]
[a,a]
[a,a,a]
Okay, that's no problem. I really just want all combinations up to a certain length. So I decided to first get the ones that have exactly a particular length:
membersWithLength(Members, List, Bound) :-
L = Bound,
length(Members, L), members(Members, List).
This works great, e.g. for length 2:
[a,a]
[a,b]
[a,c]
...
And so on. Now my attempt to use clpfd to leverage the above function to get all lists up to a certain length went awry:
:- use_module(library(clpfd)).
membersLessThan(Members, List, Bound) :-
L in 0..Bound, % I also tried L #=< Bound
membersWithLength(Members, List, L).
Kind of works. Finds the right results (lists with length less than Bound).
But after it finds them, it loops continuously searching for more results. E.g. for length 2:
[]
[a]
[b]
[c]
[a,a]
[a,b]
...
[c,c]
Hangs looking for more solutions.
I guess this is the heart of my question. Can someone explain why (according to the trace) prolog continues to check larger and larger lists as possible solutions, even though they are all doomed to failure? And can someone tell me if there's a way to help prolog avoid this doomed journey?
I ultimately used the following code to solve the problem, but I was disappointed that I couldn't figure out how to use clpfd's integer constraints to constrain the size of the lists.
membersLessThan_(Members, List, Bound) :-
numlist(0,Bound,ZeroToBound),
member(L, ZeroToBound),
membersWithLength(Members, List, L).
Here is all the relevant code on SWISH: http://swish.swi-prolog.org/p/allcombos.pl
With you original implementation of members, if you want to enumerate all the answers you can do:
length(L, _), members(L, [a,b,c]).
which gives you the answers:
L = [] ;
L = [a] ;
L = [b] ;
L = [c] ;
L = [a, a] ;
L = [a, b] ;
L = [a, c] ;
L = [b, a] ;
L = [b, b] ;
L = [b, c] ;
L = [c, a] ;
L = [c, b] ;
L = [c, c] ;
L = [a, a, a] ;
L = [a, a, b] ;
L = [a, a, c] ;
L = [a, b, a]
This is a common idiom for iterative deepening, which allows you to list all the answers fairly. I don't think clpfd can help you in this case.
EDIT
I see that in the title you explicitly ask about CLPFD. The reason your code doesn't work is that when you do
L in 0..Bound
you are not actually enumerating those values. For the next predicates, L is still unbound and carries a constraint. So membersWithLength will keep looping trying new lengths, and once the length it's instantiated, it will see that the constraint fails and try again. You can see it in these examples:
L in 0..2, length(X, L)
loops like in your code, because length keeps trying. If you want to limit it, L has to be instantiated before calling length. You can use label for that. This next example doesn't loop:
L in 0..2, label([L]), length(X, L)
i encounter a problem with facts. Let's say i got 3 facts and check(X) question.
fact(a,b).
fact(b,c).
fact(a,d).
check(X):-
//some calculation with fact()
How to make above question to return list of elements for given X from all facts?
For instance: check(a) would give result b and d. So i can use this const later.
check(b) would return c. I would be grateful for help!
You need an extra argument for the list. So you cannot call it check/1 having a single argument, but — let's say — related_to/2.
related_to(X, Ys) :-
setof(Y, fact(X, Y), Ys).
Sample queries:
?- related_to(a, Xs).
Xs = [b, d].
?- related_to(b, Xs).
Xs = [c].
?- related_to(d, Xs).
false.
?- related_to(X, Xs).
X = a, Xs = [b,d]
; X = b, Xs = [c].
Note that the relation will fail for inexistent nodes like d above. On the other hand, you can even ask the most general goal getting all possible answers at once.
Also note that this relation is not monotone: If you add further facts, previously obtained results no longer hold. Like by adding fact(a,f) the goal related_to(a, [b,d]) no longer holds. Instead related_to(a,[b,d,f]) now holds.
I have to define some more constraints for my list.
I want to split my list is separate lists.
Example:
List=[[1,1],[_,0],[_,0],[_,0],[3,1],[_,0],[9,1],[2,0],[4,0]]
I need three Lists which i get from the main list:
[[_,0],[_,0],[_,0]] and [[_,0]] and [[2,0],[4,0]]
SO I always need a group of lists between a term with [X,1].
It would be great if u could give me a tip. Don’t want the solution, only a tip how to solve this.
Jörg
This implementation tries to preserve logical-purity without restricting the list items to be [_,_], like
#false's answer does.
I can see that imposing above restriction does make a lot of sense... still I would like to lift it---and attack the more general problem.
The following is based on if_/3, splitlistIf/3 and reified predicate, marker_truth/2.
marker_truth(M,T) reifies the "marker"-ness of M into the truth value T (true or false).
is_marker([_,1]). % non-reified
marker_truth([_,1],true). % reified: variant #1
marker_truth(Xs,false) :-
dif(Xs,[_,1]).
Easy enough! Let's try splitlistIf/3 and marker_truth/2 together in a query:
?- Ls=[[1,1],[_,0],[_,0],[_,0],[3,1],[_,0],[9,1],[2,0],[4,0]],
splitlistIf(marker_truth,Ls,Pss).
Ls = [[1,1],[_A,0],[_B,0],[_C,0],[3,1],[_D,0],[9,1],[2,0],[4,0]],
Pss = [ [[_A,0],[_B,0],[_C,0]], [[_D,0]], [[2,0],[4,0]]] ? ; % OK
Ls = [[1,1],[_A,0],[_B,0],[_C,0],[3,1],[_D,0],[9,1],[2,0],[4,0]],
Pss = [ [[_A,0],[_B,0],[_C,0]], [[_D,0],[9,1],[2,0],[4,0]]],
prolog:dif([9,1],[_E,1]) ? ; % BAD
%% query aborted (6 other BAD answers omitted)
D'oh!
The second answer shown above is certainly not what we wanted.
Clearly, splitlistIf/3 should have split Ls at that point,
as the goal is_marker([9,1]) succeeds. It didn't. Instead, we got an answer with a frozen dif/2 goal that will never be woken up, because it is waiting for the instantiation of the anonymous variable _E.
Guess who's to blame! The second clause of marker_truth/2:
marker_truth(Xs,false) :- dif(Xs,[_,1]). % BAD
What can we do about it? Use our own inequality predicate that doesn't freeze on a variable which will never be instantiated:
marker_truth(Xs,Truth) :- % variant #2
freeze(Xs, marker_truth__1(Xs,Truth)).
marker_truth__1(Xs,Truth) :-
( Xs = [_|Xs0]
-> freeze(Xs0, marker_truth__2(Xs0,Truth))
; Truth = false
).
marker_truth__2(Xs,Truth) :-
( Xs = [X|Xs0]
-> when((nonvar(X);nonvar(Xs0)), marker_truth__3(X,Xs0,Truth))
; Truth = false
).
marker_truth__3(X,Xs0,Truth) :- % X or Xs0 have become nonvar
( nonvar(X)
-> ( X == 1
-> freeze(Xs0,(Xs0 == [] -> Truth = true ; Truth = false))
; Truth = false
)
; Xs0 == []
-> freeze(X,(X == 1 -> Truth = true ; Truth = false))
; Truth = false
).
All this code, for expressing the safe logical negation of is_marker([_,1])? UGLY!
Let's see if it (at least) helped above query (the one which gave so many useless answers)!
?- Ls=[[1,1],[_,0],[_,0],[_,0],[3,1],[_,0],[9,1],[2,0],[4,0]],
splitlistIf(marker_truth,Ls,Pss).
Ls = [[1,1],[_A,0],[_B,0],[_C,0],[3,1],[_D,0],[9,1],[2,0],[4,0]],
Pss = [[ [_A,0],[_B,0],[_C,0]], [[_D,0]], [[2,0],[4,0]]] ? ;
no
It works! When considering the coding effort required, however, it is clear that either a code generation scheme or a
variant of dif/2 (which shows above behaviour) will have to be devised.
Edit 2015-05-25
Above implementation marker_truth/2 somewhat works, but leaves a lot to be desired. Consider:
?- marker_truth(M,Truth). % most general use
freeze(M, marker_truth__1(M, Truth)).
This answer is not what we would like to get. To see why not, let's look at the answers of a comparable use of integer_truth/2:
?- integer_truth(I,Truth). % most general use
Truth = true, freeze(I, integer(I)) ;
Truth = false, freeze(I, \+integer(I)).
Two answers in the most general case---that's how a reified predicate should behave like!
Let's recode marker_truth/2 accordingly:
marker_truth(Xs,Truth) :- subsumes_term([_,1],Xs), !, Truth = true.
marker_truth(Xs,Truth) :- Xs \= [_,1], !, Truth = false.
marker_truth([_,1],true).
marker_truth(Xs ,false) :- nonMarker__1(Xs).
nonMarker__1(T) :- var(T), !, freeze(T,nonMarker__1(T)).
nonMarker__1(T) :- T = [_|Arg], !, nonMarker__2(Arg).
nonMarker__1(_).
nonMarker__2(T) :- var(T), !, freeze(T,nonMarker__2(T)).
nonMarker__2(T) :- T = [_|_], !, dif(T,[1]).
nonMarker__2(_).
Let's re-run above query with the new implementation of marker_truth/2:
?- marker_truth(M,Truth). % most general use
Truth = true, M = [_A,1] ;
Truth = false, freeze(M, nonMarker__1(M)).
It is not clear what you mean by a "group of lists". In your example you start with [1,1] which fits your criterion of [_,1]. So shouldn't there be an empty list in the beginning? Or maybe you meant that it all starts with such a marker?
And what if there are further markers around?
First you need to define the criterion for a marker element. This for both cases: When it applies and when it does not apply and thus this is an element in between.
marker([_,1]).
nonmarker([_,C]) :-
dif(1, C).
Note that with these predicates we imply that every element has to be [_,_]. You did not state it, but it does make sense.
split(Xs, As, Bs, Cs) :-
phrase(three_seqs(As, Bs, Cs), Xs).
marker -->
[E],
{marker(E)}.
three_seqs(As, Bs, Cs) -->
marker,
all_seq(nonmarker, As),
marker,
all_seq(nonmarker, Bs),
marker,
all_seq(nonmarker, Cs).
For a definition of all_seq//2 see this
In place of marker, one could write all_seq(marker,[_])
You can use a predicate like append/3. For example, to split a list on the first occurence of the atom x in it, you would say:
?- L = [a,b,c,d,x,e,f,g,x,h,i,j], once(append(Before, [x|After], L)).
L = [a, b, c, d, x, e, f, g, x|...],
Before = [a, b, c, d],
After = [e, f, g, x, h, i, j].
As #false has pointed out, putting an extra requirement might change your result, but this is what is nice about using append/3:
"Split the list on x so that the second part starts with h:
?- L = [a,b,c,d,x,e,f,g,x,h,i,j], After = [h|_], append(Before, [x|After], L).
L = [a, b, c, d, x, e, f, g, x|...],
After = [h, i, j],
Before = [a, b, c, d, x, e, f, g].
This is just the tip.