Add some stuff about provable properties of our system.
[matthijs/master-project/report.git] / Chapters / Normalization.tex
index 445c32389ad91ccd8f874ddbd49ebb8f7fa71682..17a37c6713fbbf057cbf0a72fd86d2a3e044e1e2 100644 (file)
 }
 
 
-% A transformation example
-\definefloat[example][examples]
-\setupcaption[example][location=top] % Put captions on top
-
 \define[3]\transexample{
   \placeexample[here]{#1}
   \startcombination[2*1]
@@ -318,7 +314,7 @@ subtractor.}
     {\boxedgraphic{NormalComplete}}{The architecture described by the normal form.}
   \stopcombination
 
-\subsection{Normal form definition}
+\subsection{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 completely captures the intended structure (and
@@ -606,31 +602,44 @@ notations, which we will define here.
 
 \subsubsection{Other concepts}
 A \emph{global variable} is any variable that is bound at the
-top level of a program, or an external module. A local variable is any other
-variable (\eg, variables local to a function, which can be bound by lambda
-abstractions, let expressions and case expressions).
-
-A \emph{hardware representable} type is a type that we can generate
-a signal for in hardware. For example, a bit, a vector of bits, a 32 bit
-unsigned word, etc. Types that are not runtime representable notably
-include (but are not limited to): Types, dictionaries, functions.
-
-A \emph{builtin function} is a function for which a builtin
-hardware translation is available, because its actual definition is not
-translatable. A user-defined function is any other function.
+top level of a program, or an external module. A \emph{local variable} is any
+other variable (\eg, variables local to a function, which can be bound by
+lambda abstractions, let expressions and pattern matches of case
+alternatives).  Note that this is a slightly different notion of global versus
+local than what \small{GHC} uses internally.
+\defref{global variable} \defref{local variable}
+
+A \emph{hardware representable} (or just \emph{representable}) type or value
+is (a value of) a type that we can generate a signal for in hardware. For
+example, a bit, a vector of bits, a 32 bit unsigned word, etc. Types that are
+not runtime representable notably include (but are not limited to): Types,
+dictionaries, functions.
+\defref{representable}
+
+A \emph{builtin 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{builtin function} \defref{user-defined function}
+
+For these functions, Cλash has a \emph{builtin hardware translation}, so calls
+to these functions can still be translated. These are functions like
+\lam{map}, \lam{hwor} and \lam{length}.
+
+A \emph{user-defined} function is a function for which we do have a Cλash
+implementation available.
 
 \subsubsection{Functions}
 Here, we define a number of functions that can be used below to concisely
 specify conditions.
 
-\emph{gvar(expr)} is true when \emph{expr} is a variable that references a
+\refdef{global variable}\emph{gvar(expr)} is true when \emph{expr} is a variable that references a
 global variable. It is false when it references a local variable.
 
-\emph{lvar(expr)} is the inverse of \emph{gvar}; it is true when \emph{expr}
+\refdef{local variable}\emph{lvar(expr)} is the complement of \emph{gvar}; it is true when \emph{expr}
 references a local variable, false when it references a global variable.
 
-\emph{representable(expr)} or \emph{representable(var)} is true when
-\emph{expr} or \emph{var} has a type that is representable at runtime.
+\refdef{representable}\emph{representable(expr)} or \emph{representable(var)} is true when
+\emph{expr} or \emph{var} is \emph{representable}.
 
 \subsection{Binder uniqueness}
 A common problem in transformation systems, is binder uniqueness. When not
@@ -771,21 +780,66 @@ foo = λa.λx.(case a of
 
 \transexample{η-abstraction}{from}{to}
 
-\subsection{Extended β-reduction}
+\subsection{β-reduction}
+β-reduction is a well known transformation from lambda calculus, where it is
+the main reduction step. It reduces applications of labmda abstractions,
+removing both the lambda abstraction and the application.
+
+In our transformation system, this step helps to remove unwanted lambda
+abstractions (basically all but the ones at the top level). Other
+transformations (application propagation, non-representable inlining) make
+sure that most lambda abstractions will eventually be reducable by
+β-reduction.
+
+TODO: Define substitution syntax
+
+\starttrans
+(λx.E) M
+-----------------
+E[M/x]
+\stoptrans
+
+% And an example
+\startbuffer[from]
+(λa. 2 * a) (2 * b)
+\stopbuffer
+
+\startbuffer[to]
+2 * (2 * b)
+\stopbuffer
+
+\transexample{β-reduction}{from}{to}
+
+\subsection{Application propagation}
 This transformation is meant to propagate application expressions downwards
-into expressions as far as possible. In lambda calculus, this reduction
-is known as β-reduction, but it is of course only defined for
-applications of lambda abstractions. We extend this reduction to also
-work for the rest of core (case and let expressions).
+into expressions as far as possible. This allows partial applications inside
+expressions to become fully applied and exposes new transformation
+possibilities for other transformations (like β-reduction).
 
-For let expressions:
 \starttrans
 let binds in E) M
 -----------------
 let binds in E M
 \stoptrans
 
-For case statements:
+% And an example
+\startbuffer[from]
+( let 
+    val = 1
+  in 
+    add val
+) 3
+\stopbuffer
+
+\startbuffer[to]
+let 
+  val = 1
+in 
+  add val 3
+\stopbuffer
+
+\transexample{Application propagation for a let expression}{from}{to}
+
 \starttrans
 (case x of
   p1 -> E1
@@ -798,35 +852,21 @@ case x of
   pn -> En M
 \stoptrans
 
-For lambda expressions:
-\starttrans
-(λx.E) M
------------------
-E[M/x]
-\stoptrans
-
 % And an example
 \startbuffer[from]
-( let a = (case x of 
-            True -> id
-            False -> neg
-          ) 1
-      b = (let y = 3 in add y) 2
-  in
-    (λz.add 1 z)
-) 3
+( case x of 
+    True -> id
+    False -> neg
+) 1
 \stopbuffer
 
 \startbuffer[to]
-let a = case x of 
-           True -> id 1
-           False -> neg 1
-    b = let y = 3 in add y 2
-in
-  add 1 3
+case x of 
+  True -> id 1
+  False -> neg 1
 \stopbuffer
 
-\transexample{Extended β-reduction}{from}{to}
+\transexample{Application propagation for a case expression}{from}{to}
 
 \subsection{Let derecursification}
 This transformation is meant to make lets non-recursive whenever possible.
@@ -842,7 +882,7 @@ in scope for the function return value).
 Note that this transformation does not try to be smart when faced with
 recursive lets, it will just leave the lets recursive (possibly joining a
 recursive and non-recursive let into a single recursive let). The let
-rederursification transformation will do this instead.
+rederecursification transformation will do this instead.
 
 \starttrans
 letnonrec x = (let bindings in M) in N
@@ -1472,3 +1512,150 @@ x = let x = add 1 2 in x
 \stopbuffer
 
 \transexample{Return value simplification}{from}{to}
+
+\section{Provable properties}
+  When looking at the system of transformations outlined above, there are a
+  number of questions that we can ask ourselves. The main question is of course:
+  \quote{Does our system work as intended?}. We can split this question into a
+  number of subquestions:
+
+  \startitemize[KR]
+  \item[q:termination] Does our system \emph{terminate}? Since our system will
+  keep running as long as transformations apply, there is an obvious risk that
+  it will keep running indefinitely. One transformation produces a result that
+  is transformed back to the original by another transformation, for example.
+  \item[q:soundness] Is our system \emph{sound}? Since our transformations
+  continuously modify the expression, there is an obvious risk that the final
+  normal form will not be equivalent to the original program: Its meaning could
+  have changed.
+  \item[q:completeness] Is our system \emph{complete}? Since we have a complex
+  system of transformations, there is an obvious risk that some expressions will
+  not end up in our intended normal form, because we forgot some transformation.
+  In other words: Does our transformation system result in our intended normal
+  form for all possible inputs?
+  \item[q:determinism] Is our system \emph{deterministic}? Since we have defined
+  no particular order in which the transformation should be applied, there is an
+  obvious risk that different transformation orderings will result in
+  \emph{different} normal forms. They might still both be intended normal forms
+  (if our system is \emph{complete}) and describe correct hardware (if our
+  system is \emph{sound}), so this property is less important than the previous
+  three: The translator would still function properly without it.
+  \stopitemize
+
+  \subsection{Graph representation}
+    Before looking into how to prove these properties, we'll look at our
+    transformation system from a graph perspective. The nodes of the graph are
+    all possible Core expressions. The (directed) edges of the graph are
+    transformations. When a transformation α applies to an expression \lam{A} to
+    produce an expression \lam{B}, we add an edge from the node for \lam{A} to the
+    node for \lam{B}, labeled α.
+
+    \startuseMPgraphic{TransformGraph}
+      save a, b, c, d;
+
+      % Nodes
+      newCircle.a(btex \lam{(λx.λy. (+) x y) 1} etex);
+      newCircle.b(btex \lam{λy. (+) 1 y} etex);
+      newCircle.c(btex \lam{(λx.(+) x) 1} etex);
+      newCircle.d(btex \lam{(+) 1} etex);
+
+      b.c = origin;
+      c.c = b.c + (4cm, 0cm);
+      a.c = midpoint(b.c, c.c) + (0cm, 4cm);
+      d.c = midpoint(b.c, c.c) - (0cm, 3cm);
+
+      % β-conversion between a and b
+      ncarc.a(a)(b) "name(bred)";
+      ObjLabel.a(btex $\xrightarrow[normal]{}{β}$ etex) "labpathname(bred)", "labdir(rt)";
+      ncarc.b(b)(a) "name(bexp)", "linestyle(dashed withdots)";
+      ObjLabel.b(btex $\xleftarrow[normal]{}{β}$ etex) "labpathname(bexp)", "labdir(lft)";
+
+      % η-conversion between a and c
+      ncarc.a(a)(c) "name(ered)";
+      ObjLabel.a(btex $\xrightarrow[normal]{}{η}$ etex) "labpathname(ered)", "labdir(rt)";
+      ncarc.c(c)(a) "name(eexp)", "linestyle(dashed withdots)";
+      ObjLabel.c(btex $\xleftarrow[normal]{}{η}$ etex) "labpathname(eexp)", "labdir(lft)";
+
+      % η-conversion between b and d
+      ncarc.b(b)(d) "name(ered)";
+      ObjLabel.b(btex $\xrightarrow[normal]{}{η}$ etex) "labpathname(ered)", "labdir(rt)";
+      ncarc.d(d)(b) "name(eexp)", "linestyle(dashed withdots)";
+      ObjLabel.d(btex $\xleftarrow[normal]{}{η}$ etex) "labpathname(eexp)", "labdir(lft)";
+
+      % β-conversion between c and d
+      ncarc.c(c)(d) "name(bred)";
+      ObjLabel.c(btex $\xrightarrow[normal]{}{β}$ etex) "labpathname(bred)", "labdir(rt)";
+      ncarc.d(d)(c) "name(bexp)", "linestyle(dashed withdots)";
+      ObjLabel.d(btex $\xleftarrow[normal]{}{β}$ etex) "labpathname(bexp)", "labdir(lft)";
+
+      % Draw objects and lines
+      drawObj(a, b, c, d);
+    \stopuseMPgraphic
+
+    \placeexample[right][ex:TransformGraph]{Partial graph of a labmda calculus
+    system with β and η reduction (solid lines) and expansion (dotted lines).}
+        \boxedgraphic{TransformGraph}
+
+    Of course our graph is unbounded, since we can construct an infinite amount of
+    Core expressions. Also, there might potentially be multiple edges between two
+    given nodes (with different labels), though seems unlikely to actually happen
+    in our system.
+
+    See \in{example}[ex:TransformGraph] for the graph representation of a very
+    simple lambda calculus that contains just the expressions \lam{(λx.λy. (+) x
+    y) 1}, \lam{λy. (+) 1 y}, \lam{(λx.(+) x) 1} and \lam{(+) 1}. The
+    transformation system consists of β-reduction and η-reduction (solid edges) or
+    β-reduction and η-reduction (dotted edges).
+
+    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 expression to which
+    no transformation applies anymore. We call this set of nodes the \emph{normal
+    set}.
+
+    From such a graph, we can derive some properties easily:
+    \startitemize[KR]
+      \item A system will \emph{terminate} if there is no path of infinite length
+      in the graph (this includes cycles).
+      \item Soundness is not easily represented in the graph.
+      \item A system is \emph{complete} if all of the nodes in the normal set have
+      the intended normal form. The inverse (that all of the nodes outside of
+      the normal set are \emph{not} in the intended normal form) is not
+      strictly required.
+      \item A system is deterministic if all paths from a node, which end in a node
+      in the normal set, end at the same node.
+    \stopitemize
+
+    When looking at the \in{example}[ex:TransformGraph], we see that the system
+    terminates for both the reduction and expansion systems (but note that, for
+    expansion, this is only true because we've limited the possible expressions!
+    In comlete lambda calculus, there would be a path from \lam{(λx.λy. (+) x y)
+    1} to \lam{(λx.λy.(λz.(+) z) x y) 1} to \lam{(λx.λy.(λz.(λq.(+) q) z) x y) 1}
+    etc.)
+
+    If we would consider the system with both expansion and reduction, there would
+    no longer be termination, since there would be cycles all over the place.
+
+    The reduction and expansion systems have a normal set of containing just
+    \lam{(+) 1} or \lam{(λx.λy. (+) x y) 1} respectively. Since all paths in
+    either system end up in these normal forms, both systems are \emph{complete}.
+    Also, since there is only one normal form, it must obviously be
+    \emph{deterministic} as well.
+
+  \subsection{Termination}
+    Approach: Counting.
+
+    Church-Rosser?
+
+  \subsection{Soundness}
+    Needs formal definition of semantics.
+    Prove for each transformation seperately, implies soundness of the system.
+   
+  \subsection{Completeness}
+    Show that any transformation applies to every Core expression that is not
+    in normal form. To prove: no transformation applies => in intended form.
+    Show the reverse: Not in intended form => transformation applies.
+
+  \subsection{Determinism}
+    How to prove this?