2011-12-29 23 views
6

Tôi đã viết mã đơn giản sau đây, và tôi mong rằng khi tôi viết 'nam', mã này hỏi tôi một lần "là nam không?" và nếu tôi nhập 'Không' nó viết trên màn hình "cô ấy là nữ".Tôi muốn tạo các sự kiện động trong prolog

male :- (print('is it male ? '),read(yes)) -> true; asserta(not(male)),female. 
female:- not(male),print('she is female'). 
not(P) :- (call(P) -> fail ; true) . 

nhưng mã này đã lỗi sau:

uncaught exception: error(permission_error(modify,static_procedure,not/1),asserta/1); 

lỗi trong SWI-Prolog là:

ERROR: asserta/1: No permission to modify static_procedure `not/1' 
+1

không/1 là quy trình tĩnh được xác định trước. Xem xét việc đổi tên thành cái gì khác. Ngoài ra nó có vẻ không hoàn toàn đúng những gì bạn đang làm. – gusbro

Trả lời

7

Như gusbro nói, không/1 là một thủ tục tĩnh được xác định trước (và do đó nó không phải là một ý tưởng tốt để sử dụng cùng một tên). Tuy nhiên, đây không phải là lý do bạn nhận được lỗi trong SWI-Prolog như bạn có thể ghi đè lên độ nét tiêu chuẩn:

?- assert(not(42)). 
true. 

?- not(42). 
true. 

vấn đề là bạn đã xác định không/1 trong mã của bạn và khi bạn không khai báo một vị từ rõ ràng là dynamic, swi-prolog sẽ giả định rằng nó là tĩnh và sẽ không cho phép bạn thay đổi nó.

Bạn có thể khai báo nó như động bằng cách chèn dòng này trong mã của bạn:

:-dynamic(not/1). 

Tôi nghĩ rằng điều này sẽ không giải quyết được vấn đề trong triển khai prolog khác (ví dụ gnu-prolog) như thông báo lỗi nói permission_error(modify,static_procedure,not/1) ; trong mọi trường hợp, bạn nên đổi tên.

Nhân tiện, sẽ đơn giản và rõ ràng hơn để chỉ cần kiểm tra xem đối số là gì và in thông điệp tương ứng. Tuy nhiên, nếu bạn muốn tạo một cái gì đó phức tạp hơn (sử dụng một trạng thái có thể), bạn có thể sử dụng các biến toàn cục vì chúng có hiệu quả hơn để khẳng định/rút lại.

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