很多人对 Prolog 的印象都是“不就是枚举吗?”。实际上 Prolog 是跟 C/C++/Java 一样的通用编程语言。Prolog程序通常跑在WAM虚拟机上。和JVM不同的是,WAM是一个概念模型,因而各家WAM差别还是蛮大的。
既然 Prolog 是跑在虚拟机上的编程语言,那就有字节码,而对应的字节码也有相应的汇编形式。因此我们也可以对我们的 Prolog 代码进行反汇编。下面介绍如何对 Prolog 代码进行反汇编。
SWI Prolog
在 SWI Prolog 中对代码进行反汇编很简单,可以用 vm_list/1
做到。如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| ?- listing(append/3). lists:append([], L, L). lists:append([H|T], L, [H|R]) :- append(T, L, R).
true.
?- vm_list(append/3). ======================================================================== append/3 ======================================================================== 0 s_virgin 1 i_exit ---------------------------------------- clause 1 (<clause>(0000017A0D4FFD90)): ---------------------------------------- 0 h_nil 1 h_void 2 h_var(1) 4 i_exitfact ---------------------------------------- clause 2 (<clause>(0000017A0D4A1BC0)): ---------------------------------------- 0 h_list_ff(3,4) 3 h_void 4 h_list 5 h_var(3) 7 h_firstvar(5) 9 h_pop 10 i_enter 11 b_var(4) 13 b_var1 14 b_var(5) 16 i_depart(lists:append/3) 18 i_exit true.
|
Sicstus Prolog
在 Sicstus Prolog 中反汇编,可以用 disassembler:disassemble/1
。如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| | ?- [user].
| is_digesting(X,Y) :- just_ate(X,Y). is_digesting(X,Y) :- just_ate(X,Z), is_digesting(Z,Y).
just_ate(mosquito,blood(john)). just_ate(frog,mosquito). just_ate(stork,frog).
end_of_file.
yes | ?- use_module(library(disassembler)). ... lots of loading messages ... yes | ?- disassemble(is_digesting/2).
yes
|