# Inline subterm naming syntax (was: Syntax for unify-and-remember in head?)

**URL:** <https://swi-prolog.discourse.group/t/inline-subterm-naming-syntax-was-syntax-for-unify-and-remember-in-head/4360>\
**Category:** Request For Comments\
**Created:** [September 1, 2021, 1:43am UTC](https://swi-prolog.discourse.group/t/inline-subterm-naming-syntax-was-syntax-for-unify-and-remember-in-head/4360 "2021-09-01T01:43:29Z")\
**Posts on this page:** 1\
**Showing post:** 3

<div class="post-metadata">

**Author:** ![EricGT](https://avatars.discourse-cdn.com/v4/letter/e/f1d935/32.png) [@EricGT](https://swi-prolog.discourse.group/u/EricGT)\
**Post date:** [September 1, 2021, 9:03am UTC](https://swi-prolog.discourse.group/t/inline-subterm-naming-syntax-was-syntax-for-unify-and-remember-in-head/4360/3 "2021-09-01T09:03:36Z")

</div>

> [@dmchurch](#):
>
> That’s all I can think of at the moment, though I’m sure I’ve missed something

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](https://www.swi-prolog.org/pldoc/man?section=byrd-box-model) and possible [added ports](https://www.swi-prolog.org/pldoc/doc_for?object=prolog_trace_interception/4).

* * *

Is the proposal only for deterministic code, e.g. could the clauses be rewritten using [single sided unification](https://www.swi-prolog.org/pldoc/man?section=ssu)?

The patterns @peter.ludemann and you show remind me of [C# Deconstructors](https://docs.microsoft.com/en-us/archive/msdn-magazine/2016/connect/net-framework-what-s-new-in-csharp-7-0) and [F# Pattern Matching](https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/pattern-matching) which leads to [Algebraic Data Types](https://en.wikipedia.org/wiki/Algebraic_data_type). 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](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself))
> 
> * * *
> 
> [optimise\_unify](https://www.swi-prolog.org/pldoc/man?section=flags#flag:optimise_unify)
> 
> SWI-Prolog Documentation 2.18.3 [Indexing for body code](https://www.swi-prolog.org/pldoc/man?section=indexbody)
> 
> * * *
> 
> Displaying the VM Instructions
> 
> File: `examples_optimise_unify_true.pl`
> 
> ```prolog
> :- 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)]).
> 
> ```
> 
> ```prolog
> ?-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`
> 
> ```prolog
> :- 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)]).
> 
> ```
> 
> ```prolog
> ?- 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](https://www.swi-prolog.org/pldoc/man?section=implhistory)  
> [ref 2](https://swi-prolog.discourse.group/t/curious-how-does-prolog-byte-code-compare-to-net-il-and-some-thoughts-about-enterprise-ready-systems/1101/8)  
> Bowen _et al._ , 1983 - " A portable Prolog compiler" - (ResearchGate PDF [download](https://www.researchgate.net/publication/273888197_A_portable_Prolog_compiler))  
> Neumerkel, 1993 - “The binary WAM,a simplified Prolog engine” ([pdf](http://www.complang.tuwien.ac.at/ulrich/papers/PDF/binwam-nov93.pdf))
> 
> * * *
> 
> SWI-Prolog VM Instructions at the C level  
> [pl-comp.c](https://github.com/SWI-Prolog/swipl-devel/blob/master/src/pl-comp.c)  
> [pl-wam.c](https://github.com/SWI-Prolog/swipl-devel/blob/master/src/pl-wam.c)  
> [pl-vmi.c](https://github.com/SWI-Prolog/swipl-devel/blob/master/src/pl-vmi.c)
> 
> * * *
> 
> Ref: [pl-vmi.c](https://github.com/SWI-Prolog/swipl-devel/blob/984bb191bb1c989d4fc930f558ae0906bfbbc339/src/pl-vmi.c#L115-L122)
> 
> ```plaintext
> 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](https://github.com/SWI-Prolog/swipl-devel/blob/984bb191bb1c989d4fc930f558ae0906bfbbc339/src/pl-vmi.c#L61-L83)
> 
> > 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](https://github.com/SWI-Prolog/swipl-devel/blob/984bb191bb1c989d4fc930f558ae0906bfbbc339/src/pl-vmi.c#L799-L806)
> 
> > 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](https://github.com/SWI-Prolog/swipl-devel/blob/984bb191bb1c989d4fc930f558ae0906bfbbc339/src/pl-vmi.c#L1221-L1248)
> 
> > 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.
> 
>  
> 
> ```plaintext
> B_INLINEVAR 
> H_INLINEVAR
> 
> ```
> 
>  
> * * *
>  
> 
> (Prolog) Conformity Testing I: Syntax ([ref](https://www.complang.tuwien.ac.at/ulrich/iso-prolog/conformity_testing))  
> (Works for ISO/IEC JTC1 SC22 WG17)
> 
> * * *

---

_[View the full topic](https://swi-prolog.discourse.group/t/inline-subterm-naming-syntax-was-syntax-for-unify-and-remember-in-head/4360)._
