Пролог: невозможно унифицировать второе выражение из-за предпочтения первого выражения

У меня есть следующее выражение пролога в моем файле, которое говорит само за себя. У меня есть все необходимые функции, необходимые для этого правила (назовем его 1), реализованные и протестированные правильно.

cal(plus(X,Y),Z):-cal(X,int(Z1)),cal(Y,int(Z2)),add(Z1,Z2,Z3),Z=int(Z3) ; cal(X,real(Z1)),cal(Y,real(Z2)),add(Z1,Z2,Z3),Z=real(Z3).

После нескольких часов попыток я не смог понять следующее:

?-call(plus(int(9),int(10)),Z). 

работает правильно и возвращает: -

Z = int(19).

но это не унифицируется с

?-call(plus(real(9.0),real(10.0),Z).

Я пробовал много вещей и пришел к выводу, что это связано с тем, что целая часть (до;) в правиле 1 была указана первой, чем действительная часть (я поменял две, и это начало работать в обратном порядке). Он пытается объединиться с первой частью и продолжается неоднократно. Поскольку такого факта нет, он просто входит в бесконечный цикл. Пожалуйста, укажите альтернативный способ сделать то же самое. Это единственная часть моего задания, которая осталась, и я часами блуждаю по ней.

Заранее спасибо!


person higherDefender    schedule 04.04.2011    source источник


Ответы (2)


Проблема в приоритете ";" против оператора ",". Используйте скобки или запишите два отдельных правила:

cal(plus(X,Y),Z):- 
    cal(X,int(Z1)),
    cal(Y,int(Z2)),
    add(Z1,Z2,Z3),
    Z=int(Z3).
cal(plus(X,Y),Z):- 
    cal(X,real(Z1)),
    cal(Y,real(Z2)),
    add(Z1,Z2,Z3),
    Z=real(Z3).
person hardmath    schedule 04.04.2011
comment
Вы не поняли проблемы. Ваш тоже не работает. Та же ошибка. - person higherDefender; 04.04.2011

Ну вот и ответ.

cal(plus(X,Y),G,Z):-cal(X,G,Z1),cal(Y,G,Z2),((Z2 = int(Z22),Z1 = int(Z11));(Z2 = real(Z22),Z1 = real(Z11))),add(Z11,Z22,Z3),(Z3=int(Z4) -> Z=int(Z3); Z=real(Z3)).

Вы должны вызывать функцию cal только один раз для определенного ввода. Избыточный вызов вызывает проблемы.

person higherDefender    schedule 04.04.2011