on de6bb41 help sign in
Idris-dev/tutorial/theorems.tex
295 lines 8.0 kB history raw
1\section{Theorem Proving}
3\subsection{Equality}
5\Idris{} allows propositional equalities to be declared, allowing theorems about
6programs to be stated and proved. Equality is built in, but conceptually has
7the following definition:
9\begin{SaveVerbatim}{}
11data (=) : a -> b -> Set where
12 refl : x = x
14\end{SaveVerbatim}
15\useverb{}
17\noindent
18Equalities can be proposed between any values of any types, but the only way to
19construct a proof of equality is if values actually are equal. For example:
21\begin{SaveVerbatim}{eqprf}
23fiveIsFive : 5 = 5
24fiveIsFive = refl
26twoPlusTwo : 2 + 2 = 4
27twoPlusTwo = refl
29\end{SaveVerbatim}
30\useverb{eqprf}
32\subsection{Simple Theorems}
34When type checking dependent types, the type itself gets \emph{normalised}. So imagine
35we want to prove the following theorem about the reduction behaviour of \texttt{plus}:
37\begin{SaveVerbatim}{plusred}
39plusReduces : (n:Nat) -> plus O n = n
41\end{SaveVerbatim}
42\useverb{plusred}
44\noindent
45We've written down the statement of the theorem as a type, in just the same way
46as we would write the type of a program. In fact there is no real distinction
47between proofs and programs. A proof, as far as we are concerned here, is
48merely a program with a precise enough type to guarantee a particular property
49of interest.
51We won't go into details here, but the Curry-Howard
52correspondence~\cite{howard} explains this relationship.
53The proof itself is trivial, because \texttt{plus O n} normalises to \texttt{n}
54by the definition of \texttt{plus}:
56\begin{SaveVerbatim}{plusredp}
58plusReduces n = refl
60\end{SaveVerbatim}
61\useverb{plusredp}
63\noindent
64It is slightly harder if we try the arguments the other way, because plus is
65defined by recursion on its first argument. The proof also works by recursion
66on the first argument to \texttt{plus}, namely \texttt{n}.
68\begin{SaveVerbatim}{plusRedO}
70plusReducesO : (n:Nat) -> n = plus n O
71plusReducesO O = refl
72plusReducesO (S k) = eqRespS (plusReducesO k)
74\end{SaveVerbatim}
75\useverb{plusRedO}
77\noindent
78\texttt{eqRespS} is a function defined in the library which states that
79equality respects successor:
81\begin{SaveVerbatim}{resps}
83eqRespS : m = n -> S m = S n
85\end{SaveVerbatim}
86\useverb{resps}
88\noindent
89We can do the same for the reduction behaviour of plus on successors:
91\begin{SaveVerbatim}{plusRedS}
93plusReducesS : (n:Nat) -> (m:Nat) -> S (plus n m) = plus n (S m)
94plusReducesS O m = refl
95plusReducesS (S k) m = eqRespS (plusReducesS k m)
97\end{SaveVerbatim}
98\useverb{plusRedS}
100\noindent
101Even for trival theorems like these, the proofs are a little tricky to
102construct in one go. When things get even slightly more complicated, it becomes
103too much to think about to construct proofs in this 'batch mode'. \Idris{}
104therefore provides an interactive proof mode.
106\subsection{Interactive theorem proving}
108Instead of writing the proof in one go, we can use \Idris{}'s interactive
109proof mode. To do this, we write the general \emph{structure} of the proof,
110and use the interactive mode to complete the details. We'll be constructing
111the proof by \emph{induction}, so we write the cases for \texttt{O} and
112\texttt{S}, with a recursive call in the \texttt{S} case giving the inductive
113hypothesis, and insert \emph{metavariables} for the rest of the definition:
115\begin{SaveVerbatim}{prOstruct}
117plusReducesO' : (n:Nat) -> n = plus n O
118plusReducesO' O = ?plusredO_O
119plusReducesO' (S k) = let ih = plusReducesO' k in
120 ?plusredO_S
122\end{SaveVerbatim}
123\useverb{prOstruct}
125\noindent
126On running \Idris{}, two global names are created, \texttt{plusredO\_O} and
127\texttt{plusredO\_S}, with no definition. We can use the \texttt{:m} command
128at the prompt to find out which metavariables are still to be solved (or, more
129precisely, which functions exist but have no definitions), then the
130\texttt{:t} command to see their types:
132\begin{SaveVerbatim}{showmetas}
134*theorems> :m
135Global metavariables:
136 [plusredO_S,plusredO_O]
138\end{SaveVerbatim}
140\begin{SaveVerbatim}{metatypes}
142*theorems> :t plusredO_O
143plusredO_O : O = plus O O
145*theorems> :t plusredO_S
146plusredO_S : (k : Nat) -> (k = plus k O) -> S k = S (plus k O)
148\end{SaveVerbatim}
149\useverb{showmetas}
151\useverb{metatypes}
153\noindent
154The \texttt{:p} command enters interactive proof mode, which can be used to complete
155the missing definitions.
157\begin{SaveVerbatim}{proveO}
159*theorems> :p plusredO_O
161---------------------------------- (plusredO_O) --------
162{hole0} : O = plus O O
164\end{SaveVerbatim}
165\useverb{proveO}
167\noindent
168This gives us a list of premisses
169(above the line; there are none here) and the current goal (below the line;
170named \texttt{\{hole0\}} here).
171At the prompt we can enter tactics to direct the construction of the proof. In this case,
172we can normalise the goal with the \texttt{compute} tactic:
174\begin{SaveVerbatim}{compute}
176-plusredO_O> compute
178---------------------------------- (plusredO_O) --------
179{hole0} : O = O
181\end{SaveVerbatim}
182\useverb{compute}
184\noindent
185Now we have to prove that \texttt{O} equals \texttt{O}, which is easy to prove by
186\texttt{refl}. To apply a function, such as \texttt{refl}, we use \texttt{refine}
187which introduces subgoals for each of the function's explicit arguments (\texttt{refl}
188has none):
190\begin{SaveVerbatim}{refrefl}
192-plusredO_O> refine refl
193plusredO_O: no more goals
195\end{SaveVerbatim}
196\useverb{refrefl}
198\noindent
199Here, we could also have used the \texttt{trivial} tactic, which tries to refine by
200\texttt{refl}, and if that fails, tries to refine by each name in the local context.
201When a proof is complete, we use the \texttt{qed} tactic to add the proof to the
202global context, and remove the metavariable from the unsolved metavariables list.
203This also outputs a trace of the proof:
205\begin{SaveVerbatim}{prOprooftrace}
207-plusredO_O> qed
208plusredO_O = proof {
209 compute;
210 refine refl;
213\end{SaveVerbatim}
214\useverb{prOprooftrace}
216\begin{SaveVerbatim}{showmetasO}
218*theorems> :m
219Global metavariables:
220 [plusredO_S]
222\end{SaveVerbatim}
223\useverb{showmetasO}
225\noindent
226The \texttt{:addproof} command, at the interactive prompt, will add the proof to
227the source file (effectively in an appendix).
228Let us now prove the other required lemma, \texttt{plusredO\_S}:
230\begin{SaveVerbatim}{plusredOSprf}
232*theorems> :p plusredO_S
234---------------------------------- (plusredO_S) --------
235{hole0} : (k : Nat) -> (k = plus k O) -> S k = S (plus k O)
237\end{SaveVerbatim}
238\useverb{plusredOSprf}
240\noindent
241In this case, the goal is a function type, using \texttt{k} (the argument accessible by
242pattern matching) and \texttt{ih} (the local variable containing the result of
243the recursive call). We can introduce these as premisses using the \texttt{intro} tactic
244twice (or \texttt{intros}, which introduces all arguments as premisses). This gives:
246\begin{SaveVerbatim}{prSintros}
248 k : Nat
249 ih : k = plus k O
250---------------------------------- (plusredO_S) --------
251{hole2} : S k = S (plus k O)
253\end{SaveVerbatim}
254\useverb{prSintros}
256\noindent
257We know, from the type of \texttt{ih}, that \texttt{k = plus k O}, so we would like to
258use this knowledge to replace \texttt{plus k O} in the goal with \texttt{k}. We can
259achieve this with the \texttt{rewrite} tactic:
261\begin{SaveVerbatim}{}
263-plusredO_S> rewrite ih
265 k : Nat
266 ih : k = plus k O
267---------------------------------- (plusredO_S) --------
268{hole3} : S k = S k
270-plusredO_S>
272\end{SaveVerbatim}
273\useverb{}
275\noindent
276The \texttt{rewrite} tactic takes an equality proof as an argument, and tries to rewrite
277the goal using that proof. Here, it results in an equality which is trivially provable:
279\begin{SaveVerbatim}{prOStrace}
281-plusredO_S> trivial
282plusredO_S: no more goals
283-plusredO_S> qed
284plusredO_S = proof {
285 intros;
286 rewrite ih;
287 trivial;
290\end{SaveVerbatim}
291\useverb{prOStrace}
293\noindent
294Again, we can add this proof to the end of our source file using the \texttt{:addproof}
295command at the interactive prompt.