Prolog从不同的关系中获取列表

时间:2016-11-24 14:14:51

标签: graph prolog

我想从图表中获取一个列表。两个字母的变量是点,一个字母是一行。每行可以包含多个点。

conn(bs, oc, c).
conn(oc, tc, c).
conn(bs, gp, j).
conn(gp, cc, j).
conn(gp, pc, p).
conn(pc, ls, p).
conn(gp, oc, v).
conn(oc, pc, b).
conn(pc, cc, b).
conn(tc, ls, n).
conn(ls, cc, n).

link(X, Y, Z) :- conn(X, Y, Z), !.
link(X, Y, Z) :- conn(Y, X, Z).

现在我想获得一个包含属于某一行的所有点的列表。输入:

getpoints(c, X).

我希望

X = [bs, oc, tc]

这就是我试图获得结果的方式:

getpoints(Line, [First|[]]) :- not(link(First, _Second, Line)).
getpoints(Line, [First|Rest]) :- link(First, _Second, Line), getpoints(Line, Rest).

有人有想法吗?

1 个答案:

答案 0 :(得分:0)

如果您对点的特定顺序不感兴趣,可以使用setof/3

以示例

getpoints(Line, Points) :-
  setof(X, Y^(conn(X, Y, Line) ; conn(Y, X, Line)), Points).

---编辑---

  

获得积分的顺序是否非常复杂?

如果你的点真的是一条线(不是更通用的图形),你可以写一些像

nextLine(Line, EndLine, []) :-
  \+ conn(EndLine, _, Line).

nextLine(Line, Start, [NextPoint | NextLine]) :-
  conn(Start, NextPoint, Line),
  nextLine(Line, NextPoint, NextLine).

getpoints(Line, [Start, NextPoint | NextLine]) :-
  conn(Start, NextPoint, Line),    
  \+ conn(_, Start, Line),
  nextLine(Line, NextPoint, NextLine).

我的想法是在getpoints/2中找到该行的Start点,即conn/3conn(Start, NextPoint, Line))左侧的点,但不在conn/3\+ conn(_, Start, Line))的右侧。

通过这种方式,您可以获得该行的前两个点,并以递归方式调用nextLine/3,您可以按正确的顺序检测以下几点。