prolog中的处理对象拓扑:从三角形列表中查找双向边

时间:2015-05-21 13:24:32

标签: prolog

这就是我想要做的事。

鉴于声明:

vertex(v0, coord(-1.0, 1.0, 0.0)).
vertex(v1, coord(1.0, 1.0, 0.0)).
vertex(v2, coord(-1.0, -1.0, 0.0)).
vertex(v3, coord(1.0, -1.0, 0.0)).

face(f0, v0, v1, v2).
face(f1, v0, v2, v3).

bidirEdge(A, B) :-
    edge(A, B),
    edge(B, A).

运行查询bidirEdge(X, Y).并接收X = v0, Y = v2; Y = v0, X = v2作为回答。

声明是简单的3d quad的拓扑:

 v0----v1
 | \ f0 |
 |  \   |
 |   \  |
 | f1 \ |
 v3----v2

其中v0..v3表示顶点索引,f0..f1表示面。

我该怎么做?

我已尝试过的内容:

我试图将face声明为:

face(_, A, B, C) :-
    vertex(A, _),
    vertex(B, _),
    vertex(C, _),
    edge(A, B),
    edge(B, C),
    edge(C, A).

直接蝙蝠,查询不起作用,因为prolog不知道“边缘”是什么意思。

如果我尝试

edge(A, B) :-
    vertex(A, _),
    vertex(B, _).

或(不太正确)。

edge(A, B) :-
    vertex(A, _),
    vertex(B, _),
    A \== B.

这导致了有趣的输出。

63 ?- edge(X, Y).
X = Y, Y = v0 ;
X = v0,
Y = v1 ;
X = v0,
Y = v2 ;
X = v0,
Y = v3 ;
X = v1,
Y = v0 ;
X = Y, Y = v1 ;
X = v1,
Y = v2 ...

基本上,prolog“总结”“对于所有声明的顶点,有一条边连接它们”并列出所有可能的连接:

 v0--v1
 | \/ |
 | /\ |
 v3--v2

几乎忽略了我提供的拓扑,而不是我想要的。

我认为如果我做这样的事情:

faceEdge(FaceID, A, B) :-
    belongsTo(FaceID, edge(A, B)).

face(FaceID, A, B, C) :-
    vertex(A, _),
    vertex(B, _),
    vertex(C, _),
    faceEdge(FaceID, A, B),
    faceEdge(FaceID, B, C),
    faceEdge(FaceID, C, A).

我应该得到必需的行为,但是我不知道如何声明belongsTo(并且预感不是应该怎么做),这种查询往往会导致无限循环并挂起我的swi序言

主要问题似乎是我希望prolog为我确定边缘列表而不明确指定它,这意味着在遇到“face(A,B,C)”时它应该将其视为seeral“edge() “声明和我对”边缘“的声明是不正确的。

那么,如何在这种情况下正确声明“边缘”?

1 个答案:

答案 0 :(得分:1)

保持简单:

edge(X, Y) :- face(_, A, B, C), (X=A,Y=B ; X=B,Y=C ; X=C,Y=A).

你会得到

?- bidirEdge(X,Y).
X = v2,
Y = v0 ;
X = v0,
Y = v2 ;
false.

解决方案订单与要求不符。应该很容易根据需要改变......