Prolog 在沃伦';s抽象机器,如果其中一个参数是寄存器,绑定如何工作?

Prolog 在沃伦';s抽象机器,如果其中一个参数是寄存器,绑定如何工作?,prolog,unification,warren-abstract-machine,Prolog,Unification,Warren Abstract Machine,我正在尝试创建我自己的WAM实现,但我在 我无法理解如何执行图2.4中的指令unified_value X4 据我所知,这条指令应该将程序中的Y与查询中的f(W)统一起来 unify\u value X4调用unify(X4,S)其中S=2(见图2.1),相应的堆单元为“REF 2”,X4为“STR 5” Unify(图2.7)应该bind这些值,但我不知道如何deref寄存器 “REF 2”在堆中,“STR 5”在寄存器中。如何将某个东西绑定到寄存器?我们谈论的是沃伦的“新”引擎WAM,而不是

我正在尝试创建我自己的WAM实现,但我在

我无法理解如何执行图2.4中的指令
unified_value X4

据我所知,这条指令应该将程序中的Y与查询中的f(W)统一起来

unify\u value X4
调用
unify(X4,S)
其中S=2(见图2.1),相应的堆单元为“REF 2”,X4为“STR 5”

Unify
(图2.7)应该
bind
这些值,但我不知道如何
deref
寄存器


“REF 2”在堆中,“STR 5”在寄存器中。如何将某个东西绑定到寄存器?

我们谈论的是沃伦的“新”引擎WAM,而不是旧引擎PLM

在WAM中,变量分配在两个位置

  • 本地堆栈(环境堆栈)

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

    与您的问题密切相关的是,WAM如何巧妙地维持这一顺序,同时进行非常便宜的最后一次呼叫优化。在(确定的)最后一次调用的时间点,作为最后一次调用的参数的局部变量必须以某种方式移动。在更传统的Prolog机器(如ZIP)中,这是一项极其艰巨的任务,基本上需要扫描环境框架中仍然存在的变量

    然而,WAM有一个更好的调用约定:大多数变量已经在一个安全的地方,在编译期间可以对其进行简单的分析。剩下的极少数需要一个显式的PUT_不安全指令来检查值,如果它仍然是一个局部变量,该变量将被传输到堆中

    考虑WAM中的安全变量:

  • 发生在头部的所有变量

  • 显示为结构参数的所有变量

  • 因此,只有在目标和最后一个目标中最先出现的变量以及在某些结构中没有出现的变量必须具有PUT_。没那么多。此外,动态检查可以将实际复制到堆的次数减少到最小

    起初,这个PUT_看起来需要做很多工作,但千万不要忘记WAM允许删除许多PUT,而ZIP必须为每个参数至少执行一条指令

    下面是一个小的典型示例,使用:

    扩展至:

    a(S0,S) :- b(S0,S1), c(S1,S).
    
    并使用命令
    pl2wam
    编译为:

    predicate(a/2,1,static,private,monofile,global,[ allocate(2), get_variable(y(0),1), % S put_variable(y(1),1), % S1 call(b/2), put_unsafe_value(y(1),0), % S1 put_value(y(0),1), % S deallocate, execute(c/2)]). 谓词(a/2,1、静态、专用、单文件、全局、[ 分配(2), 获取变量(y(0),1),%S put_变量(y(1),1),%S1 电话(b/2), 放置不安全值(y(1),0),%S1 放置值(y(0),1),%S 解除分配, 执行(c/2)])。
    谢谢你写得这么好。如果你正在执行你自己的WAM,考虑使用而不是原来的,过于复杂的三指针类型方案。 predicate(a/2,1,static,private,monofile,global,[ allocate(2), get_variable(y(0),1), % S put_variable(y(1),1), % S1 call(b/2), put_unsafe_value(y(1),0), % S1 put_value(y(0),1), % S deallocate, execute(c/2)]).