跟踪prolog代码

时间:2015-06-26 06:45:54

标签: list recursion prolog trace sublist

所以我试图追踪这个"子列表"代码,我真的需要帮助...

此功能基本上检查第二个列表是否是第一个列表的子列表,其中顺序很重要;

(1) isSublist([],[]).
(2) isSublist([H1|T1], [H1|T2]) :- isSublist(T1,T2),!.
(3) isSublist([_|T1], T2) :- isSublist(T1,T2).

我感到困惑的是,如何识别H1?例如, 如果输入是子列表[1,4,7,9],[4,7],并且具有相同的H1,它是否重叠?还是会有[1 | 4,7,9],[4 | 7]?即使H1没有在条件中使用,取出它们或分配H1和H2确实会影响结果......

另外第二个问题是,在检查第二个条件(2)后,它是否会进入下一个具有更新列表的条件?还是上去了基础案例(1)" ?

即使它转到基本情况(1)或(3),我所看到的只是摆脱头部,直到两个列表都为空...你能解释这段代码是如何工作的吗?也许暗示如何追踪它?

3 个答案:

答案 0 :(得分:1)

我不确定你是否真的了解prolog如何运作。也许您需要阅读指南或其他内容。

在你的情况下,每当你调用isSublist时,prolog将选择加工给定参数的第一个定义。它将在(2)和(3)之间进行选择,直到它返回返回true的(1)语句。如果prolog找不到(1)语句的路径,它将返回false。

您还可以注意到'!'告诉prolog停止回溯这一点。

我希望这会对你有所帮助,但就像我说的那样,我认为你需要阅读更多关于prolog和他的特殊范例的内容。仅通过阅读代码并不容易理解。如果你愿意,我发现这本书非常适合作为一个起点,它得到了很好的解释:Learn Prolog Now!

如评论中所述,您可以使用?- trace.进入跟踪模式。有关它的更多信息,请参阅prolog文档。

答案 1 :(得分:1)

在Prolog中,我认为追踪是最后的手段。每当我试图启动跟踪器时,我就会想到我花费了无数个小时来跟踪代码无济于事。

回想起来,可以花更多时间来更好地完成以下活动:

  • 远离问题,然后再次接近。
  • 想想手头的问题。
  • 制定测试用例。 (大小,一般和具体)
  • 使用自然语言将视图倾斜到不同的角度。
  • 重构现有代码。
  • 从一张干净的工作表开始,然后重新编码我要调试的代码。

自我注意:当感觉到启动示踪剂的冲动时,请阅读this post:)

答案 2 :(得分:0)

你在正确的路线上。

我的建议:

  1. 将参数的顺序颠倒到isSubList,即 isSublist(X,Y)表示X是Y的子列表。那就更多了 对大多数Prolog读者来说清晰可读(但是,嘿,那里只有少数几个 我们...)。如果你使用' op'这是最有意义的。操作员和 将isSublist定义为中缀运算符,因此您可以编写" X isSublist Y"这同样有效Prolog。
  2. 尽量避免削减(!) - 它是一个非逻辑谓词和     引导你一直思考着兔子洞     订购Prolog将解释您的条款。对于这样一个简单的关系     您应该能够保留您的代码'声明'。
  3. 你真的有两种不同的匹配情况 - 首先     在另一个列表中匹配任何地方的子列表,其次     完全匹配第一个元素的列表(即在第一个匹配后发生这种情况)。即你有一个 subList(X,Y)(我     放弃了')和frontList(X,Y)只放置了前列表(X,Y)     如果列表X是列表Y的第一部分,则成功。
  4. 所以你最终得到以下代码:

    subList([H|T1],[H|T2]) :- frontList(T1,T2).
    subList([H1|T1],[H2|T2]) :- H1 \= H2, subList([H1|T1],T2).
    
    frontList([],_).
    frontList([X|T1],[X|T2]) :- frontList(T1,T2).
    

    对于额外标记,您可以看到frontList(X,Y)实际上与

    相同
    append(X,_,Y)
    

    考虑一下......向X附加一个列表,你得到Y意味着X的元素必须是Y的第一个元素...