2012-05-25 4 views
1

최근에 나는 http://www.amzi.com/ExpertSystemsInProlog에서 무료로 사용할 수있는 "프롤로그로 건물 전문가 시스템"이라는 책을 시도했습니다.네이티브 프롤로그 쉘

새 식별 데이터베이스와 함께 부록에 native shell이라는 코드가 있습니다. 문제는 셸로 문의하여 실행 후 :

main입니다.

로드.

해결.

"nostrils : external_tubular?"라고 묻습니다.

아니오로 대답하면 스택 오버플로가 발생합니다. 문제는 아마도 블로우 섹션에서 발생했을 것입니다.

prove(true,_) :- !. 
prove((Goal,Rest),Hist) :- 
    prov(Goal,[Goal|Hist]), 
    prove(Rest,Hist). 
prove(Goal,Hist) :- 
    prov(Goal,[Goal|Hist]). 

prov(true,_) :- !. 
prov(menuask(X,Y,Z),Hist) :- menuask(X,Y,Z,Hist), !. 
prov(ask(X,Y),Hist) :- ask(X,Y,Hist), !. 
prov(Goal,Hist) :- 
    clause(Goal,Body), 
    prove(Body,Hist). 

제발 도와 주실 수 있습니까? 어떤 도움을 주셔서 감사합니다. 쉘의

전체 코드 : 데이터베이스에 대한 http://www.amzi.com/ExpertSystemsInProlog/code/native/native.pro

전체 코드 : 나는 SWI 프롤로그를 사용하고 http://www.amzi.com/ExpertSystemsInProlog/code/native/birds.nkb

.

+1

! SWI-Prolog 인터프리터를 사용하여 프롤로그를 작성하십시오. 따라서 첫 번째 생각은 구문 불일치가 있다는 것입니다. 그러나보고하는 오류 (스택 오버플로)는 수정이 필요한 코드의 위치를 ​​정확히 파악하는 데 도움이되지 않습니다. 아마도 [SWI-Prolog의 디버깅 기능] (http://www.swi-prolog.org/pldoc/man?predicate=trace/0)이 다음 단계가되어야합니다. [SWI-Prolog 그래픽 트레이서] (http://www.swi-prolog.org/gtrace.html)에는 XPCE 콘솔이 필요합니다. – hardmath

+0

현재 Logtalk 배포판 (http://logtalk.org/)에는 Amzi 포트가 포함되어 있습니다! 조류 식별 전문가 시스템. 여기에서 소스 코드를 검색 할 수도 있습니다. http://trac.logtalk.org/browser/trunk/examples/birds 대부분의 Prolog 컴파일러 Logtalk 백엔드 컴파일러. –

답변

1

나는 문제가 여기 발견 h])를 두 번째 증명 술어와 일치 시키려면 어떻게 든 유추 과정에서 무한 루프가 발생하게하는 증명 (목표, Hist)이 트리거됩니다. 추적을 분석하는 데 8 시간이 걸렸습니다.

따라서 문제를 해결하려면 prove ((목표, 휴식), Hist)의 시작 부분에 커팅을 배치해야합니다.코드는 다음과 같아야합니다

prove((Goal,Rest),Hist) :- 
    !, 
    prov(Goal,[Goal|Hist]), 
    prove(Rest,Hist). 
prove(Goal,Hist) :- 
    prov(Goal,[Goal|Hist]). 
1

문제는 참으로 Head는 해당 조항 몸 조항의 머리와 Body으로 통합 할 수있는 경우는 true해야

prove(Goal,Hist) :- 
    prov(Goal,[Goal|Hist]). 

prov(Goal,Hist) :- 
    clause(Goal,Body), 
    prove(Body,Hist). 

clause(:Head, ?Body)을 통해 자체 명단. 죄송 합니다만 프로그램의 경우 SWI-Prolog는 clause(call(X), call(X))이 맞다고 생각합니다. 즉, clause(call(nostrils(external_tubular)), X)이 성공하고 prove이 호출되며, 차례로 prov이 계속 증가하는 두 번째 인수를 호출합니다.

clause/2은 정적 조건 자이므로 retractall 또는 abolish으로 내용을 수정할 수 없습니다. 가능한 해결 방법은 다음과 같습니다

  1. Report a bug to SWI developers
  2. myclause처럼 무언가에 의해 birds.nkb에 절을 교체하고 쉘의 구현에 myclause을 참조하십시오. [)

    prove((Goal,Rest),Hist) :- 
        prov(Goal,[Goal|Hist]), 
        prove(Rest,Hist). 
    prove(Goal,Hist) :- 
        prov(Goal,[Goal|Hist]). 
    

    SWI-프롤로그 헤드 ((X, Y, Z를 허용하기 때문에 : 다른 프롤로그 방언에

  3. 찾는 ...
+0

알렉산더에게 감사드립니다. 솔루션으로 실제 원인을 추가했습니다. 9 시간 안에 현상금을 수여합니다. 나는 다음 9 시간 내에 그것을 할 수있다. –

+0

'(Goal, Body)'절 뒤에'\ + Body = Goal '을 추가하면''call (X), call (X))'문제를 해결할 수있을 것 같습니다. –

0

당신은 마우스 오른쪽 섹션 위의 조건 prov((_,_),_) :- !, fail.를 추가하여 문제를 해결할 수 있습니다 : 당신은 Amzi 용으로 작성된 샘플 코드를 사용하는

prov(true,_) :- !. 
prov(menuask(X,Y,Z),Hist) :- menuask(X,Y,Z,Hist), !. 
prov(ask(X,Y),Hist) :- ask(X,Y,Hist), !. 
prov(Goal,Hist) :- 
    clause(Goal,Body), 
    prove(Body,Hist).