Related
solution([ ], List, List).
solution([Head|Tail], List,[Head|Result]):-
solution(Tail, List,Result).
expected output
| ?- Solution(X,Y,[a,b,c]).
X = [a,b,c]
Y = [] ? ;
X = [a,b]
Y = [c] ? ;
X = [a,c]
Y = [b] ? ;
X = [a]
Y = [b,c] ? ;
X = [b,c]
Y = [a] ? ;
X = [b]
Y = [a,c] ? ;
X = [c]
Y = [a,b] ? ;
X = []
Y = [a,b,c] ? ;
actual output
X = []
Y = [a,b,c] ? ;
X = [a]
Y = [b,c] ? ;
X = [a,b]
Y = [c] ? ;
X = [a,b,c]
Y = [] ? ;
It is not going through all the possible solutions that can be made from the predicate defined. i am expecting the output to be as shown above containing all the solutions of combining 2 lists together
Any help?
Your predicate is missing some clauses. The first clause says that if the first list is exhausted, then the result is the second list.
The second clause specifies that if the first list is not exhausted, we simply take the first element of that list as a result. This thus means that you basically implemented an append/3 predicate [swi-doc].
Based on your sample output, there is however a decision whether to take from the first list, or the second list. We thus should implement a clause like:
solution([H1|T1], L2, [H1|R]) :-
solution(T1, L2, R).
solution(L1, [H1|T2], [H1|R]) :-
solution(L1, T2, R).
If both lists are exhausted, we can return an empty list, so we can define a base-clause like:
solution([], [], []).
and thus obtain as full solution:
solution([], [], []).
solution([H1|T1], L2, [H1|R]) :-
solution(T1, L2, R).
solution(L1, [H1|T2], [H1|R]) :-
solution(L1, T2, R).
This then gives us:
?- solution(X,Y,[a,b,c]).
X = [a, b, c],
Y = [] ;
X = [a, b],
Y = [c] ;
X = [a, c],
Y = [b] ;
X = [a],
Y = [b, c] ;
X = [b, c],
Y = [a] ;
X = [b],
Y = [a, c] ;
X = [c],
Y = [a, b] ;
X = [],
Y = [a, b, c].
Hello I wish some advice or words about this task:
Define a statement with three parameters where the first one is a list, the second one is an element (atom or list) and the last one is a list which must accomplish it is equal to the first but first's list' elements which match second parameter,are gone.
Examples:
> elimina([f, e, d, [a, h], a, d, a], a, L)
L = [f, e, d, [a, h], d]
> elimina([f, e, d, [ a, h], a, [d, a]], [a, h], L)
L = [f, e, d, a, [d, a]]
I tried:
elimina([],_,[]).
elimina([X],X,[]).
elimina([X],Y,[X]).
elimina([H|T],H,Result) :-
elimina([T],H,Result).
elimina([H|T],Y,Result):-
elimina([T],H,Result).
I have the doubt about what to write when I shout the recursive call:
elimina([T],H,Result).
Because first I don't know how differently should be the behave when the input second element matchs the head rather than don't matching the head; so I put the same call.
Also I doubt because: Is really needed to put the base case: elimina([X],Y,[X]).? I thought we could pass the exercise with just matching the element to delete with the ones which are really into the list.
Thank you for your time.
There is a very general method how you can test your own code in Prolog. Simply ask Prolog to generate via the most general question all possibilities.
?- elimina([], D, Ys).
Ys = []. % 1: nice!
?- elimina([X], D, Ys).
D = X, Ys = [] % 1: nice!
; Ys = [X] % 2: lacks dif(X, D)
; X = [], D = [], Ys = [] % 3: correct but subsumed by 1
; D = X, Ys = [[]] % 4: incorrect
; X = [], D = [], Ys = [] % 5: correct but subsumed by 1
; X = [], D = [], Ys = [[]] % 6: incorrect
; X = [], D = [], Ys = [] % 7: correct but subsumed by 1
; ... .
For the empty list everything is fine. But for the one-element list, there are many superfluous answers! Actually, there should only be two answers:
D = X, Ys = []
; dif(D, X), Ys = [X].
So now pick some case you want to improve!
Maybe take answer #4 and set D = a, X = a:
?- elimina([a], a, Ys).
Ys = [] % 1: nice
; Ys = [a] % 2: incorrect
; Ys = [[]] % 3: incorrect
; Ys = [] % 4: correct but subsumed by 1
; Ys = [[]] % 5: incorrect and subsumed by 3
; Ys = [] % 6: correct but subsumed by 1
; ... .
So I will pick #3 which actually should fail, but does not
?- elimina([a],a,[[]]).
true
; true
; ... .
Narrow down the culprit by inserting false and some extra equations:
?- elimina([a],a,[[]]).
false.
elimina([],_,[]) :- false.
elimina([X],X,[]) :- false.
elimina([X],Y,[X]) :- Y = a, X = [].
elimina([H|T],H,Result) :- false,
elimina([T],H,Result).
elimina([H|T],Y,Result):- Result = [[]],
elimina([T],H,Result).
Now look at what is left and think about it. Should these remaining rules really hold?
In the remaining visible part there must be an error!
When describing lists, it's usually worthwhile to consider using DCGs for the task. You could describe the relation like so:
elimina(L1,X,L2) :- % L2 is described by
phrase(elimina_x(L1,X),L2). % elimina_x//2
elimina_x([],_X) --> % nothing to delete
[]. % from the empty list
elimina_x([X|Xs],X) --> % if the head of the list equals X
elimina_x(Xs,X). % it's not in the list, same for the tail
elimina_x([X|Xs],Y) --> % if the head of the list
{dif(X,Y)}, % differs from Y
[X], % it is in the list
elimina_x(Xs,Y). % same for the tail
Your example queries yield the desired result.
?- elimina([f, e, d, [a, h], a, d, a], a, L).
L = [f,e,d,[a,h],d] ? ;
no
?- elimina([f, e, d, [ a, h], a, [d, a]], [a, h], L).
L = [f,e,d,a,[d,a]] ? ;
no
Alternatively, you can also express this relation more compactly, using if_/3, (=)/3 and tfilter/3:
dif_t(X,Y,T) :-
if_(X=Y,T=false,T=true).
elimina(L1,X,L2) :-
tfilter(dif_t(X),L1,L2).
The above queries yield the same answers with this version.
I'm trying to rewrite code from Haskell to Prolog.
count :: Eq a => a -> [a] -> Int
count x = length . filter (x==)
f :: [Integer] -> [Integer]
f [] = []
f list = filter (\x -> count x list == 1) list
This code return list that contains elements that appears only once in the list.
So if I have list [1,1,2,2,3,4,4,5] this function returns [3,5]
I tried to find filter construction in Prolog but seems there no such thing. How can I make similar function in Prolog ?
To the existing answers, I would like to add an answer that is quite general in the sense that you can use it in multiple directions.
Building block: list_element_number/3
I start with the following predicate, defining a relation between:
a list Ls0
an element E
the number N of occurrences of E in Ls0
Here it is:
list_element_number(Ls0, E, N) :-
tfilter(=(E), Ls0, Ls),
length(Ls, N).
This solution uses tfilter/3 from library(reif). The predicate subsumes the function count you have posted. The main benefit of this predicate over the function is that the predicate can be used not only in those cases that even Haskell can do easily, such as:
?- list_element_number([a,b,c], a, N).
N = 1.
No, we can use it also in other directions, such as:
?- list_element_number([a,b,c], X, 1).
X = a ;
X = b ;
X = c ;
false.
Or even:
?- list_element_number([a,b,E], X, 2).
E = X, X = a ;
E = X, X = b ;
false.
Or even:
?- list_element_number([A,B,C], X, 3).
A = B, B = C, C = X ;
false.
And even in the most general case, in which all arguments are fresh variables:
?- list_element_number(Ls, E, N).
Ls = [],
N = 0 ;
Ls = [E],
N = 1 ;
Ls = [E, E],
N = 2 ;
Ls = [E, E, E],
N = 3 .
We can fairly enumerate all answers like this:
?- length(Ls, _), list_element_number(Ls, E, N).
Ls = [],
N = 0 ;
Ls = [E],
N = 1 ;
Ls = [_160],
N = 0,
dif(E, _160) ;
Ls = [E, E],
N = 2 .
Main predicate: list_singletons/2
Using this building block, we can define list_singletons/2 as follows:
list_singletons(Ls, Singles) :-
tfilter(count_one(Ls), Ls, Singles).
count_one(Ls, E, T) :-
list_element_number(Ls, E, Num),
cond_t(Num=1, true, T).
This uses cond_t/3 and (again) tfilter/3 from library(reif).
Sample queries
Here are a few sample queries. First, the test case you have posted:
?- list_singletons([1,1,2,2,3,4,4,5], Singles).
Singles = [3, 5].
It works as desired.
Now a case involving variables:
?- list_singletons([A,B], Singles).
A = B,
Singles = [] ;
Singles = [A, B],
dif(A, B).
On backtracking, all possibilities are generated: Either A = B holds, and in that case, there is no element that occurs only once. Or A is different from B, and in that case both A and B occur exactly once.
As a special case of the above query, we can post:
?- list_singletons([A,A], Singles).
Singles = [].
And as a generalization, we can post:
?- length(Ls, _), list_singletons(Ls, Singles).
Ls = Singles, Singles = [] ;
Ls = Singles, Singles = [_7216] ;
Ls = [_7216, _7216],
Singles = [] ;
Ls = Singles, Singles = [_7828, _7834],
dif(_7828, _7834) ;
Ls = [_7216, _7216, _7216],
Singles = [] ;
Ls = [_7910, _7910, _7922],
Singles = [_7922],
dif(_7910, _7922) .
Enjoy the generality of this relation, obtained via logical-purity.
A more simple version :
filter_list(L,OutList):-findall(X, (select(X,L, L1),\+member(X, L1)) , OutList).
?- filter_list([1,1,2,2,3,4,4,5],L).
L = [3, 5].
Without findall, you can try
filter_list(In, Out) :- filter_list(In, _, Out).
filter_list([], [], []).
filter_list([H|T], L1, L2) :-
filter_list(T, LL1, LL2),
( member(H, LL1)
-> L1 = LL1, L2 = LL2
; (select(H, LL2, L2)
-> L1 = [H|LL1]
; L1 = LL1, L2 = [H|LL2])).
without counting...
filter_uniques([],[]).
filter_uniques([H|T],F) :-
delete(T,H,D),
( D=T -> F=[H|R],S=T ; F=R,S=D ),
filter_uniques(S,R).
a more direct rewrite of your code, with library(yall) support for inlining of the filter predicate (the first argument to include/3)
filt_uniq(L,F) :-
include({L}/[E]>>aggregate(count,member(E,L),1),L,F).
A simple version:
(see the comment by #false below, the version with findall/3 has some inconsistency problems in more complex queries but second version looks ok however it is definitely not so efficient ).
filter_list(L,OutList):-findall(X, (member(X,L),count(X,L,N),N=:=1) , OutList).
count(_,[],0).
count(X,[X|T],N):-count(X,T,N1),N is N1+1.
count(X,[X1|T],N):-dif(X,X1),count(X,T,N).
The predicate filter_list/2 uses findall/3 and simply states find all X that belong to the list L and count returns 1 and store them in OutList.
Example:
?- filter_list([1,1,2,2,3,4,4,5],L).
L = [3, 5].
You could write filter_list/2 without using findall/3 like:
filter_list(L,OutList):- filter_list(L,OutList,L).
filter_list([],[],_).
filter_list([H|T],[H|T1],L):-count(H,L,N), N=:=1, filter_list(T,T1,L).
filter_list([H|T],T1,L):-count(H,L,N), N > 1, filter_list(T,T1,L).
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 have a doubt about how work this query for this del/3 predicate:
/* BASE CASE: If I delete X from List and X is the HEAD of List, NewList is
the Tail of List
*/
del(X, [X|Tail], Tail).
/* GENERAL CASE: If the head of List is not X then the program have to delete
X in the Tail of List
*/
del(X, [Y|Tail], [Y|Tail1]) :- del(X, Tail, Tail1).
The predicate logic is very simple: delete X item form a list creating a new list without X: if X is in the head of the list the newlist is its tail. Otherwise, if the X item is not in the head of the list, try to find it (and delete) in the Tail creating a new tail Tail1.
Ok, so I have no problem with the predicate logic but I am having some problem trying to understand how work this query (I have to use it in another program):
del([Top1|Stack1], [[a,b,c],[],[]], Stacks1).
So this query have to delete [Top1|Stack1] from [[a,b,c],[],[]] that is a list of stacks (in this particular case I have 3 stacks: [a,b,c] and 2 empty stacks: []) generating so a new list of stacks named Stacks1
If I try to execute a trace of the query I obtain this:
[trace] ?- del([Top1|Stack1], [[a,b,c],[],[]], Stacks1).
Call: (7) del([_G389|_G390], [[a, b, c], [], []], _G412) ? creep
Exit: (7) del([a, b, c], [[a, b, c], [], []], [[], []]) ? creep
Top1 = a,
Stack1 = [b, c],
Stacks1 = [[], []] .
I have some difficulties to understand why: [Top1|Stack1] is unified with the first stack [a, b, c]
EDIT:
I think that maybe work in this way: The list of Stacks is: [[a,b,c],[],[]] that is a list of lists wherein the first list is: [a,b,c] (that is the head of this list of list**
So when I write: [Top1|Stack1] happens that:
Top1 = [a,b,c]
*Stack1 = [[],[]]*
So happens that Top1 is the first stack in the stacks list and Stack1 is the list of others stacks.
So when I write the predicate:
del([Top1|Stack1], Stacks, Stacks1).
(where, for example: Stacks = [[a,b,c],[],[]])
It work in this way:
It unifiest Top1 with the first stack in stack list: [a,b,c] and delete it from Stacks list...
My dount is related on Prolog semantic viz when I execute a simple query as:
del(b, [a,b,c], NewList).
it delete b item from the list and NewList=[a,c]
but when I have that the field of the item that have be delete is something like: [Head|Tail] is it the Head item that have be to deleted?
The query D=[[a,b,c],[],[]], del([A|B], D, C) picks any list matching [A|B] from among D's elements. The only possibility here is [A|B]=[a,b,c] and the leftovers are C=[[],[]].
In general del fully backtracks, finding all possibilities one by one. Here there is only one possibility.
To better understand del, try this:
2 ?- del(X,[A,B,C],D).
X = A,
D = [B, C] ;
X = B,
D = [A, C] ;
X = C,
D = [A, B] ;
false.
It isn't trying to "find" X; it's just picking it one by one from among the possibilities (the 2nd argument). That's what the predicate says that it is / does.
Of course if the lists are instantiated to ground terms, some might not match and will be rejected, creating an impression of a value being searched for:
4 ?- del(b, [a,b,c,d], R).
R = [a, c, d] ;
false.
5 ?- del(b, [a,b,X,d], R).
R = [a, X, d] ;
X = b,
R = [a, b, d] ;
false.
The term [A|B] just matches any non-empty list (or a logical variable):
6 ?- del([A|B], [[a],b,X,d], R).
A = a,
B = [],
R = [b, X, d] ;
X = [A|B],
R = [[a], b, d] ;
false.
7 ?- del([A|B], [[a],b,[],d], R).
A = a,
B = [],
R = [b, [], d] ;
false.
So e.g. del([A|B], [[1,2,3], [4,5], [], [6]], R) will pick any non-empty list from the 4 lists given in the 2nd argument of this sample call, and while it does that, it will bind A to the head element and B to the rest of elements of the list that was picked.
This predicate is known as select/3 in the wild. :)
Illustration:
del(X, [X|Tail], Tail).
X X
--------------------
T T
a a
i i
l l
del(X, [Y|Tail], [Y|Tail1]) :- del(X, Tail, Tail1).
Y Y
--------------------
T T
/ . a
X - . i
\ . l
. 1
l