2015-05-08 2 views
-1

У меня есть следующий код:Basic Прологе рекурсия трассировку

my_length([],0). 
my_length([_|L],N) :- my_length(L,N1), N is N1 + 1. 

Который должен существенно подсчитать количество элементов в списке. Вот след:

Call:my_length([1, 2, 3], _G4652) 
Call:my_length([2, 3], _G4746) 
Call:my_length([3], _G4746) 
Call:my_length([], _G4746) 
Exit:my_length([], 0) 
Call:_G4748 is 0+1 
Exit:1 is 0+1 
Exit:my_length([3], 1) 
Call:_G4751 is 1+1 
Exit:2 is 1+1 
Exit:my_length([2, 3], 2) 
Call:_G4652 is 2+1 
Exit:3 is 2+1 
Exit:my_length([1, 2, 3], 3) 
Length = 3 

До здесь Exit:my_length([], 0) и Call:_G4748 is 0+1 Я понимаю, что Пролог нашел факт, и что единая N1 с 0 и N было сделано, чтобы добавить 1 к этому значению.

Что я не понимаю, это то, что следует после этого. Почему Prolog возвращается к Exit:my_length([3], 1). В частности, откуда взялись [3]? Я пытаюсь представить его, как идти вверх по стеку вызовов, но не имеет никакого смысла, как эти переменные передаются.

+0

Эти переменные * * уже находятся в стеке. Пролог не разматывает стек на * exit *. Он делает на * redo * или * fail *. – CapelliC

ответ

2

Вы должны прочитать трассировку путем соединения вызова или повтора с выходом или сбоем. В этом случае

Exit:my_length([3], 1) 

в паре с предыдущим

Call:my_length([3], _G4746) 

Таким образом, это означает, что выполнение my_length([3], _G4746) связана переменная _G4746 к 1.

Зов новая запись в стеке и Fail a pop.

Смежные вопросы