Nếu bạn muốn chuyển đổi một danh sách các số vào một biểu thức phụ gia, từ
[1,2,3]
để
1 + 2 + 3
bạn có thể làm một cái gì đó như thế này, sử dụng một cái gì đó như a danh sách chênh lệch:
list_to_additive_expr([] , 0).
list_to_additive_expr([X|Xs] , X + RHS) :-
sum_of(Xs , RHS).
Ngoài ra, bạn có thể sử dụng một ắc:
list_to_additive_expr(Xs , Expr) :-
list_to_additive_expr(Xs , 0 , Expr)
.
list_to_additive_expr([] , Expr , Expr) .
list_to_additive_expr([X|Xs] , RHS , Expr) :-
sum_of(Xs , X + RHS , Expr)
.
Tôi tin rằng bạn sẽ tìm thấy phong cách đầu tiên là không đúng đuôi đệ quy và như vậy sẽ không được tối ưu hóa thành một vòng qua đuôi đệ quy tối ưu hóa (TRO) — và vì vậy, nếu danh sách đủ dài, sẽ bị tràn ngăn xếp. Cách tiếp cận thứ hai nên có TRO được áp dụng và nên làm việc cho các danh sách có độ dài bất kỳ.
TRO là gì, bạn có thể hỏi? Dưới đây là Wikipedia with an answer for you:
Trong khoa học máy tính, một cuộc gọi đuôi là lời kêu gọi chương trình con điều đó xảy ra bên trong một thủ tục và tạo ra một giá trị trả về, sau đó được ngay lập tức quay trở lại bởi các thủ tục gọi . Trang web cuộc gọi sau đó được cho là ở vị trí đuôi, tức là vào cuối quy trình gọi điện. Nếu một chương trình con thực hiện một cuộc gọi đuôi cho chính nó, nó được gọi là đuôi đệ quy. Đây là trường hợp đặc biệt của đệ quy.
Cuộc gọi đuôi rất quan trọng vì chúng có thể được triển khai mà không cần thêm khung ngăn xếp mới vào ngăn xếp cuộc gọi. Hầu hết các khung của thủ tục hiện tại là không cần thiết bất kỳ nhiều hơn, và nó có thể được thay thế bằng khung của cuộc gọi đuôi, sửa đổi khi thích hợp (tương tự như lớp phủ cho quy trình, nhưng cho các cuộc gọi chức năng). Sau đó, chương trình có thể nhảy tới chương trình con được gọi.Tạo mã như vậy thay vì chuỗi cuộc gọi chuẩn được gọi là loại bỏ cuộc gọi đuôi hoặc tối ưu hóa cuộc gọi đuôi.
Ít nhất trong SWI Prolog, cho rằng để đánh giá ghi 'Tổng là Trưởng + Sum1' thay vì sử dụng' = 'dấu. Các manh mối để suy nghĩ lại để sử dụng Tail Recursion Optimization là hợp lệ, nhưng nếu bạn đang cố gắng học lập trình Declarative, chúng không phải là bản chất, vì nó là điểm yếu của thực tế mà lập trình khai báo đúng không tồn tại, và như Prolog như bất kỳ ngôn ngữ nào khác cũng bị các điểm yếu như thứ tự đánh giá theo thủ tục, trong trường hợp này là tối ưu. – Matej
"Mã này trả về true". - cho truy vấn nào? – ShiDoiSi