2012-04-25 2 views
4

누군가이 프롤로그 쿼리가 어떻게 작동하는지 설명 할 수 있습니까? 정의는 다음과 같습니다succ를 사용하여 재귀 쿼리를 통해 프롤로그를 실행하는 방법은 무엇입니까?

add(0,Y,Y). 
add(succ(X),Y,succ(Z)):- add(X,Y,Z). 

이 주어진 :

을 Heres
?- add(succ(succ(succ(0))), succ(succ(0)), R). 

쿼리의 추적 : 사실을 가장하는 튜토리얼에 대해 나에게 혼동했다

Call: (6) add(succ(succ(succ(0))), succ(succ(0)), R) 

Call: (7) add(succ(succ(0)), succ(succ(0)), _G648) 

Call: (8) add(succ(0), succ(succ(0)), _G650) 

Call: (9) add(0, succ(succ(0)), _G652) 

Exit: (9) add(0, succ(succ(0)), succ(succ(0))) 

Exit: (8) add(succ(0), succ(succ(0)), succ(succ(succ(0)))) 

Exit: (7) add(succ(succ(0)), succ(succ(0)), 
               succ(succ(succ(succ(0))))) 

Exit: (6) add(succ(succ(succ(0))), succ(succ(0)), 
               succ(succ(succ(succ(succ(0)))))) 

부분에서 그 succ는 제거되고 재발합니다. 재귀하는 동안 R은 succ를 얻습니다 ... 어떻게?! 또한, 0은 첫 번째 출구 (9)에서 오는 것입니까? 나는 프롤로그를 처음 사용하고 숙제 언어를 이해하려고 노력하고 있습니다. 어떤 도움을 많이 주셨습니다. 고맙습니다.

참고 : 관심있는 사람들을 위해,이 튜토리얼에 대한 링크는 http://www.learnprolognow.org/lpnpage.php?pagetype=html&pageid=lpn-htmlse9

+0

보통,'SUCC은/1''S/1'로 기록됩니다. [tag : successor-arithmetics]라는 답변을 확인하십시오. – false

답변

1

는 "여기서 제로는 첫번째 출구 (9)에서 오는가?"입니다

add(0, succ(succ(0)), _G652)add의 첫번째 인자는 다음 두 번째 제로 및 제 경우가 동일한 것을 말한다 제 절 단일화된다. 이 특정 상황 변수 _G652succ(succ(0))이됩니다.

"되풀이하면서 R은 succ ...를 얻습니다.

이것은 두 번째 절의 적용 결과입니다. 이 절에서는 첫 번째 인수에서 succ을 먼저 제거한 다음 add을 반복적으로 호출하고 마지막으로이 재귀 호출에서 돌아 오는 세 번째 인수에 succ의 다른 "계층"을 추가한다고 설명합니다. http://en.wikipedia.org/wiki/Peano_axioms#Addition

+0

나는 네가하는 말을보고, 나는 이것을 조금 더 이해하고있다. 내가 이해하지 못했던 것은 규칙의 머리도 뭔가를하고 있다는 것이 었습니다. 나는 시체가 증명 될 때까지 아무것도하지 않았다고 생각했습니다. – Andy

4

당신은 참조 callexitverbs, 인터프리터는 포즈 쿼리를 해결하려고 소요되는 작업입니다 :

술어 add은 페 아노의를 arithmetics에 추가의 직접 구현에 불과하다. 그런 다음 실제 작업에 대한 세부 정보를 보여 주며 역사적인 관점에서 볼 수 있습니다.

프롤로그해야 선택이 규칙의 (a call)는, 당신이 그것을주는 name를 사용

(그래서 functor라고도 함), 및 시도 규칙의 머리에 각 인수 unify로한다. Prolog는 선택을 위해 인수의 수인 arity을 고려한다고 보통 말합니다.

Unification 두 개의 용어로 '같음'을 시도하면 주목할만한 결과가 변수라고합니다 (예 : bindings). 변수가 Uppercase을 시작하는 이름이라는 것을 이미 알고 있습니다. 이러한 이름은 규칙에서 지정되지 않은 값을 식별합니다. 즉, 인수로는 placeholders입니다. 혼동을 피하기 위해 Prolog가 추적을 표시 할 때 변수가 이름을 바꿀 수 있도록 이름이 바뀌 었습니다. 관련 세부 정보가 identities이거나 증명 중에 바인딩이 설정 되었기 때문입니다.

그런 다음 _G648 기호가 추적에 표시됩니다.그들은 에 아직 머무르지 않고이라는 목표의 인수, 즉 RZ을 유지합니다. R은 고유합니다 (최상위 레벨 호출에서 발생 함). 따라서이 프롤로그는 친절하게 사용자 친화적 인 이름을 유지하지만 Z는 프로그램에서 왔을 가능성이 있으므로 여러 번 발생하고 이름이 바뀌 었습니다. SUCC (SUCC (SUCC (0)) 다음에 0 에 동일하게 할 수 없기 때문에

이 쿼리를

add(0,Y,Y). 

일치 실패

?- add(succ(succ(succ(0))), succ(succ(0)), R). 

프롤로그 첫 번째 시도에 응답하려면 시도

add(succ(X),Y,succ(Z)) :- add(X,Y,Z). 

따라서 이러한 바인딩 (왼쪽은 발신자 측 용어)을 해결해야합니다.X는 succ(succ(0))이되는 이유 7,

succ(succ(succ(0))) = succ(X) 
succ(succ(0)) = Y 
R = Z 

당신은 볼 수 있습니다, 우리는 단지 설립 바인딩 규칙 본체 즉 add(X,Y,Z), 증명하기 위해 새로운 목표를 가지고 :

추가 (SUCC (SUCC (0)), SUCC (SUCC (0)) _ G648)

와 ... X는 0되고 목표는

add(0,Y,Y).

일치 할 때까지그러면 Y는 succ (succ (0))가되며 주목할만한 것은 호출 규칙에서 Z의 값을 제공한다는 것입니다.

HTH는