5

Tôi đang học Prolog, và như một bài tập, tôi đang thử nghiệm với một cơ sở dữ liệu đơn giản tính tổng của tất cả các con số lên đến số đã cho (ví dụ 0 = 0, 1 = 1, 2 = 3, 3 = 6 , 4 = 10, ...). Dễ dàng đủ:Điều này có thể được thực hiện đuôi đệ quy trong Prolog?

counting_sum(0, 0). 
counting_sum(Num, Sum) :- Num > 0, PrevNum is Num - 1, 
    counting_sum(PrevNum, PrevSum), Sum is Num + PrevSum. 

Điều đó thổi lên một nơi nào đó xung quanh counting_sum(150000, X). với tràn ngăn xếp. Tôi hiểu rằng Prolog có thể làm đuôi đệ quy, nhưng nếu tôi di chuyển các cuộc gọi đệ quy đến hết quy tắc, tôi nhận được

error(instantiation_error,(is)/2) 

mà tôi giả sử là nói với tôi rằng tôi không thể sử dụng PrevSum trước khi nó được thống nhất với counting_sum(PrevNum, PrevSum) . Điều đó có đúng không, và có cách nào để làm cho cái đuôi này đệ quy không? Tôi đang sử dụng GNU Prolog 1.3.1 nếu điều đó tạo ra bất kỳ sự khác biệt nào.

P.S. Tôi vẫn run rẩy về thuật ngữ. Hãy cho tôi biết nếu tôi đã sử dụng các điều khoản không chính xác.

+1

Bạn có quyền về nguyên nhân của lỗi instantiation. –

Trả lời

8

Hãy thử một cái gì đó như thế này (sử dụng một ắc):

counting_sum(Count, Sum):- 
    counting_sum(Count, 0, Sum). 

counting_sum(0, Sum, Sum). 
counting_sum(Num, PrevSum, Sum):- Num > 0, PrevNum is Num - 1, 
    NextSum is PrevSum + Num, 
    counting_sum(PrevNum, NextSum, Sum). 
+1

Cảm ơn. Tôi đã không gặp phải những người tích lũy. Nó [trông giống như một thành ngữ hữu ích] (http://www.lix.polytechnique.fr/~liberti/public/computing/prog/prolog/prolog-tutorial.html#iteration). Có đọc và hiểu những gì một người tích lũy là, tôi đã có thể viết một thực hiện mới bằng cách sử dụng một và sau đó kiểm tra nó chống lại mã của bạn. Tôi đã nghĩ ra điều tương tự. Vấn đề: Tôi vẫn nhận được một ngăn xếp tràn vào khoảng 'counting_sum (350000, X) .' Bất kỳ ý tưởng tại sao đó là? –

+1

Thật kỳ lạ. Tôi đã thử mã tôi cung cấp với SWI với '3500000' (mười lần con số của bạn) và nó xử lý nó một cách dễ dàng. – gusbro

+2

Tôi đang suy đoán, nhưng GNU Prolog có thể không làm tối ưu hóa đuôi trong chế độ diễn giải (nhưng SWI Prolog nào). @RyanStewart: làm thế nào về việc xác nhận xem bạn đã sử dụng một trình biên dịch gprolog biên dịch hay chỉ là trình thông dịch? – hardmath

Các vấn đề liên quan