prolog - Prolog 前身数学
问题描述
我有一个add2
谓词,它像这样解析ies(0)
的继承者在哪里0
1
?- add2(s(0)+s(s(0)), s(s(0)), Z).
Z = s(s(s(s(s(0)))))
?- add2(0, s(0)+s(s(0)), Z).
Z = s(s(s(0)))
?- add2(s(s(0)), s(0)+s(s(0)), Z).
Z = s(s(s(s(s(0)))))
ETC..
我正在尝试添加一个前任谓词,它将像这样工作
?- add2(p(s(0)), s(s(0)), Z).
Z = s(s(0))
?- add2(0, s(p(0)), Z).
Z = 0
?- add2(p(0)+s(s(0)),s(s(0)),Z).
Z = s(s(s(0)))
?- add2(p(0), p(0)+s(p(0)), Z).
Z = p(p(0))
我似乎找不到办法做到这一点。我的代码如下。
numeral(0).
numeral(s(X)) :- numeral(X).
numeral(X+Y) :- numeral(X), numeral(Y).
numeral(p(X)) :- numeral(X).
add(0,X,X).
add(s(X),Y,s(Z)) :- add(X,Y,Z).
add(p(X),Y,p(Z)) :- add(X,Y,Z).
resolve(0,0).
resolve(s(X),s(Y)) :-
resolve(X,Y).
resolve(p(X),p(Y)) :-
resolve(X,Y).
resolve(X+Y,Z) :-
resolve(X,RX),
resolve(Y,RY),
add(RX,RY,Z).
add2(A,B,C) :-
resolve(A,RA),
resolve(B,RB),
add(RA,RB,C).
解决方案
通常,使用后继算术相加意味着处理后继项,这些后继项具有形状0
或s(X)
whereX
也是后继项。这部分代码完全解决了这个问题:
add(0,X,X).
add(s(X),Y,s(Z)) :- add(X,Y,Z).
现在你必须做出决定;您可以在此处处理前辈和附加术语add/3
,或者您可以将此谓词包装在另一个将处理它们的谓词中。您似乎已选择add/3
使用add2/3
. 在这种情况下,您肯定需要创建一个缩减项,例如您在此处使用 构建的resolve/2
,并且我同意您对其中一部分的实现:
resolve(0,0).
resolve(s(X),s(Y)) :-
resolve(X,Y).
resolve(X+Y,Z) :-
resolve(X,RX),
resolve(Y,RY),
add(RX,RY,Z).
这一切都很好。您现在缺少的是一种处理p(X)
条款的方法。正确的做法是注意你已经有一种减一的方法,通过使用add/3
with s(0)
:
resolve(p(X), R) :-
resolve(X, X1),
add(s(0), R, X1).
换句话说,我们不是使用 X = Y - 1 来计算 X,而是使用 X + 1 = Y 来计算 X。
如果您的输入永远不会是负数,那么您的add2/3
谓词现在就可以工作了。
推荐阅读
- javascript - 角。如何根据服务的操作切换组件
- python - 如果“pip install”有效,为什么要“sudo pip install”?(HelloAnalytics.py 的问题)
- e-commerce - 按语言 ID 获取内容资产
- php - 我的 PHP 登录页面无法正常工作
- css - Child's padding mixes with Parent's padding
- macos - 编写此代码后,每当我打开我的 Mac 时,第三方应用程序都会得到验证
- laravel - 未定义密码重置器 [users]
- java - 如何使用Java在每个pdf文件中具有不同索引的两个字符串之间获取一个字符串
- angular - 从源“http://localhost:4200”访问“http://[::1]:3000/api/requests/...”处的 XMLHttpRequest 已被 CORS 策略阻止
- javascript - 来自相机的 Expo/React Native 图像路径