I need to find the combinations in a list of lists.
For example give the following list,
List = [[1, 2], [1, 2, 3]]
These should be the output,
Comb = [[1,1],[1,2],[1,3],[2,1],[2,2],[2,3]]
Another example:
List = [[1,2],[1,2],[1,2,3]]
Comb = [[1,1,1],[1,1,2],[1,1,3],[1,2,1],[1,2,2],[1,2,3]....etc]
I know how to do it for a list with two sublists but it needs to work for any number of sublists.
I'm new to prolog, please help.
try([],[]).
try([L|Ls],[M|Ms]):-
member(M,L),
try(Ls,Ms).
all(L,All) :- findall(M, try(L,M), All).
try returns one list composed of elements of the sublists of the first argument. all finds all such lists.
Here is your answer, cut and dry, as a fellow new prolog programmer myself.
%elementInList(input list, output answer)
answer(ListOfList, AnswerInList) :-
findall(Ans, combList(ListOfList, Ans), AnswerInList).
%combList(ListOfList, Comb) :-
combList([], []).
combList([Head|Tail], Comb) :-
combList(Tail, [Element|Tempcomb]),
elementInList(Head, Element).
%elementInList(List, Element)
elementInList([Head|_], Head).
elementInList([Head|Tail], Element) :-
elementInList(Tail, Element).
Using the definition answer(InputList, OutputResult), where e.g.
answer([[1,2],[7,8]],Comb).
Comb = [[1, 7], [2, 7], [1, 8], [2, 8]].
and e.g.
answer([[1,2],[2,8],[3,6,9]],Comb).
Comb = [[1, 2, 3], [2, 2, 3], [1, 8, 3], [2, 8, 3], [1, 2, 6], [2, 2, 6], [1, 8|...], [2|...], [...|...]|...].
and so on [X,Y,Z,..] for any number of sublists. You're welcome.
Related
My problem is that I have a functor with the next structure:
something(Perms, New_perms) :-
bagof(New_perm, aux_something(Perms, New_perm), <New_perms>).
aux_something(Perms, New_perm) :-
member(Perm, Perms),
take_impossible(Perm, New_perms).
take_impossible(Perm_poss, New_perm) :-
Perm_poss = [Var, Perm],
bagof(P, member(P, Perm), subsumes_term(Var, P)), New_perms),
New_perm = [Var, New_perms].
This takes a list of elements of the form:
[[A, 2, C], [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]]
It returns the list of possible permutations:
[[A, 2, C], [[1, 2, 3], [3, 2, 1]]]
But with the list containing an impossible element:
[[A, 4, C], [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]]
The functor should return false.
I need that, when it takes an element of the list which has no possible permutations, the list returns false. A forall instead of the bagof doesn't work because it doesn't change any variable bindings, and a forall before the bagof is too expensive, as I am doing the same operation to all elements of the list twice (it exceeds the limit time in the test). How can I break the execution of a bagof if the condition fails, or is there any other predicate that can do what I am looking for?
(Functor and aux_functor are not the real names of the variables, but this is college work, and so I am trying not to give too much info).
Stupid, question when I found the answer...
A bagof that fails when its objective fails is just a maplist.
Thanks for the help, anyway.
In this case, the correct answer would be:
something(Perms, New_perms) :-
maplist(take_impossible, Perms, New_perms).
take_impossible(Perm_poss, New_perm) :-
Perm_poss = [Var, Perm],
bagof(P, member(P, Perm), subsumes_term(Var, P)), New_perms),
New_perm = [Var, New_perms].
I am generating permutations:
takeout(X,[X|T],T).
takeout(X,[F|R],[F|S]):-
takeout(X,R,S).
perm([],[]).
perm([X|Y],Z):-
perm(Y,W),
takeout(X,Z,W).
I want to know how to create a list of all the permutations without using findall.
Example:
?-perm([1,2,3],List).
List = [[1, 2, 3], [2, 1, 3], [2, 3, 1], [1, 3, 2], [3, 1, 2], [3, 2, 1]]
Group permutations by the element it starts with.
Take an element X and create permutations Ys1 without it in the original list.
Adding this element X as the first element of all these permutations we have the list XP of permutations starting with X.
Appending all the groups will give you all permutations.
cons(X, Xs, [X|Xs]).
perm([], [[]]).
perm(Xs, Ys) :-
dif(Xs, []),
maplist({Xs}/[X, XP]>>(select(X, Xs, Xs1),
perm(Xs1, Ys1),
maplist(cons(X), Ys1, XP)),
Xs, Yss),
append(Yss, Ys).
?- perm([1, 2, 3], X).
X = [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]] ;
false.
?- length(Y, 8), perm(Y, X), length(X, N). %8 factorial
N = 40320
The idea is to generate permutations and test if you already created this permutation. I'm using the inbuild predicate permutation/2.
perm(Ori,Out):-
perm(Ori,[],Out).
perm(Ori,Acc,Ret):-
permutation(Ori,Perm),
\+ member(Perm,Acc),
!,
perm(Ori,[Perm|Acc],Ret).
perm(_,L,L).
?- perm([1,2,3],E).
E = [[3, 2, 1], [3, 1, 2], [2, 3, 1], [2, 1, 3], [1, 3, 2], [1, 2, 3]].
The code is not the fastest one since it checks multiple times for membership.
I am trying to solve a maze in Prolog using backtracking.
My problem is that when I run the program, it runs correctly for the first time, but after that it takes the end position as the starting position and keeps finding paths from there, hence goes into endless loop. It works correctly when path doesn't exist between 2 positions. I have tried lots of things but nothing seems to be working. Here's my code:
path(Dest, Dest, _, [], _) :- !.
path([Row0,Col0],[Row1,Col1],M,Path,1) :-
next_move([Row0,Col0],[Rnew,Cnew]),
is_available(Rnew, Cnew,Ret),
write(Rnew),
write(Cnew),
not(member([Rnew, Cnew], M)),
path([Rnew, Cnew], [Row1, Col1], [[Rnew,Cnew]|M], Path, Ret).
path([X0,Y0], [X1,Y1], [[X0,Y0]|M], [[X,Y]|Path], 0) :-
path([X,Y],[X1,Y1],M,Path,1).
Sample output:
?- solves([1,1],[1,7],P).
P = [[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7]] ;
P = [[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [2, 6], [2, 7], [2|...],
[...|...]|...] ;
P = [[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [2, 6], [2, 7], [2|...],
[...|...]|...] ;
P = [[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [2, 6], [2, 7], [2|...],
[...|...]|...] .
When executing the program, it should display all the paths if a path exists between 2 positions. It should return false otherwise. As you can see above, my code goes into infinite loop and keep generating paths.
Please help as I am not very experienced in Prolog.
Thanks.
The first clause of the path/5 predicate and the recursive call in its second clause are wrong. It should be:
path(Dest, Dest, _, [], _) :- !.
path([Row0,Col0],[Row1,Col1],M,[[Rnew,Cnew]|Path],1) :-
next_move([Row0,Col0],[Rnew,Cnew]),
is_available(Rnew, Cnew,Ret),
write(Rnew),
write(Cnew),
\+ member([Rnew, Cnew], M),
path([Rnew, Cnew], [Row1, Col1], [[Rnew,Cnew]|M], Path, Ret).
Also, use the ISO Prolog standard \+/1 predicate instead of the not/1 legacy predicate.
Ha there's a fair amount of irony here that I even saw this post - you are on the PPL course? :)
Generally returning a value of 0 or 1 to say whether a statement is true or false is not necessary in prolog - it is implicit in whether the predicate has passed.
For example
is_available(Rnew, Cnew,Ret) would be better written as is_available(Rnew, Cnew) - if is_available resolves as false then it would already STOP and begin to backtrack to look for other solutions along its alternate lines if there was no alternative.
Furthermore this will mean that if there is no solution, a value of 'false' would be printed when you try to evaluate the maze.
On your output issues - actually that is not 'broken'; it is just suppressed output!
Try running this in your swi terminal before you run the maze solving expression:
set_prolog_flag(answer_write_options,[max_depth(0)]).
as per SWI-Prolog how to show entire answer (list)?
I want to sort the sublists of a list which contains integers eliminating the duplicates. Example:
[1, 2, [4, 1, 4], 3, 6, [7, 10, 1, 3, 9], 5, [1, 1, 1], 7]
=>>>
[1, 2, [1, 4], 3, 6, [1, 3, 7, 9, 10], 5, [1], 7].
I know that i have to work with functor s(but i didn't really get it).
Here is my code : (the (insert+sorting) function works in a simple list of integers,but don't work here. i'm getting red false everytime)
insert(E,[],[E]).
insert(E,[H|T],[H|L]):-
E>H,
insert(E,T,L).
insert(E,[H|T],[H|T]):-
E=H,
!.
insert(E,[H|T],[E|[H|T]]):-
E<H,
!.
sort([],[]).
sort([i(H)|T],L):-
sort(T,L1),
insert(i(H),L1,L).
You could try a solution like this, it uses the the sort/2 predicate to sort sublists:
sort_sublists([], []).
sort_sublists([X|Xs], List) :-
(integer(X) ->
List = [X | List1]
;
sort(X, Sorted),
List = [Sorted | List1]
),
sort_sublists(Xs, List1).
Example call:
?- set_prolog_flag(answer_write_options,[max_depth(0)]).
true.
?- sort_sublists([1, 2, [4, 1, 4], 3, 6, [7, 10, 1, 3, 9], 5, [1, 1, 1], 7], X).
X = [1,2,[1,4],3,6,[1,3,7,9,10],5,[1],7].
#Eduard Adrian it's hard to answer in comments, so first thing you need to do is to remove duplicates from the nested lists.
Here i tried that and you can see different cases that you need to handle. One example:(Head of your list can be a list but it's tail will be empty this happends if last element of your list is a list) in that case you need to define another predicate which will match your recursive call.
Once you have removed duplicates you can use simple sorting algorithm but you have to check if the head is a list then you sort innner list first and place it to the same place otherwise call sort predicate.
As you asked how check if an element is_list or integer, for that you can always use built-in because those predicates you can't write by yourself.
Let us consider lists such as L=[[7,3,4],9,[4,5],[1,3,5],4] where components could be lists or atoms. How to produce this type of permutation results:
R = [[7, 3, 4], 9, [4, 5], [1, 3, 5], 4]
R = [[7, 4, 3], 9, [5, 4], [1, 3, 5], 4]
R = [[7, 4, 3], 9, [4, 5], [1, 5, 3], 4]
....
In fact, we would like to have all the possible permutations of the sub-lists of L while the atom should remain unchanged.
I wrote a classical predicate permutation(OriginalList,PermutedList), and an allperm predicate that apply the maplist function to this permutation predicate:
permutation([],[]).
permutation(L,[T|Q]) :-
select(T,L,L1),
permutation(L1,Q).
/*L is the list to permute, R the result*/
allperm(L,R) :-
maplist(permutation,L,R).
It functions only in the special case where L is composed of lists and doesn't function when L is heterogeneous (atoms and lists).
Could you provide hints or elements of solution to do the right permutation?
The following modification should do:
permutation(X,X).
permutation(L,[T|Q]) :-
dif(L,[T|Q]),
select(T,L,L1),
permutation(L1,Q).
allperm(L,R) :-
maplist(permutation,L,R).
We extend the “identity” permutation to any Prolog term (first clause of permutation) and disallow it in the second clause (which can only be applied to lists anyway).