기존의 술어를 알아 내거나 새로운 술어를 설계 할 때 Prolog가 작동하는 방식을 이해하는 데 도움이됩니다. 당신과 같은 쿼리를 만들 때 :
sum(succ(succ(0)), succ(succ(succ(0))), Answer).
프롤로그 sum(_, _, _)
(sum/3
를) 일치하는 사실과 규칙 모양과 일치하는 첫 번째 하나를 선택합니다. 규칙은 다음과 같습니다.
(1) sum(succ(X), Y, succ(Z)) :- sum(X, Y, Z).
(2) sum(0, X, X).
쿼리를 보면 규칙 # 1의 패턴과 명확하게 일치합니다. Prolog에서 변수는 모든 종류의 용어로 인스턴스화 될 수 있고 동일한 이름의 변수는 단일화되어 (동일한 값으로 인스턴스화 됨) 기억하십시오. 프롤로그는 쿼리 규칙 # 1의 "머리"를 통합하면 다음과 같이 변수를 통일하여 그렇게 : Answer
할당 succ(Z)
도 Z
불구하고이 구속되지 않은 값을 (이
X = succ(0)
Y = succ(succ(succ(0)))
(A) Answer = succ(Z)
공지하는 구체적인 가치). 이 sum/3
에 대한 새 쿼리이기 때문에
sum(succ(0), succ(succ(succ(0))), Z)
| | |
X Y Z
프롤로그 이제 다시 정상에서 시작됩니다 : 이제 우리는 쿼리 될 것입니다 쿼리합니다 규칙, sum(X, Y, Z)
을 따릅니다. 그냥 처음처럼, 다음 통일화와 규칙 # 1 일치 : 나는 위의 Z'
을 사용하고있는 sum(succ(0), succ(succ(succ(0))), Z)
의 다른 변수 Z
구별하기 위해
X = 0
Y = succ(succ(succ(0)))
(B) Z = succ(Z')
, 그것이 사용 된 것과 다른 Z
때문에 머리는 sum(..., succ(Z))
입니다. 이것은 C에서 int f(x) { return 2*x; }
으로 선언 된 함수가 있고 어딘가에서 다른 로컬 변수 x
으로 호출하면 그 이름이 x
은 두 개의 다른 장소에서 사용되고 두 개의 다른 변수를 나타냅니다).
sum(0, succ(succ(succ(0))), Z')
| | |
X Y Z'
이 재귀 쿼리는 succ(X)
일치하지 않는 첫 번째 인수, 0
때문에 규칙 # 1과 일치하지 않습니다
그럼 우리가되는, 다시 sum(X, Y, Z')
을 다음 재귀 쿼리를 수행 할 수 있습니다.
0 = 0
X = succ(succ(succ(0)))
(C) X = Z'
이제 X = succ(succ(succ(0)))
그래서 Z' = succ(succ(succ(0)))
: 그러나, 규칙 # 2 일치합니다. 이 룰에는 더 이상 질의가 없기 때문에 질의를받은 곳으로 마침내 성공합니다. 위의 (B)이 다시 돌아 :
Z = succ(Z') = succ(succ(succ(succ(0))))
및 (A)이 다시 돌아 :
Answer = succ(Z) = succ(succ(succ(succ(succ(0)))))
을 그리고 거기 당신은 그것이있다. @CapelliC에서 언급 한 trace
기능을 사용하면 이러한 연속 단계가 Prolog 인터프리터에서 발생하는 것을 볼 수 있으며 변수의 인스턴스화를 따를 수 있습니다. 일치 대체에 따라, 프로그램의 규칙 '머리에 주어진 쿼리와 일치하고, 일치하는 규칙의 몸를 진행하여
와우! 아주 좋은 설명, 지금 나는 그것을 얻는다. 고마워. –