prolog如何循环遍历此代码

时间:2016-02-04 14:45:27

标签: loops prolog

此代码如何工作?我很难对CX的第一个可能的值起作用,但不知何故它会循环。

path(A, B, [A, B], X) :-
    route(A, B, X).
path(A, B, PathAB, Length) :-
    route(A, C, X),
    path(C, B, PathCB, LengthCB),
    PathAB = [A | PathCB],
    Length is X + LengthCB.

routes定义为route(bahirdar, mota, 32).

1 个答案:

答案 0 :(得分:1)

举个简单的例子,假设你有以下事实:

foo(1).
foo(2).

然后你查询:

| ?- foo(X).

Prolog将成功X = 1并提示:

X = 1 ?

?表示有一个选择点(它为foo找到了要探索的其他选项),如果按;并按Enter键,它将回溯< / em>并尝试找到另一种解决方案,并提示:

X = 2 ?

现在,如果按;并输入,则会失败并停止,因为它无法再继续成功。

让我们尝试使用连词更精细一些。使用事实:

foo(1).
foo(2).
foo(3).

规则:

odd(X) :- X /\ 1 =:= 1.   % X is odd if X bit-wise and with 1 is 1

然后执行一个查询,说我希望Xfoo 我希望Xodd

| ?- foo(X), odd(X).
X = 1 ? ;
X = 3 ? ;
no
| ?-

请注意,我们只得到奇怪的解决方案。此查询中发生的情况如下:

  1. Prolog致电foo(X)并以X = 1成功。
  2. Prolog调用odd(1)(因为X被实例化为1)并且成功
  3. Prolog显示结果X = 1
  4. 用户表示需要回溯(查找更多解决方案)
  5. Prolog回溯到odd(1),它没有要重新复制的变量,因此Prolog进一步回溯
  6. Prolog回溯到foo(X)并以X = 2成功继续前进
  7. Prolog调用odd(2)并失败。失败导致Prolog回溯到foo电话
  8. Prolog回溯到foo(X)并以X = 3成功继续前进
  9. Prolog致电odd(3)并成功并显示解决方案X = 3&lt;
  10. ...
  11. 立即将此应用于您的谓词:

    path(A, B, [A, B], X) :-
        route(A, B, X).
    path(A, B, PathAB, Length) :-
        route(A, C, X),
        path(C, B, PathCB, LengthCB),
        PathAB = [A | PathCB],
        Length is X + LengthCB.
    

    如果对path进行查询,则Prolog首先尝试将查询与第一个子句path(A, B, [A, B], X)的头部匹配。与此头部的匹配意味着第三个参数必须是由恰好2个元素组成的列表。如果匹配,Prolog将致电route(A, B, X)。如果route(A, B, X)成功,Prolog将显示导致成功的ABX的值。如果用户提示提供更多解决方案,Prolog将会回溯,如果先前的呼叫中有剩余选择点,则(a)再次呼叫route(A, B, X),或者(b)进一步回溯并尝试将原始呼叫与path到第二个条款path(A, B, PathAB, Length)。同样,如果对route(A, B, X)的原始调用失败,Prolog会回溯以尝试匹配第二个子句。

    如果执行第二个子句,则您具有如先前简化示例中所示的连接情况。在这里,它是以route(A, C, X)开头的四个调用的连接序列。 Prolog将按顺序尝试每个这些调用,并且只要先前成功,就会移动到下一个调用。遇到失败时,Prolog将回溯到先前的调用,如果有选择点,则尝试重新实例化参数以使先前的调用再次成功,等等。

    也许您可以看到这与循环有何不同。在典型的命令式语言中,您可能有一个由以下语句组成的循环:

    while (something) do
        A
        B
        C
    end
    

    在满足循环条件之前,将以A B C A B C A B C ...执行。在Prolog中,你可能有:

    A,
    B,
    C,
    

    可以执行:A(succeeds) B(fails - backtrack) A(succeeds) B(fails - backtrack) A(succeeds) B(succeeds) C(fails - backtrack) B(succeeds) C(succeeds)然后最终产生结果。

    如果这是真正的好答案,我会附上一堆图表来说明这一点。但我希望描述有足够的帮助。 :)