1

我在加入声明式推理时遇到了一些问题......所以我在这里问你我的推理是否正确,或者是否有问题,或者我是否遗漏了什么......

我有以下问题:编写一个反转列表元素的 Prolog 程序

例如,如果我调用类似:

myreverse([a,b,c,d,e],X)。我必须获得 X=[e,d,c,b,a]

我有以下解决方案:

naiverev([],[]).  
naiverev([H|T],R):- naiverev(T,RevT),
                    append(RevT,[H],R).

这是我的解释:

我有一个事实是空列表的逆是一个空列表。

如果第一个列表不为空,则事实不正确且不匹配,因此继续下一条规则。

规则说:证明列表 R 是列表 [H|T] 的逆的程序

我可以通过以下方式从右到左阅读逻辑含义:

如果 naivrev(T, RevT) AND append(RevT, [H], R) 为 TRUE ---> naivrev([H|T],R) 为 TRUE

所以(在规则的主体中)我假设“函数” naivrev(T,RevT)如果 RevT 是 T 的倒数则响应 TRUE,否则响应 FALSE。

同时我假设* **append(RevT,[H],R)如果 R 为 [H|RevT] 则响应 TRUE,否则响应 FALSE。

然后,如果规则体的两个部分都为 TRUE,则程序可以推断 HEAD 为 TRUE(在这种情况下,R 是 [H|T] 的倒数)

这个推理好还是我错过了什么?

4

1 回答 1

2

与前两次一样,您再次将 Prolog 的计算引擎与纯声明式阅读混合在一起。每当您在程序上说“规则不匹配所以继续前进”或类似的话时,您是在调用 Prolog 的算法来解释正在发生的事情,而不是逻辑。但是你正在变得更好,因为你的其他东西比以前更接近了。

规则一:空列表的反面就是空列表。(和你一样。)

规则2:[H|T]的逆是T的逆,称为RevT,附加到列表[H]。

当然,使这项工作有效的原因是 Prolog 将尝试规则 1,当它不匹配时,它将尝试规则 2,并递归地建立结果(您可能意识到,以一种非常低效的方式)。但是这种检查规则并在它们之间进行选择以及如何执行该过程的“使其开始”是Prolog添加到声明性或逻辑语句中的内容。

您对逻辑含义的解读是正确的:如果 naiverev(T, RevT) 为真且 append(RevT, [H], R) 为真,则 naiverev([H|T], R) 为真。这就像@false 在您之前的问题中解释的那样,所以我会说您肯定开始明白了。你关于身体真实导致头部真实的言论是正确的。

干得好,看起来你得到了它。:)

于 2013-03-20T17:55:28.653 回答