2011-01-29 14 views
7

Mam następujący fragment kodu prolog:Dlaczego to polecenie powoduje przepełnienie stosu w prologu?

num(0). 
num(X) :- num(X1), X is X1 + 1. 

fact(0,1) :-!. 
fact(X,Y) :- X1 is X-1, fact(X1,Y1), !, Y is Y1 * X. 

fact(X) :- num(Y), fact(Y,X). 

Może ktoś proszę wyjaśnić dlaczego następujące polecenie powoduje przepełnienie stosu? Z góry dziękuję.

fact(6). 

Odpowiedz

2

pierwsze, patrząc na zasadach

num(0). 
    num(X) :- num(X1), X is X1 + 1. 

orzecznik num(Y) będzie natychmiast ważne dla Y = 0.

Zatem zasada

fact(X) :- num(Y), fact(Y,X). 

można uprościć

fact(X) :- fact(0,X). 

że znajdzie coś pasującego do fact(0,1). W przypadku X = 6 chodzi o to, że ponieważ żadna reguła nie definiuje predykatu dla fact(0,6), rozpoczyna się wyszukiwanie pod numerem fact(-1,V1), po którym następuje fact(-2,V2) itd., Dopóki nie nastąpi dopasowanie dla fact(-value, Var), gdzie lokalny wynik będzie znaleziony przez Var.

To nie może się zdarzyć, a nieskończona pętla pochłania cały stos, dopóki nie zostanie wywołany błąd.

+3

Być może należy zwrócić uwagę, że problem debiutant ty analizie można zapobiegać poprzez dodanie 'x> 0' do korpusu 2. klauzuli za ** rzeczywistości/2 **. – hardmath

2

Powodem fact(6) nie kończy można znaleźć w poniższym :

 
?- fact(6). 

num(0) :- false. 
num(X) :- 
    num(X1), false, 
    X is X1 + 1. 

fact(X) :- 
    num(Y), false, 
    fact(Y,X). 

Ponieważ ten fragment nie kończy, również oryginalny program nie zakończy. Pamiętaj, że nieterminacja jest niezależna od definicji fact/2! W najlepszym wypadku twój program może się powieść, ale nigdy (skończenie) nie.

rozważyć użycie another definition of fact/2, która kończy się również do fact(N, 6).

Powiązane problemy