2013-04-21 3 views
0

사실을 하나의 사실에서 다른 사실로 연결시키고 지정된 중지 지점까지 계속 이동하려고하는 술어를 얻으려고합니다.목록이없는 프롤로그 관계 추적

예를 들어, 사람이 패키지를 누가 가지고 있는지 알고 싶을 때 물류 기록을하고 있다고 가정 해 봅시다. 누가 끝까지 물물을 얻었습니까?

프롤로그 코드

mailRoom(m). 

    gotFrom(annie,brock). 
    gotFrom(brock,cara). 
    gotFrom(cara,daniel). 
    gotFrom(daniel,m). 


    gotFrom(X,Y) :- gotFrom(Y,_). 

당신이 무엇을 시작 이제까지 포인트는 재귀에서 목록을 아래로 이동하는 그래서 내가 술어 gotFrom로 할하려고하는 것은 (예 : gotFrom (브록, 누구)) 및 우편함 인 m에 의해 지정된 끝까지 가십시오. 나는이 술어를 실행할 때

불행하게도, 그것은

Who = annie. 
    Who = brock. 
    Who = cara. 
    etc.etc.... 

내가 그 때까지 아래로 카라와 모든 방법으로,이 애니에 브록에서가는 모든 일하지만 임 확실하지 단계별 시도를 판독 무한의 진리를 거쳐 순환합니다. 나는 그것이 함수 (_)의 와일드 카드와 관련이 있다는 생각을 가지고 있지만, 함수의 그 부분을 어떻게 표현할 수 있었는지 확실하지 않아서 술어가 프로그램에서 다음 사실을 검색하는 대신 끝까지 건너 뜁니다.

내 프로그램에서 백컷 (!)을 사용해 보았지만 동일한 오류가 발생합니다.

도움을 주시면 대단히 감사하겠습니다. 나는 코드를 원하지 않는다. 내가 뭘 잘못하고 있는지 알고 싶기 때문에 올바른 방법을 배울 수있다.

감사합니다.

답변

1

나는이 규칙은 의미가 두려워 :

특정 값으로 X 또는 Y를 제한하기 위해 여기 아무것도 없다
gotFrom(X,Y) :- gotFrom(Y,_). 

. 또한, 싱글 톤 변수 X과 익명 변수 _의 존재는 기본적으로 아무 것도 작동한다는 것을 의미합니다. 사용해보기 :

?- gotFrom([1,2,3], dogbert). 
true ; 
true ; 

내가 여기에서 설정하려고하는 것은 일시적 속성입니다. 이 경우, 당신이 원하는 것은 이런 아마 더 :

?- gotFrom(brock, Who). 
Who = cara ; 
Who = daniel ; 
Who = m ; 
ERROR: Out of local stack 

문제에 대한 이유는 바로 명확하지 않을 수 있습니다 :

gotFrom(X,Z) :- gotFrom(X, Y), gotFrom(Y, Z). 

이 흥미로운 결과를 생성합니다. 그것은 그 규칙에 두 번 일어나고있는 검사되지 않은 재귀가 있다는 것입니다. 재귀 적으로 gotFrom/2을 통합 한 다음 재귀 적으로 다시 통합합니다. 이 중 하나를 비 재귀 적으로 사용할 수 있도록 두 개의 술어로 나누는 것이 좋습니다.

got_directly_from(annie,brock). 
got_directly_from(brock,cara). 
got_directly_from(cara,daniel). 
got_directly_from(daniel,m). 

gotFrom(X,Y) :- got_directly_from(X, Y). 
gotFrom(X,Z) :- got_directly_from(X, Y), gotFrom(Y, Z). 

이 우리에게 원하는 동작을 제공합니다

?- gotFrom([1,2,3], dogbert). 
false. 

어떤 일반적인 조언 :

  1. ?- gotFrom(brock, Who). 
    Who = cara ; 
    Who = daniel ; 
    Who = m ; 
    false. 
    

    주의 사항이 하나가 의미없는 데이터의 내 공격에 탄력을 싱글 톤 변수 경고를 무시하지 마십시오. 그들은 거의 입니다. 항상 버그입니다.

  2. 무슨 일이 일어나고 있는지 이해하지 못하면 절대로 소개하지 마십시오. 커팅은 먼저 동작을 이해하고 커팅이 어떻게 영향을 주는지 이해하는 경우에만 사용해야합니다. 이상적으로는 성능에 영향을 미치고 관찰 가능한 효과가없는 녹색 절단 제거로 자신을 제한하려고 시도해야합니다. 프롤로그가 무엇인지 이해하지 못한다면, 빨간 컷을 추가하면 문제가 더욱 복잡해질 것입니다.
+0

나는 본다. Daniel, 고맙습니다 대령 님, 정말 감사드립니다. 나는 와일드 카드 연산자에 대한 생각에 매달렸고 과거에는 생각할 수 없었지만, 당신의 설명은 그것을 지나치게 받았다. 고마워. 나는 그것을 이해하기 위해 프롤로그에서 계속 일할 것입니다. – user2020331

+0

@ user2020331 좋아요, 여러분 환영합니다! 나는 당신이 Prolog를 사용하여 즐겁게하고 그것으로 붙어 있기를 바랍니다. 어려운 길이지만 가치가 있습니다! –