I'm trying to solve this question for my assignment.
The predicate acceptable_permutation(L,R) should succeed only if R represents an acceptable permutation of the list L. For example: [2,1,3] is not an acceptable permutation of the list [1,2,3] because 3 did not change its position.
The outputs are supposed to be like this:
?- acceptable_permutation([1,2,3],R).
R = [2,3,1] ;
R = [3,1,2] ;
false
?- acceptable_permutation([1,2,3,4],R).
R = [2,1,4,3] ;
R = [2,3,4,1] ;
R = [2,4,1,3] ;
R = [3,1,4,2] ;
R = [3,4,1,2] ;
R = [3,4,2,1] ;
R = [4,1,2,3] ;
R = [4,3,1,2] ;
R = [4,3,2,1] ;
false.
My outputs of my code however gives:
?- acceptable_permutation([1,2,3],R).
R = [1,2,3] ;
R = [1,3,2] ;
R = [2,1,3] ;
R = [2,3,1] ;
R = [3,1,2] ;
R = [3,2,1] ;
?- acceptable_permutation([1,2,3,4],R).
R = [1,2,3,4] ;
R = [1,2,4,3] ;
R = [1,3,2,4] ;
R = [1,3,4,2] ;
R = [1,4,2,3] ;
R = [1,4,3,2] ;
R = [2,1,3,4] ;
R = [2,1,4,3] ;
R = [2,3,1,4] ;
R = [2,3,4,1] ;
R = [2,4,1,3] ;
R = [2,4,3,1] ;
R = [3,1,2,4] ;
R = [3,1,4,2] ;
R = [3,2,1,4] ;
R = [3,2,4,1] ;
R = [3,4,1,2] ;
R = [3,4,2,1] ;
R = [4,1,2,3] ;
R = [4,1,3,2] ;
R = [4,2,1,3] ;
R = [4,2,3,1] ;
R = [4,3,1,2] ;
R = [4,3,2,1] ;
false.
My code is the following:
acceptable_permutation(list,list).
del(symbol,list,list).
del(X,[X|L1], L1).
del(X,[Y|L1], [Y|L2]):-
del(X,L1, L2).
acceptable_permutation([] , []).
acceptable_permutation(L, [X|P]):-
del(X, L, L1),
acceptable_permutation(L1, P).
Please tell me where exactly the problem is, so that my outputs should match the correct outputs. I would appreciate a lot if you show me how exactly it is done.
The problem is that you don't check that all the elements of the output list are in a different position than the input list. You should add a predicate to check this, like that:
perm(L,LO):-
acceptable_permutation(L,LO),
different_place(L,LO).
different_place([A|T0],[B|T1]):-
A \= B,
different_place(T0,T1).
different_place([],[]).
?- perm([1,2,3],R).
R = [2, 3, 1]
R = [3, 1, 2]
false
Improvement 1: instead of creating your own predicate (in this case, different_place/2
), you can use maplist/3
with \=/2
in this way:
perm(L,LO):-
acceptable_permutation(L,LO),
maplist(\=,L,LO).
Improvement 2: swi prolog offers the predicate permutation/2
that computes the permutations of a list. So you can solve your problem with only three lines:
find_perm(L,LO):-
permutation(L,LO),
maplist(\=,L,LO).
?- find_perm([1,2,3],L).
L = [2, 3, 1]
L = [3, 1, 2]
false