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