GNU Prolog中皮亚诺加法谓词查询为何返回no而非正确结果?
问题原因:混淆Peano数与普通整数的表示
你的代码实现的是Peano算术,但查询时错误使用了普通阿拉伯数字(如1),而Peano自然数是通过函子s/1(代表“后继”)嵌套定义的:
0对应自然数0s(0)对应自然数1s(s(0))对应自然数2- 以此类推
Prolog是严格的结构化匹配,整数1无法和Peano结构s(_)匹配,所以所有查询都会失败。
针对你的两段代码的具体解释
第一段plus代码
你的规则:
nat(0). nat(N) :- N > 0, M is N - 1, nat(M). plus(X, 0, X) :- nat(X). plus(X, s(Y), s(Z)) :- plus(X, Y, Z).
nat/1是验证阿拉伯数字是否为自然数,但plus/3的第二个分支用的是Peano结构s(Y),和nat/1处理的整数体系不兼容。- 查询
plus(1,1,Y)时:- 第一个规则
plus(X,0,X)不匹配(第二个参数是1不是0); - 第二个规则需要第二个参数是
s(Y)结构,但1是整数,匹配失败,最终返回no。
- 第一个规则
正确查询方式:用Peano结构替代整数
| ?- plus(s(0), s(0), Y).
会返回Y = s(s(0))(对应自然数2)。如果需要转换成阿拉伯数字,可以添加辅助谓词:
peano_to_num(0, 0). peano_to_num(s(P), N) :- peano_to_num(P, M), N is M + 1.
然后执行:
| ?- plus(s(0), s(0), Y), peano_to_num(Y, Num).
就能得到Num = 2。
第二段peano_add代码
peano_add(0, Sum, Sum). peano_add(s(N), M, s(Sum)) :- peano_add(M, N, Sum).
同样是纯Peano算术实现,参数必须是Peano结构。正确查询应该是:
| ?- peano_add(s(0), s(0), Y).
返回Y = s(s(0)),用整数1查询会因结构不匹配返回no。
内容的提问来源于stack exchange,提问作者notaorb
相关产品推荐
相关产品推荐

