我使用GNU Prolog,并被告知这可以通过有限域解算器解决,或只是member/2
和is/2
。我只能想出两者一起使用,但它不起作用。以下是我到目前为止的情况:
unique([],N,0).
unique([H|T],N,N1) :-
length([H|T],N1),
N2 is N1-1,
unique(T,N,N2),
H #> 0,
H #=< N.
\+ member(H,T).
当我使用unique(X,3,3)
调试trace
时,我可以看到,当它调用member/2
时,它会比较2个域,1..3
和{{1}并且成功,它不应该。有人可以帮忙吗?
答案 0 :(得分:2)
很抱歉,此解决方案不使用FD或member/2
。 ;)
使用prior solution来生成从1到N的整数列表的问题:
n_ups(N, Xs) :-
length(Xs, N),
numbered_from(Xs, 1).
numbered_from([], _).
numbered_from([I0|Is], I0) :-
I1 is I0+1,
numbered_from(Is, I1).
然后,您可以使用GNU内置置换谓词:
unique(N, P) :-
n_ups(N, L),
permutation(L, P).
unique(3, L)
的结果:
| ?- unique(3, L).
L = [1,2,3] ? a
L = [1,3,2]
L = [2,1,3]
L = [2,3,1]
L = [3,1,2]
L = [3,2,1]
no
| ?-
如果你想推出自己的排列,那么:
perm([], []).
perm(List, [H|Perm]) :-
select(H, List, Rest),
perm(Rest, Perm).