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.
解决方案顺序不符合要求。应该很容易根据需要更改...
这是我想要做的。
鉴于声明:
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.
解决方案顺序不符合要求。应该很容易根据需要更改...