swi-prolog中的peano整数乘法

swi-prolog中的peano整数乘法,prolog,multiplication,successor-arithmetics,Prolog,Multiplication,Successor Arithmetics,我现在正试图在Prolog中解决一个简单的“乘法peano整数”问题,几乎要发疯了 基本规则 peano整数的定义如下:0->0;1->s(0);2->s(s(0))s(s(s(0)->3等 该关系定义如下:乘法(N1,N2,R) 在哪里 N1是第一个peano整数(即类似于s(s(0))的值) N2是第二个peano整数(即类似于s(s(0))的值) R是生成的新peano整数(如s(s(s(0))) 我知道Prolog默认提供基本算术逻辑,但我尝试使用peano整数实现基本算术逻

我现在正试图在Prolog中解决一个简单的“乘法peano整数”问题,几乎要发疯了

基本规则
  • peano整数的定义如下:0->0;1->s(0);2->s(s(0))s(s(s(0)->3等
  • 该关系定义如下:乘法(N1,N2,R)
    • 在哪里
      • N1是第一个peano整数(即类似于s(s(0))的值)
      • N2是第二个peano整数(即类似于s(s(0))的值)
      • R是生成的新peano整数(如s(s(s(0)))
我知道Prolog默认提供基本算术逻辑,但我尝试使用peano整数实现基本算术逻辑

因为乘法基本上是一个重复的加法,我认为它可能看起来像这样:

?- prod(s(s(s(0))),s(s(s(0))),Result).
Result = s(s(s(s(s(s(s(s(s(0))))))))).

?- prod2(s(s(s(0))),s(s(s(0))),Result).
Result = s(s(s(s(s(s(s(s(s(0))))))))).
序言尝试 问题是,我不知道如何让prolog根据系数运行循环N次,添加peano整数并建立正确的结果。我相信这很容易实现,并且生成的代码可能不会超过几行代码。我已经尝试了几个小时了这让我开始发疯了

非常感谢你的帮助,还有…圣诞快乐


迈克

感谢@false对这篇文章的提示:

这篇文章中引用的PDF文档有助于澄清有关peano整数的一些特性,以及如何让简单的算术工作——第11页和第12页特别有趣:

代码可以这样设置-请注意整数相乘的两种方法:

%Basic assumptions
int(0). %0 is an integer
int(s(M)) :- int(M). %the successor of an integer is an integer

%Addition
sum(0,M,M). %the sum of an integer M and 0 is M.
sum(s(N),M,s(K)) :- sum(N,M,K). %The sum of the successor of N and M is the successor of the sum of N and M.

%Product
%Will work for prod(s(s(0)),s(s(0)),X) but not terminate for prod(X,Y,s(s(0)))
prod(0,M,0). %The product of 0 with any integer is 0
prod(s(N),M,P) :- 
    prod(N,M,K), 
    sum(K,M,P).%The product of the successor of N and M is the sum of M with the product of M and N. --> (N+1)*M = N*M + M

%Product #2
%Will work in both forward and backward direction, note the order of the calls for sum() and prod2()
prod2(0,_,0). %The product of 0 with any given integer is 0
prod2(s(N), M, P) :- % implements (N+1)*M = M + N*M
   sum(M, K, P),
   prod2(M,N,K).
在查阅数据库时,您会得到如下信息:

?- prod(s(s(s(0))),s(s(s(0))),Result).
Result = s(s(s(s(s(s(s(s(s(0))))))))).

?- prod2(s(s(s(0))),s(s(s(0))),Result).
Result = s(s(s(s(s(s(s(s(s(0))))))))).
请注意反向查询Prolog时,
prod()
prod2()
的不同行为-跟踪时,请注意Prolog在递归调用期间绑定其变量的方式:

?- prod(F1,F2,s(s(s(s(0))))).
F1 = s(0),
F2 = s(s(s(s(0)))) ;
F1 = F2, F2 = s(s(0)) ;
ERROR: Out of global stack

?- prod2(F1,F2,s(s(s(s(0))))).
F1 = s(s(s(s(0)))),
F2 = s(0) ;
F1 = F2, F2 = s(s(0)) ;
F1 = s(0),
F2 = s(s(s(s(0)))) ;
false.
因此,我不鼓励使用
prod()
,因为它不会在所有可想象的场景中可靠地终止,而是使用
prod2()

StackOverflow的员工让我非常兴奋。我得到了很多有用的反馈,这真的帮助我深入了解了Prolog的工作原理。非常感谢大家

迈克


编辑:感谢@false和下面的帖子,再次关注了这个问题:

也祝你圣诞快乐,欢迎来到Stack Overflow!可能是@MikeFloyd的副本:你可以在该链接下找到你需要的所有答案!@false:谢谢,我一定会查出来的!你使用了不以
prod(M,N,s(s(0))
!这个问题的目的是解决这些问题。谢谢@false,我修改了代码并添加了更多的描述性文本。