从Prolog递归函数获取输出值

从Prolog递归函数获取输出值,prolog,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([],_,

这些天我在学习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 varable的值:

?- 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]]

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

我看到这六行代码有点混乱。以下是一些有问题的线索:

你的问题定义为三件事,但是你的谓词有四个参数。最后两个应该是什么? 您有一个单例变量newpath,这是一个灾难 您的基本案例将空列表与其他三件事关联起来!试试看:延伸我的道路[],闪电,[声音,雨],新鲜咖啡是真的!这似乎不太可能是你想要的。 人们想知道什么是原始路径,或者路径与这里的任何东西有什么关系。拼写错误很重要,修复它们! 归纳案例以两个NewPaths1的副本结束,这似乎很可疑,因为我们在开始时有两个非常不同的变量,正如你在基本案例中看到的,它们是什么并不重要。古怪的 我认为这里发生的事情是,您认为向列表中添加内容的唯一正确方法是使用append/3,但事实并非如此。我认为Prolog的单赋值语义进一步说服了您,您需要另一个参数来创建要附加到的空列表。您错过了递归的基本情况,因此您从未得到合理的回报;让它敞开,至少让你明白了真相,但没有给你一个约束。这里的根本问题是,代码中没有一个合理的关系。让我们再试一次

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

% extend_path(Path, Possibilities, 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的新用户!注意他们


希望这有帮助

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

你的问题定义为三件事,但是你的谓词有四个参数。最后两个应该是什么? 您有一个单例变量newpath,这是一个灾难 您的基本案例将空列表与其他三件事关联起来!试试看:延伸我的道路[],闪电,[声音,雨],新鲜咖啡是真的!这似乎不太可能是你想要的。 人们想知道什么是原始路径,或者路径与这里的任何东西有什么关系。拼写错误很重要,修复它们! 归纳案例以两个NewPaths1的副本结束,这似乎很可疑,因为我们在开始时有两个非常不同的变量,正如你在基本案例中看到的,它们是什么并不重要。古怪的 我认为这里发生的事情是,您认为向列表中添加内容的唯一正确方法是使用append/3,但事实并非如此。我认为Prolog的单赋值语义进一步说服了您,您需要另一个参数来创建要附加到的空列表。您错过了递归的基本情况,因此您从未得到合理的回报;让它敞开,至少让你明白了真相,但没有给你一个约束。这里的根本问题是,代码中没有一个合理的关系。让我们再试一次

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

% extend_path(Path, Possibilities, NewPaths)
这里不需要第四个参数,因为您不需要知道到目前为止在创建新路径方面做了什么,您只需要为当前可能性构建路径,并且知道递归正在处理其余的部分

你的基本情况就是你没有更多的可能性 s、 因此,没有新的路径:

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的新用户!注意他们


希望这有帮助

与其尝试修复现有代码,不如尝试重新解决问题。您将展示以下示例:

ListA:[],ListB:[]=>ResultList:[] ListA:[],ListB:[a,b,c]=>结果列表:[[a],[b],[c]] ListA:[1,2],ListB:[a,b,c]=>结果列表:[[1,2,a],[1,2,b],[1,2,c]] 及

?-扩展我的路径[a,b,c],[1,2],],结果。 结果=[[1,2,a],[1,2,b],[1,2,c]] 第三个参数看起来完全不合适,与第一批示例相比,第一个和第二个参数是交换的,所以我们假设它应该是

?-ListA=[1,2],ListB=[a,b,c],扩展我的路径ListA,ListB,ResultList。 结果列表=[[1,2,a],[1,2,b],[1,2,c]] 因此,我们开始编写代码,只列出我们知道必须保存的案例:

扩展我的路径。 扩展我的路径[u ex[],[a,b,c],[a],[b],[c]]。 扩展我的路径[1,2],[a,b,c],[1,2,a],[1,2,b],[1,2,c]]。 把它概括起来给我们

扩展我的路径3[]、[]、[]。 将我的路径3扩展到两个[A,B,C],[OneTwoA,OneTwoB,OneTwoC]:- 附加一个二,[A],一个二, 追加OneTwo[B],OneTwoB,%。。。正当所有的例子都能说明问题 追加OneTwo[C],OneTwoC.%同样的答案。检查一下! 如果只有两个呢

