Я хочу создать динамические факты в 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) .

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

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'

1 ответов


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

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

?- not(42).
true.

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

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

:-dynamic(not/1).

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

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