Пролог дополнение упражнения - PullRequest
3 голосов
/ 27 октября 2011

У меня есть этот очень простой код для представления чисел. Проблема в том, что я использую функцию add2.

Пример: add2(s(0)+s(s(0)), s(s(0)), Z). возвращает s(s(s(s(s(0))))) правильно. Однако add2(0, s(0)+s(s(0)), Z). всегда returns s(0)+s(s(0)). Кто-нибудь может понять, почему это происходит?

numeral(0).
numeral(s(X)) :- numeral(X).
numeral(X+Y) :- numeral(X), numeral(Y).

add(0,X,X).
add(s(X),Y,s(Z)) :- add(X,Y,Z).

%%  exercise 1
add2(X,Y,R) :- add(X,Y,R).
add2(X+Y,Z,R) :- add(X,Y,A),add2(A,Z,R).
add2(X,Y+Z,R) :- add(Y,Z,A),add2(X,A,R).

Ответы [ 3 ]

2 голосов
/ 27 октября 2011

Это происходит из-за комбинации первого предложения add2 и первого предложения add. Ваш add2(0, ..., ...) вызовет add(0, ..., ...), который всегда объединяет второй и третий аргумент.

2 голосов
/ 27 октября 2011

В функции Prolog символы, такие как инфикс +, не оцениваются. Кажется, вы пытаетесь оценить все вхождения +. Однако некоторые из них все еще не оценены, и это может быть довольно сложно, если вы попытаетесь сделать это ad hoc, как в add2/3. Рассматривать add2(0+0+0,0,R), что не соответствует вашему определению.

То, что вы называете numeral/1, лучше назвать expression/1.

Рассмотрим определение вспомогательного предиката eval/2 для упрощения выражений до s (X) -номер. Тем не менее, обратите внимание, что даже такое определение по-прежнему не удастся для целей, подобных add2(0,0,0+0). Это неотъемлемая проблема, которая может быть решена только с помощью ограничений или аналогичных методов ...

0 голосов
/ 27 октября 2011

Когда вы вызываете add2(0, s(0)+s(s(0)), Z), он будет унифицирован с первым предложением add2/3, так как это первое предложение содержит только три переменные в заголовке, поэтому его можно объединить с любым вызовом add2/3.Это, в свою очередь, в вашем примере приведет к вызову первого предложения add/3, поэтому Z будет связан с s(0)+s(s(0)).

. Проблема с вашим кодом состоит в том, что более конкретные предложения add2/3размещены после общего положения.Таким образом, чтобы ваш код работал, поместите первое предложение add2/3 last и добавьте сокращения к двум другим, например,

add2(X+Y,Z,R) :- !,add(X,Y,A),add2(A,Z,R).

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

...