Sử dụng các mục tiêu dư thừa trong các truy vấn


12

(Theo đề xuất của @repeat ) Hãy xem xét một truy vấn của chương trình thuần túy 1 ?- G_0. Sử dụng nếu có bất kỳ truy vấn ?- G_0, G_0.nào?

Chú thích
1 Không có tabling (để an toàn), các ràng buộc là OK.
Bài trước về chủ đề.


Bình phương số lượng kết quả?
Willem Van Onsem

1
Tôi cho rằng không có thông tin nhà nước nào được bảo tồn khỏi hoạt động liên tiếp của mục tiêu. Nói cách khác, một biến thể của câu hỏi không được phép, ví dụ: ?- G_0(State), G_0(State).Ngoài ra không có trạng thái nào được chuyển qua ngăn xếp từ kết quả của mục tiêu đầu tiên sang mục tiêu thứ hai?
Guy Coder

1
G_0có thể là bất kỳ mục tiêu (thuần túy) nào, bao gồm, giả sửG_0 = append(Xs,Ys,Zs)
sai

1
@GuyCoder: kết hợp là bắt buộc. (Với G_0;G_0một người có thể kiểm tra các tác dụng phụ hoặc các vấn đề về hiệu năng / bộ nhớ đệm / tab)
sai

1
BTW, thay vì G_0(State),G_0(State)viết thaycall(G_1,State), call(G_1,State)
sai

Câu trả lời:


3

Truy vấn ?- G_0, G_0.giúp xác định câu trả lời dư thừa của?- G_0.

Để làm như vậy, nó đủ để so sánh số lượng câu trả lời ?- G_0.với số lượng câu trả lời của ?- G_0, G_0.. Không cần lưu trữ những câu trả lời đó (dù sao đây cũng là nguồn thường xuyên xảy ra lỗi). Chỉ cần hai số nguyên là đủ! Nếu chúng bằng nhau, thì không có sự dư thừa. Nhưng nếu ?- G_0, G_0.có nhiều câu trả lời hơn, thì có một số dư thừa. Đây là một ví dụ:

p(f(_,a)).
p(f(b,_)).

?- p(X).
   X = f(_A, a)
;  X = f(b, _A).  % two answers

?- p(X), p(X).
   X = f(_A, a) 
;  X = f(b, a)
;  X = f(b, a)
;  X = f(b, _A).   % four answers
                   % thus p(X) contains redundancies

... và bây giờ hãy sửa lỗi này:

p(f(B,a)) :-
   dif(B, b).
p(f(b,_)).

?- p(X).
   X = f(_A, a), dif(_A, b)
;  X = f(b, _A).

?- p(X), p(X).
   X = f(_A, a), dif(_A, b), dif(_A, b).
;  X = f(b, _A).    % again two answers, thus no redundancy

Không cần phải tự kiểm tra các ràng buộc liên quan.

Điều này có thể được mở rộng hơn nữa khi chúng tôi rõ ràng đang tìm kiếm câu trả lời dư thừa chỉ bằng cách sử dụng call_nth/2.

?- G_0, call_nth(G_0, 2).

1

Xem xét truy vấn của chương trình thuần túy1? - G_0. Sử dụng nếu có bất kỳ truy vấn nào? - G_0, G_0. có không

Tôi thấy không có ích gì cho mục tiêu thứ hai, đặc biệt là khi tối ưu hóa đệ quy đuôi ( tối ưu hóa cuộc gọi cuối cùng ) được BẬT .

Tôi có thể nhận ra một vấn đề về GC (stack / heap overflow) khi truy vấn là tài nguyên tham lam và các tùy chọn ở trên là TẮT (ví dụ: khi gỡ lỗi).

Tôi nghĩ rằng cuộc gọi thứ hai là dư thừa (đối với chương trình thuần túy) và cần được loại bỏ bởi trình biên dịch.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.