这就是我想要做的事。
鉴于声明:
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() “声明和我对”边缘“的声明是不正确的。
那么,如何在这种情况下正确声明“边缘”?
答案 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.
解决方案订单与要求不符。应该很容易根据需要改变......