Prolog:冗余会导致涉及匿名变量的子句



考虑以下Prolog程序。

a(X) :- b(_), c(X).
b(1).
b(2).
b(3).
c(1).

运行查询:

a(X).

在SWI-Prolog中,我们得到三个结果,所有X = 1。

鉴于我们不关心匿名变量,是什么阻止了SWI-Prolog返回单个结果?为什么不执行此优化?

谢谢

对于Prolog来说,下划线只是一个匿名变量。所以a/1谓词等效于:

a(X) :-
b(Y),
c(X).

现在,回溯b(Y)条款可能看起来毫无用处,因为一旦满足,Y就无处使用,因此不应该对程序的其余部分产生影响。此外,YX没有影响b(Y)因此X不应有丝毫影响。

然而,在真正的Prolog中,有一些事情可能会产生影响:

  1. b/1谓词可能会执行 I/O。假设谓词实现为:

    b(a) :-
    print(a).
    b(a) :-
    print(b).
    

    然后它将在第一个分支中打印a,在第二个分支中打印b

  2. b/1可能会在第二个、第三个、...路径。在这种情况下,我们可能想要处理错误;

  3. b/1可能会使用asserta/1assertz/1等并更改程序。例如,它可以为c/1添加事实,以便在第二次运行中c/1有其他结果。

  4. 许多Prolog解释器都有一个不可回溯的存储,使得不同的回溯路径可以相互共享信息。

  5. 其他编码工具,使得b/1的结果可能对c/1产生影响。

通过使用once/1元谓词,可以避免这种b/1回溯。例如:

a(X) :-
once(b(_)),
c(X).

相关内容

  • 没有找到相关文章

最新更新