我想从图表中获取一个列表。两个字母的变量是点,一个字母是一行。每行可以包含多个点。
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).
有人有想法吗?
答案 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/3
(conn(Start, NextPoint, Line)
)左侧的点,但不在conn/3
(\+ conn(_, Start, Line)
)的右侧。
通过这种方式,您可以获得该行的前两个点,并以递归方式调用nextLine/3
,您可以按正确的顺序检测以下几点。