Как я могу проверить WAM-код в SICStus Prolog
В контексте взлома clpz на sicstus-prolog я хочу взглянуть на код warren -abstract-machine, сгенерированный SICStus Prolog. В качестве примера рассмотрим следующий предикат!
is_list([]).
is_list([_|Es]) :- is_list(Es).
Вот что я делаю сейчас:
Разделите 2 пункта
is_list/1
в 2 отдельных предиката и добавьте 2 фиктивных предложения:is_list__clause1 (dummy1). % фиктивная оговорка is_list __clause1 ([]). is_list__clause2 (dummy2). % фиктивная оговорка is_list __clause2 ([_ | Es]): - is_list (Es).
(Ab-) используйте пролог-уровень SICStus, например:
|? - is_list__clause1 (X). X = dummy1? T... 0x7eff37281300: GET_NIL_X0 0x7eff37281304: ПРОДОЛЖИТЬ 0x7eff37281308: END_OF_CLAUSEQ пользователь:is_list__clause1/1... |? - is_list__clause2 (X). X = dummy2? T... 0x7eff37281150: GET_LIST_X0 0x7eff37281154: U2_VOID_XVAR 1,x(0) 0x7eff37281160: EXECUTEQ пользователь:is_list/1 0x7eff37281170: END_OF_CLAUSEQ пользователь:is_list__clause2/1...
Этот вывод, хотя и несколько загадочный, дает мне ощущение того, что происходит на уровне WAM. Мне нравится!
Но есть более простой способ... пожалуйста, помогите!
1 ответ
Есть более простой способ: недокументированный, неподдерживаемый, 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
| ?-