【问题标题】:Prolog compiler return errorProlog编译器返回错误
【发布时间】:2014-12-02 17:26:30
【问题描述】:

我有这个假设的程序来检查从 A 点到 B 点是否存在路径。

/*city rules*/

edge(phx, tuc).
edge(tuc, ccg).
edge(ccg, sf).

connected(C1, C2) :-
   edge(C1, C2).
connected(C1, C2) :- 
   edge(C1, X),
   connected(X, C2).

问题是它返回 true,然后返回 false。哪里来的假?

【问题讨论】:

    标签: prolog logic prolog-toplevel transitive-closure


    【解决方案1】:

    让我们看看您从 Prolog 得到的确切回复!首先你得到一个true,然后按 SPACE; 你最终得到:

    ?- connected(phx,sf).
    true ;
    false.
    

    所以你得到了true ; false. 作为完整的答案。 ; 表示“或”。所以 Prolog 本质上说:你的查询 connected(phx,sf).true ; false. 相同所以你需要查看整个答案才能理解它的含义。当然这有点奇怪,true. 就足够了。

    但首先让我们再举一个例子:

    ?- connected(phx,X).
    X = tuc ;
    X = ccg ;
    X = sf ;
    false.
    

    这里 Prolog 的完整答案是:connected(phx,X). 描述了与 X = tuc ; X = ccg ; X = fg ; false. 相同的一组解决方案,如果省略 false,这同样会更短。

    那么,Prolog 为什么要写出这个false? Prolog 以增量方式计算答案。它首先向您显示X = tuc,然后等待您要做什么。从某种意义上说,不一次向您展示所有内容有点懒惰。有时,Prolog 确实知道不会有进一步的答案,这种情况下,它直接写一个点:

    ?- member(X,[1,2]).
    X = 1 ;
    X = 2.
    

    Prolog 在这里说:dixi!我已经说过了。

    但有时,不确定:

    ?- member(1,[1,2]).
    true ;
    false.
    

    在证明 1 是成员后,它会停止,否则它必须进一步探索列表。

    所以这个; false. 的意思是:在最后一个答案/解决方案之后,Prolog 还不确定一切都已经探索过了。这可能是一种低效率,它可能表明某些事情可以改进。但是,永远不会以此为借口在您的程序中插入剪辑。另一个答案的删减完全是恶意的。它是许多许多错误的根源。在开始使用剪辑之前,您真的应该首先学习 Prolog 的另一个纯粹部分。

    顺便说一句:这是connected/2 的更好定义,它通过使用closure/3 来避免无限循环(单击它以获取定义)。

    connected(C0,C) :-
       edge(C0,C1)
       closure0(edge,C1,C).
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-31
      • 1970-01-01
      相关资源
      最近更新 更多