此代码可能会有所帮助:
peano_redux.pl
我花了很长时间才完成它,它仍然有坏的角落。我试图保持“关闭皮亚诺公理”,但必须采取一些捷径——这是编程,而不是一般定理证明。
我还使用了老派和凌乱的 Peano 表示法s(s(s(s(z)))
,而不是更清洁和适当的基于列表的表示法:[s,s,s,s]
.
能够在两个变量 PN 和 NN 之间建立一个约束是非常酷的,这样如果 NN 绑定到一个自然数,PN 就会自动绑定到对应的 Peano 数,反之亦然。这可能可以通过使用属性变量来完成,但我没有考虑过。
计算预计非常慢。尝试在 padd/pmult 谓词上建表会很有趣。
Peano Numbers 和 Naturals 之间的双向转换存在两个版本:一个使用 CLP(FD),另一个使用基本 Prolog。注释掉你不想要的版本。
这总体上是一个有趣的(但耗时的练习)。它提供了大量调试和思考控制流的实践,并迫使您注意不希望的统一、不终止、提前终止和绑定/新变量配置的特殊情况。
它还强调了在编程时编写单元测试的绝对必要性,为您提供进步的脚手架,
由于难以解释的原因,看似无害的代码重新排列可能会导致以前工作的 Prolog 程序失败或无限循环。让测试用例回到正轨可以避免在“修复问题直到它们工作”和可能的“手动运行测试”上浪费时间。
单元测试对于传达你的问题规范也很有用 编程课程应该首先围绕这个概念进行——现在已经不是 80 年代了。
通过发出命令运行所有测试用例以rtall
获得巨大成功:
?- rt_all.
Correct to: "rtall"? yes
% PL-Unit: pm ................... done
% All 19 tests passed
% PL-Unit: pnat ......... done
% All 9 tests passed
% PL-Unit: pequal .... done
% All 4 tests passed
% PL-Unit: padd ................................. done
% All 33 tests passed
% PL-Unit: pless ................. done
% All 17 tests passed
% PL-Unit: pmult .......................
% 1,649 inferences, 0.000 CPU in 0.000 seconds (100% CPU, 8951351 Lips)
.
% 3,097 inferences, 0.000 CPU in 0.000 seconds (98% CPU, 10109979 Lips)
.
% 5,813 inferences, 0.001 CPU in 0.001 seconds (100% CPU, 11183341 Lips)
.
% 2,598 inferences, 0.000 CPU in 0.000 seconds (100% CPU, 9577492 Lips)
.
% 768 inferences, 0.000 CPU in 0.000 seconds (100% CPU, 8491724 Lips)
.
% 1,847 inferences, 0.000 CPU in 0.000 seconds (96% CPU, 9731501 Lips)
.
% 8,453,914 inferences, 0.668 CPU in 0.674 seconds (99% CPU, 12651865 Lips)
.
% 4,273 inferences, 0.000 CPU in 0.000 seconds (100% CPU, 10987655 Lips)
.
% 8,389 inferences, 0.001 CPU in 0.001 seconds (99% CPU, 11702424 Lips)
.
% 12,506 inferences, 0.001 CPU in 0.001 seconds (100% CPU, 11900038 Lips)
.
% 45,453 inferences, 0.004 CPU in 0.004 seconds (100% CPU, 11844692 Lips)
. done
% All 34 tests passed
% PL-Unit: pqr ................Found: 16*13+8=216
Found: 37*12+8=452
Found: 7*53+1=372
Found: 28*7+13=209
Found: 33*14+6=468
Found: 23*5+19=134
Found: 21*3+3=66
Found: 31*8+1=249
Found: 14*20+9=289
Found: 5*2+4=14
Found: 4*9+0=36
Found: 30*3+6=96
Found: 40*11+16=456
Found: 11*4+8=52
Found: 10*12+3=123
Found: 18*20+0=360
Found: 5*61+2=307
Found: 46*2+0=92
Found: 1*215+0=215
Found: 47*7+30=359
. done
% All 17 tests passed
true.
模糊地查阅了一些参考资料: