2011-04-11 9 views
0

Prolog에서 톱니 바퀴 세트를 모델링하려고합니다. 그리고 두 개의 바퀴가 다른 체인으로 연결되어 있는지 확인하기 위해 쿼리합니다. 나는 하드 유선 술어의 관점에 종사을 정의하면Prolog : 계산 된 종료 조건의 재귀 문제

connected(X,Y) :- 
    engages(X,Y). 

connected(X,Y) :- 
    engages(X,Z), 
    connected(Z,Y). 

:

touches(z1,z2). 
touches(z2,z3). 
touches(z3,z4). 

engages(X,Y) :- touches(X,Y). 

다음이 작동

나는 간단한 재귀가 있습니다.

connected(z1,z4). 

의 테스트가 진정한 생산

connected(z1,z5). 

는 false를 생산하고 있습니다.

그러나 굴림 조건자를 계산으로 바꾼 경우 (두 반지름의 합계는 대략 두 센터 사이의 거리 임),이 검색은 무한 재귀 (스택 오버플로)처럼 보입니다. 대답은 거짓이어야합니다.

"터치"계산 자체가 "연결된"펑터라고하지 않는 이유는 무엇입니까? 그것은 functor가 명시 적 술어보다 더 많은 원자를 일치 시키려고 할 것이기 때문입니까?

는 대략 내 계산 된 접촉 (A와 B는 ARAD 브래드가 반경이며, 바퀴이고, D는 거리이고 대강 기능을 "거의 같다"이다.

touches(A,B) :- 
    wheel(A,_,_,ARAD), 
    wheel(B,_,_,BRAD), 
    distance(A,B,D), 
    approx(D,(ARAD+BRAD),2), 
    A \== B. 

답변

3

무한 순환이며 프로그램이 사이클을 확인하지 않습니다 발생하기 때문에 여기에서 발생할 수있는 작업은 다음과 같습니다..

  1. 이 프로그램은 바퀴를 AB, 그 터치를 발견
  2. B을 감안할 때, 난 터치하는 바퀴를 찾습니다. 그것은 A을 찾습니다.
  3. 고토 1.

은 이미 connected에 추가 인수를 고려 바퀴의 "폐쇄 된 세트"를 유지하고이를 방지 할 수 있습니다

connected(X,Y) :- 
    connected(X,Y,[]). 
connected(X,Y,Closed) :- 
    touches(X,Y), 
    \+ memberchk(Y,Closed). 
connected(X,Z,Closed) :- 
    touches(X,Y), 
    \+ memberchk(Y,Closed), 
    connected(Y,Z,[Y|Closed]). 

(운동을 독자들에게이 단축.)

+0

확인. 터치가 계산되는 두 번째 경우에만 발생합니다. 접촉이 (A, B)와 터치 (B, A)가 모두 참이기 때문입니다. 그것을 시도해 보도록하겠습니다. – interstar

+0

OK, 좋습니다. 감사. :-) – interstar