prolog - 在沃伦的抽象机器中,如果参数之一是寄存器,绑定(bind)如何工作?

标签 prolog unification warren-abstract-machine

我正在尝试创建自己的 WAM 实现,但我被困在 the exercise 2.4

我不明白如何执行指令 unify_value X4在图 2.4 中。

据我了解,该指令应将程序中的 Y 与查询中的 f(W) 统一起来。
unify_value X4来电unify (X4,S)其中 S=2(见图 2.1),相应的堆单元是“REF 2”,X4 是“STR 5”。
Unify (图 2.7)应该 bind这些值,但我不明白如何 deref一个寄存器。

“REF 2”在堆中,“STR 5”在寄存器中。你好吗bind东西登记?

最佳答案

我们谈论的是 Warren 的"new"引擎 WAM,而不是旧引擎,即 PLM。

在 WAM 中,变量被分配在两个地方。

  • 本地栈(环境栈)

  • 寄存器不能保存变量。但是,它们可能包含对变量的引用。请注意,来自堆的引用仅指向堆。

    与您的问题密切相关的是 WAM 如何维护此订单并同时拥有 的巧妙方式。非常便宜的最后通话优化 .在(确定的)最后一次调用的时间点,作为最后一次调用的参数的局部变量必须以某种方式移动。在像 ZIP 这样的更传统的 Prolog 机器中,这是一项极其费力的工作,基本上需要扫描环境框架以查找仍然存在于其中的变量。

    然而,WAM 有一个更好的调用约定:大多数变量已经在一个安全的地方,可以在编译期间进行简单的分析。剩下的极少数需要一个显式的 PUT_UNSAFE 指令来检查值,并且如果它仍然是一个局部变量,那么该变量会被转移到堆上。

    考虑什么是 WAM 中的安全变量:
  • 头部出现的所有变量
  • 作为结构参数出现的所有变量

  • 因此,只有首先出现在目标和最后一个目标中且未出现在某些结构中的变量必须具有 PUT_UNSAFE。那不是那么多。此外,动态检查可以将实际复制到堆上的操作减少到最低限度。

    起初,这个 PUT_UNSAFE 看起来工作量很大,但永远不要忘记 WAM 允许删除许多 PUT,而 ZIP 必须为每个参数执行至少一条指令。

    这是一个使用 GNU 的典型示例。 :
    a --> b, c.
    

    扩展为:
    a(S0,S) :- b(S0,S1), c(S1,S).
    

    并使用命令 pl2wam 编译到:

    谓词(a/2,1,静态,私有(private),单文件,全局,[
    分配(2),
    get_variable(y(0),1), % S
    put_variable(y(1),1), % S1
    通话(b/2),
    put_unsafe_value(y(1),0), % S1
    put_value(y(0),1), % S
    解除分配,
    执行(c/2)])。

    关于prolog - 在沃伦的抽象机器中,如果参数之一是寄存器,绑定(bind)如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28665732/

    相关文章:

    list - 在指定元素处拆分列表

    haskell - 不能从 f x = f₁ y 推导出 f = f₁?

    Prolog 和列表统一

    prolog - GNU 序言 : Displaying WAM code for query?

    performance - 测量执行时间 ECLiPSe CLP(或 Prolog)

    list - 在序言中合并两个列表

    prolog - 如何在 SICStus Prolog 中检查 WAM 代码

    prolog - 列表的子列表 - 替代方法

    haskell - 指定一种类型如果已经存在于 Haskell 中的其他类中,则只能存在于一个类中