: L의 변수에 제약 조건을 적용프롤로그 제약는 프로그래밍도 찾아 홀수 내가 술어 만들 필요가
applyConstraints(L)
을 같은 L에 두 개의 연속적인 요소는 모두 홀수 또는 내가 할 수있는 방법조차 없다는 것을 그? 고정 크기 L을 사용하면 간단하지만 가변 크기 L은 어떨까요? sicstus-prolog clpfd 라이브러리를 사용하여이 작업을 수행해야합니다.
: L의 변수에 제약 조건을 적용프롤로그 제약는 프로그래밍도 찾아 홀수 내가 술어 만들 필요가
applyConstraints(L)
을 같은 L에 두 개의 연속적인 요소는 모두 홀수 또는 내가 할 수있는 방법조차 없다는 것을 그? 고정 크기 L을 사용하면 간단하지만 가변 크기 L은 어떨까요? sicstus-prolog clpfd 라이브러리를 사용하여이 작업을 수행해야합니다.
@ MatsCarlsson의 버전에서 영감을 얻어 관련 제약 변수의 수를 최소화하려고 시도했습니다.
applyConstraints(Xs) :-
S #\= R,
applyConstraints(Xs, S, R).
applyConstraints([], _, _).
applyConstraints([X|Xs], S, R) :-
X mod 2 #= S,
applyConstraints(Xs, R, S).
편집 :이 버전은 목표가 applyConstraints([])
인데 쉽게 볼 수없는 결함이 있습니다. 사실, 하나는과 같이 SICStus에 full_answer
모드로 전환 할 필요가 :
| ?- applyConstraints([]).
yes
| ?- assertz(clpfd:full_answer).
yes
| ?- applyConstraints([]).
clpfd:(_A#\=_B),
_A in inf..sup,
_B in inf..sup ? ;
no
그래서 우리는 자원을 먹을 수있는 주위를 어슬렁이 쓸모없는 제약이있다. 이 결핍을 극복하기 위해, 특별한 케이스가 필요하다 :
applyConstraints([]).
applyConstraints([X|Xs]) :-
X mod 2 #= S,
S #\= R,
applyConstraints(Xs, R, S).
주 1 — YAP SWI 또는에서 전체 응답 모드를 전환하는 직접적인 방법이 없습니다. 문제의 보류를 얻을 수있는 유일한 방법과 같이 call_residue_vars/2
주위에 쿼리를 래핑하는 것입니다 :
?- applyConstraints([]).
true.
?- call_residue_vars(applyConstraints([]),RVs).
RVs = [_G794, _G797],
_G794#\=_G797.
주에게 @mat 2 개 — 감사, SWI 7.3 이후 비슷한 기능이있다 (기억이 SWI 7 필요 --traditional
호환성) :
?- set_prolog_flag(toplevel_residue_vars, true).
true.
?- applyConstraints([]).
% with detached residual goals
_G430#\=_G433.
("분리 된"은 이러한 맥락에서 의미해야하는지 아주 명확하지 않다, 결국 이이 잔류 목표 대답은 진정한하게, 진실하게 반군 디 태치먼트가 없습니다 그래서. .)
그냥 요소
applyConstraints([A,B|R]) :-
A mod 2 #\= B mod 2,
applyConstraints([B|R]).
applyConstraints([_]).
테스트
한 쌍의?- L=[X,Y,Z], applyConstraints(L), L ins 1..4, label(L).
L = [1, 2, 1],
X = Z, Z = 1,
Y = 2 ;
L = [1, 2, 3],
X = 1,
Y = 2,
Z = 3 ;
...
% SICStus:
applyConstraints([]).
applyConstraints([X|Xs]) :-
X mod 2 #= R,
applyConstraints(Xs, R).
applyConstraints([], _).
applyConstraints([X|Xs], R) :-
X mod 2 #= S,
S #\= R,
applyConstraints(Xs, S).
% Query:
| ?- applyConstraints(L), length(L,2), !, domain(L,-2,2), labeling([],L).
L = [-2,-1] ? ;
L = [-2,1] ? ;
L = [-1,-2] ? ;
L = [-1,0] ? ;
L = [-1,2] ? ;
L = [0,-1] ? ;
L = [0,1] ? ;
L = [1,-2] ? ;
L = [1,0] ? ;
L = [1,2] ? ;
L = [2,-1] ? ;
L = [2,1] ? ;
no
() SWI - 프롤로그 라이브러리 (clpfd를 사용하여가, 어쩌면 당신이 Sicstus에서 상대와 인/2를 대체해야합니다) 고려
원래 한 줄짜리 해결책을 버릴 필요가 없다고 생각합니다. OP가 * 가변 크기 L *에 대해 말하면 아마 컴파일 시간에 고정되어 있지 않을 것입니다 *. 제약 조건 설정 단계에서 선택 점이있는 프로그램을 보여줌으로써 나쁜 예가 될 수 있습니다. – jschimpf
은 루프보다 더 간단 할 수있는 방법을 상상할 수 없습니다. – CapelliC