Add Scrutinee binder removal.
[matthijs/master-project/report.git] / Chapters / Normalization.tex
index aa168e0bc2771e87b842654d127233ec8c742327..2768ba2c0a2c89e87e989471bd5d7a3c53ea5e4c 100644 (file)
@@ -36,7 +36,7 @@
     to this form as the \emph{normal form} of the program. The formal
     definition of this normal form is quite simple:
 
-    \placedefinition{}{\startboxed A program is in \emph{normal form} if none of the
+    \placedefinition[force]{}{\startboxed A program is in \emph{normal form} if none of the
     transformations from this chapter apply.\stopboxed}
 
     Of course, this is an \quote{easy} definition of the normal form, since our
       other expression.
     \stopitemize
 
-    \todo{Intermezzo: functions vs plain values}
-
-    A very simple example of a program in normal form is given in
-    \in{example}[ex:MulSum]. As you can see, all arguments to the function (which
-    will become input ports in the generated \VHDL) are at the outer level.
-    This means that the body of the inner lambda abstraction is never a
-    function, but always a plain value.
-
-    As the body of the inner lambda abstraction, we see a single (recursive)
-    let expression, that binds two variables (\lam{mul} and \lam{sum}). These
-    variables will be signals in the generated \VHDL, bound to the output port
-    of the \lam{*} and \lam{+} components.
-
-    The final line (the \quote{return value} of the function) selects the
-    \lam{sum} signal to be the output port of the function. This \quote{return
-    value} can always only be a variable reference, never a more complex
-    expression.
-
-    \todo{Add generated VHDL}
-
     \startbuffer[MulSum]
     alu :: Bit -> Word -> Word -> Word
     alu = λa.λb.λc.
       ncline(add)(sum);
     \stopuseMPgraphic
 
-    \placeexample[here][ex:MulSum]{Simple architecture consisting of a
+    \placeexample[][ex:MulSum]{Simple architecture consisting of a
     multiplier and a subtractor.}
       \startcombination[2*1]
         {\typebufferlam{MulSum}}{Core description in normal form.}
         {\boxedgraphic{MulSum}}{The architecture described by the normal form.}
       \stopcombination
 
+    \todo{Intermezzo: functions vs plain values}
+
+    A very simple example of a program in normal form is given in
+    \in{example}[ex:MulSum]. As you can see, all arguments to the function (which
+    will become input ports in the generated \VHDL) are at the outer level.
+    This means that the body of the inner lambda abstraction is never a
+    function, but always a plain value.
+
+    As the body of the inner lambda abstraction, we see a single (recursive)
+    let expression, that binds two variables (\lam{mul} and \lam{sum}). These
+    variables will be signals in the generated \VHDL, bound to the output port
+    of the \lam{*} and \lam{+} components.
+
+    The final line (the \quote{return value} of the function) selects the
+    \lam{sum} signal to be the output port of the function. This \quote{return
+    value} can always only be a variable reference, never a more complex
+    expression.
+
+    \todo{Add generated VHDL}
+
     \in{Example}[ex:MulSum] showed a function that just applied two
     other functions (multiplication and addition), resulting in a simple
     architecture with two components and some connections.  There is of
       ncline(mux)(res) "posA(out)";
     \stopuseMPgraphic
 
-    \placeexample[here][ex:AddSubAlu]{Simple \small{ALU} supporting two operations.}
+    \placeexample[][ex:AddSubAlu]{Simple \small{ALU} supporting two operations.}
       \startcombination[2*1]
         {\typebufferlam{AddSubAlu}}{Core description in normal form.}
         {\boxedgraphic{AddSubAlu}}{The architecture described by the normal form.}
     \stopuseMPgraphic
 
     \todo{Don't split registers in this image?}
-    \placeexample[here][ex:NormalComplete]{Simple architecture consisting of an adder and a
+    \placeexample[][ex:NormalComplete]{Simple architecture consisting of an adder and a
     subtractor.}
       \startcombination[2*1]
         {\typebufferlam{NormalComplete}}{Core description in normal form.}
 
     \subsection[sec:normalization:intendednormalform]{Intended normal form definition}
       Now we have some intuition for the normal form, we can describe how we want
-      the normal form to look like in a slightly more formal manner. The following
-      EBNF-like description captures most of the intended structure (and
-      generates a subset of \GHC's core format). 
+      the normal form to look like in a slightly more formal manner. The
+      EBNF-like description in \in{definition}[def:IntendedNormal] captures
+      most of the intended structure (and generates a subset of \GHC's core
+      format). 
       
-      There are two things missing: cast expressions are sometimes
-      allowed by the prototype, but not specified here and the below
+      There are two things missing from this definition: cast expressions are
+      sometimes allowed by the prototype, but not specified here and the below
       definition allows uses of state that cannot be translated to \VHDL\
       properly. These two problems are discussed in
       \in{section}[sec:normalization:castproblems] and
           {\defref{intended normal form definition}
            \typebufferlam{IntendedNormal}}
 
-      When looking at such a program from a hardware perspective, the
-      top level lambda abstractions define the input ports. Lambda
-      abstractions cannot appear anywhere else. The variable reference
-      in the body of the recursive let expression is the output port.
-      Most function applications bound by the let expression define a
-      component instantiation, where the input and output ports are
-      mapped to local signals or arguments. Some of the others use a
-      built-in construction (\eg\ the \lam{case} expression) or call a
-      built-in function (\eg\ \lam{+} or \lam{map}). For these, a
-      hardcoded \small{VHDL} translation is available.
+      When looking at such a program from a hardware perspective, the top
+      level lambda abstractions (\italic{lambda}) define the input ports.
+      Lambda abstractions cannot appear anywhere else. The variable reference
+      in the body of the recursive let expression (\italic{toplet}) is the
+      output port.  Most binders bound by the let expression define a
+      component instantiation (\italic{userapp}), where the input and output
+      ports are mapped to local signals (\italic{userarg}). Some of the others
+      use a built-in construction (\eg\ the \lam{case} expression) or call a
+      built-in function (\italic{builtinapp}) such as \lam{+} or \lam{map}.
+      For these, a hardcoded \small{VHDL} translation is available.
 
   \section[sec:normalization:transformation]{Transformation notation}
     To be able to concisely present transformations, we use a specific format
       dictionaries, functions.
       \defref{representable}
 
-      A \emph{built-in function} is a function supplied by the Cλash framework, whose
-      implementation is not valid Cλash. The implementation is of course valid
-      Haskell, for simulation, but it is not expressable in Cλash.
-      \defref{built-in function} \defref{user-defined function}
+      A \emph{built-in function} is a function supplied by the Cλash
+      framework, whose implementation is not used to generate \VHDL. This is
+      either because it is no valid Cλash (like most list functions that need
+      recursion) or because a Cλash implementation would be unwanted (for the
+      addition operator, for example, we would rather use the \VHDL addition
+      operator to let the synthesis tool decide what kind of adder to use
+      instead of explicitly describing one in Cλash). \defref{built-in
+      function}
 
-      For these functions, Cλash has a \emph{built-in hardware translation}, so calls
-      to these functions can still be translated. These are functions like
-      \lam{map}, \lam{hwor} and \lam{length}.
+      These are functions like \lam{map}, \lam{hwor}, \lam{+} and \lam{length}.
 
-      A \emph{user-defined} function is a function for which we do have a Cλash
-      implementation available.
+      For these functions, Cλash has a \emph{built-in hardware translation},
+      so calls to these functions can still be translated.  Built-in functions
+      must have a valid Haskell implementation, of course, to allow
+      simulation. 
+
+      A \emph{user-defined} function is a function for which no built-in
+      translation is available and whose definition will thus need to be
+      translated to Cλash. \defref{user-defined function}
 
       \subsubsection[sec:normalization:predicates]{Predicates}
         Here, we define a number of predicates that can be used below to concisely
         \stoptrans
 
         \starttrans
-        x = λv0 ... λvn.E
-        ~                                \lam{E} is representable
+        x = λv0 ... λvn.E                \lam{E} is representable
+        ~                                \lam{E} is not a lambda abstraction
         E                                \lam{E} is not a let expression
         ---------------------------      \lam{E} is not a local variable reference
         letrec x = E in x
           \stopframedtext
         }
 
+      \subsubsection{Scrutinee binder removal}
+        This transformation removes (or rather, makes wild) the binder to
+        which the scrutinee is bound after evaluation. This is done by
+        replacing the bndr with the scrutinee in all alternatives. To prevent
+        duplication of work, this transformation is only applied when the
+        scrutinee is already a simple variable reference (but the previous
+        transformation ensures this will eventually be the case). The
+        scrutinee binder itself is replaced by a wild binder (which is no
+        longer displayed).
+
+        Note that one could argue that this transformation can change the
+        meaning of the Core expression. In the regular Core semantics, a case
+        expression forces the evaluation of its scrutinee and can be used to
+        implement strict evaluation. However, in the generated \VHDL,
+        evaluation is always strict. So the semantics we assign to the Core
+        expression (which differ only at this particular point), this
+        transformation is completely valid.
+
+        \starttrans
+        case x of bndr
+          alts
+        -----------------        \lam{x} is a local variable reference
+        case x of
+          alts[bndr=>x]
+        \stoptrans
+
+        \startbuffer[from]
+        case x of y
+          True -> y
+          False -> not y
+        \stopbuffer
+
+        \startbuffer[to]
+        case x of
+          True -> x
+          False -> not x
+        \stopbuffer
+
+        \transexample{scrutbndrremove}{Scrutinee binder removal}{from}{to}
+
       \subsubsection{Case normalization}
         This transformation ensures that all case expressions get a form
         that is allowed by the intended normal form. This means they
 
       \todo{Define β-reduction and η-reduction?}
 
-      Note that the normal form of such a system consists of the set of nodes
-      (expressions) without outgoing edges, since those are the expressions to which
-      no transformation applies anymore. We call this set of nodes the \emph{normal
-      set}. The set of nodes containing expressions in intended normal
-      form \refdef{intended normal form} is called the \emph{intended
-      normal set}.
+      In such a graph a node (expression) is in normal form if it has no
+      outgoing edges (meaning no transformation applies to it). The set of
+      nodes without outgoing edges is called the \emph{normal set}. Similarly,
+      the set of nodes containing expressions in intended normal form
+      \refdef{intended normal form} is called the \emph{intended normal set}.
 
       From such a graph, we can derive some properties easily:
       \startitemize[KR]