1

내 의도는 Prolog에서 단순성 (transmitivity)에 대한 간단한 예제를 구현하는 것이 었습니다. Prolog : 간단한 사실에 대한 전 이성 검사

내 사실이다 : 나는 확인하려면이 조건을 서면으로 작성했습니다

trust_direct(p1, p2). 
trust_direct(p1, p3). 
trust_direct(p2, p4). 
trust_direct(p2, p5). 
trust_direct(p5, p6). 
trust_direct(p6, p7). 
trust_direct(p7, p8). 
trust_direct(p100, p200). 

여부 A 신탁 사실 CCA 신탁이 B 트러스트하는 B이있을 때마다 :

trusts(A, B) :- 
    trust_direct(A, B). 

trusts(A, C) :- 
    trusts(A, B), 
    trusts(B, C). 

술어는 trusts(p1, p2) 또는 trusts(p1, p5)의 경우 true을 반환하지만, 예를 들어 trusts(p5, p6)은 이미 ERROR: Out of local stack을 반환합니다.

Prolog가 스택을 빠르게 플러딩합니까?

내 생각/구현 trusts 나쁜/낭비 시스템 메모리입니까?

답변

3

, 프롤로그가 로컬 스택을 빠르게 플러딩합니다.

 
trusts(A, C) :- 
     trusts(A, B), 
     false, 
     trusts(B, C). 

이것은 라고 :

이를 참조하려면, 그것은 은 다음의 프로그램 조각은 고려 충분 모든 후 false/0이  가 무시 될 수 있도록 내가 false/0을 삽입했습니다. 나는 삼진 아웃 텍스트로 무시할 수있는 부분을 나타냅니다. 위의 조각 중 하나를 사용하여, 우리는 즉시 얻을

 
trusts(A, C) :- 
     trusts(A, B), 
     false. 

지금 :

 
?- trusts(p5, p6). 
ERROR: Out of local stack 

이 문제를 제거하려면, 당신에게

이 코드 조각은 실제로 동등하다는 것을 의미 남은 단편을 변경해야합니다. 이러한 이유로, 그러한 단편은 설명의 문제가됩니다.

 
trusts(A, B) :- 
     trust_direct(A, B). 
trusts(A, C) :- 
     trust_direct(A, B), 
     trusts(B, C). 

샘플 쿼리 : 예상대로이 지금 작동

 
?- trusts(p5, p6). 
true ; 
false. 

는 예를 들어, 다음 버전을 고려하십시오. 그것은 당신이 게시 된 버전으로 선언적으로 동등하고, 더 나은 종료 속성이 있습니다

 
?- trusts(X, Y), false. 
false. 

이 프로그램이 지금 보편적 종료 있음을 보여준다.

대체 솔루션은 다음과 같습니다

+1

니스 설명의 정의를 사용하여 프롤로그 시스템의 테이블 화 기능을 사용! 그러나 우리는 이미'trusts (A, C) : trust_direct (A, B), trusts (B, C)'('trust_direct/2'에 대한 호출)을 가지고 있다면, 우리는 두 번째'트러스트 (A, B) : - trust_direct (A, B)가 필요합니다 .'? – daniel451

+0

그건 좋은 질문이며, 스스로 게시 할 가치가 아주 많습니다! 이에 대한 새로운 질문을 제기하고 계속하십시오. – mat

+1

여기에 : [단순 전이 검사를위한 불필요한 술어 정의?] (https://stackoverflow.com/questions/42496415/unnecessary-predicate-definition-for-simple-transitivity-checkup) – daniel451