加入声明性推理我有一些问题...所以我在这里问你我的推理是否正确,或者是否有什么问题,或者我是否遗漏了什么......
我遇到以下问题:编写一个反转列表元素的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)和追加(RevT,[H],R)---> naivrev([H | T],R)它是真的
所以(在规则的主体中)我假设如果RevT是T的倒数,那么“function” naivrev(T,RevT)会响应TRUE,否则就错了。
同时我假设*如果R为[H | RevT]则**追加(RevT,[H],R)为TRUE,否则为FALSE。
然后,如果规则体的两个部分都为TRUE,程序可以推断出HEAD为TRUE(在这种情况下,R是[H | T]的倒数)
这种推理是好还是我遗失了什么?
答案 0 :(得分:2)
就像最后两次一样,你再次将Prolog的计算引擎与纯粹的声明性读数混合在一起。每当你说,程序上“规则不匹配所以继续”或类似的东西时,你就会调用Prolog的算法来解释发生了什么,而不是逻辑。但是你会变得更好,因为你的其他东西比以前更接近了。
规则1:空列表的反向是空列表。 (和你一样。)
规则2:[H | T]的反向与T的反向,称为RevT,附加到列表[H]。
当然,这项工作的原因在于Prolog将尝试规则1,当它不匹配时,它将尝试规则2,并递归地构建结果(以极低效的方式,正如您可能意识到的那样) 。但是,这种“逐步”检查规则并在它们之间进行选择以及如何执行进程,这是Prolog在声明或逻辑声明中添加的内容。
你对逻辑含义的解读是正确的:如果naiverev(T,RevT)为真且追加(RevT,[H],R)为真,那么naiverev([H | T],R)为真。这就像你在上一个问题中解释@false一样,所以我会说你肯定会开始得到它。你关于身体真实导致头部成真的评论是现实。
这么好的工作,看起来你得到了它。 :)