扩展我的路径2[],[],[]。 将我的路径2扩展到两个[B,C],[OneTwoB,OneTwoC]:- 附加一个二,[B],一个沃布, 追加OneTwo[C],OneTwoC.%。。。正当 所以我们实际上可以把它按语法改写为

扩展我的路径3[]、[]、[]。 扩展我的路径3-OneTwo,[A |[B,C]],[OneTwoA |[OneTwoB,OneTwoC]]:- 附加一个二,[A],一个二, 将我的路径2扩展到两个[B,C],[OneTwoB,OneTwoC]。 但是你看!无论我们用这三个元素做什么,我们用这两个元素做的基本上是一样的

为什么我们要把自己局限于三个因素,或者仅仅局限于两个因素?这些没有什么特别的。让我们再概括一下

扩展我的路径[],[],[]。 将我的路径扩展到两个[A | B | C],[OneTwoA | OneTwoB | OneTwoC]:- 附加一个二,[A],一个二, 把我的路径延伸到两个,B,C,C。
您能从这里开始吗?

与其尝试修复现有代码,不如尝试重新解决问题。您将展示以下示例:

ListA:[],ListB:[]=>ResultList:[] ListA:[],ListB:[a,b,c]=>结果列表:[[a],[b],[c]] ListA:[1,2],ListB:[a,b,c]=>结果列表:[[1,2,a],[1,2,b],[1,2,c]] 及

?-扩展我的路径[a,b,c],[1,2],],结果。 结果=[[1,2,a],[1,2,b],[1,2,c]] 第三个参数看起来完全不合适,与第一批示例相比,第一个和第二个参数是交换的,所以我们假设它应该是

?-ListA=[1,2],ListB=[a,b,c],扩展我的路径ListA,ListB,ResultList。 结果列表=[[1,2,a],[1,2,b],[1,2,c]] 因此,我们开始编写代码,只列出我们知道必须保存的案例:

扩展我的路径。 扩展我的路径[u ex[],[a,b,c],[a],[b],[c]]。 扩展我的路径[1,2],[a,b,c],[1,2,a],[1,2,b],[1,2,c]]。 把它概括起来给我们

扩展我的路径3[]、[]、[]。 将我的路径3扩展到两个[A,B,C],[OneTwoA,OneTwoB,OneTwoC]:- 附加一个二,[A],一个二, 追加OneTwo[B],OneTwoB,%。。。正当所有的例子都能说明问题 追加OneTwo[C],OneTwoC.%同样的答案。检查一下! 如果只有两个呢

扩展我的路径2[],[],[]。 将我的路径2扩展到两个[B,C],[OneTwoB,OneTwoC]:- 附加一个二,[B],一个沃布, 追加OneTwo[C],OneTwoC.%。。。正当 所以我们实际上可以把它按语法改写为

扩展我的路径3[]、[]、[]。 扩展我的路径3-OneTwo,[A |[B,C]],[OneTwoA |[OneTwoB,OneTwoC]]:- 附加一个二,[A],一个二, 将我的路径2扩展到两个[B,C],[OneTwoB,OneTwoC]。 但是你看!不管我们对这三个人做了什么 事实上,我们正在做同样的事情,本质上,这两件事

为什么我们要把自己局限于三个因素,或者仅仅局限于两个因素?这些没有什么特别的。让我们再概括一下

扩展我的路径[],[],[]。 将我的路径扩展到两个[A | B | C],[OneTwoA | OneTwoB | OneTwoC]:- 附加一个二,[A],一个二, 把我的路径延伸到两个,B,C,C。
你能从这里开始吗?

非常感谢你的回答。你的解释帮助我更好地理解序言。@RogerRoger好的,我想让你理解序言!:非常感谢你的回答。你的解释帮助我更好地理解序言。@RogerRoger好的,我想让你理解序言!:谢谢你的回答,不客气。我很重视你的反馈,如果有帮助的话?你能跟上吗?有趣吗?它给了你一个惊喜吗我想它没有。。。但也许你以后会回到它,当你对Prolog更满意的时候…谢谢你的回答。不客气。我很重视你的反馈,如果有帮助的话?你能跟上吗?有趣吗?它给了你一个惊喜吗我想它没有。。。但也许你以后会回到它,当你对Prolog更满意的时候。。。