В вашем определении mult/3
должны быть известны первые два аргумента. Если один из них все еще является переменной, произойдет ошибка создания экземпляра. Например. mult(2, X, 6)
приведет к ошибке создания экземпляра, хотя X = 3
- правильный ответ; на самом деле единственный ответ.
Есть несколько вариантов:
арифметика-преемник , ограничения или мета-логические предикаты.
Вот отправная точка с арифметикой-преемником:
add(0,Y,Y).
add(s(X),Y,s(Z)) :- add(X,Y,Z).
Другой подход заключается в использовании ограничений на целые числа. YAP и SWI имеют library(clpfd)
, который можно использовать очень гибко: как для обычных целочисленных вычислений, так и для более общих ограничений. Конечно, умножение уже предопределено:
?- A * B #= C.
A*B#=C.
?- A * B #= C, C = 6.
C = 6,
A in -6.. -1\/1..6,
A*B#=6,
B in -6.. -1\/1..6.
?- A * B #= C, C = 6, A = 2.
A = 2,
B = 3,
C = 6.
Метатологические предикаты: я не могу рекомендовать эту опцию, в которой вы будете использовать var/1
, nonvar/1
, ground/1
, чтобы различать различные случаи и обрабатывать их по-разному. Это настолько подвержено ошибкам, что я редко видел правильную программу, использующую их. На самом деле, даже очень известные учебники содержат серьезные ошибки!