988 lines
31 KiB
TeX
988 lines
31 KiB
TeX
|
\part{Basic Definitions}
|
||
|
|
||
|
\frame[plain]{\partpage}
|
||
|
|
||
|
\section{Definitions, Axioms and Oracles}
|
||
|
|
||
|
\begin{frame}
|
||
|
\frametitle{Definitional Extensions}
|
||
|
\begin{itemize}
|
||
|
\item there are \emph{conservative definition principles} for types and constants
|
||
|
\item conservative means that all theorems that can be proved in extended theory can also be proved in original one
|
||
|
\item however, such extensions make the theory more comfortable
|
||
|
\item definitions introduce \alert{no new inconsistencies}
|
||
|
\item the HOL community has a very strong tradition of a purely definitional approach
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
\begin{frame}
|
||
|
\frametitle{Axiomatic Extensions}
|
||
|
\begin{itemize}
|
||
|
\item \alert{axioms} are a different approach
|
||
|
\item they allow postulating arbitrary properties, \ie extending the logic with arbitrary theorems
|
||
|
\item this approach might introduce new inconsistencies
|
||
|
\item in HOL axioms are very rarely needed
|
||
|
\item using definitions is often considered more elegant
|
||
|
\item it is hard to keep track of axioms
|
||
|
\item use axioms only if you really know what you are doing
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
\begin{frame}
|
||
|
\frametitle{Oracles}
|
||
|
\begin{itemize}
|
||
|
\item \alert{oracles} are families of axioms
|
||
|
\item however, they are used differently than axioms
|
||
|
\item they are used to enable usage of external tools and knowledge
|
||
|
\item you might want to use an external automated prover
|
||
|
\item this external tool acts as an oracle
|
||
|
\begin{itemize}
|
||
|
\item it provides answers
|
||
|
\item it does not explain or justify these answers
|
||
|
\end{itemize}
|
||
|
\item you don't know, whether this external tool might be buggy
|
||
|
\item all theorems proved via it are tagged with a special oracle-tag
|
||
|
\item tags are propagated
|
||
|
\item this allows keeping track of everything depending on the correctness of this tool
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
\begin{frame}
|
||
|
\frametitle{Oracles II}
|
||
|
\begin{itemize}
|
||
|
\item Common oracle-tags
|
||
|
\begin{itemize}
|
||
|
\item \ml{DISK\_THM} --- theorem was written to disk and read again
|
||
|
\item \ml{HolSatLib} --- proved by MiniSat
|
||
|
\item \ml{HolSmtLib} --- proved by external SMT solver
|
||
|
\item \ml{fast\_proof} --- proof was skipped to compile a theory rapidly
|
||
|
\item \ml{cheat} --- we cheated :-)
|
||
|
\end{itemize}
|
||
|
\item \alert{cheating} via \eg the \hol{cheat} tactic means skipping proofs
|
||
|
\item it can be helpful during proof development
|
||
|
\begin{itemize}
|
||
|
\item test whether some lemmata allow you finishing the proof
|
||
|
\item skip lengthy but boring cases and focus on critical parts first
|
||
|
\item experiment with exact form of invariants
|
||
|
\item \ldots
|
||
|
\end{itemize}
|
||
|
\item cheats should be removed reasonable quickly
|
||
|
\item HOL warns about cheats and skipped proofs
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}
|
||
|
\frametitle{Pitfalls of Definitional Approach}
|
||
|
\begin{itemize}
|
||
|
\item definitions can't introduce new inconsistencies
|
||
|
\item they force you to state all assumed properties at one location
|
||
|
\item however, you still need to be careful
|
||
|
\item Is your definition really expressing what you had in mind ?
|
||
|
\item Does your formalisation correspond to the real world artefact ?
|
||
|
\item How can you convince others that this is the case ?
|
||
|
\item we will discuss methods to deal with this later in this course
|
||
|
\begin{itemize}
|
||
|
\item formal sanity
|
||
|
\item conformance testing
|
||
|
\item code review
|
||
|
\item comments, good names, clear coding style
|
||
|
\item \ldots
|
||
|
\end{itemize}
|
||
|
\item this is highly complex and needs a lot of effort in general
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
|
||
|
\section{Primitive Definition Principles}
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Specifications}
|
||
|
\begin{itemize}
|
||
|
\item HOL allows to introduce new constants with certain properties, provided the
|
||
|
existence of such constants has been shown
|
||
|
\begin{exampleblock}{Specification of \texttt{EVEN} and \texttt{ODD}}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
> EVEN\_ODD\_EXISTS
|
||
|
val it = |- ?even odd. even 0 \holAnd{} ~odd 0 \holAnd{} (!n. even (SUC n) <=> odd n) \holAnd{}
|
||
|
(!n. odd (SUC n) <=> even n)
|
||
|
|
||
|
> val EO\_SPEC = new\_specification ("EO\_SPEC", ["EVEN", "ODD"], EVEN\_ODD\_EXISTS);
|
||
|
val EO\_SPEC = |- EVEN 0 \holAnd{} ~ODD 0 \holAnd{} (!n. EVEN (SUC n) <=> ODD n) \holAnd{}
|
||
|
(!n. ODD (SUC n) <=> EVEN n)
|
||
|
\end{semiverbatim}
|
||
|
\end{exampleblock}
|
||
|
\item \hol{new\_specification} is a convenience wrapper
|
||
|
\begin{itemize}
|
||
|
\item it uses existential quantification instead of Hilbert's choice
|
||
|
\item deals with pair syntax
|
||
|
\item stores resulting definitions in theory
|
||
|
\end{itemize}
|
||
|
\item \hol{new\_specification} captures the underlying principle nicely
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Definitions}
|
||
|
\begin{itemize}
|
||
|
\item special case: new constant defined by equality
|
||
|
\begin{exampleblock}{Specification with Equality}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
> double_EXISTS
|
||
|
val it =
|
||
|
|- ?double. (!n. double n = (n + n))
|
||
|
|
||
|
> val double_def = new_specification ("double_def", ["double"], double_EXISTS);
|
||
|
val double_def =
|
||
|
|- !n. double n = n + n
|
||
|
\end{semiverbatim}
|
||
|
\end{exampleblock}
|
||
|
\item there is a specialised methods for such simple definitions
|
||
|
\begin{exampleblock}{Non Recursive Definitions}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
> val DOUBLE_DEF = new_definition ("DOUBLE_DEF", ``DOUBLE n = n + n``)
|
||
|
val DOUBLE_DEF =
|
||
|
|- !n. DOUBLE n = n + n
|
||
|
\end{semiverbatim}
|
||
|
\end{exampleblock}
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Restrictions for Definitions}
|
||
|
\begin{itemize}
|
||
|
\item all variables occurring on right-hand-side (rhs) need to be arguments
|
||
|
\begin{itemize}
|
||
|
\item \eg \hol{new\_definition (..., ``F n = n + m``)} fails
|
||
|
\item \hol{m} is free on rhs
|
||
|
\end{itemize}
|
||
|
\item all type variables occurring on rhs need to occur on lhs
|
||
|
\begin{itemize}
|
||
|
\item \eg \hol{new\_definition ("IS\_FIN\_TY", \\
|
||
|
\-\qquad\quad``IS\_FIN\_TY = FINITE (UNIV : 'a set)``)} fails
|
||
|
\item \hol{IS\_FIN\_TY} would lead to inconsistency
|
||
|
\item \hol{|- FINITE (UNIV : bool set)}
|
||
|
\item \hol{|- \holNeg{}FINITE (UNIV : num set)}
|
||
|
\item \hol {T <=> FINITE (UNIV:bool set) <=> \\ IS\_FIN\_TY <=>\\ FINITE (UNIV:num set) <=> F}
|
||
|
\item therefore, such definitions can't be allowed
|
||
|
\end{itemize}
|
||
|
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Underspecified Functions}
|
||
|
\begin{itemize}
|
||
|
\item function specification do not need to define the function precisely
|
||
|
\item multiple different functions satisfying one spec are possible
|
||
|
\item functions resulting from such specs are called \emph{underspecified}
|
||
|
\item underspecified functions are still total, one just lacks knowledge
|
||
|
\item one common application: modelling \emph{partial functions}
|
||
|
\begin{itemize}
|
||
|
\item functions like \eg \hol{HD} and \hol{TL} are total
|
||
|
\item they are defined for empty lists
|
||
|
\item however, it is not specified, which value they have for empty lists
|
||
|
\item only known: \hol{HD [] = HD []} and \hol{TL [] = TL []}
|
||
|
\begin{minipage}{.7\textwidth}\medskip
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
val MY_HD_EXISTS = prove (``?hd. !x xs. (hd (x::xs) = x)``, ...);
|
||
|
val MY_HD_SPEC =
|
||
|
new_specification ("MY_HD_SPEC", ["MY_HD"], MY_HD_EXISTS)
|
||
|
\end{semiverbatim}
|
||
|
\end{minipage}
|
||
|
\end{itemize}
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
|
||
|
\begin{frame}
|
||
|
\frametitle{Primitive Type Definitions}
|
||
|
\begin{itemize}
|
||
|
\item HOL allows introducing non-empty subtypes of existing types
|
||
|
\item a predicate \hol{P : ty -> bool} describes a subset of an existing type \hol{ty}
|
||
|
\item \hol{ty} may contain type variables
|
||
|
\item only \emph{non-empty} types are allowed
|
||
|
\item therefore a non-emptyness proof \hol{ex-thm} of form \hol{?e.\ P e} is needed
|
||
|
\item \hol{new\_type\_definition (op-name, ex-thm)} then introduces a new type \hol{op-name}
|
||
|
specified by \hol{P}
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Primitive Type Definitions - Example 1}
|
||
|
\begin{itemize}
|
||
|
\item lets try to define a type \hol{dlist} of lists containing no duplicates
|
||
|
\item predicate \hol{ALL\_DISTINCT : 'a list -> bool} is used to define it
|
||
|
\item easy to prove theorem \texttt{dlist\_exists}: \hol{|- ?l.\ ALL\_DISTINCT l}
|
||
|
\item \hol{val dlist\_TY\_DEF = new\_type\_definitions("dlist", dlist\_exists)} defines
|
||
|
a new type \ml{'a dlist} and returns a theorem\bigskip
|
||
|
\begin{semiverbatim}
|
||
|
|- ?(rep :'a dlist -> 'a list).
|
||
|
TYPE_DEFINITION ALL_DISTINCT rep
|
||
|
\end{semiverbatim}\bigskip
|
||
|
\item \ml{rep} is a function taking a \hol{'a dlist} to the list representing it
|
||
|
\begin{itemize}
|
||
|
\item \hol{rep} is injective
|
||
|
\item a list satisfies \hol{ALL\_DISTINCT} iff there is a corresponding \hol{dlist}
|
||
|
\end{itemize}
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Primitive Type Definitions - Example 2}
|
||
|
\begin{itemize}
|
||
|
\item \hol{define\_new\_type\_bijections} can be used to define bijections between old and new type
|
||
|
\medskip
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
> \hol{define_new_type_bijections \{name="dlist_tybij", ABS="abs_dlist",
|
||
|
REP="rep_dlist", tyax=\alert{dlist_TY_DEF}\}}
|
||
|
|
||
|
val it =
|
||
|
|- (!a. abs_dlist (rep_dlist a) = a) \holAnd{}
|
||
|
(!r. ALL_DISTINCT r <=> (rep_dlist (abs_dlist r) = r))
|
||
|
\end{semiverbatim}\medskip
|
||
|
\item other useful theorems can be automatically proved by
|
||
|
\begin{itemize}
|
||
|
\item \hol{prove\_abs\_fn\_one\_one}
|
||
|
\item \hol{prove\_abs\_fn\_onto}
|
||
|
\item \hol{prove\_rep\_fn\_one\_one}
|
||
|
\item \hol{prove\_rep\_fn\_onto}
|
||
|
\end{itemize}
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}
|
||
|
\frametitle{Primitive Definition Principles Summary}
|
||
|
\begin{itemize}
|
||
|
\item primitive definition principles are easily explained
|
||
|
\item they lead to conservative extensions
|
||
|
\item however, they are cumbersome to use
|
||
|
\item LCF approach allows implementing more convenient definition tools
|
||
|
\begin{itemize}
|
||
|
\item \alert{\texttt{Datatype}} package
|
||
|
\item \alert{\texttt{TFL}} (Total Functional Language) package
|
||
|
\item \ml{IndDef} (Inductive Definition) package
|
||
|
\item \ml{quotientLib} Quotient Types Library
|
||
|
\item ...
|
||
|
\end{itemize}
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
|
||
|
\section{Functional Programming}
|
||
|
|
||
|
\begin{frame}
|
||
|
\frametitle{Functional Programming}
|
||
|
\begin{itemize}
|
||
|
\item the \hol{Datatype} package allows to define datatypes conveniently
|
||
|
\item the \hol{TFL} package allows to define (mutually recursive) functions
|
||
|
\item the \hol{EVAL} conversion allows evaluating those definitions
|
||
|
\item this gives many HOL developments the feeling of a functional program
|
||
|
\item there is really a close connection between functional programming and definitions in HOL
|
||
|
\begin{itemize}
|
||
|
\item functional programming design principles apply
|
||
|
\item \hol{EVAL} is a great way to test quickly, whether your definitions are working as intended
|
||
|
\end{itemize}
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Functional Programming Example}
|
||
|
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
> \hol{Datatype `mylist = E | L 'a mylist`}
|
||
|
val it = (): unit
|
||
|
|
||
|
> \hol{Define `(mylen E = 0) \holAnd{} (mylen (L x xs) = SUC (mylen xs))`}
|
||
|
Definition has been stored under "mylen\_def"
|
||
|
val it =
|
||
|
|- (mylen E = 0) \holAnd{} !x xs. mylen (L x xs) = SUC (mylen xs):
|
||
|
thm
|
||
|
|
||
|
> \hol{EVAL ``mylen (L 2 (L 3 (L 1 E)))``}
|
||
|
val it =
|
||
|
|- mylen (L 2 (L 3 (L 1 E))) = 3:
|
||
|
thm
|
||
|
\end{semiverbatim}
|
||
|
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\section{Datatype Definitions}
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Datatype Package}
|
||
|
\begin{itemize}
|
||
|
\item the \hol{Datatype} package allows to define SML style datatypes easily
|
||
|
\item there is support for
|
||
|
\begin{itemize}
|
||
|
\item algebraic datatypes
|
||
|
\item record types
|
||
|
\item mutually recursive types
|
||
|
\item ...
|
||
|
\end{itemize}
|
||
|
\item many constants are automatically introduced
|
||
|
\begin{itemize}
|
||
|
\item constructors
|
||
|
\item case-split constant
|
||
|
\item size function
|
||
|
\item field-update and accessor functions for records
|
||
|
\item ...
|
||
|
\end{itemize}
|
||
|
\item many theorems are derived and stored in current theory
|
||
|
\begin{itemize}
|
||
|
\item injectivity and distinctness of constructors
|
||
|
\item nchotomy and structural induction theorems
|
||
|
\item rewrites for case-split, size and record update functions
|
||
|
\item ...
|
||
|
\end{itemize}
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Datatype Package - Example I}
|
||
|
\begin{block}{Tree Datatype in SML}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
datatype ('a,'b) btree = Leaf of 'a
|
||
|
| Node of ('a,'b) btree * 'b * ('a,'b) btree
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
\begin{block}{Tree Datatype in HOL}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
Datatype `btree = Leaf 'a
|
||
|
| Node btree 'b btree`
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
\begin{block}{Tree Datatype in HOL --- Deprecated Syntax}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
Hol_datatype `btree = Leaf of 'a
|
||
|
| Node of btree => 'b => btree`
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
\end{frame}
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Datatype Package - Example I - Derived Theorems 1}
|
||
|
\begin{block}{\texttt{btree\_distinct}}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
|- !a2 a1 a0 a. Leaf a <> Node a0 a1 a2
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
\begin{block}{\texttt{btree\_11}}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
|- (!a a'. (Leaf a = Leaf a') <=> (a = a')) \holAnd{}
|
||
|
(!a0 a1 a2 a0' a1' a2'.
|
||
|
(Node a0 a1 a2 = Node a0' a1' a2') <=>
|
||
|
(a0 = a0') \holAnd{} (a1 = a1') \holAnd{} (a2 = a2'))
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
\begin{block}{\texttt{btree\_nchotomy}}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
|- !bb. (?a. bb = Leaf a) \holOr{} (?b b1 b0. bb = Node b b1 b0)
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
\begin{block}{\texttt{btree\_induction}}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
|- !P. (!a. P (Leaf a)) \holAnd{}
|
||
|
(!b b0. P b \holAnd{} P b0 ==> !b1. P (Node b b1 b0)) ==>
|
||
|
!b. P b
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Datatype Package - Example I - Derived Theorems 2}
|
||
|
|
||
|
\begin{block}{\texttt{btree\_size\_def}}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
|- (!f f1 a. btree_size f f1 (Leaf a) = 1 + f a) \holAnd{}
|
||
|
(!f f1 a0 a1 a2.
|
||
|
btree_size f f1 (Node a0 a1 a2) =
|
||
|
1 + (btree_size f f1 a0 + (f1 a1 + btree_size f f1 a2)))
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
\begin{block}{\texttt{btree\_case\_def}}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
|- (!a f f1. btree_CASE (Leaf a) f f1 = f a) \holAnd{}
|
||
|
(!a0 a1 a2 f f1. btree_CASE (Node a0 a1 a2) f f1 = f1 a0 a1 a2)
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
\begin{block}{\texttt{btree\_case\_cong}}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
|- !M M' f f1.
|
||
|
(M = M') \holAnd{} (!a. (M' = Leaf a) ==> (f a = f' a)) \holAnd{}
|
||
|
(!a0 a1 a2.
|
||
|
(M' = Node a0 a1 a2) ==> (f1 a0 a1 a2 = f1' a0 a1 a2)) ==>
|
||
|
(btree_CASE M f f1 = btree_CASE M' f' f1')
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Datatype Package - Example II}
|
||
|
\begin{block}{Enumeration type in SML}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
datatype my_enum = E1 | E2 | E3
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
\begin{block}{Enumeration type in HOL}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
Datatype `my_enum = E1 | E2 | E3`
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Datatype Package - Example II - Derived Theorems}
|
||
|
|
||
|
\begin{block}{\texttt{my\_enum\_nchotomy}}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
|- !P. P E1 \holAnd{} P E2 \holAnd{} P E3 ==> !a. P a
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
\begin{block}{\texttt{my\_enum\_distinct}}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
|- E1 <> E2 \holAnd{} E1 <> E3 \holAnd{} E2 <> E3
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
\begin{block}{\texttt{my\_enum2num\_thm}}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
|- (my_enum2num E1 = 0) \holAnd{} (my_enum2num E2 = 1) \holAnd{} (my_enum2num E3 = 2)
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
\begin{block}{\texttt{my\_enum2num\_num2my\_enum}}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
|- !r. r < 3 <=> (my_enum2num (num2my_enum r) = r)
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Datatype Package - Example III}
|
||
|
\begin{block}{Record type in SML}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
type rgb = \{ r : int, g : int, b : int \}
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
\begin{block}{Record type in HOL}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
Datatype `rgb = <| r : num; g : num; b : num |>`
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
\end{frame}
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Datatype Package - Example III - Derived Theorems}
|
||
|
|
||
|
\begin{block}{\texttt{rgb\_component\_equality}}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
|- !r1 r2. (r1 = r2) <=>
|
||
|
(r1.r = r2.r) \holAnd{} (r1.g = r2.g) \holAnd{} (r1.b = r2.b)
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
\begin{block}{\texttt{rgb\_nchotomy}}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
|- !rr. ?n n0 n1. rr = rgb n n0 n1
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
\begin{block}{\texttt{rgb\_r\_fupd}}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
|- !f n n0 n1. rgb n n0 n1 with r updated_by f = rgb (f n) n0 n1
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
\begin{block}{\texttt{rgb\_updates\_eq\_literal}}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
|- !r n1 n0 n.
|
||
|
r with <|r := n1; g := n0; b := n|> = <|r := n1; g := n0; b := n|>
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Datatype Package - Example IV}
|
||
|
\begin{itemize}
|
||
|
\item nested record types are not allowed
|
||
|
\item however, mutual recursive types can mitigate this restriction
|
||
|
\end{itemize}
|
||
|
|
||
|
\begin{block}{Filesystem Datatype in SML}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
datatype file = Text of string
|
||
|
| Dir of \{owner : string ,
|
||
|
files : (string * file) list\}
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
|
||
|
\begin{alertblock}{\textbf{Not Supported} Nested Record Type Example in HOL}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
Datatype `file = Text string
|
||
|
| Dir <| owner : string ;
|
||
|
files : (string # file) list |>`
|
||
|
\end{semiverbatim}
|
||
|
\end{alertblock}
|
||
|
|
||
|
\begin{block}{Filesystem Datatype - Mutual Recursion in HOL}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
Datatype `file = Text string
|
||
|
| Dir directory
|
||
|
;
|
||
|
directory = <| owner : string ;
|
||
|
files : (string # file) list |>`
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Datatype Package - No support for Co-Algebraic Types}
|
||
|
\begin{itemize}
|
||
|
\item there is no support for co-algebraic types
|
||
|
\item the \texttt{Datatype} package could be extended to do so
|
||
|
\item other systems like Isabelle/HOL provide high-level methods for defining such types
|
||
|
\end{itemize}
|
||
|
\begin{block}{Co-algebraic Type Example in SML --- Lazy Lists}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
datatype 'a lazylist = Nil
|
||
|
| Cons of ('a * (unit -> 'a lazylist))
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Datatype Package - Discussion}
|
||
|
|
||
|
\begin{itemize}
|
||
|
\item \texttt{Datatype} package allows to define many useful datatypes
|
||
|
\item however, there are many limitations
|
||
|
\begin{itemize}
|
||
|
\item some types cannot be defined in HOL, \eg empty types
|
||
|
\item some types are not supported, \eg co-algebraic types
|
||
|
\item there are bugs (currently \eg some trouble with certain mutually recursive definitions)
|
||
|
\end{itemize}
|
||
|
\item biggest restrictions in practice (in my opinion and my line of work)
|
||
|
\begin{itemize}
|
||
|
\item no support for co-algebraic datatypes
|
||
|
\item no nested record datatypes
|
||
|
\end{itemize}
|
||
|
\item depending on datatype, different sets of useful lemmata are derived
|
||
|
\item most important ones are added to \hol{TypeBase}
|
||
|
\begin{itemize}
|
||
|
\item tools like \hol{Induct\_on}, \hol{Cases\_on} use them
|
||
|
\item there is support for pattern matching
|
||
|
\end{itemize}
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\section{Recursive Function Definitions}
|
||
|
|
||
|
\begin{frame}
|
||
|
\frametitle{Total Functional Language (\texttt{TFL}) package}
|
||
|
\begin{itemize}
|
||
|
\item \ml{TFL} package implements support for terminating functional definitions
|
||
|
\item \hol{Define} defines functions from high-level descriptions
|
||
|
\item there is support for pattern matching
|
||
|
\item look and feel is like function definitions in SML
|
||
|
\item based on \emph{well-founded recursion} principle
|
||
|
\item \hol{Define} is the most common way for definitions in HOL
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}
|
||
|
\frametitle{Well-Founded Relations}
|
||
|
\begin{itemize}
|
||
|
\item a relation \texttt{R : 'a -> 'a -> bool} is called \emph{well-founded}, iff
|
||
|
there are no infinite descending chains\\[.5em]
|
||
|
\hol{wellfounded R = \holNeg{}?f.\ !n.\ R (f (SUC n)) (f n)}
|
||
|
\bigskip
|
||
|
\item Example: \texttt{\$< :\ num -> num -> bool} is well-founded
|
||
|
\item if arguments of recursive calls are smaller according to well-founded relation,
|
||
|
the recursion terminates
|
||
|
\item this is the essence of termination proofs
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}
|
||
|
\frametitle{Well-Founded Recursion}
|
||
|
\begin{itemize}
|
||
|
\item a well-founded relation \hol{R} can be used to define recursive functions
|
||
|
\item this recursion principle is called \hol{WFREC} in HOL
|
||
|
\item idea of \hol{WFREC}
|
||
|
\begin{itemize}
|
||
|
\item if arguments get smaller according to \hol{R}, perform recursive call
|
||
|
\item otherwise abort and return \hol{ARB}
|
||
|
\end{itemize}
|
||
|
\item \hol{WFREC} always defines a function
|
||
|
\item if all recursive calls indeed decrease according to \hol{R}, the original recursive
|
||
|
equations can be derived from the \hol{WFREC} representation
|
||
|
\item TFL uses this internally
|
||
|
\item however, this is well-hidden from the user
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{\texttt{Define} - Initial Examples}
|
||
|
|
||
|
\begin{block}{Simple Definitions}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
> \hol{val DOUBLE_def = Define `DOUBLE n = n + n`}
|
||
|
val DOUBLE_def =
|
||
|
|- !n. DOUBLE n = n + n:
|
||
|
thm
|
||
|
|
||
|
> \hol{val MY_LENGTH_def = Define `(MY_LENGTH [] = 0) \holAnd{}
|
||
|
(MY_LENGTH (x::xs) = SUC (MY_LENGTH xs))`}
|
||
|
val MY_LENGTH_def =
|
||
|
|- (MY_LENGTH [] = 0) \holAnd{} !x xs. MY_LENGTH (x::xs) = SUC (MY_LENGTH xs):
|
||
|
thm
|
||
|
|
||
|
> \hol{val MY_APPEND_def = Define `(MY_APPEND [] ys = ys) \holAnd{}
|
||
|
(MY_APPEND (x::xs) ys = x :: (MY_APPEND xs ys))`}
|
||
|
val MY_APPEND_def =
|
||
|
|- (!ys. MY_APPEND [] ys = ys) \holAnd{}
|
||
|
(!x xs ys. MY_APPEND (x::xs) ys = x::MY_APPEND xs ys):
|
||
|
thm
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}
|
||
|
\frametitle{\texttt{Define} discussion}
|
||
|
\begin{itemize}
|
||
|
\item \hol{Define} feels like a function definition in HOL
|
||
|
\item it can be used to define "terminating" recursive functions
|
||
|
\item \hol{Define} is implemented by a large, non-trivial piece of SML code
|
||
|
\item it uses many heuristics
|
||
|
\item outcome of \hol{Define} sometimes hard to predict
|
||
|
\item the input descriptions are only hints
|
||
|
\begin{itemize}
|
||
|
\item the produced function and the definitional theorem might be different
|
||
|
\item in simple examples, quantifiers added
|
||
|
\item pattern compilation takes place
|
||
|
\item earlier ``conjuncts'' have precedence
|
||
|
\end{itemize}
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{\texttt{Define} - More Examples}
|
||
|
|
||
|
\begin{block}{}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
> \hol{val MY_HD_def = Define `MY_HD (x :: xs) = x`}
|
||
|
val MY_HD_def = |- !x xs. MY_HD (x::xs) = x : thm
|
||
|
|
||
|
> \hol{val IS_SORTED_def = Define `
|
||
|
(IS_SORTED (x1 :: x2 :: xs) = ((x1 < x2) \holAnd{} (IS_SORTED (x2::xs)))) \holAnd{}
|
||
|
(IS_SORTED _ = T)`}
|
||
|
val IS_SORTED_def =
|
||
|
|- (!xs x2 x1. IS_SORTED (x1::x2::xs) <=> x1 < x2 \holAnd{} IS_SORTED (x2::xs)) \holAnd{}
|
||
|
(IS_SORTED [] <=> T) \holAnd{} (!v. IS_SORTED [v] <=> T)
|
||
|
|
||
|
> \hol{val EVEN_def = Define `(EVEN 0 = T) \holAnd{} (ODD 0 = F) \holAnd{}
|
||
|
(EVEN (SUC n) = ODD n) \holAnd{} (ODD (SUC n) = EVEN n)`}
|
||
|
val EVEN_def =
|
||
|
|- (EVEN 0 <=> T) \holAnd{} (ODD 0 <=> F) \holAnd{} (!n. EVEN (SUC n) <=> ODD n) \holAnd{}
|
||
|
(!n. ODD (SUC n) <=> EVEN n) : thm
|
||
|
|
||
|
> \hol{val ZIP_def = Define `(ZIP (x::xs) (y::ys) = (x,y)::(ZIP xs ys)) \holAnd{}
|
||
|
(ZIP \_ \_ = [])`}
|
||
|
val ZIP_def =
|
||
|
|- (!ys y xs x. ZIP (x::xs) (y::ys) = (x,y)::ZIP xs ys) \holAnd{}
|
||
|
(!v1. ZIP [] v1 = []) \holAnd{} (!v4 v3. ZIP (v3::v4) [] = []) : thm
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Primitive Definitions}
|
||
|
\begin{itemize}
|
||
|
\item \hol{Define} introduces (if needed) the function using \hol{WFREC}
|
||
|
\item intended definition derived as a theorem
|
||
|
\item the theorems are stored in current theory
|
||
|
\item usually, one never needs to look at it
|
||
|
\end{itemize}
|
||
|
\begin{block}{Examples}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
val IS_SORTED_primitive_def =
|
||
|
|- IS_SORTED =
|
||
|
WFREC (@R.\ WF R \holAnd{} !x1 xs x2. R (x2::xs) (x1::x2::xs))
|
||
|
(\textbsl{}IS_SORTED a.
|
||
|
case a of
|
||
|
[] => I T
|
||
|
| [x1] => I T
|
||
|
| x1::x2::xs => I (x1 < x2 \holAnd{} IS_SORTED (x2::xs)))
|
||
|
|
||
|
|- !R M. WF R ==> !x. WFREC R M x = M (RESTRICT (WFREC R M) R x) x
|
||
|
|- !f R x. RESTRICT f R x = (\textbsl{}y. if R y x then f y else ARB)
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Induction Theorems}
|
||
|
\begin{itemize}
|
||
|
\item \hol{Define} automatically defines induction theorems
|
||
|
\item these theorems are stored in current theory with suffix \hol{ind}
|
||
|
\item use \hol{DB.fetch "-" "something\_ind"} to retrieve them
|
||
|
\item these induction theorems are useful to reason about corresponding recursive functions
|
||
|
\end{itemize}
|
||
|
\begin{block}{Example}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
val IS_SORTED_ind = |- !P.
|
||
|
((!x1 x2 xs. P (x2::xs) ==> P (x1::x2::xs)) \holAnd{}
|
||
|
P [] \holAnd{}
|
||
|
(!v. P [v])) ==>
|
||
|
!v. P v
|
||
|
\end{semiverbatim}
|
||
|
\end{block}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{\texttt{Define} failing}
|
||
|
\begin{itemize}
|
||
|
\item \hol{Define} might fail for various reasons to define a function
|
||
|
\begin{itemize}
|
||
|
\item such a function cannot be defined in HOL
|
||
|
\item such a function can be defined, but not via the methods used by TFL
|
||
|
\item TFL can define such a function, but its heuristics are too weak and user guidance is required
|
||
|
\item there is a bug :-)
|
||
|
\end{itemize}
|
||
|
\item \emph{termination} is an important concept for \hol{Define}
|
||
|
\item it is easy to misunderstand termination in the context of HOL
|
||
|
\item we need to understand what is meant by termination
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Termination in HOL}
|
||
|
\begin{itemize}
|
||
|
\item in SML it is natural to talk about termination of functions
|
||
|
\item in the HOL logic there is no concept of execution
|
||
|
\item thus, there is no concept of termination in HOL
|
||
|
\begin{minipage}{.8\textwidth}
|
||
|
\begin{exampleblock}{3 characterisations of a function \texttt{f :\ num -> num}}
|
||
|
\begin{itemize}
|
||
|
\item \hol{|- !n.\ f n = 0}
|
||
|
\item \hol{|- (f 0 = 0) \holAnd{} !n.\ (f (SUC n) = f n)}
|
||
|
\item \hol{|- (f 0 = 0) \holAnd{} !n.\ (f n = f (SUC n))}
|
||
|
\end{itemize}
|
||
|
Is \hol{f} terminating? All 3 theorems are equivalent.
|
||
|
\end{exampleblock}
|
||
|
\end{minipage}\bigskip
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Termination in HOL II}
|
||
|
\begin{itemize}
|
||
|
\item it is useful to think in terms of termination
|
||
|
\item the TFL package implements heuristics to define functions that would terminate in SML
|
||
|
\item the TFL package uses well-founded recursion
|
||
|
\item the required well-founded relation corresponds to a termination proof
|
||
|
\item therefore, it is very natural to think of \hol{Define} searching a termination proof
|
||
|
\item important: this is the idea behind this function definition package, not a property of HOL
|
||
|
\end{itemize}
|
||
|
\bottomstatement{\alert{HOL is not limited to "terminating" functions}}
|
||
|
\end{frame}
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Termination in HOL III}
|
||
|
\begin{itemize}
|
||
|
\item one can define "non-terminating" functions in HOL
|
||
|
\item however, one cannot do so (easily) with \hol{Define}
|
||
|
\end{itemize}
|
||
|
\begin{exampleblock}{Definition of \texttt{WHILE} in HOL}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
\emph{|- !P g x. WHILE P g x = if P x then WHILE P g (g x) else x}
|
||
|
\end{semiverbatim}
|
||
|
\end{exampleblock}
|
||
|
|
||
|
|
||
|
\begin{exampleblock}{Execution Order}\scriptsize
|
||
|
There is no "execution order". One can easily define a complicated constant function:
|
||
|
\vspace{-.7em}
|
||
|
\begin{semiverbatim}
|
||
|
\emph{(myk : num -> num) (n:num) = (let x = myk (n+1) in 0)}
|
||
|
\end{semiverbatim}
|
||
|
\end{exampleblock}
|
||
|
|
||
|
\begin{alertblock}{Unsound Definitions}\scriptsize
|
||
|
A function \hol{f : num -> num} with the following property cannot be defined in HOL unless HOL has an inconsistancy:
|
||
|
\begin{semiverbatim}
|
||
|
\hol{!n. f n = ((f n) + 1)}
|
||
|
\end{semiverbatim}
|
||
|
Such a function would allow to prove \hol{0 = 1}.
|
||
|
\end{alertblock}
|
||
|
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Manual Termination Proofs I}
|
||
|
\begin{itemize}
|
||
|
\item TFL uses various heuristics to find a well-founded relation
|
||
|
\item however, these heuristics may not be strong enough
|
||
|
\item in such cases the user can provide a well-founded relation manually
|
||
|
\item the most common well-founded relations are \emph{measures}
|
||
|
\item measures map values to natural numbers and use the less relation\\
|
||
|
\hol{|- !(\alert{f:'a -> num}) x y.\ measure f x y <=> (f x < f y)}
|
||
|
\item all measures are well-founded: \hol{|- !f.\ WF (measure f)}
|
||
|
\item moreover, existing well-founded relations can be combined
|
||
|
\begin{itemize}
|
||
|
\item lexicographic order \hol{LEX}
|
||
|
\item list lexicographic order \hol{LLEX}
|
||
|
\item \ldots
|
||
|
\end{itemize}
|
||
|
\end{itemize}
|
||
|
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Manual Termination Proofs II}
|
||
|
\begin{itemize}
|
||
|
\item if \hol{Define} fails to find a termination proof, \hol{Hol\_defn} can be used
|
||
|
\item \hol{Hol\_defn} defers termination proofs
|
||
|
\item it derives termination conditions and
|
||
|
sets up the function definitions
|
||
|
\item all results are packaged as a value of type \hol{defn}
|
||
|
\item after calling \hol{Hol\_defn} the defined function(s) can be used
|
||
|
\item however, the intended definition theorem has not been derived yet
|
||
|
\item to derive it, one needs to
|
||
|
\begin{itemize}
|
||
|
\item provide a well-founded relation
|
||
|
\item show that termination conditions respect that relation
|
||
|
\end{itemize}
|
||
|
\item \hol{Defn.tprove} and \hol{Defn.tgoal} are intended for this
|
||
|
\item proofs usually start by providing relation via tactic \hol{WF\_REL\_TAC}
|
||
|
\end{itemize}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Manual Termination Proof Example 1}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
> \hol{val qsort_defn = Hol_defn "qsort" `
|
||
|
(qsort ord [] = []) \holAnd{}
|
||
|
(qsort ord (x::rst) =
|
||
|
(qsort ord (FILTER (\$\holNeg{} o ord x) rst)) ++
|
||
|
[x] ++
|
||
|
(qsort ord (FILTER (ord x) rst)))`}
|
||
|
|
||
|
val qsort_defn = HOL function definition (recursive)
|
||
|
|
||
|
Equation(s) :
|
||
|
[...] |- qsort ord [] = []
|
||
|
[...] |- qsort ord (x::rst) =
|
||
|
qsort ord (FILTER ($\holNeg{} o ord x) rst) ++ [x] ++
|
||
|
qsort ord (FILTER (ord x) rst)
|
||
|
|
||
|
Induction : ...
|
||
|
|
||
|
Termination conditions :
|
||
|
0. !rst x ord. R (ord,FILTER (ord x) rst) (ord,x::rst)
|
||
|
1. !rst x ord. R (ord,FILTER ($\holNeg{} o ord x) rst) (ord,x::rst)
|
||
|
2. WF R
|
||
|
\end{semiverbatim}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Manual Termination Proof Example 2}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
> \hol{Defn.tgoal qsort_defn}
|
||
|
|
||
|
Initial goal:
|
||
|
|
||
|
?R.
|
||
|
WF R \holAnd{}
|
||
|
(!rst x ord. R (ord,FILTER (ord x) rst) (ord,x::rst)) \holAnd{}
|
||
|
(!rst x ord. R (ord,FILTER (\$\holNeg{} o ord x) rst) (ord,x::rst))
|
||
|
|
||
|
\pause
|
||
|
> \hol{e (WF_REL_TAC `measure (\textbsl{}(\_, l).\ LENGTH l)`)}
|
||
|
|
||
|
1 subgoal :
|
||
|
|
||
|
(!rst x ord. LENGTH (FILTER (ord x) rst) < LENGTH (x::rst)) \holAnd{}
|
||
|
(!rst x ord. LENGTH (FILTER (\textbsl{}x'.\ \holNeg{}ord x x') rst) < LENGTH (x::rst))
|
||
|
|
||
|
> \hol{...}
|
||
|
\end{semiverbatim}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
\begin{frame}[fragile]
|
||
|
\frametitle{Manual Termination Proof Example 3}
|
||
|
\begin{semiverbatim}\scriptsize
|
||
|
> \hol{val (qsort_def, qsort_ind) =
|
||
|
Defn.tprove (qsort_defn,
|
||
|
WF_REL_TAC `measure (\textbsl{}(\_, l).\ LENGTH l)`) >> ...)}
|
||
|
|
||
|
val qsort_def =
|
||
|
|- (qsort ord [] = []) \holAnd{}
|
||
|
(qsort ord (x::rst) =
|
||
|
qsort ord (FILTER ($~ o ord x) rst) ++ [x] ++
|
||
|
qsort ord (FILTER (ord x) rst))
|
||
|
|
||
|
val qsort_ind =
|
||
|
|- !P. (!ord. P ord []) \holAnd{}
|
||
|
(!ord x rst.
|
||
|
P ord (FILTER (ord x) rst) \holAnd{}
|
||
|
P ord (FILTER ($~ o ord x) rst) ==>
|
||
|
P ord (x::rst)) ==>
|
||
|
!v v1. P v v1
|
||
|
\end{semiverbatim}
|
||
|
\end{frame}
|
||
|
|
||
|
|
||
|
%%% Local Variables:
|
||
|
%%% mode: latex
|
||
|
%%% TeX-master: "current"
|
||
|
%%% End:
|