如果你想深入研究终止性质,使用
successor-arithmetics的程序是一个理想的研究对象:你事先知道它们应该描述什么,因此可以集中精力处理更多的技术细节。你需要理解几个概念。
全局终止
最简单的方法是考虑Goal, false
。当且仅当Goal
普遍终止时,它才终止。也就是说:查看跟踪器是最无效的方式——它们只会向你展示单个执行路径。但你需要同时理解所有路径!而当你想要普遍终止时,永远不要查看答案,它们只会让你分心。如上所述:你得到了三个整洁而正确的答案,然后你的程序循环。因此最好用false
“关闭”答案。这样可以消除所有干扰。
失败切片
你需要了解的下一个概念是
失败切片。取一个纯单调逻辑程序并添加一些
false
目标。如果得到的失败切片不会(普遍地)终止,则原始程序也不会。在您的示例中,请考虑以下内容:这些
false
目标有助于消除程序中的不相关装饰:剩余部分清楚地显示了为什么
prod(X,Y,s(s(s(s(s(s(0)))))))。
不终止。它不终止,因为该片段根本不关心
P
!您希望第三个参数有助于使
prod/3
终止,但该片段向您展示这一切都是徒劳的,因为
P
在任何目标中都不出现。不需要啰嗦的跟踪器。
通常很难找到最小的故障片段。但一旦找到了,确定其终止或非终止属性就变得非常简单。经过一段时间后,您可以使用直觉来想象一个片段,然后使用理性来检查该片段是否相关。
关于故障片段的概念,最引人注目的是:如果您想改进程序,则必须修改上述片段中可见的部分!只要不更改它,问题就会持续存在。因此,故障片段是程序中非常重要的部分。
终止推断
那是你所需要的最后一件事情:一个终止推断器(或分析器),例如
cTI,将帮助您快速识别终止条件。查看
prod/3
和改进后的
prod2/3
的推断终止条件
这里!
编辑:由于这是一个作业问题,我没有发布最终解决方案。但为了明确起见,以下是迄今为止获得的终止条件:
如果 b(A),b(B),则 prod(A,B,C) 终止。
如果 b(A),b(B) 或者 b(A),b(C),则 prod2(A,B,C) 终止。
因此,新的
prod2/3
比原始程序严格更好!
现在,你需要找到最终程序。它的终止条件是:
如果 b(A),b(B) 或者 b(C),则 prod3(A,B,C) 终止。
首先,试着找到
prod2(A,B,s(s(s(s(s(s(0)))))))
的失败切片!我们期望它会终止,但它仍然没有。所以把程序加上手动的
false
目标!剩下的部分将向你展示关键!
最后一个提示:你需要添加一个额外的目标和一个事实。
编辑:根据要求,这里是prod2(A,B,s(s(s(s(s(s(0)))))))
的失败片段:
prod2(0,_,0) :false。
prod2(s(N),M,P):
sum(M,K,P),
prod2(N,M,K),false。
sum(0,M,M)。
sum(s(N),M,s(K)): false,
sum(N,M,K)。
请注意sum/3
的显着简化定义。它只说:0加上任何东西都是任何东西。没有更多了。因此,即使是更专业的prod2(A,0,s(s(s(s(s(s(0)))))))
也会循环,而prod2(0,X,Y)
则优雅地终止...