【问题标题】:setof/3 does not seem to be removing duplicatessetof/3 似乎没有删除重复项
【发布时间】:2016-07-27 10:20:16
【问题描述】:

我正在尝试查找列表的补集,给定列表 L1 和通用列表 L2,代码如下:

complement(L1, L2, Res):-
    setof(X, (nth0(N, L2, X), not(member(X,L1))),Res).

但是,我的结果包含重复项,并且没有按照我的意愿以列表形式给出:

23 ?- complement([1,3], [-1,1,3,5,2,4,2,55,1,0], Res).
Res = [-1] ;
Res = [5] ;
Res = [2] ;
Res = [4] ;
Res = [2] ;
Res = [55] ;
Res = [0].

我认为这可能是由于 Prolog 的内置回溯,但我不确定如何解决此问题以正确格式化结果并删除结果中的任何重复项。

【问题讨论】:

    标签: prolog prolog-setof


    【解决方案1】:

    您从您的代码中收到警告,关于 N 是一个单例,并且 setof/3 要求声明每个变量“普遍量化”。 所以,你有两个问题一起消失了:用 member/2 替换 nth0/3:

    complement(L1, L2, Res):-
        setof(X, (member(X, L2), not(member(X, L1))), Res).
    

    编辑

    对称差可能是

    symdiff(L1,L2,Diff) :-
        setof(X,(eldiff(L1,L2,X);eldiff(L2,L1,X)),Diff).
    eldiff(L1,L2,X) :-
        member(X,L1), \+member(X,L2).
    

    如果 L1 和 L2 是有序集,最好使用ord_symdiff

    【讨论】:

    • 修复了它。谢谢你:)
    • 有没有办法同时使用 setof/findall/bagof?我已经做了很长的路,但是上面的解决方案可以用来实现这个吗?
    • @ildsarria:抱歉,我不确定。可以计算对称差异 - IIRC - 从库(ordsets)
    猜你喜欢
    • 1970-01-01
    • 2015-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-26
    • 1970-01-01
    • 2016-02-11
    相关资源
    最近更新 更多