docs -> doc

lol
This commit is contained in:
crumbtoo
2023-12-04 14:51:44 -07:00
parent cb6321fbf8
commit 6767bd0b4f
304 changed files with 29610 additions and 0 deletions

View File

@@ -0,0 +1,425 @@
================================
G-Machine State Transition Rules
================================
*********************
Core Transition Rules
*********************
#. Lookup a global by name and push its value onto the stack
.. math::
\gmrule
{ \mathtt{PushGlobal} \; f : i
& s
& d
& h
& m
\begin{bmatrix}
f : a
\end{bmatrix}
}
{ i
& a : s
& d
& h
& m
}
#. Allocate an int node on the heap, and push the address of the newly created
node onto the stack
.. math::
\gmrule
{ \mathtt{PushInt} \; n : i
& s
& d
& h
& m
}
{ i
& a : s
& d
& h
\begin{bmatrix}
a : \mathtt{NNum} \; n
\end{bmatrix}
& m
}
#. Allocate an application node on the heap, applying the top of the stack to
the address directly below it. The address of the application node is pushed
onto the stack.
.. math::
\gmrule
{ \mathtt{MkAp} : i
& f : x : s
& d
& h
& m
}
{ i
& a : s
& d
& h
\begin{bmatrix}
a : \mathtt{NAp} \; f \; x
\end{bmatrix}
& m
}
#. Push a function's argument onto the stack
.. math::
\gmrule
{ \mathtt{Push} \; n : i
& a_0 : \ldots : a_n : s
& d
& h
& m
}
{ i
& a_n : a_0 : \ldots : a_n : s
& d
& h
& m
}
#. Tidy up the stack after instantiating a supercombinator
.. math::
\gmrule
{ \mathtt{Slide} \; n : i
& a_0 : \ldots : a_n : s
& d
& h
& m
}
{ i
& a_0 : s
& d
& h
& m
}
#. If the top of the stack is in WHNF (currently this just means a number) is on
top of the stack, :code:`Unwind` considers evaluation complete. In the case
where the dump is **not** empty, the instruction queue and stack is restored
from the top.
.. math::
\gmrule
{ \mathtt{Unwind} : \nillist
& a : s
& \langle i', s' \rangle : d
& h
\begin{bmatrix}
a : \mathtt{NNum} \; n
\end{bmatrix}
& m
}
{ i'
& a : s'
& d
& h
& m
}
#. Bulding on the previous rule, in the case where the dump **is** empty, leave
the machine in a halt state (i.e. with an empty instruction queue).
.. math::
\gmrule
{ \mathtt{Unwind} : \nillist
& a : s
& \nillist
& h
\begin{bmatrix}
a : \mathtt{NNum} \; n
\end{bmatrix}
& m
}
{ \nillist
& a : s
& \nillist
& h
& m
}
#. Again, building on the previous rules, this rule makes the machine consider
unapplied supercombinators to be in WHNF
.. math::
\gmrule
{ \mathtt{Unwind} : \nillist
& a_0 : \ldots : a_n : \nillist
& \langle i, s \rangle : d
& h
\begin{bmatrix}
a_0 : \mathtt{NGlobal} \; k \; c
\end{bmatrix}
& m
}
{ i
& a_n : s
& d
& h
& m \\
\SetCell[c=2]{c}
\text{when $n < k$}
}
#. If an application is on top of the stack, :code:`Unwind` continues unwinding
.. math::
\gmrule
{ \mathtt{Unwind} : \nillist
& a : s
& d
& h
\begin{bmatrix}
a : \mathtt{NAp} \; f \; x
\end{bmatrix}
& m
}
{ \mathtt{Unwind} : \nillist
& f : a : s
& d
& h
& m
}
#. When a supercombinator is on top of the stack (and the correct number of
arguments have been provided), :code:`Unwind` sets up the stack and jumps to
the supercombinator's code (:math:`\beta`-reduction)
.. math::
\gmrule
{ \mathtt{Unwind} : \nillist
& a_0 : \ldots : a_n : s
& d
& h
\begin{bmatrix}
a_0 : \mathtt{NGlobal} \; n \; c \\
a_1 : \mathtt{NAp} \; a_0 \; e_1 \\
\vdots \\
a_n : \mathtt{NAp} \; a_{n-1} \; e_n \\
\end{bmatrix}
& m
}
{ c
& e_1 : \ldots : e_n : a_n : s
& d
& h
& m
}
#. Pop the stack, and update the nth node to point to the popped address
.. math::
\gmrule
{ \mathtt{Update} \; n : i
& e : f : a_1 : \ldots : a_n : s
& d
& h
\begin{bmatrix}
a_1 : \mathtt{NAp} \; f \; e \\
\vdots \\
a_n : \mathtt{NAp} \; a_{n-1} \; e_n
\end{bmatrix}
& m
}
{ i
& f : a_1 : \ldots : a_n : s
& d
& h
\begin{bmatrix}
a_n : \mathtt{NInd} \; e
\end{bmatrix}
& m
}
#. Pop the stack.
.. math::
\gmrule
{ \mathtt{Pop} \; n : i
& a_1 : \ldots : a_n : s
& d
& h
& m
}
{ i
& s
& d
& h
& m
}
#. Follow indirections while unwinding
.. math::
\gmrule
{ \mathtt{Unwind} : \nillist
& a : s
& d
& h
\begin{bmatrix}
a : \mathtt{NInd} \; a'
\end{bmatrix}
& m
}
{ \mathtt{Unwind} : \nillist
& a' : s
& d
& h
& m
}
#. Allocate uninitialised heap space
.. math::
\gmrule
{ \mathtt{Alloc} \; n : i
& s
& d
& h
& m
}
{ i
& a_1 : \ldots : a_n : s
& d
& h
\begin{bmatrix}
a_1 : \mathtt{NUninitialised} \\
\vdots \\
a_n : \mathtt{NUninitialised} \\
\end{bmatrix}
& m
}
#. Evaluate the top of the stack to WHNF
.. math::
\gmrule
{ \mathtt{Eval} : i
& a : s
& d
& h
& m
}
{ \mathtt{Unwind} : \nillist
& a : \nillist
& \langle i, s \rangle : d
& h
& m
}
#. Reduce a primitive binary operator :math:`*`.
.. math::
\gmrule
{ * : i
& a_1 : a_2 : s
& d
& h
\begin{bmatrix}
a_1 : x \\
a_2 : y
\end{bmatrix}
& m
}
{ i
& a' : s
& d
& h
\begin{bmatrix}
a' : (x * y)
\end{bmatrix}
& m
}
#. Reduce a primitive unary operator :math:`\neg`.
.. math::
\gmrule
{ \neg : i
& a : s
& d
& h
\begin{bmatrix}
a : x
\end{bmatrix}
& m
}
{ i
& a' : s
& d
& h
\begin{bmatrix}
a' : (\neg x)
\end{bmatrix}
& m
}
***************
Extension Rules
***************
#. A sneaky trick to enable sharing of :code:`NNum` nodes. We note that the
global environment is a mapping of plain old strings to heap addresses.
Strings of digits are not considered valid identifiers, so putting them on
the global environment will never conflict with a supercombinator! We abuse
this by modifying Core Rule 2 to update the global environment with the new
node's address. Consider how this rule might impact garbage collection
(remember that the environment is intended for *globals*).
.. math::
\gmrule
{ \mathtt{PushInt} \; n : i
& s
& d
& h
& m
}
{ i
& a : s
& d
& h
\begin{bmatrix}
a : \mathtt{NNum} \; n
\end{bmatrix}
& m
\begin{bmatrix}
n' : a
\end{bmatrix}
\\
\SetCell[c=5]{c}
\text{where $n'$ is the base-10 string rep. of $n$}
}
#. In order for the previous rule to be effective, we are also required to take
action when a number already exists in the environment:
.. math::
\gmrule
{ \mathtt{PushInt} \; n : i
& s
& d
& h
& m
\begin{bmatrix}
n' : a
\end{bmatrix}
}
{ i
& a : s
& d
& h
& m
\\
\SetCell[c=5]{c}
\text{where $n'$ is the base-10 string rep. of $n$}
}

View File

@@ -0,0 +1,334 @@
============================================
Template Instantiator State Transition Rules
============================================
Evaluation is complete when a single :code:`NNum` remains on the stack and the
dump is empty.
.. math::
\transrule
{ a : \nillist
& \nillist
& h
\begin{bmatrix}
a : \mathtt{NNum} \; n
\end{bmatrix}
& g
}
{ \mathtt{HALT}
}
Dereference an indirection passed as an argument to a function.
.. math::
\transrule
{a : s & d & h
\begin{bmatrix}
a : \mathtt{NAp} \; a_1 \; a_2 \\
a_2 : \mathtt{NInd} \; a_3
\end{bmatrix} & g}
{a : s & d & h[a : \mathtt{NAp} \; a_1 \; a_3] & g}
Dereference an indirection on top of the stack.
.. math::
\transrule
{p : s & d & h
\begin{bmatrix}
p : \mathtt{NInd} \; a
\end{bmatrix} & g}
{a : s & d & h & g}
Perform a unary operation :math:`o(n)` with internal :code:`Prim` constructor
:code:`O` on an argument in normal form.
.. math::
\transrule
{ f : a : s
& d
& h
\begin{bmatrix}
f : \mathtt{NPrim} \; \mathtt{O} \\
a : \mathtt{NAp} \; f \; x \\
x : \mathtt{NNum} \; n
\end{bmatrix}
& g
}
{ a : s
& d
& h
\begin{bmatrix}
a : \mathtt{NNum} \; (o(n))
\end{bmatrix}
& g
}
Evaluate the argument of a unary operation with internal :code:`Prim`
constructor :code:`O`.
.. math::
\transrule
{ f : a : \nillist
& d
& h
\begin{bmatrix}
f : \mathtt{NPrim} \; \mathtt{O} \\
a : \mathtt{NAp} \; f \; x
\end{bmatrix}
& g
}
{ x : \nillist
& (f : a : \nillist) : d
& h
& g
}
Restore the stack when a sub-computation has completed.
.. math::
\transrule
{ a : \nillist
& s : d
& h
\begin{bmatrix}
a : \mathtt{NNum} \; n
\end{bmatrix}
& g
}
{ s
& d
& h
& g
}
Reduce a supercombinator and update the root with the :math:`\beta`-reduced form
.. math::
\transrule
{ a_0 : a_1 : \ldots : a_n : s
& d
& h
\begin{bmatrix}
a_0 : \mathtt{NSupercomb} \; [x_1,\ldots,x_n] \; e
\end{bmatrix}
& g
}
{ a_n : s
& d
& h'
& g
\\
& \SetCell[c=3]{c}
\text{where } h' = \mathtt{instantiateU} \; e \; a_n \; h \; g
}
Perform a binary operation :math:`o(x,y)` associated with internal :code:`Prim`
constructor :code:`O` on two :code:`NNum` s both in normal form.
.. math::
\transrule
{ f : a_1 : a_2 : s
& d
& h
\begin{bmatrix}
f : \mathtt{NPrim} \; \mathtt{O} \\
a_1 : \mathtt{NAp} \; f \; (\mathtt{NNum} \; x) \\
a_2 : \mathtt{NAp} \; a_1 \; (\mathtt{NNum} \; y)
\end{bmatrix}
& g
}
{ a_2 : s
& d
& h
\begin{bmatrix}
a_2 : \mathtt{NNum} \; (o(x,y))
\end{bmatrix}
& g
}
In a conditional primitive, perform the reduction if the condition has been
evaluated as True (:code:`NData 1 []`).
.. math::
\transrule
{ f : a_1 : a_2 : a_3 : s
& d
& h
\begin{bmatrix}
f : \mathtt{NPrim} \; \mathtt{IfP} \\
c : \mathtt{NPrim} \; (\mathtt{NData} \; 1 \; \nillist) \\
a_1 : \mathtt{NAp} \; f \; c \\
a_2 : \mathtt{NAp} \; a_1 \; x \\
a_3 : \mathtt{NAp} \; a_2 \; y
\end{bmatrix}
& g
}
{ x : s
& d
& h
& g
}
In a conditional primitive, perform the reduction if the condition has been
evaluated as False (:code:`NData 0 []`).
.. math::
\transrule
{ f : a_1 : a_2 : a_3 : s
& d
& h
\begin{bmatrix}
f : \mathtt{NPrim} \; \mathtt{IfP} \\
c : \mathtt{NPrim} \; (\mathtt{NData} \; 0 \; \nillist) \\
a_1 : \mathtt{NAp} \; f \; c \\
a_2 : \mathtt{NAp} \; a_1 \; x \\
a_3 : \mathtt{NAp} \; a_2 \; y
\end{bmatrix}
& g
}
{ y : s
& d
& h
& g
}
In a conditional primitive, evaluate the condition.
.. math::
\transrule
{ f : a_1 : \nillist
& d
& h
\begin{bmatrix}
f : \mathtt{NPrim} \; \mathtt{IfP} \\
a_1 : \mathtt{NAp} \; f \; x
\end{bmatrix}
& g
}
{ x : \nillist
& (f : a_1 : \nillist) : d
& h
& g
}
Construct :code:`NData` out of a constructor and its arguments
.. math::
\transrule
{ c : a_1 : \ldots : a_n : \nillist
& d
& h
\begin{bmatrix}
c : \mathtt{NPrim} \; (\mathtt{ConP} \; t \; n) \\
a_1 : \mathtt{NAp} \; c \; x_1 \\
\vdots \\
a_n : \mathtt{NAp} \; a_{n-1} \; x_n
\end{bmatrix}
& g
}
{ a_n : \nillist
& d
& h
\begin{bmatrix}
a_n : \mathtt{NData} \; t \; [x_1, \ldots, x_n]
\end{bmatrix}
& g
}
Pairs
-----
Evaluate the first argument if necessary
.. math::
\transrule
{ c : a_1 : a_2 : \nillist
& d
& h
\begin{bmatrix}
c : \mathtt{NPrim} \; \mathtt{CasePairP} \\
p : \mathtt{NAp} \; \_ \: \_ \\
a_1 : \mathtt{NAp} \; c \; p \\
a_2 : \mathtt{NAp} \; a_2 \; f
\end{bmatrix}
& g
}
{ p : \nillist
& (a_1 : a_2 : \nillist) : d
& h
& g
}
Perform the reduction if the first argument is in normal form
.. math::
\transrule
{ c : a_1 : a_2 : s
& d
& h
\begin{bmatrix}
c : \mathtt{NPrim} \; \mathtt{CasePairP} \\
p : \mathtt{NData} \; 0 \; [x,y] \\
a_1 : \mathtt{NAp} \; c \; p \\
a_2 : \mathtt{NAp} \; a_1 \; f
\end{bmatrix}
& g
}
{ a_1 : a_2 : s
& d
& h
\begin{bmatrix}
a_1 : \mathtt{NAp} \; f \; x \\
a_2 : \mathtt{NAp} \; a_1 \; y
\end{bmatrix}
& g
}
Lists
-----
Evaluate the scrutinee
.. math::
\transrule
{ c : a_1 : a_2 : a_3 : \nillist
& d
& h
\begin{bmatrix}
c : \mathtt{NPrim} \; \mathtt{CaseListP} \\
a_1 : \mathtt{NAp} \; c \; x
\end{bmatrix}
& g
}
{ x
& (a_1 : a_2 : a_3) : \nillist
& h
& g
}
If the scrutinee is :code:`Nil`, perform the appropriate reduction.
.. math::
\transrule
{ c : a_1 : a_2 : a_3 : s
& d
& h
\begin{bmatrix}
c : \mathtt{NPrim} \; \mathtt{CaseListP} \\
p : \mathtt{NData} \; 1 \; \nillist \\
a_1 : \mathtt{NAp} \; c \; p \\
a_2 : \mathtt{NAp} \; p \; f_\text{nil} \\
a_3 : \mathtt{NAp} \; a_2 \; f_\text{cons}
\end{bmatrix}
& g
}
{ a_3 : s
& d
& h
\begin{bmatrix}
a_3 : \mathtt{NAp} \; f_\text{nil}
\end{bmatrix}
& g
}