(SWI-PL) 我不知道如何创建序言规则来匹配这种特定类型的输入
(SWI-PL) I can't figure out how to create a prolog rule to match this particular type of input
所以我有一个家庭作业,我给出了以下代码:
numeral(0).
numeral(succ(X)) :- numeral(X).
numeral(X+Y) :- numeral(X), numeral(Y).
add(0,X,X).
add(succ(X),Y,succ(Z)) :- add(X,Y,Z).
我要定义一个 prolog 谓词 add2(X,Y,Z),它将产生例如以下输出
% Exercise 1 Test Cases (for copy-paste to the REPL
%% 1. add2(succ(0)+succ(succ(0)), succ(succ(0)), Z).
%% >>>> Z = succ(succ(succ(succ(succ(0)))))
%%
%% 2. add2(0, succ(0)+succ(succ(0)), Z).
%% >>>> Z = succ(succ(succ(0)))
%%
%% 3. add2(succ(succ(0)), succ(0)+succ(succ(0)), Z).
%% >>>> Z = succ(succ(succ(succ(succ(0)))).
%%
%% 4. add2(succ(0)+succ(0), succ(0+succ(succ(0))), Z).
%% >>>> Z = succ(succ(succ(succ(succ(0))))).
所以最近几天我一直在研究这个问题,并且对解决方案进行了合理的尝试。到目前为止,这是我一直在尝试的:
% Exercise 1 Solution
add2(X,Y,Z):- add(X,Y,Z).
add2(A+B,Y,Z):- add2(A,B,X), add2(X,Y,Z).
add2(X,A+B,Z):- add2(A,B,Y), add2(X,Y,Z).
现在,上面的代码对于提供的前 3 个输入工作得很好。我很难思考序言如何解释最后一个,以及我如何利用它。
这是我认为可能有效的方法。
add2(X, succ(A+B), Z):- add2(A,B,Y), add2(X, succ(Y), Z).
我在想的是,解释器会把 succ(0+succ(...)) 这样的输入识别为 succ(A+B),然后上面的规则就可以解析了0+succ(...) 变成 succ(...) 。我从 SWI-PL REPL 收到的输出很简单:
Z = succ(succ(succ(0+succ(succ(0)))))
我进行的另一个尝试如下:
add2(X,succ(0+succ(Y), Z)):- add2(X,succ(Y),Z).
但是,这会产生与以前相同的输出。我不确定为什么以上两种尝试似乎对我不起作用,虽然我做了其他猜测,但以上两种或其他谓词或多或少存在随机变化,如果我通过这种方法成功了,我会可能在不理解我在做什么的情况下得到了正确的答案。
我正在使用 SWI-PL 作为我的 prolog 发行版。
我认为在这里使用辅助谓词可能有助于解决问题。辅助函数会将用 succ(…)
和 … + …
级联表示的数字转换为统一样式(因此只有 succ(…)
)。
这样我们就可以实现这样的功能:
normsucc(0, 0).
normsucc(succ(X), succ(NX)) :-
normsucc(X, NX).
normsucc(X+Y, NXY) :-
normsucc(X, NX),
normsucc(Y, NY),
add(NX, NY, NXY).
那么我们可以利用normsucc
来计算总和:
add2(X, Y, Z) :-
normsucc(X, NX),
normsucc(Y, NY),
add(NX, NY, Z).
或更简单,如 建议:
add2(X, Y, Z) :-
normsucc(X+Y, Z).
所以我有一个家庭作业,我给出了以下代码:
numeral(0).
numeral(succ(X)) :- numeral(X).
numeral(X+Y) :- numeral(X), numeral(Y).
add(0,X,X).
add(succ(X),Y,succ(Z)) :- add(X,Y,Z).
我要定义一个 prolog 谓词 add2(X,Y,Z),它将产生例如以下输出
% Exercise 1 Test Cases (for copy-paste to the REPL
%% 1. add2(succ(0)+succ(succ(0)), succ(succ(0)), Z).
%% >>>> Z = succ(succ(succ(succ(succ(0)))))
%%
%% 2. add2(0, succ(0)+succ(succ(0)), Z).
%% >>>> Z = succ(succ(succ(0)))
%%
%% 3. add2(succ(succ(0)), succ(0)+succ(succ(0)), Z).
%% >>>> Z = succ(succ(succ(succ(succ(0)))).
%%
%% 4. add2(succ(0)+succ(0), succ(0+succ(succ(0))), Z).
%% >>>> Z = succ(succ(succ(succ(succ(0))))).
所以最近几天我一直在研究这个问题,并且对解决方案进行了合理的尝试。到目前为止,这是我一直在尝试的:
% Exercise 1 Solution
add2(X,Y,Z):- add(X,Y,Z).
add2(A+B,Y,Z):- add2(A,B,X), add2(X,Y,Z).
add2(X,A+B,Z):- add2(A,B,Y), add2(X,Y,Z).
现在,上面的代码对于提供的前 3 个输入工作得很好。我很难思考序言如何解释最后一个,以及我如何利用它。
这是我认为可能有效的方法。
add2(X, succ(A+B), Z):- add2(A,B,Y), add2(X, succ(Y), Z).
我在想的是,解释器会把 succ(0+succ(...)) 这样的输入识别为 succ(A+B),然后上面的规则就可以解析了0+succ(...) 变成 succ(...) 。我从 SWI-PL REPL 收到的输出很简单:
Z = succ(succ(succ(0+succ(succ(0)))))
我进行的另一个尝试如下:
add2(X,succ(0+succ(Y), Z)):- add2(X,succ(Y),Z).
但是,这会产生与以前相同的输出。我不确定为什么以上两种尝试似乎对我不起作用,虽然我做了其他猜测,但以上两种或其他谓词或多或少存在随机变化,如果我通过这种方法成功了,我会可能在不理解我在做什么的情况下得到了正确的答案。
我正在使用 SWI-PL 作为我的 prolog 发行版。
我认为在这里使用辅助谓词可能有助于解决问题。辅助函数会将用 succ(…)
和 … + …
级联表示的数字转换为统一样式(因此只有 succ(…)
)。
这样我们就可以实现这样的功能:
normsucc(0, 0).
normsucc(succ(X), succ(NX)) :-
normsucc(X, NX).
normsucc(X+Y, NXY) :-
normsucc(X, NX),
normsucc(Y, NY),
add(NX, NY, NXY).
那么我们可以利用normsucc
来计算总和:
add2(X, Y, Z) :-
normsucc(X, NX),
normsucc(Y, NY),
add(NX, NY, Z).
或更简单,如
add2(X, Y, Z) :-
normsucc(X+Y, Z).