这是我的序言代码:
figure(1, middle(circle, circle)).
figure(2, top_left(circle, circle)).
figure(3, bottom_right(circle, circle)).
figure(4, middle(square, square)).
figure(5, top_left(square, square)).
figure(6, top_right(square, square)).
figure(7, bottom_right(square, square)).
figure(8, bottom_left(square, square)).
relate(F1, F2, Relation) :-
( figure(F1, middle(X, Y)), figure(F2, middle(Y, X)), F1 \== F2 ->
Relation = invert
; figure(F1, middle(X, X)), figure(F2, middle(Y, Y)), F1 \== F2 ->
Relation = same_in_out
; figure(F1, top_left(X, X)), figure(F2, bottom_right(Y, Y)), F1 \== F2 ->
Relation = opposite
; figure(F1, top_right(X, X)), figure(F2, bottom_left(Y, Y)), F1 \== F2 ->
Relation = opposite
; relate(F2, F1, Relation)
).
analogy((F1, F2), (F3, X)) :-
relate(F1, F2, Relation), relate(F3, X, Relation).
代表此集
这是一个简单的执行:
| ?- relate(2, X, Y).
X = 3
Y = opposite;
no
| ?- relate(2, 7, X).
X = opposite;
no
我的问题是,为什么我没有X = 7,Y =相反,当我确实相关时(2,X,Y)?
谢谢。
答案 0 :(得分:4)
因为你使用if-then-else,而Prolog不会回溯这样的结构:
?- (member(X, [1,2,3]) -> Y = hello ; Y = goodbye).
X = 1,
Y = hello.
?-
If-then-else真正意味着有效的确定性计算。如果你想要非确定性/回溯,你应该使用普通的连词,析取和事实列表来重写你的谓词:
relate(F1, F2, Relation) :-
figure(F1, Fig1),
figure(F2, Fig2),
relate_(Fig1, Fig2, Relation),
F1 \== F2.
relate_(middle(X, Y), middle(Y, X), invert).
% etc.
答案 1 :(得分:2)
除了larsmans回答:
如果您的Prolog系统具有“软切换”(例如,ECLiPSe,SWI-Prolog),那么您可以将' - >'/ 2替换为'* - >'/ 2,即
figure(F1, top_left(X, X)), figure(F2, bottom_right(Y, Y)), F1 \== F2 ->
Relation = opposite
替换为
figure(F1, top_left(X, X)), figure(F2, bottom_right(Y, Y)), F1 \== F2 *->
Relation = opposite
如果条件成功,则软切换允许回溯到条件,以便返回条件和结果的替代解决方案。如果条件成功,则永远不会执行替代分支。只有当条件完全失败时,才会执行替代分支。