2017-03-29 3 views
1

Prolog (나는 버전 7.4.0-rc1을 사용 중이다)에서 술어 insertPermutation/2을 정의하려고하는데, 두 인수가 모두 목록 일 경우에만 하나의 순열 .Prolog의 순열 술어

delete(X,[X|T],T). % Base case, element equals head. 
delete(X,[A|B],[A|C]) :- delete(X,B,C). % And/or repeat for the tail. 

insert(X,Y,Z) :- delete(X,Z,Y). % Inserting is deletion in reverse. 

insertPermutation([],[]). % Base case. 
insertPermutation([H|T],P) :- insertPermutation(Q,T), insert(H,Q,P). % P permutation of T, H inserted. 

위의 도우 술어에 대한 삭제가 좋은 이름이 아니라는 것을 이미 알고 있습니다. 우리는이 술어를 작성해야하며 내장 술어는 사용할 수 없습니다. 이것이 내가 위의 코드를 이런 식으로 작성한 이유이며, 나는 엘리먼트를 삭제하기 위해 먼저 작성했기 때문에 내가 선택한 이름을 선택했다. 세 번째 인수가 첫 번째 인수의 첫 번째 인스턴스가 제거 된 두 번째 인수의 목록과 같은 목록 인 경우에만 true입니다.

insertPermutation 술어는 P가 첫 번째 목록의 꼬리 순열과 같고 순열의 임의 위치에 머리가 추가되었는지 재귀 적으로 테스트합니다. 이렇게하면 빈리스트가되는 기본 케이스로 작동합니다.

그러나 순열 술어는 내가 원하는대로 작동하지 않습니다. 예를 들어 쿼리에

?- insertPermutation([1,2,2],[1,2,3]). 

프롤로그는 false를 반환하지 않지만 고정시킵니다. 쿼리에

?- insertPermutation(X,[a,b,c]). 

프롤로그 다시 정지 후

X = [a, b, c] ; 
X = [b, a, c] ; 
X = [c, a, b] ; 
X = [a, c, b] ; 
X = [b, c, a] ; 
X = [c, b, a] ; 

로 응답합니다. 나는이 문제들이 어떻게 관련이 있는지는 알지 못한다. 누군가 내가 놓친 경우를 지적 할 수 있습니까?

편집 : 두 가지, 숙제이며 삽입 조건자를 사용하여이 문제를 해결해야합니다. 나는 이것을 썼다.

+0

프롤로그가 어떻게하는지 보지 않겠습니까? [permutation/2] (http://www.swi-prolog.org/pldoc/man?predicate=permutation/2)를 참조하십시오. 두 버전을 [표준 형식] (https : //en.wikipedia)으로 변환하는 것이 좋습니다. .org/wiki/Canonical_form)을 입력 한 다음 비교해보십시오. 그들이 동일한 정식 양식을 가지고 있다면 그들은 서로의 순열이거나 서로 동일 할 수 있습니다. –

+0

이 문제에 대해 요소를 삽입하는 함수를 사용해야합니다. 그 이유는 바로! 이미 작동하는 대체 정의를 작성했지만 삽입 술어를 사용하여 작동하게 할 수는 없습니다. – Kermit

+1

질문에 숙제라고 말하면됩니다. –

답변

0

대답은 마지막 행을 변경하는 것입니다

% P permutation of T, H inserted. 
insertPermutation([H|T],P) :- 
    insertPermutation(Q,T), 
    insert(H,Q,P). 

% P permutation of T, H inserted. 
insertPermutation(P,[H|T]) :- 
    insertPermutation(Q,T), 
    insert(H,Q,P). 

첫 번째 요소는 후자가 아닌 다른 방법으로 주위에 (또는 그 반대)의 순열인지 확인하는 데 필요한 사용 사례. 안티 기후지만, 내 문제에 대한 답변.

+1

Y 꼬리 재귀를 사용하지 않습니까? –