То, как вы определили свои предикаты для odd
и even
, выглядит странно. Вы сказали, что variable(X)
- это четное число или нечетное число. И вы сказали, что variable(X)
нечетно, если это число или нет. В этом логе c вы говорили, что любое число всегда четное и нечетное, а любое нечисловое вызовет ошибку переполнения стека.
Кроме того, причина ошибки «Нет разрешения на изменение состояния. c процедура 'число / 1' "связана с тем, что уже существует встроенный предикат для определения того, является ли параметр числом. Это просто number(X)
.
Также существует предикат для выполнения целочисленного деления с остатком. Например:
?- divmod(42,5,X,Y).
X = 8,
Y = 2.
Итак, в этом примере говорится, что 8 x 5 + 2 = 42
.
Мы можем использовать это для определения even
и odd
.
even(X) :- number(X),divmod(X,2,_,0).
odd(X) :- number(X),divmod(X,2,_,1).
Число будет четным при делении на 2
, оно имеет остаток 0
и нечетным, если остаток равен 1
.
Вместо того, чтобы определять odd(X) :- not(even(X))
, я определил оба предиката как Как правило, лучше определять предикаты положительно, чем отрицанием, поскольку это может повлиять на ожидаемое поведение. В данном случае это не имеет значения, но в целом это хорошая привычка.