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

Processing object topology in prolog: finding bidirectional edges from list of triangles

这是我想要做的。

鉴于声明:

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 四边形的拓扑结构:

 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" 是什么意思。

如果我尝试

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 "concludes" 即 "for all declared vertices, there is an edge connecting them" 并列出所有可能的连接:

 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.

主要问题似乎是我希望 prolog 在不明确指定的情况下为我确定边缘列表,这意味着在遇到 "face(A, B, C)" 时它应该将其视为 seeral "edge()" 语句并且我的 "edge" 声明不正确。

那么,在这种情况下如何正确声明 "edge"?

保持简单:

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.

解决方案顺序不符合要求。应该很容易根据需要更改...