2011-11-22 2 views
1

, 그래서 명시 적으로 아무것도 결과, 제발 :프롤로그 복귀 숙제

발견되는 다른 목표를 무시하면서 프롤로그 프로그램에 의해 발견에만 목표를 돌려받을 수있는 방법이 있나요? 프로그램 주어진 예시를위한

:

permutation([X|Xs],Zs):-permutation(Xs,Ys), insert(X,Ys,Zs). 
permutation([],[]). 

이 프로그램은 유일한 솔루션으로 순열을 반환 할 수있는 방법이 있습니까? 다음과 같은 경우 :

| ?- permutation([1,2,3],X). 

X = [1,2,3] ? ; 

X = [1,3,2] ? ; 

X = [2,1,3] ? ; 

X = [2,3,1] ? ; 

X = [3,1,2] ? ; 

X = [3,2,1] ? ; 

no 

우리는 단지 솔루션으로

X = [1,2,3] ?; 
no 

을 할 수 있습니까?

답변

6

그것은 당신이 찾고있는 컨트롤입니다. 솔루션에 커밋해야 할 위치에 놓습니다 (여기에 최상위 수준입니다.). 또한 /1 인 커밋 범위가 '로컬'커밋 범위를 제한 할 수 있습니다 (예 : findall/3에 인라인 된 연결에서 유용함).

4

프롤로그는 검색 트리에서 다른 분기가 가능할 때마다 선택 점을 설정합니다. 선택 점으로 되돌아가는 것을 피하고 그러한 대안을 탐색하기 위해서는 컷 (!/0)을 추가해야합니다.

프로그램에서 선택 점이 설정되어 있는지 확인하고 해당 통화 이후에 잘라내기를 추가해야합니다.

2

첫 번째 해결 방법을 고수하는 가장 좋은 방법은 입니다.이 방법은 효과를 가능한 한 지역적으로 유지하기 때문입니다. !/0을 사용하면 !/0의 범위가 더 크기 때문에 이미 의도하지 않은 영향이있는 경우가 많습니다. 의 아주 간단한 예를 들어 보자 :

p(X) :- (X = 1 ; X = 2 ; X = 3). 
p(4). 

once/1 사용에 쿼리 (X = 1 ; X = 2 ; X = 3)를 우리가 얻을 : 종종 이것이

p2(X) :- (X = 1 ; X = 2 ; X = 3), !. 
p2(4). 

?- p2(X). 
X = 1. 

: !를 사용

p1(X) :- once((X = 1 ; X = 2 ; X = 3)). 
p1(4). 

?- p1(X). 
X = 1 ; 
X = 4. 

, 우리는 단 하나의 답변을 얻을 의도하지 않았다.

그러나 첫 번째 해결 방법을 사용하는 것이 일반적인 문제입니다.

?- p1(2). 
true. 

?- dif(X,1),p1(X). 
X = 2 ; 
X = 4. 

이제 2도 첫 번째 해결책이 되었습니까? 커밋은 매우 신중하게 사용해야합니다. p1/1과 유사한 동작을 나타내는 술어는 견고성이 부족합니다. 이러한 술어는 실제 조회에 따라 그 의미가 변경되기 때.에 관계로 이해 될 수 없습니다.