首页 > 解决方案 > 从 Prolog 递归函数获取输出值

问题描述

这些天我正在学习 Prolog,需要将两个列表合并为一个遵循此规则的列表:

ListA: [], ListB: [] => ResultList: []
ListA: [], ListB:[a,b,c] => ResultList: [[a],[b],[c]]
ListA: [1,2], ListB:[a,b,c] => ResultList: [[1,2,a],[1,2,b],[1,2,c]]

我遇到了递归函数输出值问题,这是我的编码:

extend_my_path([],_,_,_).
extend_my_path([H|T],OriginalPath,OrignailMewPaths,NewPaths) :-
    append(OriginalPath,[H],NewPath),
    append(OrignailMewPaths,[NewPath],NewPaths1),
    print("NewPaths1:"),print(NewPaths1), nl,
    extend_my_path(T,OriginalPath,NewPaths1,NewPaths1).

运行它会给出以下输出,但没有 Result 变量的值:

?- extend_my_path([a,b,c],[1,2],[],Result).
"NewPaths1:"[[1,2,a]]
"NewPaths1:"[[1,2,a],[1,2,b]]
"NewPaths1:"[[1,2,a],[1,2,b],[1,2,c]]
true.

我希望得到它的价值,如:

Result=[[1,2,a],[1,2,b],[1,2,c]]

如果有人能指出原因,我们将不胜感激。谢谢。

标签: prolog

解决方案


我在这六行代码中看到了相当多的混乱。以下是一些有问题的线索:

  • 您的问题是根据三件事定义的,但您的谓词有四个参数。最后两个应该是什么?
  • 你有一个单例变量NewPaths,这是一场灾难
  • 您的基本案例将一个空列表与任何其他三件事联系起来!试试看:extend_my_path([], lightning, [the,sound,of,rain], "fresh coffee")是真的!这似乎不太可能是您想要的。
  • 有人想知道“Orignail Mew Paths”是什么,或者“路径”与这里的任何东西有什么关系。错别字很重要,改正!
  • 归纳案例以 的两个副本结束NewPaths1,这似乎很可疑,因为我们在开始时有两个非常不同的变量,并且正如您在基本案例中看到的那样,它们是什么并不重要。奇怪的!

我认为这里发生的事情是您认为将内容添加到列表的唯一且正确的方法是 with append/3,这是不正确的。我认为 Prolog 的单赋值语义进一步说服了您,您需要另一个参数来创建空列表供您附加。你错过了递归的基本情况,所以你永远不会得到合理的回报;让它敞开至少让你变得真实,但没有给你束缚。这里的根本问题是您的代码中没有合理的关系。让我们再试一次。

您正在尝试编写一个谓词,其名称和参数更像这样:

% extend_path(Path, Possibilities, NewPaths)

这里不需要第四个参数,因为你不需要知道到目前为止你在创建 NewPaths 时做了什么,你可以为当前的可能性构建路径,并且知道递归正在处理其余的事情。

然后,您的基本情况将是您没有更多可能性的情况,因此没有新的路径:

extend_path(_, [], []).

这并没有说任何与任何相关的东西,它说“当我没有可能时,任何前缀的路径扩展都是空的。”

然后,您的归纳案例采用您的第一个论点并将其附加到您的可能性列表中的下一项。这在您的新路径列表中。

extend_path(Prefix, [Ext1|ExtRest], [Next1|NextRest]) :-
    append(Prefix, [Ext1], Next1),
    extend_path(Prefix, ExtRest, NextRest).

这实际上是说“给定一些前缀,并且我的扩展列表中还有一个 Ext,将生成一个新的路径扩展 Next1,例如:Prefix + [Ext1] 是 Next1。” 实际上,它说的比递归步骤多一点。但是这里的想法是咬掉一部分,Ext1然后将其与一部分结果Next1匹配,然后将其余的输入与其余的输出进行匹配。

最后,不要单例变量“警告”视为警告。这不像Python 会因为函数之间没有足够的换行符而生气。单例变量几乎总是严重错误,尤其是对于 Prolog 的新用户!注意他们!

希望这可以帮助!


推荐阅读