如何检查SICStus Prolog中的WAM代码



在sicstus-prolog上破解clpz的背景下,我想瞥一看SICStus Prolog生成的warren-abstract-machine代码。 作为示例,让我们剖析以下谓词!

is_list([]).
is_list([_|Es]) :- is_list(Es).

这是我现在正在做的事情:

  1. is_list/1的 2 个子句拆分为 2 个单独的谓词,并在前面加上 2 个虚拟子句:

    is_list__clause1(假人1(。% 虚拟子句 is_list__clause1([](.is_list__clause2(假人2(。% 虚拟子句 is_list__clause2([_|Es]( :- is_list(Es(.
  2. (Ab-(使用 SICStus prolog-toplevel,如下所示:

    | ?-is_list__clause1(X(.X = 假人1 ?...... 0x7eff37281300:GET_NIL_X0 0x7eff37281304:继续 0x7eff37281308: END_OF_CLAUSEQ 用户:is_list__clause1/1 ... | ?-is_list__clause2(X(.X = 假人2 ?...... 0x7eff37281150:GET_LIST_X0 0x7eff37281154: U2_VOID_XVAR 1,x(0( 0x7eff37281160: 执行 用户:is_list/1 0x7eff37281170:END_OF_CLAUSEQ用户:is_list__clause2/1 。

这个输出 - 虽然有些神秘 - 让我感受到WAM级别正在发生的事情。我喜欢!

但是有一个更简单的方法...请帮忙!

有一种更简单的方法:未记录、不支持的library(disassembler)

除了 WAM 指令之外,还可以使用它以编程方式获取有关第一个参数索引的信息。有关详细信息,请参阅来源。

| ?- use_module(library(disassembler)).
% ...
yes
| ?- [user].
% compiling user...
| foo([],Ys,Ys). foo([X|Xs],Ys,[X|Zs]) :- foo(Xs,Ys,Zs). end_of_file.
% compiled user in module user, 89 msec 599696 bytes
yes
| ?- disassemble(foo/3).
% Predicate: user:foo/3 (user)
% Varcase: [4343940512-4343958960,4346212208-4343221120]
% Lstcase: [4346212212]
% Switch: [[]=4343940516], default: failcode
% clause indexed [var,number,atom,structure] (user)
%    4343940512: 'GET_NIL_X0'
%    4343940516: 'GET_X_VALUE_PROCEED'(x(1),x(2))
%    4343940528: 'END_OF_CLAUSEQ'(user:foo/3)
% clause indexed [var,list] (user)
%    4346212208: 'GET_LIST_X0'
%    4346212212: 'U2_XVAR_XVAR'(x(3,0),x(0,0))
%    4346212224: 'GET_LIST'(x(2))
%    4346212232: 'U2_XVAL_XVAR'(x(3),x(2,0))
%    4346212244: 'EXECUTE'(user:foo/3)
%    4346212256: 'END_OF_CLAUSEQ'(user:foo/3)
yes
| ?- 

最新更新