Использование отличного, все еще приводящего к дубликатам - PullRequest
0 голосов
/ 28 февраля 2020

Я новичок в прологе, и, насколько я понимаю, цель «отличного» - отсеять дубликаты. Однако этот блок кода:

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.

Я не уверен, что мне не хватает, но я был бы признателен, если бы кто-то мог указать мне на правильное направление.

Ответы [ 2 ]

1 голос
/ 28 февраля 2020

distinct/1 - это совершенно новый предикат. Это имеет значение только в том случае, если дополнительная оценка важна либо из-за бесконечных данных, либо потому, что (по какой-то непонятной причине) точный порядок ответов имеет значение. Хорошо, и, возможно, также потому, что есть много избыточных ответов, и место для их хранения было бы запрещено, но тогда хорошая реализация setof / 3 могла бы также использовать подобную технику. В вашем случае у вас есть только база данных конечного числа фактов.

С 1982 года 1 , предикат classi c для вашей цели равен setof/3.

* 1008. * Вы не дали минимальный воспроизводимый пример . Так что мне нужно сделать предположение. В любом случае, доверяйте для печати. ​​
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) 
         ), _).
0 голосов
/ 28 февраля 2020

Как вы уже писали, целевая часть / 5, которая предоставляет отображаемые значения, не связана с соединением, которое вы запрашивали в отличном / 1. Если я правильно понимаю вашу проблему, скорее всего, вам следует использовать вместо нее / 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.
...