2011-12-15 23 views
27

Vấn đề mà tôi gặp phải là hơi tầm thường. Tôi muốn sử dụng logic không trong Prolog, nhưng có vẻ như not/1 không phải là điều mà tôi muốn:Hợp lý 'không' trong Prolog là gì?

course(ai). 
course(pl). 
course(os). 

have(X,Y) :- course(X),course(Y),not(X = Y). 

tôi truy vấn:

have(X,Y), write(X-Y), nl , fail. 

Và tôi không nhận được kết quả tôi muốn: (

+6

kết quả bạn muốn là gì? –

+2

kết quả mà bạn nhận được cũng sẽ là tốt đẹp cho câu hỏi dễ đọc btw – m09

+0

Tôi muốn nó in cho tôi kết hợp các tên khóa học, trong đó hai không bằng nhau, ý tôi là: ai-pl ai-os pl-ai pl -os os-ai os-pl –

Trả lời

12

Trong cả hai SWI-Prolog và GNU Prolog, sau đây nên làm việc:

have(X, Y) :- course(X), course(Y), X \= Y. 

Trong SWI-Prolog, bạn cũng có thể sử dụng dif/2, có thể thuận tiện hơn vì bạn có thể sử dụng nó trước đó trong ngữ:

have(X, Y) :- dif(X, Y), course(X), course(Y). 
+7

anyway, OP được gắn thẻ swi-pl mà không kiểm tra trên swi Tôi đoán kể từ phiên bản của mình hoạt động trên swi, ngay cả khi không/1 là không được chấp nhận ở đó. – m09

33

Thay not(X = Y) bạn cần phải viết \+ X = Y hoặc X \= Y. Nhưng hãy cân nhắc sử dụng dif(X,Y) để thay thế. dif/2 có trong B, SWI, YAP, SICStus. Để thấy sự khác biệt:

?- X = b, dif(a, X). 
X = b. 

?- X = b, \+ a = X. 
X = b. 

Vì vậy, cho đến giờ mọi thứ có vẻ ổn. Nhưng điều gì, nếu chúng ta chỉ đơn giản là trao đổi thứ tự của hai mục tiêu?

?- \+ a = X, X = b. 
false. 

?- dif(a, X), X = b. 
X = b. 

(\+)/1 nay cho chúng ta một kết quả khác nhau, bởi vì có một câu trả lời cho a = X, mục tiêu \+ a = X sẽ thất bại.

(\+)/1 do đó không phủ định, nhưng có nghĩa là không thể kích hoạt tại thời điểm này trong thời gian.

A safe approximation cũng có thể có trong ISO Prolog.

+3

Chỉ vì mục đích đầy đủ, "âm thanh phủ định" này cũng có sẵn trong ECLiPSe, sử dụng '~/2' hoặc' ~ =/2', và các truy vấn tương đương sẽ là '? - ~ (a = X), X = b.' hoặc '? - a ~ = X, X = b.' – twinterer

+0

Có bất kỳ Prolog nào khác ngoài ECLiPSe sử dụng' (~ =)/2' cho 'dif/2' không? Từ trí nhớ, Mu- và Nu-Prolog đã từng có nó. – false

1

Như bạn đã nói, OP, điều này là tầm thường.

Hãy thử

course(ai). 
course(pl). 
course(os). 

have(X,Y) :- course(X), course(Y), X \== Y). 

Đó nên sửa chữa vị của bạn.

Nhìn đi trước một bước, mặc dù về mặt toán học phân nhịp, có thể bạn đang tìm kiếm các giải pháp cho (n C 2) như trái ngược với (n P 2) mà vị ngữ của bạn hiện đang cung cấp sự kết hợp thay vì hoán vị, sự lựa chọn lựa chọn thay vì sắp xếp các lựa chọn lựa chọn. Đây là điều mà tôi nghĩ.

Nếu đây là những gì bạn muốn, tôi sẽ đề nghị bạn thử

course(ai). 
course(pl). 
course(os). 

have(X,Y) :- course(X), course(Y), X @< Y). 

Trong đó sẽ ngăn chặn trùng lặp đảo ngược kết quả.

@< có nghĩa là ít hơn nguyên tử. < là số nguyên, @< là dành cho các nguyên tử.

3

Là một sự bổ sung cho câu trả lời của thành viên "false" ở trên, tức là

"Thay vì không (X = Y), bạn cần phải viết \ + X = Y,"

này có thể cung cấp ấn tượng rằng:

a. "không" và "\ +" là những thứ khác nhau

b. Các \ + sẽ làm việc trong khi không sẽ, err, không.

Sự hiểu biết của tôi là "không" và "\ +" là tương đương, nhưng rằng \ + được ưu tiên hơn trong các chương trình Prolog hiện đại, vì nó chuyển tải ý nghĩa trực quan hơn. Cụ thể, trong khi "không" có thể gợi ý "không đúng" với người lập trình không tự nguyện, "\ +" gợi ý "không thể chứng minh được" gần hơn với sự thật về hoạt động đó thực sự nói. Trong Prolog, "not" là một ví dụ về "phủ định là thất bại", nhưng nó cảm thấy rằng \ + sẽ làm cho nó rõ ràng hơn cho lập trình viên chính xác những gì đang được khẳng định trong bất kỳ quy tắc nào. Vì vậy, bạn có thể sử dụng "không" (hầu hết các triển khai PL giữ nó cho khả năng tương thích ngược) nhưng để trở thành một lập trình viên PL hiện đại thành ngữ, có lẽ bạn nên sử dụng \ +.

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