Thomas Tuerk
3c35cc25c3
cleaned-up the sources of the ITP course - remove internal notes - remove exercise solutions - remove KTH logo - add Creative Commons license
1209 lines
38 KiB
TeX
1209 lines
38 KiB
TeX
\part{Rewriting}
|
|
|
|
\frame[plain]{\partpage}
|
|
|
|
\begin{frame}
|
|
\frametitle{Rewriting in HOL}
|
|
|
|
\begin{itemize}
|
|
\item simplification via rewriting was already a strength of Edinburgh LCF
|
|
\item it was further improved for Cambridge LCF
|
|
\item HOL inherited this powerful rewriter
|
|
\item equational reasoning is still the main workhorse
|
|
\item there are many different equational reasoning tools in HOL
|
|
\begin{itemize}
|
|
\item \hol{Rewrite} library\\
|
|
inherited from Cambridge LCF\\you have seen it in the form of \hol{REWRITE\_TAC}
|
|
\item \hol{computeLib} --- fast evaluation\\
|
|
build for speed, optimised for ground terms\\seen in the form of \hol{EVAL}
|
|
\item \hol{simpLib} --- Simplification\\
|
|
sophisticated rewrite engine, HOL's main workhorse\\
|
|
not discussed in this lecture, yet
|
|
\item \ldots
|
|
\end{itemize}
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
\section{Rewrite Library}
|
|
|
|
\begin{frame}
|
|
\frametitle{Semantic Foundations}
|
|
\begin{itemize}
|
|
\item we have seen primitive inference rules for equality before
|
|
|
|
\begin{columns}
|
|
\begin{column}{.35\textwidth}
|
|
\begin{center}
|
|
$\inferrule*[right=COMB]{\Gamma \entails s = t\\\Delta \entails u = v \\\\ \textit{types fit}}{\Gamma \cup \Delta \entails s(u) = t(v)}$\\[1em]
|
|
$\inferrule*[right=TRANS] {\Gamma \entails s = t\\\Delta \entails t = u}{\Gamma \cup \Delta \entails s = u}$\\[1em]
|
|
\end{center}
|
|
\end{column}
|
|
\begin{column}{.25\textwidth}
|
|
\begin{center}
|
|
$\inferrule*[right=ABS]{\Gamma \entails s = t\\x\ \textit{not free in}\ \Gamma}{\Gamma \entails \lambda{}x.\ s = \lambda{}x.\ t}$\\[1em]
|
|
$\inferrule* [right=REFL] {\ }{\entails t = t}$\\[1em]
|
|
\end{center}
|
|
\end{column}
|
|
\end{columns}\medskip
|
|
\item these rules allow us to replace any subterm with an equal one
|
|
\item this is the core of rewriting
|
|
\end{itemize}
|
|
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Conversions}
|
|
\begin{itemize}
|
|
\item in HOL, equality reasoning is implemented by \emph{conversions}
|
|
\item a conversion is a SML function of type \hol{term -> thm}
|
|
\item given a term \hol{t}, a conversion
|
|
\begin{itemize}
|
|
\item produces a theorem of the form \hol{|- t = t'}
|
|
\item raises an \hol{UNCHANGED} exception or
|
|
\item fails, \ie raises an \hol{HOL\_ERR} exception
|
|
\end{itemize}
|
|
\end{itemize}
|
|
\begin{exampleblock}{Example}
|
|
\begin{semiverbatim}\scriptsize
|
|
> \hol{BETA\_CONV ``(\textbsl{}x. SUC x) y``}
|
|
val it = |- (\textbsl{}x. SUC x) y = SUC y
|
|
|
|
> \hol{BETA\_CONV ``SUC y``}
|
|
Exception-HOL_ERR ... raised
|
|
|
|
> \hol{REPEATC BETA\_CONV ``SUC y``}
|
|
Exception- UNCHANGED raised
|
|
\end{semiverbatim}
|
|
\end{exampleblock}
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Conversionals}
|
|
\begin{itemize}
|
|
\item similar to tactics and tacticals there are \emph{conversionals} for conversions
|
|
\item conversionals allow building conversions from simpler ones
|
|
\item there are many of them
|
|
\begin{itemize}
|
|
\item \hol{THENC}
|
|
\item \hol{ORELSEC}
|
|
\item \hol{REPEATC}
|
|
\item \hol{TRY\_CONV}
|
|
\item \hol{RAND\_CONV}
|
|
\item \hol{RATOR\_CONV}
|
|
\item \hol{ABS\_CONV}
|
|
\item \ldots
|
|
\end{itemize}
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}
|
|
\frametitle{Depth Conversionals}
|
|
\begin{itemize}
|
|
\item for rewriting depth-conversionals are important
|
|
\item a depth-conversional applies a conversion to all subterms
|
|
\item there are many different ones
|
|
\begin{itemize}
|
|
\item \hol{ONCE\_DEPTH\_CONV c} --- top down, applies \hol{c} once at highest possible positions in distinct subterms
|
|
\item \hol{TOP\_SWEEP\_CONV c} --- top down, like \hol{ONCE\_DEPTH\_CONV}, but continues processing rewritten terms
|
|
\item \hol{TOP\_DEPTH\_CONV c} --- top down, like \hol{TOP\_SWEEP\_CONV}, but try top-level again after change
|
|
\item \hol{DEPTH\_CONV c} --- bottom up, recurse over subterms, then apply \hol{c} repeatedly at top-level
|
|
\item \hol{REDEPTH\_CONV c} --- bottom up, like \hol{DEPTH\_CONV}, but revisits subterms
|
|
\end{itemize}
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}
|
|
\frametitle{\hol{REWR\_CONV}}
|
|
\begin{itemize}
|
|
\item it remains to rewrite terms at top-level
|
|
\item this is achieved by \hol{REWR\_CONV}
|
|
\item given a term \hol{t} and a theorem \hol{|- t1 = t2}, \texttt{REWR\_CONV t thm}
|
|
\begin{itemize}
|
|
\item searches an instantiation of term and type variables such that \hol{t1} becomes $\alpha$-equivalent to \hol{t}
|
|
\item fails, if no instantiation is found
|
|
\item otherwise, instantiate the theorem and get \hol{|- t1' = t2'}
|
|
\item return theorem \hol{|- t = t2'}
|
|
\end{itemize}
|
|
\begin{exampleblock}{Example}\scriptsize
|
|
term \hol{LENGTH [1;2;3]}, theorem \hol{|- LENGTH ((x:'a)::xs) = SUC (LENGTH xs)}\\
|
|
found type instantiation: \hol{[``:'a`` |-> ``:num``]}\\
|
|
found term instantiation: \hol{[``x:num`` |-> ``1``; ``xs`` |-> ``[2;3]``]}\\
|
|
returned theorem: \hol{|- LENGTH [1;2;3] = SUC (LENGTH [2;3])}
|
|
\end{exampleblock}
|
|
|
|
\item the tricky part is finding the instantiation
|
|
\item this problem is called the (term) \emph{matching} problem
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}
|
|
\frametitle{Term Matching}
|
|
\begin{itemize}
|
|
\item given term \hol{t\_org} and a term \hol{t\_goal} try to find
|
|
\begin{itemize}
|
|
\item type substitution \hol{ty\_s}
|
|
\item term substitution \hol{tm\_s}
|
|
\end{itemize}
|
|
\item such that \hol{subst tm\_s (inst ty\_s t\_org) \aequiv t\_goal}
|
|
\item this can be easily implemented by a recursive search
|
|
\bigskip
|
|
|
|
{\small
|
|
\begin{tabular}{lll}
|
|
\emph{\texttt{t\_org}} & \emph{\texttt{t\_goal}} & \emph{action} \\
|
|
\texttt{t1\_org t2\_org} & \texttt{t1\_goal t2\_goal} & recurse \\
|
|
\texttt{t1\_org t2\_org} & otherwise & fail \\
|
|
\texttt{\textbsl{}x.\ t\_org x} & \texttt{\textbsl{}y.\ t\_goal y} & match types of \texttt{x}, \texttt{y} and recurse \\
|
|
\texttt{\textbsl{}x.\ t\_org x} & otherwise & fail \\
|
|
\texttt{const} & same \texttt{const} & match types \\
|
|
\texttt{const} & otherwise & fail \\
|
|
\texttt{var} & anything & try to bind \texttt{var}, \\ & & take care of existing bindings
|
|
\end{tabular}
|
|
}
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
\frametitle{Examples Term Matching}
|
|
|
|
{\scriptsize
|
|
\begin{tabular}{lll}
|
|
\emph{\texttt{t\_org}} & \emph{\texttt{t\_goal}} & \emph{substs}\\
|
|
\texttt{LENGTH ((x:'a)::xs)} & \texttt{LENGTH [1;2;3]} &
|
|
\texttt{'a $\to$ num},
|
|
\texttt{x $\to$ 1},
|
|
\texttt{xs $\to$ [2;3]} \\
|
|
\texttt{[]:'a list} & \texttt{[]:'b list} &
|
|
\texttt{'a $\to$ 'b} \\
|
|
\texttt{0} & \texttt{0} &
|
|
\texttt{empty substitution} \\
|
|
\texttt{b \holAnd{} T} & \texttt{(P (x:'a) ==> Q) \holAnd{} T} &
|
|
\texttt{b $\to$ P x ==> Q} \\
|
|
\texttt{b \holAnd{} b} & \texttt{P x \holAnd{} P x} &
|
|
\texttt{b $\to$ P x} \\
|
|
\texttt{b \holAnd{} b} & \texttt{P x \holAnd{} P y} &
|
|
fail \\
|
|
\texttt{!x:num.\ P x \holAnd{} Q x} & \texttt{!y:num.\ P' y \holAnd{} Q' y} &
|
|
\texttt{P $\to$ P'},
|
|
\texttt{Q $\to$ Q'} \\
|
|
\texttt{!x:num.\ P x \holAnd{} Q x} & \texttt{!y.\ (2 = y) \holAnd{} Q' y} &
|
|
\texttt{P $\to$ (\$= 2)},
|
|
\texttt{Q $\to$ Q'} \\
|
|
\texttt{!x:num.\ P x \holAnd{} Q x} & \texttt{!y.\ (y = 2) \holAnd{} Q' y} &
|
|
fail
|
|
\end{tabular}
|
|
}
|
|
\bigskip
|
|
|
|
\begin{itemize}
|
|
\item it is often very annoying that the last match in the list above fails
|
|
\item it prevents us for example rewriting \hol{!y.\ (2 = y) \holAnd{} Q y} to\\
|
|
\hol{(!y.\ (2=y)) \holAnd{} (!y.\ Q y)}
|
|
\item Can we do better? Yes, with higher order (term) matching.
|
|
\end{itemize}
|
|
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}
|
|
\frametitle{Higher Order Term Matching}
|
|
|
|
\begin{itemize}
|
|
\item term matching searches for substitutions such that \texttt{t\_org} becomes $\alpha$-equivalent to \texttt{t\_goal}
|
|
\item \emph{higher order term matching} searches for substitutions such that \texttt{t\_org} becomes \texttt{t\_subst} such that the $\beta\eta$-normalform of \texttt{t\_subst} is $\alpha$-equivalent equivalent to $\beta\eta$-normalform of \texttt{t\_goal}, \ie
|
|
|
|
\textbf{higher order term matching is aware of the semantics of $\lambda$}
|
|
\bigskip
|
|
|
|
$\begin{array}{ll}
|
|
\beta\text{-reduction} & (\lambda x.\ f)\ y = f [y/x] \\
|
|
\eta\text{-conversion} & (\lambda x.\ f\ x) = f \text{ where $x$ is not free in $f$}
|
|
\end{array}$\bigskip
|
|
\item the HOL implementation expects \texttt{t\_org} to be a \emph{higher-order pattern}
|
|
\begin{itemize}
|
|
\item \texttt{t\_org} is $\beta$-reduced
|
|
\item if \texttt{X} is a variable that should be instantiated, then all arguments should be
|
|
distinct variables
|
|
\end{itemize}
|
|
\item for other forms of \texttt{t\_org}, HOL's implementation might fail
|
|
\item higher order matching is used by \ml{HO\_REWR\_CONV}
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
\begin{frame}
|
|
\frametitle{Examples Higher Order Term Matching}
|
|
|
|
{\scriptsize
|
|
\begin{tabular}{lll}
|
|
\emph{\texttt{t\_org}} & \emph{\texttt{t\_goal}} & \emph{substs}\\
|
|
\texttt{!x:num.\ P x \holAnd{} Q x} & \texttt{!y.\ (y = 2) \holAnd{} Q' y} &
|
|
\texttt{P $\to$ (\textbsl{}y.\ y = 2)},
|
|
\texttt{Q $\to$ Q'} \\
|
|
\texttt{!x.\ P x \holAnd{} Q x} & \texttt{!x.\ P x \holAnd{} Q x \holAnd{} Z x} &
|
|
\texttt{Q $\to$ \textbsl{}x.\ Q x \holAnd{} Z x} \\
|
|
\texttt{!x.\ P x \holAnd{} Q} & \texttt{!x.\ P x \holAnd{} Q x} &
|
|
\text{fails} \\
|
|
\texttt{!x.\ P (x, x)} & \texttt{!x.\ Q x} &
|
|
\text{fails} \\
|
|
\texttt{!x.\ P (x, x)} & \texttt{!x.\ FST (x,x) = SND (x,x)} &
|
|
\texttt{P $\to$ \textbsl{}xx.\ FST xx = SND xx}
|
|
\end{tabular}}
|
|
|
|
\bottomstatement{Don't worry, it might look complicated, but\\in practice it is easy to get a feeling for higher order matching.}
|
|
\end{frame}
|
|
|
|
\begin{frame}
|
|
\frametitle{\ml{Rewrite} Library}
|
|
|
|
\begin{itemize}
|
|
\item the rewrite library combines \hol{REWR\_CONV} with depth conversions
|
|
\item there are many different conversions, rules and tactics
|
|
\item at their core, they all work very similarly
|
|
\begin{itemize}
|
|
\item given a list of theorems, a set of rewrite theorems is derived
|
|
\begin{itemize}
|
|
\item split conjunctions
|
|
\item remove outermost universal quantification
|
|
\item introduce equations by adding \hol{= T} (or \hol{= F}) if needed
|
|
\end{itemize}
|
|
\item \texttt{REWR\_CONV} is applied to all the resulting rewrite theorems
|
|
\item a depth-conversion is used with resulting conversion
|
|
\end{itemize}
|
|
\item for performance reasons an efficient indexing structure is used
|
|
\item by default implicit rewrites are added
|
|
\end{itemize}
|
|
|
|
\end{frame}
|
|
|
|
\begin{frame}
|
|
\frametitle{\ml{Rewrite} Library II}
|
|
|
|
\begin{itemize}
|
|
\item \hol{REWRITE\_CONV}
|
|
\item \hol{REWRITE\_RULE}
|
|
\item \hol{REWRITE\_TAC}
|
|
\item \hol{ASM\_REWRITE\_TAC}
|
|
\item \hol{ONCE\_REWRITE\_TAC}
|
|
\item \hol{PURE\_REWRITE\_TAC}
|
|
\item \hol{PURE\_ONCE\_REWRITE\_TAC}
|
|
\item \ldots
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}
|
|
\frametitle{\ml{Ho\_Rewrite} Library}
|
|
|
|
\begin{itemize}
|
|
\item similar to \ml{Rewrite} lib, but uses higher order matching
|
|
\item internally uses \ml{HO\_REWR\_CONV}
|
|
\item similar conversions, rules and tactics as \ml{Rewrite} lib
|
|
\begin{itemize}
|
|
\item \hol{Ho\_Rewrite.REWRITE\_CONV}
|
|
\item \hol{Ho\_Rewrite.REWRITE\_RULE}
|
|
\item \hol{Ho\_Rewrite.REWRITE\_TAC}
|
|
\item \hol{Ho\_Rewrite.ASM\_REWRITE\_TAC}
|
|
\item \hol{Ho\_Rewrite.ONCE\_REWRITE\_TAC}
|
|
\item \hol{Ho\_Rewrite.PURE\_REWRITE\_TAC}
|
|
\item \hol{Ho\_Rewrite.PURE\_ONCE\_REWRITE\_TAC}
|
|
\item \ldots
|
|
\end{itemize}
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Examples \ml{Rewrite} and \ml{Ho\_Rewrite} Library}
|
|
|
|
\begin{semiverbatim}\scriptsize
|
|
> \hol{REWRITE\_CONV [LENGTH] ``LENGTH [1;2]``}
|
|
val it = |- LENGTH [1; 2] = SUC (SUC 0)
|
|
|
|
> \hol{ONCE\_REWRITE\_CONV [LENGTH] ``LENGTH [1;2]``}
|
|
val it = |- LENGTH [1; 2] = SUC (LENGTH [2])
|
|
|
|
> \hol{REWRITE\_CONV [] ``A \holAnd{} A \holAnd{} \holNeg{}A``}
|
|
Exception- UNCHANGED raised
|
|
|
|
> \hol{PURE\_REWRITE\_CONV [NOT\_AND] ``A \holAnd{} A \holAnd{} \holNeg{}A``}
|
|
val it = |- A \holAnd{} A \holAnd{} \holNeg{}A <=> A \holAnd{} F
|
|
|
|
> \hol{REWRITE\_CONV [NOT\_AND] ``A \holAnd{} A \holAnd{} \holNeg{}A``}
|
|
val it = |- A \holAnd{} A \holAnd{} \holNeg{}A <=> F
|
|
|
|
> \hol{REWRITE\_CONV [FORALL_AND_THM] ``!x. P x \holAnd{} Q x \holAnd{} R x``}
|
|
Exception- UNCHANGED raised
|
|
|
|
> \hol{Ho_Rewrite.REWRITE\_CONV [FORALL_AND_THM] ``!x. P x \holAnd{} Q x \holAnd{} R x``}
|
|
val it = |- !x. P x \holAnd{} Q x \holAnd{} R x <=> (!x. P x) \holAnd{} (!x. Q x) \holAnd{} (!x. R x)
|
|
\end{semiverbatim}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}
|
|
\frametitle{Summary \ml{Rewrite} and \ml{Ho\_Rewrite} Library}
|
|
|
|
\begin{itemize}
|
|
\item the \ml{Rewrite} and \ml{Ho\_Rewrite} library provide powerful infrastructure for term rewriting
|
|
\item thanks to clever implementations they are reasonably efficient
|
|
\item basics are easily explained
|
|
\item however, efficient usage needs some experience
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
\section{Term Rewriting Systems}
|
|
|
|
\begin{frame}
|
|
\frametitle{Term Rewriting Systems}
|
|
|
|
\begin{itemize}
|
|
\item to use rewriting efficiently, one needs to understand about term rewriting systems
|
|
\item this is a large topic
|
|
\item unluckily, it cannot be covered here in detail for time constraints
|
|
\item however, in practise you quickly get a feeling
|
|
\item important points in practise
|
|
\begin{itemize}
|
|
\item ensure termination of your rewrites
|
|
\item make sure they work nicely together
|
|
\end{itemize}
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
\begin{frame}
|
|
\frametitle{Term Rewriting Systems --- Termination}
|
|
|
|
\begin{block}{Theory}
|
|
\begin{itemize}
|
|
\item choose well-founded order $\prec$
|
|
\item for each rewrite theorem \hol{|- t1 = t2} ensure \hol{t2 $\prec$ t1}
|
|
\end{itemize}
|
|
\end{block}
|
|
|
|
\begin{block}{Practice}
|
|
\begin{itemize}
|
|
\item informally define for yourself what \emph{simpler} means
|
|
\item ensure each rewrite makes terms simpler
|
|
\item good heuristics
|
|
\begin{itemize}
|
|
\item subterms are simpler than whole term
|
|
\item use an order on functions
|
|
\end{itemize}
|
|
\end{itemize}
|
|
\end{block}
|
|
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}
|
|
\frametitle{Termination --- Subterm examples}
|
|
|
|
\begin{itemize}
|
|
\item a proper subterm is always simpler
|
|
\begin{itemize}
|
|
\item \hol{!l.\ APPEND [] l = l}
|
|
\item \hol{!n.\ n + 0 = n}
|
|
\item \hol{!l.\ REVERSE (REVERSE l) = l}
|
|
\item \hol{!t1 t2.\ if T then t1 else t2 <=> t1}
|
|
\item \hol{!n.\ n * 0 = 0}
|
|
\end{itemize}\medskip
|
|
\item the right hand side should not use extra vars, throwing parts away is usually simpler
|
|
\begin{itemize}
|
|
\item \hol{!x xs.\ (SNOC x xs = []) = F}
|
|
\item \hol{!x xs.\ LENGTH (x::xs) = SUC (LENGTH xs)}
|
|
\item \hol{!n x xs.\ DROP (SUC n) (x::xs) = DROP n xs}
|
|
\end{itemize}
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
\begin{frame}
|
|
\frametitle{Termination --- use simpler terms}
|
|
|
|
\begin{itemize}
|
|
\item it is useful to consider some functions simple and other complicated
|
|
\item replace complicated ones with simple ones
|
|
\item never do it in the opposite direction
|
|
\item clear examples
|
|
\begin{itemize}
|
|
\item \hol{|- !m n.\ MEM m (COUNT\_LIST n) <=> (m < n)}
|
|
\item \hol{|- !ls n.\ (DROP n ls = []) <=> (n >= LENGTH ls)}
|
|
\end{itemize}\medskip
|
|
\item unclear example
|
|
\begin{itemize}
|
|
\item \hol{|- !L.\ REVERSE L = REV L []}
|
|
\end{itemize}
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}
|
|
\frametitle{Termination --- Normalforms}
|
|
|
|
\begin{itemize}
|
|
\item some equations can be used in both directions
|
|
\item one should decide on one direction
|
|
\item this implicitly defines a \emph{normalform} one wants terms to be in
|
|
\item examples
|
|
\begin{itemize}
|
|
\item \hol{|- !f l.\ MAP f (REVERSE l) = REVERSE (MAP f l)}
|
|
\item \hol{|- !l1 l2 l3.\ l1 ++ (l2 ++ l3) = l1 ++ l2 ++ l3}
|
|
\end{itemize}
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
\begin{frame}
|
|
\frametitle{Termination --- Problematic rewrite rules}
|
|
|
|
\begin{itemize}
|
|
\item some equations immediately lead to non-termination, \eg
|
|
\begin{itemize}
|
|
\item \hol{|- !m n.\ m + n = n + m}
|
|
\item \hol{|- !m.\ m = m + 0}
|
|
\end{itemize}\medskip
|
|
\item slightly more subtle are rules like
|
|
\begin{itemize}
|
|
\item \hol{|- !n.\ fact n = if (n = 0) then 1 else n * fact(n-1)}
|
|
\end{itemize}\medskip
|
|
\item often combination of multiple rules leads to non-termination\\
|
|
this is especially problematic when adding to predefined sets of rewrites
|
|
\begin{itemize}
|
|
\item \hol{|- !m n p.\ m + (n + p) = (m + n) + p} and \\
|
|
\hol{|- !m n p.\ (m + n) + p = m + (n + p)}
|
|
\end{itemize}\medskip
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}
|
|
\frametitle{Rewrites working together}
|
|
|
|
\begin{itemize}
|
|
\item rewrite rules should not compete with each other
|
|
\item if a term \hol{ta} can be rewritten to \hol{ta1} and \hol{ta2} applying different rewrite rules, then \hol{ta1} and \hol{ta2} it should be possible to further rewrite them both to a common \hol{tb}
|
|
\item this can often be achieved by adding extra rewrite rules
|
|
\end{itemize}
|
|
|
|
\begin{exampleblock}{Example}
|
|
Assume we have the rewrite rules \hol{|- DOUBLE n = n + n} and\\
|
|
\hol{|- EVEN (DOUBLE n) = T}.\\
|
|
With these the term \hol{EVEN (DOUBLE 2)} can be rewritten to
|
|
\begin{itemize}
|
|
\item \hol{T} or
|
|
\item \hol{EVEN (2 + 2)}.
|
|
\end{itemize}
|
|
To avoid a hard to predict result, \hol{EVEN (2+2)} should be rewritten to \hol{T}. Adding an extra rewrite rule \hol{|- EVEN (n + n) = T} achieves this.
|
|
\end{exampleblock}
|
|
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}
|
|
\frametitle{Rewrites working together II}
|
|
\begin{itemize}
|
|
\item to design rewrite systems that work well, normalforms are vital
|
|
\item a term is in \emph{normalform}, if it cannot be rewritten any further
|
|
\item one should have a clear idea what the normalform of common terms looks like
|
|
\item all rules should work together to establish this normalform
|
|
\item the right-hand-side of each rule should be in normalform
|
|
\item the left-hand-side should not be simplifiable by any other rule
|
|
\item the order in which rules are applied should not influence the final result
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
\section{\texttt{computeLib}}
|
|
|
|
\begin{frame}
|
|
\frametitle{\hol{computeLib}}
|
|
|
|
\begin{itemize}
|
|
\item \hol{computeLib} is the library behind \hol{EVAL}
|
|
\item it is a rewriting library designed for evaluating ground terms (\ie terms without variables) efficiently
|
|
\item it uses a call-by-value strategy similar to SML's
|
|
\item it uses first order term matching
|
|
\item it performs $\beta$ reduction in addition to rewrites
|
|
\end{itemize}
|
|
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}
|
|
\frametitle{\hol{compset}}
|
|
|
|
\begin{itemize}
|
|
\item \hol{computeLib} uses \hol{compset}s to store its rewrites
|
|
\item a \hol{compset} stores
|
|
\begin{itemize}
|
|
\item rewrite rules
|
|
\item extra conversions
|
|
\end{itemize}
|
|
\item the extra conversions are guarded by a term pattern for efficiency
|
|
\item users can define their own compsets
|
|
\item however, \hol{computeLib} maintains one special compset called \hol{the\_compset}
|
|
\item \hol{the\_compset} is used by \hol{EVAL}
|
|
\end{itemize}
|
|
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}
|
|
\frametitle{\hol{EVAL}}
|
|
|
|
\begin{itemize}
|
|
\item \hol{EVAL} uses \hol{the\_compset}
|
|
\item tools like the \hol{Datatype} or \hol{TFL} libraries automatically extend \hol{the\_compset}
|
|
\item this way, \hol{EVAL} knows about (nearly) all types and functions
|
|
\item one can extended \hol{the\_compset} manually as well
|
|
\item rewrites exported by \hol{Define} are good for ground terms but may lead to non-termination for non-ground terms
|
|
\item \hol{zDefine} prevents \hol{TFL} from automatically extending \hol{the\_compset}
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
\section{\texttt{simpLib}}
|
|
|
|
\begin{frame}
|
|
\frametitle{\hol{simpLib}}
|
|
|
|
\begin{itemize}
|
|
\item \hol{simpLib} is a sophisticated rewrite engine
|
|
\item it is HOL's main workhorse
|
|
\item it provides
|
|
\begin{itemize}
|
|
\item higher order rewriting
|
|
\item usage of context information
|
|
\item conditional rewriting
|
|
\item arbitrary conversions
|
|
\item support for decision procedures
|
|
\item simple heuristics to avoid non-termination
|
|
\item fancier preprocessing of rewrite theorems
|
|
\item \ldots
|
|
\end{itemize}
|
|
\item it is very powerful, but compared to \hol{Rewrite} lib sometimes slow
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}
|
|
\frametitle{Basic Usage I}
|
|
|
|
\begin{itemize}
|
|
\item \hol{simpLib} uses \emph{simpsets}
|
|
\item simpsets are special datatypes storing
|
|
\begin{itemize}
|
|
\item rewrite rules
|
|
\item conversions
|
|
\item decision procedures
|
|
\item congruence rules
|
|
\item \ldots
|
|
\end{itemize}
|
|
\item in addition there are simpset-fragments
|
|
\item simpset-fragments contain similar information as simpsets
|
|
\item fragments can be added to and removed from simpsets
|
|
\item common usage: basic simpset combined with one or more simpset-fragments, \eg
|
|
\begin{itemize}
|
|
\item \hol{list\_ss ++ pairSimps.gen\_beta\_ss}
|
|
\item \hol{std\_ss ++ QI\_ss}
|
|
\item \ldots
|
|
\end{itemize}
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}
|
|
\frametitle{Basic Usage II}
|
|
|
|
\begin{itemize}
|
|
\item a call to the simplifier takes as arguments
|
|
\begin{itemize}
|
|
\item a simpset
|
|
\item a list of rewrite theorems
|
|
\end{itemize}
|
|
\item common high-level entry points are
|
|
\begin{itemize}
|
|
\item \hol{SIMP\_CONV ss thmL} --- conversion
|
|
\item \hol{SIMP\_RULE ss thmL} --- rule
|
|
\item \hol{SIMP\_TAC ss thmL} --- tactic without considering assumptions
|
|
\item \hol{ASM\_SIMP\_TAC ss thmL} --- tactic using assumptions to simplify goal
|
|
\item \hol{FULL\_SIMP\_TAC ss thmL} --- tactic simplifying assumptions with each other and goal with assumptions
|
|
\item \hol{REV\_FULL\_SIMP\_TAC ss thmL} --- similar to \texttt{FULL\_SIMP\_TAC} but with reversed order of assumptions
|
|
\end{itemize}
|
|
\item there are many derived tools not discussed here
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Basic Simplifier Examples}
|
|
|
|
\begin{semiverbatim}\scriptsize
|
|
> \hol{SIMP_CONV bool_ss [LENGTH] ``LENGTH [1;2]``}
|
|
val it = |- LENGTH [1; 2] = SUC (SUC 0)
|
|
|
|
> \hol{SIMP_CONV std_ss [LENGTH] ``LENGTH [1;2]``}
|
|
val it = |- LENGTH [1; 2] = 2
|
|
|
|
> \hol{SIMP_CONV list_ss [] ``LENGTH [1;2]``}
|
|
val it = |- LENGTH [1; 2] = 2
|
|
\end{semiverbatim}
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{\hol{FULL\_SIMP\_TAC} Example}
|
|
|
|
\begin{exampleblock}{Current GoalStack}
|
|
\begin{semiverbatim}\scriptsize
|
|
P (SUC (SUC x0)) (SUC (SUC y0))
|
|
------------------------------------
|
|
0. SUC y1 = y2
|
|
1. x1 = SUC x0
|
|
2. y1 = SUC y0
|
|
3. SUC x1 = x2
|
|
\end{semiverbatim}
|
|
\end{exampleblock}
|
|
|
|
\begin{exampleblock}{Action}
|
|
\begin{semiverbatim}\scriptsize
|
|
FULL_SIMP_TAC std_ss []
|
|
\end{semiverbatim}
|
|
\end{exampleblock}
|
|
|
|
\begin{exampleblock}{Resulting GoalStack}
|
|
\begin{semiverbatim}\scriptsize
|
|
P (SUC (SUC x0)) y2
|
|
------------------------------------
|
|
0. SUC (SUC y0) = y2
|
|
1. x1 = SUC x0
|
|
2. y1 = SUC y0
|
|
3. SUC x1 = x2
|
|
\end{semiverbatim}
|
|
\end{exampleblock}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{\hol{REV\_FULL\_SIMP\_TAC} Example}
|
|
|
|
\begin{exampleblock}{Current GoalStack}
|
|
\begin{semiverbatim}\scriptsize
|
|
P (SUC (SUC x0)) y2
|
|
------------------------------------
|
|
0. SUC (SUC y0) = y2
|
|
1. x1 = SUC x0
|
|
2. y1 = SUC y0
|
|
3. SUC x1 = x2
|
|
\end{semiverbatim}
|
|
\end{exampleblock}
|
|
|
|
\begin{exampleblock}{Action}
|
|
\begin{semiverbatim}\scriptsize
|
|
REV_FULL_SIMP_TAC std_ss []
|
|
\end{semiverbatim}
|
|
\end{exampleblock}
|
|
|
|
\begin{exampleblock}{Resulting GoalStack}
|
|
\begin{semiverbatim}\scriptsize
|
|
P x2 y2
|
|
------------------------------------
|
|
0. SUC (SUC y0) = y2
|
|
1. x1 = SUC x0
|
|
2. y1 = SUC y0
|
|
3. SUC (SUC x0) = x2
|
|
\end{semiverbatim}
|
|
\end{exampleblock}
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Common simpsets}
|
|
|
|
\begin{itemize}
|
|
\item \hol{pure\_ss} --- empty simpset
|
|
\item \hol{bool\_ss} --- basic simpset
|
|
\item \hol{std\_ss} --- standard simpset
|
|
\item \hol{arith\_ss} --- arithmetic simpset
|
|
\item \hol{list\_ss} --- list simpset
|
|
\item \hol{real\_ss} --- real simpset
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Common simpset-fragments}
|
|
|
|
\begin{itemize}
|
|
\item many theories and libraries provide their own simpset-fragments
|
|
\item \hol{PRED\_SET\_ss} --- simplify sets
|
|
\item \hol{STRING\_ss} --- simplify strings
|
|
\item \hol{QI\_ss} --- extra quantifier instantiations
|
|
\item \hol{gen\_beta\_ss} --- $\beta$ reduction for pairs
|
|
\item \hol{ETA\_ss} --- $\eta$ conversion
|
|
\item \hol{EQUIV\_EXTRACT\_ss} --- extract common part of equivalence
|
|
\item \hol{CONJ\_ss} --- use conjunctions for context
|
|
\item \hol{LIFT\_COND\_ss} --- lifting if-then-else
|
|
\item \ldots
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}
|
|
\frametitle{Build-In Conversions and Decision Procedures}
|
|
|
|
\begin{itemize}
|
|
\item in contrast to \hol{Rewrite} lib the simplifier can
|
|
run arbitrary conversions
|
|
\item most common and useful conversion is probably $\beta$-reduction
|
|
\item \hol{std\_ss} has support for basic arithmetic and numerals
|
|
\item it also has simple, syntactic conversions for instantiating quantifiers
|
|
\begin{itemize}
|
|
\item \hol{!x. ... \holAnd{} (x = c) \holAnd{} ... ==> ...}
|
|
\item \hol{!x. ... \holOr{} \holNeg(x = c) \holOr{} ...}
|
|
\item \hol{?x. ... \holAnd{} (x = c) \holAnd{} ...}
|
|
\end{itemize}
|
|
|
|
\item besides very useful conversions, there are decision procedures as well
|
|
\item the most frequently used one is probably the arithmetic decision procedure you already know from \hol{DECIDE}
|
|
|
|
\end{itemize}
|
|
|
|
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Examples I}
|
|
\begin{semiverbatim}\scriptsize
|
|
> \hol{SIMP_CONV std_ss [] ``(\textbsl{}x. x + 2) 5``}
|
|
val it = |- (\textbsl{}x. x + 2) 5 = 7
|
|
|
|
> \hol{SIMP_CONV std_ss [] ``!x. Q x \holAnd{} (x = 7) ==> P x``}
|
|
val it = |- (!x. Q x \holAnd{} (x = 7) ==> P x) <=> (Q 7 ==> P 7)``
|
|
|
|
> \hol{SIMP_CONV std_ss [] ``?x. Q x \holAnd{} (x = 7) \holAnd{} P x``}
|
|
val it = |- (?x. Q x \holAnd{} (x = 7) \holAnd{} P x) <=> (Q 7 \holAnd{} P 7)``
|
|
|
|
> \hol{SIMP_CONV std_ss [] ``x > 7 ==> x > 5``}
|
|
Exception- UNCHANGED raised
|
|
|
|
> \hol{SIMP_CONV arith_ss [] ``x > 7 ==> x > 5``}
|
|
val it = |- (x > 7 ==> x > 5) <=> T
|
|
\end{semiverbatim}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Higher Order Rewriting}
|
|
|
|
\begin{itemize}
|
|
\item the simplifier supports higher order rewriting
|
|
\item this is often very handy
|
|
\item for example it allows moving quantifiers around easily
|
|
\end{itemize}
|
|
|
|
\begin{exampleblock}{Examples}
|
|
\begin{semiverbatim}\scriptsize
|
|
> \hol{SIMP_CONV std_ss [FORALL_AND_THM] ``!x. P x \holAnd{} Q \holAnd{} R x``}
|
|
val it = |- (!x. P x \holAnd{} Q \holAnd{} R x) <=>
|
|
(!x. P x) \holAnd{} Q \holAnd{} (!x. R x)
|
|
|
|
> \hol{SIMP_CONV std_ss [GSYM RIGHT_EXISTS_AND_THM, GSYM LEFT_FORALL_IMP_THM]
|
|
``!y. (P y \holAnd{} (?x. y = SUC x)) ==> Q y``}
|
|
val it = |- (!y. P y \holAnd{} (?x. y = SUC x) ==> Q y) <=>
|
|
!x. P (SUC x) ==> Q (SUC x)
|
|
\end{semiverbatim}
|
|
\end{exampleblock}
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Context}
|
|
|
|
\begin{itemize}
|
|
\item a great feature of the simplifier is that it can use context information
|
|
\item by default simple context information is used like
|
|
\begin{itemize}
|
|
\item the precondition of an implication
|
|
\item the condition of \hol{if-then-else}
|
|
\end{itemize}
|
|
\item one can configure which context to use via congruence rules
|
|
\begin{itemize}
|
|
\item \eg by using \hol{CONJ\_ss} one can easily use context of conjunctions
|
|
\item warning: using \hol{CONJ\_ss} can be slow
|
|
\end{itemize}
|
|
\item using context often simplifies proofs drastically
|
|
\begin{itemize}
|
|
\item using \hol{Rewrite} lib, often a goal needs to be split and a precondition moved to the assumptions
|
|
\item then \hol{ASM\_REWRITE\_TAC} can be used
|
|
\item with \hol{SIMP\_TAC} there is no need to split the goal
|
|
\end{itemize}
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Context Examples}
|
|
|
|
\begin{semiverbatim}\scriptsize
|
|
> \hol{SIMP_CONV std_ss [] ``((l = []) ==> P l) \holAnd{} Q l``}
|
|
val it = |- ((l = []) ==> P l) \holAnd{} Q l <=>
|
|
((l = []) ==> P []) \holAnd{} Q l
|
|
|
|
> \hol{SIMP_CONV arith_ss [] ``if (c \holAnd{} x < 5) then (P c \holAnd{} x < 6) else Q c``}
|
|
val it = |- (if c \holAnd{} x < 5 then P c \holAnd{} x < 6 else Q c) <=>
|
|
if c \holAnd{} x < 5 then P T else Q c:
|
|
|
|
> \hol{SIMP_CONV std_ss [] ``P x \holAnd{} (Q x \holAnd{} P x ==> Z x)``}
|
|
Exception- UNCHANGED raised
|
|
|
|
> \hol{SIMP_CONV (std_ss++boolSimps.CONJ_ss) [] ``P x \holAnd{} (Q x \holAnd{} P x ==> Z x)``}
|
|
val it = |- P x \holAnd{} (Q x \holAnd{} P x ==> Z x) <=> P x \holAnd{} (Q x ==> Z x)\end{semiverbatim}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Conditional Rewriting I}
|
|
|
|
\begin{itemize}
|
|
\item perhaps the most powerful feature of the simplifier is that it supports conditional rewriting
|
|
\item this means it allows \emph{conditional} rewrite theorems of the form\\
|
|
\hol{|- cond ==> (t1 = t2)}
|
|
\item if the simplifier finds a term \hol{t1'} it can rewrite via \hol{t1 = t2} to \hol{t2'}, it tries to discharge the assumption \hol{cond'}
|
|
\item for this, it calls itself recursively on \hol{cond'}
|
|
\begin{itemize}
|
|
\item all the decision procedures and all context information is used
|
|
\item conditional rewriting can be used
|
|
\item to prevent divergence, there is a limit on recursion depth
|
|
\end{itemize}
|
|
\item if \hol{cond' = T} can be shown, \hol{t1'} is rewritten to \hol{t2'}
|
|
\item otherwise \hol{t1'} is not modified
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Conditional Rewriting Example}
|
|
|
|
\begin{itemize}
|
|
\item consider the conditional rewrite theorem \\\hol{!l n.\ LENGTH l <= n ==> (DROP n l = [])}
|
|
\item let's assume we want to prove \\\hol{(DROP 7 [1;2;3;4]) ++ [5;6;7] = [5;6;7]}
|
|
\item we can without conditional rewriting
|
|
\begin{itemize}
|
|
\item show \hol{|- LENGTH [1;2;3;4] <= 7}
|
|
\item use this to discharge the precondition of the rewrite theorem
|
|
\item use the resulting theorem to rewrite the goal
|
|
\end{itemize}
|
|
\item with conditional rewriting, this is all automated
|
|
\begin{semiverbatim}
|
|
> \hol{SIMP_CONV list_ss [DROP_LENGTH_TOO_LONG]
|
|
``(DROP 7 [1;2;3;4]) ++ [5;6;7]``}
|
|
val it = |- DROP 7 [1; 2; 3; 4] ++ [5; 6; 7] = [5; 6; 7]
|
|
\end{semiverbatim}
|
|
\item conditional rewriting often shortens proofs considerably
|
|
\end{itemize}
|
|
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Conditional Rewriting Example II}
|
|
|
|
\begin{block}{Proof with Rewrite}
|
|
\begin{semiverbatim}\scriptsize
|
|
prove (``(DROP 7 [1;2;3;4]) ++ [5;6;7] = [5;6;7]``,
|
|
`DROP 7 [1;2;3;4] = []` by (
|
|
MATCH_MP_TAC DROP_LENGTH_TOO_LONG >>
|
|
REWRITE_TAC[LENGTH] >>
|
|
DECIDE_TAC
|
|
) >>
|
|
ASM_REWRITE_TAC[APPEND])
|
|
\end{semiverbatim}
|
|
\end{block}
|
|
|
|
\begin{block}{Proof with Simplifier}
|
|
\begin{semiverbatim}\scriptsize
|
|
prove (``(DROP 7 [1;2;3;4]) ++ [5;6;7] = [5;6;7]``,
|
|
SIMP_TAC list_ss [])
|
|
\end{semiverbatim}
|
|
Notice that \hol{DROP\_LENGTH\_TOO\_LONG} is part of \hol{list\_ss}.
|
|
\end{block}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Conditional Rewriting II}
|
|
|
|
\begin{itemize}
|
|
\item conditional rewriting is a very powerful technique
|
|
\item decision procedures and sophisticated rewrites can be used to discharge preconditions without cluttering proof state
|
|
\item it provides a powerful search for theorems that apply
|
|
\item however, if used naively, it can be slow
|
|
\item moreover, to work well, rewrite theorems need to of a special form
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Conditional Rewriting Pitfalls I}
|
|
|
|
\begin{itemize}
|
|
\item if the pattern is too general, the simplifier becomes very slow
|
|
\item consider the following, trivial but hopefully educational example
|
|
\begin{minipage}{.85\textwidth}
|
|
\begin{exampleblock}{Looping example}
|
|
\begin{semiverbatim}\scriptsize
|
|
> \hol{val my_thm = prove (``~P ==> (P = F)``, PROVE_TAC[])}
|
|
> \hol{time (SIMP_CONV std_ss [my_thm]) ``P1 \holAnd{} P2 \holAnd{} P3 \holAnd{} ... \holAnd{} P10``}
|
|
runtime: 0.84000s, gctime: 0.02400s, systime: 0.02400s.
|
|
Exception- UNCHANGED raised
|
|
|
|
> \hol{time (SIMP_CONV std_ss []) ``P1 \holAnd{} P2 \holAnd{} P3 \holAnd{} ... \holAnd{} P10``}
|
|
runtime: 0.00000s, gctime: 0.00000s, systime: 0.00000s.
|
|
Exception- UNCHANGED raised
|
|
\end{semiverbatim}
|
|
\end{exampleblock}
|
|
\end{minipage}
|
|
\begin{itemize}
|
|
\item notice that the rewrite is applied at plenty of places (quadratic in number of conjuncts)
|
|
\item notice that each backchaining triggers many more backchainings
|
|
\item each has to be aborted to prevent diverging
|
|
\item as a result, the simplifier becomes very slow
|
|
\item incidentally, the conditional rewrite is useless
|
|
\end{itemize}
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Conditional Rewriting Pitfalls II}
|
|
|
|
\begin{itemize}
|
|
\item good conditional rewrites \hol{|- c ==> (l = r)} should mention only variables in \hol{c} that appear in \hol{l}
|
|
\item if \hol{c} contains extra variables \hol{x1 ... xn}, the conditional rewrite engine has to search instantiations for them
|
|
\item this mean that conditional rewriting is trying discharge the precondition \hol{?x1 ... xn.\ c}
|
|
\item the simplifier is usually not able to find such instances
|
|
|
|
\begin{exampleblock}{Transitivity}
|
|
\begin{semiverbatim}\scriptsize
|
|
> \hol{val P_def = Define `P x y = x < y`;}
|
|
> \hol{val my_thm = prove (``!x y z. P x y ==> P y z ==> P x z``, ...)}
|
|
> \hol{SIMP_CONV arith_ss [my_thm] ``P 2 3 \holAnd{} P 3 4 ==> P 2 4``}
|
|
Exception- UNCHANGED raised
|
|
|
|
(* However transitivity of < build in via decision procedure *)
|
|
> \hol{SIMP_CONV arith_ss [P_def] ``P 2 3 \holAnd{} P 3 4 ==> P 2 4``}
|
|
val it = |- P 2 3 \holAnd{} P 3 4 ==> P 2 4 <=> T:
|
|
\end{semiverbatim}
|
|
\end{exampleblock}
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Conditional Rewriting Pitfalls III}
|
|
|
|
\begin{itemize}
|
|
\item let's look in detail why \hol{SIMP\_CONV} did not make progress above
|
|
\end{itemize}
|
|
|
|
\begin{semiverbatim}\scriptsize
|
|
> \hol{set_trace "simplifier" 2;}
|
|
> \hol{SIMP_CONV arith_ss [my_thm] ``P 2 3 \holAnd{} P 3 4 ==> P 2 4``}
|
|
[468000]: more context: |- !x y z. P x y ==> P y z ==> P x z
|
|
[468000]: New rewrite: |- (?y. P x y \holAnd{} P y z) ==> (P x z <=> T)
|
|
...
|
|
[584000]: more context: [.] |- P 2 3 \holAnd{} P 3 4
|
|
[584000]: New rewrite: [.] |- P 2 3 <=> T
|
|
[584000]: New rewrite: [.] |- P 3 4 <=> T
|
|
[588000]: rewriting P 2 4 with |- (?y. P x y \holAnd{} P y z) ==> (P x z <=> T)
|
|
[588000]: trying to solve: ?y. P 2 y \holAnd{} P y 4
|
|
[588000]: rewriting P 2 y with |- (?y. P x y \holAnd{} P y z) ==> (P x z <=> T)
|
|
[592000]: trying to solve: ?y'. P 2 y' \holAnd{} P y' y
|
|
...
|
|
[596000]: looping - cut
|
|
...
|
|
[608000]: looping - stack limit reached
|
|
...
|
|
[640000]: couldn't solve: ?y. P 2 y \holAnd{} P y 4
|
|
Exception- UNCHANGED raised
|
|
\end{semiverbatim}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}
|
|
\frametitle{Conditional vs.\ Unconditional Rewrite Rules}
|
|
|
|
\begin{itemize}
|
|
\item conditional rewrite rules are often much more powerful
|
|
\item however, \ml{Rewrite} lib does not support them
|
|
\item for this reason there are often two versions of rewrite theorems
|
|
\end{itemize}
|
|
|
|
\begin{exampleblock}{\hol{drop} example}
|
|
\begin{itemize}
|
|
\item \hol{DROP\_LENGTH\_NIL} is a useful rewrite rule:\\
|
|
\hol{|- !l.\ DROP (LENGTH l) l = []}
|
|
\item in proofs, one needs to be careful though to preserve exactly this form
|
|
\begin{itemize}
|
|
\item one should not (partly) evaluate \hol{LENGTH l} or modify \hol{l} somehow
|
|
\end{itemize}
|
|
\item with the conditional rewrite rule \hol{DROP\_LENGTH\_TOO\_LONG} one does not need to be as careful \\\hol{|- !l n.\ LENGTH l <= n ==> (DROP n l = [])}
|
|
\begin{itemize}
|
|
\item the simplifier can use simplify the precondition using information about \hol{LENGTH} and even arithmetic decision procedures
|
|
\end{itemize}
|
|
\end{itemize}
|
|
\end{exampleblock}
|
|
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}
|
|
\frametitle{Special Rewrite Forms}
|
|
|
|
\begin{itemize}
|
|
\item some theorems given in the list of rewrites to the simplifier are used for special purposes
|
|
\item there are marking functions that mark these theorems
|
|
\begin{itemize}
|
|
\item \hol{Once :\ thm -> thm} use given theorem at most once
|
|
\item \hol{Ntimes :\ thm -> int -> thm} use given theorem at most the given number of times
|
|
\item \hol{AC :\ thm -> thm -> thm} use given associativity and commutativity theorems for AC rewriting
|
|
\item \hol{Cong :\ thm -> thm} use given theorem as a congruence rule
|
|
\end{itemize}
|
|
\item these special forms are easy ways to add this information to a simpset
|
|
\item it can be directly set in a simpset as well
|
|
\end{itemize}
|
|
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Example \hol{Once}}
|
|
|
|
\begin{semiverbatim}\scriptsize
|
|
> \hol{SIMP_CONV pure_ss [Once ADD_COMM] ``a + b = c + d``}
|
|
val it = |- (a + b = c + d) <=> (b + a = c + d)
|
|
|
|
> \hol{SIMP_CONV pure_ss [Ntimes ADD_COMM 2] ``a + b = c + d``}
|
|
val it = |- (a + b = c + d) <=> (a + b = c + d)
|
|
|
|
> \hol{SIMP_CONV pure_ss [ADD_COMM] ``a + b = c + d``}
|
|
Exception- UNCHANGED raised
|
|
|
|
> \hol{ONCE_REWRITE_CONV [ADD_COMM] ``a + b = c + d``}
|
|
val it = |- (a + b = c + d) <=> (b + a = d + c)
|
|
|
|
> \hol{REWRITE_CONV [ADD_COMM] ``a + b = c + d``}
|
|
... diverges ...
|
|
\end{semiverbatim}
|
|
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Stateful Simpset}
|
|
|
|
\begin{itemize}
|
|
\item the simpset \hol{srw\_ss()} is maintained by the system
|
|
\begin{itemize}
|
|
\item it is automatically extended by new type-definitions
|
|
\item theories can extend it via \hol{export\_rewrites}
|
|
\item libs can augment it via \hol{augment\_srw\_ss}
|
|
\end{itemize}
|
|
\item the stateful simpset contains many rewrites
|
|
\item it is very powerful and easy to use
|
|
\end{itemize}
|
|
|
|
\begin{exampleblock}{Example}
|
|
\begin{semiverbatim}\scriptsize
|
|
> \hol{SIMP_CONV (srw_ss()) [] ``case [] of [] => (2 + 4)``}
|
|
val it = |- (case [] of [] => 2 + 4 | v::v1 => ARB) = 6
|
|
\end{semiverbatim}
|
|
\end{exampleblock}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}
|
|
\frametitle{Discussion on Stateful Simpset}
|
|
|
|
\begin{itemize}
|
|
\item the stateful simpset is very powerful and easy to use
|
|
\item however, results are hard to predict
|
|
\item proofs using it unwisely are hard to maintain
|
|
\item the stateful simpset can expand too much
|
|
\begin{itemize}
|
|
\item bigger, harder to read proof states
|
|
\item high level arguments become hard to see
|
|
\end{itemize}
|
|
\item whether to use the stateful simpset depends on personal proof style
|
|
\item I advise to not use \hol{srw\_ss} at the beginning
|
|
\item once you got a good intuition on how the simplifier works, make your own choice
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Adding Own Conversions}
|
|
|
|
\begin{itemize}
|
|
\item it is complicated to add arbitrary decision procedures to a simpset
|
|
\item however, adding simple conversions is straightforward
|
|
\item a conversion is described by a \hol{stdconvdata} record
|
|
\begin{semiverbatim}\scriptsize
|
|
type stdconvdata = \{
|
|
name: string, (* name for debugging *)
|
|
pats: term list, (* list of patterns, when to try conv *)
|
|
conv: conv (* the conversion *)
|
|
\}
|
|
\end{semiverbatim}
|
|
\item use \hol{std\_conv\_ss} to create simpset-fragement
|
|
\end{itemize}
|
|
|
|
\begin{exampleblock}{Example}
|
|
\begin{semiverbatim}\scriptsize
|
|
val WORD_ADD_ss =
|
|
simpLib.std_conv_ss
|
|
\{conv = CHANGED_CONV WORD_ADD_CANON_CONV,
|
|
name = "WORD_ADD_CANON_CONV",
|
|
pats = [``words\$word_add (w:'a word) y``]\}
|
|
\end{semiverbatim}
|
|
\end{exampleblock}
|
|
\end{frame}
|
|
|
|
|
|
\begin{frame}
|
|
\frametitle{Summary Simplifier}
|
|
|
|
\begin{itemize}
|
|
\item the simplifier is HOL's main workhorse for automation
|
|
\item it is very powerful
|
|
\item conditional rewriting very powerful
|
|
\begin{itemize}
|
|
\item here only simple examples were presented
|
|
\item experiment with it to get a feeling
|
|
\end{itemize}
|
|
\item many advanced features not discussed here at all
|
|
\begin{itemize}
|
|
\item using congruence rules
|
|
\item writing own decision procedures
|
|
\item rewriting with respect to arbitrary congruence relations
|
|
\end{itemize}
|
|
\end{itemize}
|
|
|
|
|
|
\begin{alertblock}{Warning}
|
|
The simplifier is very powerful. Make sure you understand it and are in control when using it.
|
|
Otherwise your proofs easily become lengthy, convoluted and hard to maintain.
|
|
\end{alertblock}
|
|
|
|
|
|
\end{frame}
|
|
|
|
%%% Local Variables:
|
|
%%% mode: latex
|
|
%%% TeX-master: "current"
|
|
%%% End:
|