2011-01-29 12 views
7

tengo el siguiente fragmento de código de prólogo:¿Por qué este comando causa un desbordamiento de pila en prolog?

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). 

Puede alguien explicar por qué el siguiente comando provoca un desbordamiento de pila? Gracias por adelantado.

fact(6). 

Respuesta

2

En primer lugar, mirando a las reglas

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

el predicado num(Y) será inmediatamente válido para Y = 0.

Por lo tanto la regla

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

se puede simplificar como

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

que se encuentra a la altura de fact(0,1). Para X = 6, lo que ocurre es que, como ninguna regla define un predicado para fact(0,6), se inicia una búsqueda con fact(-1,V1), seguido de fact(-2,V2) etc ... hasta que se produce una coincidencia para un fact(-value, Var) donde el resultado local sería el Var encontrado.

Esto no puede suceder, y un ciclo infinito consume toda la pila, hasta que se desencadena un error.

+3

Quizás debería señalar al novato que el problema se analiza, pueden prevenirse mediante la adición de 'X> 0' al cuerpo de la segunda cláusula para ** hecho/2 **. – hardmath

2

La razón por la fact(6) no pongan fin se puede encontrar en el siguiente :

 
?- fact(6). 

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

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

Debido a que este fragmento no termina, también su programa original no terminar. Tenga en cuenta que la no terminación es independiente de la definición de fact/2! En el mejor de los casos, su programa puede tener éxito, pero nunca (finitamente) fallará.

considerar el uso another definition of fact/2, que termina también para fact(N, 6).

Cuestiones relacionadas