0

我是序言的新手,据我了解,“不同”的目的是清除重复项。但是,此代码块:

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.

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

4

2 回答 2

1

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

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

你没有给出一个最小的可重现的例子。所以我需要做一些猜测。无论如何,请相信进行打印。

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) 
         ), _).
于 2020-02-28T16:29:40.910 回答
0

如您所写,提供显示值的目标 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.
于 2020-02-28T06:32:04.597 回答