Я хочу создавать динамические факты в прологе - PullRequest
6 голосов
/ 29 декабря 2011

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

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-прологе:

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

1 Ответ

7 голосов
/ 29 декабря 2011

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

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

?- not(42).
true.

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

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

:-dynamic(not/1).

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

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

...