Я хочу создавать динамические факты в прологе

Я написал следующий простой код, и я ожидаю, что когда я напишу «мужской», этот код спросит меня один раз: «это мужчина?» и если я ввожу «Нет», на экране написано «она женщина».

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) .

но этот код имеет следующую ошибку:

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

ошибка в swi-prolog:

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

person vakarami    schedule 29.12.2011    source источник
comment
not/1 — предопределенная статическая процедура. Подумайте о смене имени на другое. Также кажется не совсем правильным то, что вы делаете.   -  person gusbro    schedule 29.12.2011


Ответы (1)


Как сказал gusbro, not/1 — предопределенная статическая процедура (поэтому не рекомендуется использовать одно и то же имя). Однако это не причина, по которой вы получаете ошибку в swi-prolog, поскольку вы можете перезаписать стандартное определение:

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

?- not(42).
true.

проблема в том, что вы уже определили not/1 в своем коде, и если вы не объявляете предикат явно как динамический, swi-prolog будет считать его статическим и не позволит вам его изменить.

Вы можете объявить его динамическим, вставив эту строку в свой код:

:-dynamic(not/1).

Я думаю, что это не решит проблему в других реализациях пролога (например, gnu-prolog), поскольку сообщение об ошибке говорит permission_error(modify,static_procedure,not/1); в любом случае настоятельно рекомендуется изменить имя.

Кстати, было бы проще и чище просто проверить аргумент и вывести соответствующее сообщение. Однако, если вы хотите создать что-то более сложное (возможно, с использованием состояния), вы можете использовать глобальные переменные, поскольку они более эффективны, чем утверждение/опровержение.

person Thanos Tintinidis    schedule 29.12.2011