Theory WorkerWrapperNew
theory WorkerWrapperNew
imports
HOLCF
FixedPointTheorems
WorkerWrapper
begin
section‹A totally-correct fusion rule›
text‹
\label{sec:ww-fixed}
We now show that a termination-preserving worker/wrapper fusion rule
can be obtained by requiring @{term "unwrap"} to be strict. (As we
observed earlier, @{term "wrap"} must always be strict due to the
assumption that ‹wrap oo unwrap = ID›.)
Our first result shows that a combined worker/wrapper transformation
and fusion rule is sound, using the assumptions of ‹worker_wrapper_id› and the ubiquitous ‹lfp_fusion› rule.
›
lemma worker_wrapper_fusion_new:
fixes wrap :: "'b::pcpo → 'a::pcpo"
fixes unwrap :: "'a → 'b"
fixes body' :: "'b → 'b"
assumes wrap_unwrap: "wrap oo unwrap = (ID :: 'a → 'a)"
assumes unwrap_strict: "unwrap⋅⊥ = ⊥"
assumes body_body': "unwrap oo body oo wrap = body' oo (unwrap oo wrap)"
shows "fix⋅body = wrap⋅(fix⋅body')"
proof -
from body_body'
have "unwrap oo body oo (wrap oo unwrap) = (body' oo unwrap oo (wrap oo unwrap))"
by (simp add: assoc_oo)
with wrap_unwrap have "unwrap oo body = body' oo unwrap"
by simp
with unwrap_strict have "unwrap⋅(fix⋅body) = fix⋅body'"
by (rule lfp_fusion)
hence "(wrap oo unwrap)⋅(fix⋅body) = wrap⋅(fix⋅body')"
by simp
with wrap_unwrap show ?thesis by simp
qed
text‹
We can also show a more general result which allows fusion to be
optionally performed on a per-recursive-call basis using
\texttt{parallel\_fix\_ind}:
›
lemma worker_wrapper_fusion_new_general:
fixes wrap :: "'b::pcpo → 'a::pcpo"
fixes unwrap :: "'a → 'b"
assumes wrap_unwrap: "wrap oo unwrap = (ID :: 'a → 'a)"
assumes unwrap_strict: "unwrap⋅⊥ = ⊥"
assumes body_body': "⋀r. (unwrap oo wrap)⋅r = r
⟹ (unwrap oo body oo wrap)⋅r = body'⋅r"
shows "fix⋅body = wrap⋅(fix⋅body')"
proof -
let ?P = "λ(x, y). x = y ∧ unwrap⋅(wrap⋅x) = x"
have "?P (fix⋅(unwrap oo body oo wrap), (fix⋅body'))"
proof(induct rule: parallel_fix_ind)
case 2 with retraction_strict unwrap_strict wrap_unwrap show "?P (⊥, ⊥)"
by (bestsimp simp add: cfun_eq_iff)
case (3 x y)
hence xy: "x = y" and unwrap_wrap: "unwrap⋅(wrap⋅x) = x" by auto
from body_body' xy unwrap_wrap
have "(unwrap oo body oo wrap)⋅x = body'⋅y"
by simp
moreover
from wrap_unwrap
have "unwrap⋅(wrap⋅((unwrap oo body oo wrap)⋅x)) = (unwrap oo body oo wrap)⋅x"
by (simp add: cfun_eq_iff)
ultimately show ?case by simp
qed simp
thus ?thesis
using worker_wrapper_id[OF wrap_unwrap refl] by simp
qed
text‹
This justifies the syntactically-oriented rules shown in
Figure~\ref{fig:wwc2}; note the scoping of the fusion rule.
Those familiar with the ``bananas'' work of \citet*{barbed-wire:1991}
will not be surprised that adding a strictness assumption justifies an
equational fusion rule.
\begin{figure}[tb]
\begin{center}
\fbox{\parbox{0.96\textwidth}{For a recursive definition @{haskell "comp =
body"} of type @{haskell "A"} and a pair of functions @{haskell "wrap :: B \\to A"}
and @{haskell "unwrap :: A \\to B"} where @{haskell "wrap \\circ unwrap = id_A"} and
@{haskell "unwrap\\ \\bot = \\bot"}, define:
\parbox{0.35\textwidth}{\begin{haskell}
comp & = wrap\ work\\
work & = unwrap\ (body[wrap\ work / comp])
\end{haskell}}\hfill \textsf{(the worker/wrapper transformation)}
In the scope of @{haskell "work"}, the following rewrite is admissable:
\parbox{0.35\textwidth}{\begin{haskell}
unwrap\ (wrap\ work) \Longrightarrow work
\end{haskell}}\hfill \textsf{(worker/wrapper fusion)}}}%
\end{center}%
\caption{The syntactic worker/wrapper transformation and fusion rule.}\label{fig:wwc2}
\end{figure}
›
end