먼저 더 의미있는 이름 지정 규칙을 사용하는 것이 좋습니다 : 나는 목록을 나타내는 변수의 이름에 "S"를 추가하고 (0부터 시작)보다 체계적를 번호,보다 선언적를 사용하는 것이 좋습니다를 의미있는 술어 이름 :
with_distinct_integers(E0, E) :-
term_variables(E0, Vs),
with_distinct_integers(E0, Vs, [0,1,2,3,4,5,6,7,8,9], E).
with_distinct_integers(E, [], [], E).
with_distinct_integers(E, [], _, E).
with_distinct_integers(E0, Vs0, Ns0, E) :-
select(Num, Ns0, Ns),
select(Var, Vs0, Vs),
Var is Num,
with_distinct_integers(E0, Vs, Ns, E).
이제 with_distinct_integers/4
에 초점을 맞추십시오. 첫 번째 절이 두 번째 절에 포함되어 있으므로 솔루션을 잃지 않고 첫 번째 절을 생략 할 수 있습니다. 변수 Var
는 Num
그것을 통합하는 데 사용됩니다, 그래서 당신은 바로 하나의 변수 사용할 수 있습니다 : 당신은 여전히이 단순화 된 버전으로 의도하지 않은 중복 솔루션을 찾을 수
with_distinct_integers(E, [], _, E).
with_distinct_integers(E0, Vs0, Ns0, E) :-
select(Num, Ns0, Ns),
select(Num, Vs0, Vs),
with_distinct_integers(E0, Vs, Ns, E).
을, 내가 찾을 수있는 쉬운 운동으로 떠나
?- with_distinct_integers(X-Y, [X,Y], [0,1], A).
..., A = 0-1 ;
..., A = 1-0 ;
..., A = 1-0 ;
..., A = 0-1 ;
false.
힌트 : 선언적으로 단순화 된 정의를 통해 그냥 이유 무슨 일이 원인이 부족합니다. 단순화로 계속하기 : 필요한 변수, 즉 변수가 모두 필요한 경우 원래 용어를 그대로 사용해야하는 이유는 무엇입니까? 고려 :
with_distinct_integers(E) :-
term_variables(E, Vs),
numlist(0, 9, Ns),
with_distinct_integers(Vs, Ns).
with_distinct_integers([], _).
with_distinct_integers([V|Vs], Ns0) :-
select(V, Ns0, Ns),
with_distinct_integers(Vs, Ns).
예 쿼리를 모든 솔루션을 계산 :
?- findall(., with_distinct_integers([X-Y]), Ls), length(Ls, L).
Ls = ['.', '.', '.', '.', '.', '.', '.', '.', '.'|...],
L = 90.
서프라이즈를 측면에 : 만 90 솔루션,하지 (99)이있다.
또한 당신이 쉽게 작업을 공식화하자 정수 이상의 관계입니다 유한 도메인 제약 조건, 사용을 고려 :
:- use_module(library(clpfd)).
with_distinct_integers(E) :-
term_variables(E, Vs),
Vs ins 0..9,
all_different(Vs),
label(Vs).
예 쿼리를 다음 그 아주 특별한 경우를
?- with_distinct_integers(X-Y).
X = 0,
Y = 1 ;
X = 0,
Y = 2 ;
X = 0,
Y = 3 .
위대한 anwser, cplfd를 사용하지 않는 설명 주셔서 감사합니다. – vvondra