【问题标题】:Usage of distinct still leading to duplicates使用 distinct 仍会导致重复
【发布时间】:2020-02-28 05:31:44
【问题描述】:

我是 prolog 的新手,据我了解,'distinct' 的目的是清除重复项。但是,这个代码块:

allpartsincity(City):-
    distinct((proj(Project, _, City), sppj(_, Part, Project, _), part(Part, _, _, _, _))),
    part(Part, Name, Color, Num, X),
    format('~w ~w ~w ~w ~w ~n', [Part, Name, Color, Num, X]),
    fail
    ;
    true.

产生以下结果:

?- allpartsincity(london).
p2 bolt green 17 paris 
p5 cam blue 12 paris 
p2 bolt green 17 paris 
p6 cog red 19 london 
p5 cam blue 12 paris 
true.

我不确定我错过了什么,但如果有人能指出我正确的方向,我将不胜感激。

【问题讨论】:

  • 避免像使用格式一样手动编写。相反,定义一个具有更多参数的关系,以便prolog-toplevel 可以为您打印它。在你的情况下,city_part(City, part(Part, Name, Color, Num, X)) :- ...

标签: prolog prolog-setof


【解决方案1】:

distinct/1 是一个相当新的谓词。仅当增量评估由于无限数据或因为(出于某种模糊的原因)答案的确切顺序具有相关性而具有重要性时,它才具有相关性。好的,也许还因为有很多多余的答案并且存储它们的空间会被禁止,但是好的 setof/3 实现也可能使用类似的技术。在您的情况下,您只有一个包含有限多个事实的数据库。

自 1982 年1 以来,用于您的目的的经典谓词是 setof/3

您没有提供minimal reproducible example。所以我需要做一些猜测。无论如何,请相信 进行打印。

city_part(City, CPart) :-
   setof(t, city_part0(City, CPart), _).

city_part0(City, part(Part, Name, Color, Num, X)) :-
   proj(Project, _A1, City),
   sppj(_A2, Part, Project, _A3),
   part(Part, Name, Color, Num, X).

你可以避免中间谓词,但是变量量化会变得很麻烦。我已经给这些变量命名为A1, A2, A3。这些加上Project 只是内部变量

city_part(City, CPart) :-
   setof(t, A1^A2^A3^Project^
         (  CPart = part(Part, Name, Color, Num, X), 
            proj(Project, A1, City),
            sppj(A2, Part, Project, A3),
            part(Part, Name, Color, Num, X) 
         ), _).

【讨论】:

    【解决方案2】:

    正如您所写,提供显示值的目标 part/5 与您在 distinct/1 中要求的连词无关。如果我正确理解了您的问题,则很可能您应该改用 distinct/2 。试一试

    allpartsincity(City):-
        distinct(part(Part, Name, Color, Num, X), (proj(Project, _, City), sppj(_, Part, Project, _), part(Part, _, _, _, _))),
        format('~w ~w ~w ~w ~w ~n', [Part, Name, Color, Num, X]),
        fail
        ;
        true.
    

    【讨论】:

    • distinct/1 在这里没用,而不是setof(t,Var^G?0,[t]),因为答案的顺序在这里根本没有相关性
    • @false:不明白你的意思,对不起...... distinct 不使用排序,而是记忆,afaik。 setof(t,Var^G?0,[t]) 是实际语法吗?没见过...0 是什么意思?
    • @false 关于distinct/1 在这里不起作用是正确的,但我也不确定setof(t,Var^G?0,[t]) 的语法。
    • @vio:我建议的 distinct/2 怎么样?
    • @CapelliC,实际上,我通过一些调整来实现它。谢谢! part(Part, Name, Color, Num, X), 仍然是必需的,但也可以将其插入到 distinct 子句中!
    猜你喜欢
    • 2019-07-27
    • 1970-01-01
    • 1970-01-01
    • 2021-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多