【问题标题】:Intersection in SWI-PrologSWI-Prolog 中的交叉点
【发布时间】:2013-11-23 20:51:29
【问题描述】:

我是 Prolog 的新手,我在理解递归时遇到了一些麻烦。我正在尝试编写一个关系来查找两个排序列表的交集,而不使用 SWI 的内置相交。我已经使用跟踪来查看发生了什么,并且它的行为与我预期的一样,直到我希望它终止并返回包含交集的新列表。这让我认为我的基本情况是错误的。我已经尝试了几种不同的方法来形成基本案例,但并没有取得成果。我一直使用列表 [1, 2, 3, 4] 和 [2, 4, 6] 作为具有以下关系的测试用例(顶部的基本用例只是我作为占位符放入的一个......它根本不起作用):

intersectS([], [], []).
intersectS([A | B], [C | D], Z) :- A < C, intersectS(B, [C | D], Z).
intersectS([A | B], [C | D], Z) :- A > C, intersectS([A | B], D, Z).
intersectS([A | B], [C | D], Z) :- A = C, append(Z, [A], Y), intersectS(B, D, Y). 

感谢任何帮助。我已经看到了将 cut (!) 运算符与成员/非成员一起使用的示例,但我应该利用列表已排序这一事实,所以我想我会尝试这种方法。提前致谢。

【问题讨论】:

    标签: prolog


    【解决方案1】:

    总体而言,您所拥有的解决方案已经完成了一半(正如您所观察到的)。我认为有两个方面需要修复。正如您所指出的,一种是“基本情况”。我会这样做:

    intersectS([], _, []).
    intersectS(_, [], []).
    

    换句话说,任何与空列表相交的东西都是空的。

    第二个麻烦点是A = C 的子句。你有:

    intersectS([A | B], [C | D], Z) :- A = C, append(Z, [A], Y), intersectS(B, D, Y).
    

    这表示如果两个列表的头部匹配,则附加[A](匹配头部)的交集(Z)是两个列表尾部的交集。这似乎不正确。我想你想说交集(Z)是尾部BD附加到[A]的交集,看起来像这样:

    intersectS([A | B], [C | D], Z) :- A = C, append([A], Y, Z), intersectS(B, D, Y).
    

    所以整个事情看起来像:

    intersectS([], _, []).
    intersectS(_, [], []).
    intersectS([A | B], [C | D], Z) :- A < C, intersectS(B, [C | D], Z).
    intersectS([A | B], [C | D], Z) :- A > C, intersectS([A | B], D, Z).
    intersectS([A | B], [C | D], Z) :- A = C, append([A], Y, Z), intersectS(B, D, Y).
    

    您可以更进一步,摆脱append,因为您只处理一个元素。 append([A], Y, Z)Z = [A|Y] 相同。所以你可以简单地替换最后一个子句:

    intersectS([A | B], [C | D], [A | Y]) :- A = C, intersectS(B, D, Y).
    

    运行你的测试用例:

    ?-  intersectS([1, 2, 3, 4], [2,4,6], L).
    L = [2, 4] ;
    false.
    
    ?-
    

    【讨论】:

    • 啊,我尝试添加诸如 intersectS(D, [], Z) 和 intersectS([], D, Z) 之类的事实,但我完全忘记了下划线选项。我现在在逻辑上看到了我的错误,非常感谢!
    • 附带说明,为什么这种关系仍然返回 false? Z 值的正确性是不可证明的吗?
    • @Jsh 它返回false,因为在提示一个解决方案后,您使用; 要求更多,这意味着没有更多解决方案。因此,“错误响应”不适用于找到的解决方案,而是适用于没有其他解决方案的事实。
    猜你喜欢
    • 1970-01-01
    • 2016-01-16
    • 2011-04-26
    • 2016-09-05
    • 1970-01-01
    • 2014-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多