几何类比,为什么我得不到更多答案?

时间:2011-10-23 22:29:12

标签: prolog

这是我的序言代码:

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).

代表此集enter image description here

这是一个简单的执行:

| ?- relate(2, X, Y).

X = 3
Y = opposite;

no
| ?- relate(2, 7, X).

X = opposite;

no

我的问题是,为什么我没有X = 7,Y =相反,当我确实相关时(2,X,Y)?

谢谢。

2 个答案:

答案 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

如果条件成功,则软切换允许回溯到条件,以便返回条件和结果的替代解决方案。如果条件成功,则永远不会执行替代分支。只有当条件完全失败时,才会执行替代分支。