2011-01-29 20 views
7

Tôi có đoạn mã sau đây prolog:Tại sao lệnh này gây ra tràn ngăn xếp trong 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). 

ai đó có thể vui lòng giải thích tại sao các lệnh sau đây gây ra một chồng tràn? Cảm ơn trước.

fact(6). 

Trả lời

2

Đầu tiên, nhìn vào các quy tắc

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

vị num(Y) sẽ ngay lập tức có hiệu lực cho Y = 0.

Do đó, quy tắc

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

có thể được đơn giản hóa như

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

rằng sẽ tìm thấy một phù hợp cho fact(0,1). Đối với X = 6, điều gì xảy ra thay vì, không có quy tắc xác định vị từ cho fact(0,6), tìm kiếm được bắt đầu bằng fact(-1,V1), theo sau với fact(-2,V2) v.v ... cho đến khi kết quả phù hợp với số fact(-value, Var).

Điều này không thể xảy ra và vòng lặp vô hạn tiêu thụ toàn bộ ngăn xếp cho đến khi lỗi được kích hoạt.

+3

Có lẽ bạn nên chỉ ra cho tân binh rằng vấn đề bạn phân tích có thể được ngăn chặn bằng cách thêm 'X> 0' cho cơ thể của mệnh đề thứ 2 cho ** thực tế/2 **. – hardmath

2

Lý do tại sao fact(6) không chấm dứt có thể được tìm thấy trong sau:

 
?- fact(6). 

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

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

đoạn này không chấm dứt, cũng chương trình ban đầu của bạn không chấm dứt. Lưu ý rằng việc không chấm dứt độc lập với định nghĩa của fact/2! Tốt nhất, chương trình của bạn có thể thành công, nhưng nó sẽ không bao giờ (hết sức) thất bại.

Cân nhắc sử dụng another definition of fact/2, đó cũng chấm dứt cho fact(N, 6).