2009-04-07 13 views
5

프롤로그에서 검색어를 작성하는 쉬운 방법은 각 결과를 한 번만 반환하는 것입니까? 예를 들어프롤로그의 고유 한 결과

내가 좋아하는 뭔가를 시도하고있다 :

deadly(Xn) :- scary(X), Xn is X - 1, Xp is X + 1, not(safe(Xn)), safe(Xp). 
deadly(Xp) :- scary(X), Xn is X - 1, Xp is X + 1, not(safe(Xp)), safe(Xn). 

deadly(X). 

나를 위해 유용하지 않기

X = 5 

X = 5 

X = 5 

X = 5 

.... 

를 받고.

답변

1

코드를 추가하지 않고도 말하기는 어렵지만 아마 절단 연산자 (!)를 찾고있을 것입니다. 정의 (foo)을 게시하려면 I (또는 그 외의 다른 사람)가 자세한/구체적 답변을 제공 할 수 있습니다.

+0

내가 사용했던 모든 시간을! 평가가 완전히 중단되었으며 프롤로그가 찾는 모든 가치를 원하지만 가치 당 한 번만 원합니다. (나는 시도하고 내 경우를 줄이려고한다.) – BCS

+1

언제 어디서 사용할지 문제가있다. "다시 여기 다시 오지 마라"는 말은 데이터를 처음 캡처하기 전후에 크게 다른 의미를 갖습니다. – MarkusQ

3

정확하게 기억한다면, 목록에서 고유 한 솔루션을 수집하는 술어 솔루션 (또는 비슷하지만 프롤로그를 프로그래밍 한 이후로 오랜 시간이 걸렸습니다.)이 있습니다.

편집 :setof/3 내가 생각했던 것입니다. 고마워요, 카렐.

+0

findall/3, bagof/3, setof/3 – Kaarel

4

할 수있는 한 가지는 솔루션을 생성하는 술어에 setof/3을 적용하는 것입니다. 그러나 bagof/3에 의해 전달 된 결과에 sort/2을 적용하여 setof/3을 구현합니다 (적어도 SWI-Prolog의 경우). 따라서 솔루션 생성기가 영원히 계속된다면 setof/3은 절대로 적용되지 않습니다 ...

그래서 나는 중복이 생성되지 않도록 프로그램을 시도합니다. .

+0

정확하게 기억한다면, setof는 쿼리가 유한 한 솔루션 크기를 가지고 있고 그것이 완료되었다는 것을 알고있는 경우에만 유용합니다. 그렇지 않으면, 그냥 5를 계속해서 가질 수 있습니다. 아니, 벌써 그것을 얻었고 다시보고, 또 다른 5 ... 무한 루프를 얻는다고. –

+0

감사. 나는 조금 대답을 업데이트했다. – Kaarel

3

또 다른 방법은 솔루션을 메모하는 것입니다.

:- dynamic seen/1. 

% Call this always before calling deadly_wrapper/1 
clear_seen :- 
    retractall(seen(_)). 

% This wrapper calls deadly/1 but remembers 
% the solution using assert/1, and fails 
% if the solution has been "seen" before. 
deadly_wrapper(X) :- 
    deadly(X), 
    (
     seen(X) 
    -> 
     fail 
    ; 
     assert(seen(X)) 
    ). 


% This is for testing. 
deadly(1). 
deadly(1). 
deadly(1). 
deadly(5). 
deadly(1). 
deadly(1). 

Prolog가 테이블 링을 지원하는 경우, 더 간단 해집니다. 예제 파일 :

:- table deadly/1. 

deadly(1). 
deadly(1). 
deadly(5). 
deadly(1). 
deadly(5). 

예 실행 XSB와 :

$ xsb 
[xsb_configuration loaded] 
[sysinitrc loaded] 

XSB Version 3.2 (Kopi Lewak) of March 15, 2009 
[x86_64-unknown-linux-gnu; mode: optimal; engine: slg-wam; 
scheduling: local; word size: 64] 

| ?- [deadly_tab]. 
[Compiling ./deadly_tab] 
[deadly_tab compiled, cpu time used: 0.0100 seconds] 
[deadly_tab loaded] 

yes 
| ?- deadly(X). 

X = 5; 

X = 1; 

no 
| ?- 
+0

나는 "기억하다"가 아니라 "메모하다"라고 말할 것입니다. –

관련 문제