I still have to digest what you wrote in more detail but upon a first cursory readthrough this comes to mind.
Effects on the Byrd Box model and possible added ports.
Is the proposal only for deterministic code, e.g. could the clauses be rewritten using single sided unification?
The patterns @peter.ludemann and you show remind me of C# Deconstructors and F# Pattern Matching which leads to Algebraic Data Types. Is this where you are headed?
I gave your post a like. The like is not to be interpreted as my liking the proposal, instead a like by an admin will give it more points toward being put in the e-mails for those that don’t visit the site regularly.
Personal Notes (Click triangle to see details)
violates DRY
DRY -Don’t Repeat Yourself (Wikipedia)
SWI-Prolog Documentation 2.18.3 Indexing for body code
Displaying the VM Instructions
File: examples_optimise_unify_true.pl
:- module(examples_optimise_unify_true,
[
display_record/1
]).
:- set_prolog_flag(optimise_unify,true).
display_record(Record) :-
Record = record(_, _, _, _),
format('Record: ~p~n', [Record]).
display_record(record(A, B, C, D)) :-
format('Record: ~p~n', [record(A, B, C, D)]).
?-current_prolog_flag(optimise_unify,Optimise_unify),clause(examples_optimise_unify_true:display_record(_),Body,Ref),clause_vm(Ref,VM_instructions);true.
Optimise_unify = true,
Body = format('Record: ~p~n', [_17216]),
Ref = <clause>(0000000006F3BAE0),
VM_instructions = [
vmi(h_functor(record/4), 2),
vmi(h_pop, 1),
vmi(i_enter, 1),
vmi(b_atom('Record: ~p~n'), 2),
vmi(b_list, 1),
vmi(b_argvar(0), 2),
vmi(b_nil, 1),
vmi(b_pop, 1),
vmi(i_depart(system:format/2), 2),
vmi(i_exit, 1)
] ;
Optimise_unify = true,
Body = format('Record: ~p~n', [record(_20546, _20548, _20550, _20552)]),
Ref = <clause>(0000000006E01250),
VM_instructions = [
vmi(h_functor(record/4), 2),
vmi(h_firstvar(1), 2),
vmi(h_firstvar(2), 2),
vmi(h_firstvar(3), 2),
vmi(h_firstvar(4), 2),
vmi(h_pop, 1),
vmi(i_enter, 1),
vmi(b_atom('Record: ~p~n'), 2),
vmi(b_list, 1),
vmi(b_functor(record/4), 2),
vmi(b_argvar(1), 2),
vmi(b_argvar(2), 2),
vmi(b_argvar(3), 2),
vmi(b_argvar(4), 2),
vmi(b_pop, 1),
vmi(b_nil, 1),
vmi(b_pop, 1),
vmi(i_depart(system:format/2), 2),
vmi(i_exit, 1)
] ;
true.
File: examples_optimise_unify_false.pl
:- module(examples_optimise_unify_false,
[
display_record/1
]).
:- set_prolog_flag(optimise_unify,false).
display_record(Record) :-
Record = record(_, _, _, _),
format('Record: ~p~n', [Record]).
display_record(record(A, B, C, D)) :-
format('Record: ~p~n', [record(A, B, C, D)]).
?- current_prolog_flag(optimise_unify,Optimise_unify),clause(examples_optimise_unify_false:display_record(_),Body,Ref),clause_vm(Ref,VM_instructions);true.
Optimise_unify = false,
Body = (_20=record(_96, _98, _100, _102), format('Record: ~p~n', [_20])),
Ref = <clause>(0000000006A1CDA0),
VM_instructions = [
vmi(i_enter, 1),
vmi(b_unify_var(0), 2),
vmi(h_functor(record/4), 2),
vmi(h_pop, 1),
vmi(b_unify_exit, 1),
vmi(b_atom('Record: ~p~n'), 2),
vmi(b_list, 1),
vmi(b_argvar(0), 2),
vmi(b_nil, 1),
vmi(b_pop, 1),
vmi(i_depart(system:format/2), 2),
vmi(i_exit, 1)
] ;
Optimise_unify = false,
Body = format('Record: ~p~n', [record(_3908, _3910, _3912, _3914)]),
Ref = <clause>(0000000006E227E0),
VM_instructions = [
vmi(h_functor(record/4), 2),
vmi(h_firstvar(1), 2),
vmi(h_firstvar(2), 2),
vmi(h_firstvar(3), 2),
vmi(h_firstvar(4), 2),
vmi(h_pop, 1),
vmi(i_enter, 1),
vmi(b_atom('Record: ~p~n'), 2),
vmi(b_list, 1),
vmi(b_functor(record/4), 2),
vmi(b_argvar(1), 2),
vmi(b_argvar(2), 2),
vmi(b_argvar(3), 2),
vmi(b_argvar(4), 2),
vmi(b_pop, 1),
vmi(b_nil, 1),
vmi(b_pop, 1),
vmi(i_depart(system:format/2), 2),
vmi(i_exit, 1)
] ;
true.
SWI-Prolog is not based on WAM VM instructions but ZIP VM instructions.
ref 1
ref 2
Bowen et al. , 1983 - " A portable Prolog compiler" - (ResearchGate PDF download)
Neumerkel, 1993 - “The binary WAM,a simplified Prolog engine” (pdf)
SWI-Prolog VM Instructions at the C level
pl-comp.c
pl-wam.c
pl-vmi.c
Ref: pl-vmi.c
Virtual machine instruction names. Prefixes:
I_ General instructions
B_ Body specific version
H_ Head specific versin
A_ Arithmetic compilation specific
C_ Control (compilation of ;/2, etc.)
S_ Supervisor instructions. See pl-supervisor.c
SWI-Prolog VM Instructions
virtual machine variables: pl-vmi.c
Within the scope of this file, the following virtual machine variables are available.
* FR
Current environment frame
* NFR
Next frame (used to share in various calling instructions)
* BFR
Backtrack frame: current choicepoint
* PC
Program Counter
* ARGP
Argument pointer
* CL
Running clause (= FR->clause)
* DEF
Running definition
H_FIRSTVAR: pl-vmi.c
H_FIRSTVAR: A variable in the head, which is not anonymous, but
encountered for the first time. So we know that the variable is still a
variable. Copy or make a reference. Trailing is not needed as we are
writing in this frame. ARGP is walking the argument list, but is always
in some compound term as H_FIRSTVAR is not generated for plain variables
in the head.
B_UNIFY_FIRSTVAR: pl-vmi.c
B_UNIFY_VAR, B_UNIFY_EXIT: Unification in the body. We compile A = Term
into one of the following:
Normal: A is firstvar:
B_UNIFY_VAR B_UNIFY_FIRSTVAR
B_UNIFY_EXIT B_UNIFY_EXIT
We need B_UNIFY_FIRSTVAR for the debugger as well as for
clearUninitialisedVarsFrame() in pl-gc.c. When in debug mode we simply
create a frame for =/2 and call it. Note that the `slow unify’ mode must
be consistently applied in B_UNIFY_VAR and B_UNIFY_EXIT, which is why we
copy the global value into a local variable.
TBD: B_UNIFY_CONST ,
B_UNIFY_VAR ,
Note that the B_UNIFY_FIRSTVAR assumes write mode, but this is
unimportant because the compiler generates write (B_*) instructions.
Invented by dmchurch.
B_INLINEVAR
H_INLINEVAR
(Prolog) Conformity Testing I: Syntax (ref)
(Works for ISO/IEC JTC1 SC22 WG17)