2011-01-26 8 views

Trả lời

8

Có những "ẩn" cắt trong cấu trúc if-then-else của Prolog:

abs2(X,Y) :- X < 0 -> Y is -X ; Y = X. 

Nó là một cái gì đó của một quirk, nhưng Prolog không quay trở lại trên subgoal tạo thành "tiền đề" của một nếu-sau đó hoặc nếu-sau đó xây dựng khác. Ở đây, nếu X < 0 thành công lần thử đầu tiên, thì sự lựa chọn mệnh đề "sau đó" trên mệnh đề "else" được cam kết (do đó mô tả hành vi này là một "ẩn" cắt).

Có thêm vai trò cho việc cắt giảm trong mệnh đề đầu tiên của biến vị ngữ abs2/2 như được viết trong câu hỏi. Như Nicholas đã chỉ ra, việc cắt giảm ở cuối điều khoản thứ hai không có hiệu lực (không còn điểm nào khi bạn đến đó). Nhưng như Kaarel chỉ ra, có một điểm lựa chọn được mở nếu mệnh đề đầu tiên thành công.

Vì vậy, những gì tôi đã viết, cho phép việc sử dụng một cắt, là thế này:

abs2(X,X) :- X >= 0, !. 
abs2(X,Y) :- Y is -X. 

bình luận Nicholas cũng gợi ý những cách để "arithmetize" giá trị tuyệt đối (chứ không phải sử dụng một định nghĩa logic) và tránh "cắt" theo cách đó.

+1

Điều bạn đặt tên là" cắt ẩn "không hoạt động như cắt:!/0 cũng ngăn các mệnh đề thay thế không được thử, nhưng địa phương cam kết trong if-then-else thì không. Do đó tôi tìm thấy thuật ngữ nghèo nàn này. – mat

+2

@mat: Tôi rất vui khi được học về thuật ngữ tốt hơn. Tôi đã viết "ẩn cắt" như là một tiết lộ của các loại trong việc cung cấp giải pháp của tôi tránh (rõ ràng) sử dụng cắt, do đó, người đọc có thể đánh giá liệu giải pháp của tôi là hợp lệ hoặc "ăn gian". So sánh tài liệu SWI-Prolog cho các phần mềm điều khiển (Sec. 2.4.7) để có giải thích về cam kết/cắt cục bộ trong "if-then-else". http://www.swi-prolog.org/pldoc/doc_for?object=section%282,%274.7%27,swi%28%27/doc/Manual/control.html%27%29%29 – hardmath

5

Prolog của tôi hơi bị gỉ, nhưng tại sao bạn thậm chí cần cắt? Nếu bạn viết các vị đúng cách, backtracking không thể thành công, vì vậy việc cắt giảm là không cần thiết:

abs(X, Y) :- number(X) , X < 0 , Y is -X . 
abs(X, X) :- number(X) , X >= 0 . 
+4

Mã của bạn vẫn để lại một điểm lựa chọn. Lựa chọn này dẫn đến thất bại, nhưng nó vẫn được xem xét. Một vết cắt sẽ tránh được điều đó. – Kaarel

+3

Nếu bạn biết rằng bạn đang xử lý các giá trị không thể tách rời, bạn có thể tính toán ABS bằng một điểm lựa chọn bằng các bit twiddling: http://www-graphics.stanford.edu/~seander/bithacks.html#IntegerAbs –

+6

Một tùy chọn khác là : 'abs (X, Y): - Y là ký hiệu (X) * X .' (giả sử rằng thực thi prolog của bạn hỗ trợ một biến vị ngữ/1 được xây dựng sẵn). –

3

Không cần sử dụng !

Đơn giản chỉ cần viết:

abs2(X,Y) :- Y is abs(X).