Продолжайте получать сообщение об ошибке "Аргументы не достаточно созданы" не могу понять, почему - PullRequest
3 голосов
/ 19 марта 2012

Продолжайте получать ошибку Arguments are not sufficiently instantiated для умножения на правило сложения, которое я написал, как показано ниже.

mult(_, 0, 0).                                   %base case for multiplying by 0
mult(X, 1, X).                                   % another base case
mult(X, Y, Z) :-
   Y > 1,
   Y1 is Y - 1,
   mult(X, Y1, Z1),
   Z is X + Z1. 

Я новичок в Прологе и действительно борюсь даже с такими простыми проблемами.

Любые рекомендации для книг или онлайн-учебников были бы хорошими.

Я запускаю его на SWI-Prolog в Ubuntu Linux.

Ответы [ 2 ]

4 голосов
/ 20 марта 2012

В вашем определении 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, чтобы различать различные случаи и обрабатывать их по-разному. Это настолько подвержено ошибкам, что я редко видел правильную программу, использующую их. На самом деле, даже очень известные учебники содержат серьезные ошибки!

2 голосов
/ 19 марта 2012

Я думаю, что вы перевернули последние два звонка. Разве вы не имеете в виду:

mult(X,Y,Z):- Y>1,Y1 is Y-1, Z1 is X+Z, mult(X,Y1,Z1).

Редактировать: не обращайте на это внимания, снова посмотрел на код, и он не имеет смысла. Я верю, что ваш оригинальный код верен.

Что касается того, почему происходит эта ошибка, мне нужно знать, как вы вызываете предикат. Можете ли вы привести пример ввода?

Правильный способ вызова вашего предиката: mult(+X, +Y, ?Z):

?- mult(5,0,X).
X = 0

?- mult(5,1,X).
X = 5

?- mult(5,5,X).
X = 25

?- mult(4,4,16).
yes

?- mult(3,3,10).
no

и т.д.. Вызов его со свободной переменной в первых двух аргументах вызовет эту ошибку, потому что один из них будет использоваться в правой части is или в любой из сторон <, и эти предикаты ожидают, что основные термины будут успешными .

...