on master help sign in
Move tactic proofs out of main tutorial

Also add a note that this is not intended to be used directly, but rather for building proof automation

commit035f24e4e7a88ff7d6a043d18108351d9cef9ade authorEdwin Brady <ecb10@st-andrews.ac.uk> dateMon 30 Mar 2015, 09:17 (12 years ago) parent78a55ab
4 files changed+169−157
docs/index.rst+1 docs/proofs/index.rst+1 docs/proofs/interactive.rst+166 docs/tutorial/theorems.rst+1−157
docs/index.rst+1
@@ -88,6 +88,7 @@ Theorem Proving
8888 proofs/pluscomm
8989 proofs/inductive
9090 proofs/patterns
91+ proofs/interactive
9192
9293.. _reference:
9394
docs/proofs/index.rst+1
@@ -21,4 +21,5 @@ A tutorial on theorem proving in Idris.
2121 pluscomm
2222 inductive
2323 patterns
24+ interactive
2425
docs/proofs/interactive.rstnew file+166
@@ -0,0 +1,166 @@
1+Interactive Theorem Proving
2+===========================
3+
4+Idris also supports interactive theorem proving via tactics. This
5+is generally not recommended to be used directly, but rather used as a
6+mechanism for building proof automation which is beyond the scope of this
7+tutorial. In this section, we briefly discus tactics.
8+
9+One way to write proofs interactively is to write the general *structure* of
10+the proof, and use the interactive mode to complete the details.
11+Consider the following definition, proved in :ref:`.. _sect-theorems`:
12+
13+.. code-block:: idris
14+
15+ plusReduces : (n:Nat) -> plus Z n = n
16+
17+We’ll be constructing the proof by *induction*, so we write the cases for ``Z``
18+and ``S``, with a recursive call in the ``S`` case giving the inductive
19+hypothesis, and insert *metavariables* for the rest of the definition:
20+
21+.. code-block:: idris
22+
23+ plusReducesZ' : (n:Nat) -> n = plus n Z
24+ plusReducesZ' Z = ?plusredZ_Z
25+ plusReducesZ' (S k) = let ih = plusReducesZ' k in
26+ ?plusredZ_S
27+
28+On running , two global names are created, ``plusredZ_Z`` and
29+``plusredZ_S``, with no definition. We can use the ``:m`` command at the
30+prompt to find out which metavariables are still to be solved (or, more
31+precisely, which functions exist but have no definitions), then the
32+``:t`` command to see their types:
33+
34+.. code-block:: idris
35+
36+ *theorems> :m
37+ Global metavariables:
38+ [plusredZ_S,plusredZ_Z]
39+
40+.. code-block:: idris
41+
42+ *theorems> :t plusredZ_Z
43+ plusredZ_Z : Z = plus Z Z
44+
45+ *theorems> :t plusredZ_S
46+ plusredZ_S : (k : Nat) -> (k = plus k Z) -> S k = plus (S k) Z
47+
48+The ``:p`` command enters interactive proof mode, which can be used to
49+complete the missing definitions.
50+
51+.. code-block:: idris
52+
53+ *theorems> :p plusredZ_Z
54+
55+ ---------------------------------- (plusredZ_Z) --------
56+ {hole0} : Z = plus Z Z
57+
58+This gives us a list of premises (above the line; there are none here)
59+and the current goal (below the line; named ``{hole0}`` here). At the
60+prompt we can enter tactics to direct the construction of the proof. In
61+this case, we can normalise the goal with the ``compute`` tactic:
62+
63+.. code-block:: idris
64+
65+ -plusredZ_Z> compute
66+
67+ ---------------------------------- (plusredZ_Z) --------
68+ {hole0} : Z = Z
69+
70+Now we have to prove that ``Z`` equals ``Z``, which is easy to prove by
71+``Refl``. To apply a function, such as ``Refl``, we use ``refine`` which
72+introduces subgoals for each of the function’s explicit arguments
73+(``Refl`` has none):
74+
75+.. code-block:: idris
76+
77+ -plusredZ_Z> refine Refl
78+ plusredZ_Z: no more goals
79+
80+Here, we could also have used the ``trivial`` tactic, which tries to
81+refine by ``Refl``, and if that fails, tries to refine by each name in
82+the local context. When a proof is complete, we use the ``qed`` tactic
83+to add the proof to the global context, and remove the metavariable from
84+the unsolved metavariables list. This also outputs a trace of the proof:
85+
86+.. code-block:: idris
87+
88+ -plusredZ_Z> qed
89+ plusredZ_Z = proof
90+ compute
91+ refine Refl
92+
93+.. code-block:: idris
94+
95+ *theorems> :m
96+ Global metavariables:
97+ [plusredZ_S]
98+
99+The ``:addproof`` command, at the interactive prompt, will add the proof
100+to the source file (effectively in an appendix). Let us now prove the
101+other required lemma, ``plusredZ_S``:
102+
103+.. code-block:: idris
104+
105+ *theorems> :p plusredZ_S
106+
107+ ---------------------------------- (plusredZ_S) --------
108+ {hole0} : (k : Nat) -> (k = plus k Z) -> S k = plus (S k) Z
109+
110+In this case, the goal is a function type, using ``k`` (the argument
111+accessible by pattern matching) and ``ih`` — the local variable
112+containing the result of the recursive call. We can introduce these as
113+premisses using the ``intro`` tactic twice (or ``intros``, which
114+introduces all arguments as premisses). This gives:
115+
116+.. code-block:: idris
117+
118+ k : Nat
119+ ih : k = plus k Z
120+ ---------------------------------- (plusredZ_S) --------
121+ {hole2} : S k = plus (S k) Z
122+
123+Since plus is defined by recursion on its first argument, the term
124+``plus (S k) Z`` in the goal can be simplified, so we use ``compute``.
125+
126+.. code-block:: idris
127+
128+ k : Nat
129+ ih : k = plus k Z
130+ ---------------------------------- (plusredZ_S) --------
131+ {hole2} : S k = S (plus k Z)
132+
133+We know, from the type of ``ih``, that ``k = plus k Z``, so we would
134+like to use this knowledge to replace ``plus k Z`` in the goal with
135+``k``. We can achieve this with the ``rewrite`` tactic:
136+
137+.. code-block:: idris
138+
139+ -plusredZ_S> rewrite ih
140+
141+ k : Nat
142+ ih : k = plus k Z
143+ ---------------------------------- (plusredZ_S) --------
144+ {hole3} : S k = S k
145+
146+ -plusredZ_S>
147+
148+The ``rewrite`` tactic takes an equality proof as an argument, and tries
149+to rewrite the goal using that proof. Here, it results in an equality
150+which is trivially provable:
151+
152+.. code-block:: idris
153+
154+ -plusredZ_S> trivial
155+ plusredZ_S: no more goals
156+ -plusredZ_S> qed
157+ plusredZ_S = proof {
158+ intros;
159+ rewrite ih;
160+ trivial;
161+ }
162+
163+Again, we can add this proof to the end of our source file using the
164+``:addproof`` command at the interactive prompt.
165+
166+
docs/tutorial/theorems.rst+1−157
@@ -120,163 +120,7 @@ mode’.
120120
121121Idris provides interactive editing capabilities, which can help with
122122building proofs. For more details on building proofs interactively in
123−an editor, see :ref:`proofs-index`. In the rest of this section, we discuss
124−Idris's interactive proof mode.
125−
126−Interactive theorem proving
127−---------------------------
128−
129−Instead of writing the proof in one go, we can use Idris’s interactive proof
130−mode. To do this, we write the general *structure* of the proof, and use
131−the interactive mode to complete the details. We’ll be constructing the
132−proof by *induction*, so we write the cases for ``Z`` and ``S``, with a
133−recursive call in the ``S`` case giving the inductive hypothesis, and
134−insert *metavariables* for the rest of the definition:
135−
136−.. code-block:: idris
137−
138− plusReducesZ' : (n:Nat) -> n = plus n Z
139− plusReducesZ' Z = ?plusredZ_Z
140− plusReducesZ' (S k) = let ih = plusReducesZ' k in
141− ?plusredZ_S
142−
143−On running , two global names are created, ``plusredZ_Z`` and
144−``plusredZ_S``, with no definition. We can use the ``:m`` command at the
145−prompt to find out which metavariables are still to be solved (or, more
146−precisely, which functions exist but have no definitions), then the
147−``:t`` command to see their types:
148−
149−.. code-block:: idris
150−
151− *theorems> :m
152− Global metavariables:
153− [plusredZ_S,plusredZ_Z]
154−
155−.. code-block:: idris
156−
157− *theorems> :t plusredZ_Z
158− plusredZ_Z : Z = plus Z Z
159−
160− *theorems> :t plusredZ_S
161− plusredZ_S : (k : Nat) -> (k = plus k Z) -> S k = plus (S k) Z
162−
163−The ``:p`` command enters interactive proof mode, which can be used to
164−complete the missing definitions.
165−
166−.. code-block:: idris
167−
168− *theorems> :p plusredZ_Z
169−
170− ---------------------------------- (plusredZ_Z) --------
171− {hole0} : Z = plus Z Z
172−
173−This gives us a list of premises (above the line; there are none here)
174−and the current goal (below the line; named ``{hole0}`` here). At the
175−prompt we can enter tactics to direct the construction of the proof. In
176−this case, we can normalise the goal with the ``compute`` tactic:
177−
178−.. code-block:: idris
179−
180− -plusredZ_Z> compute
181−
182− ---------------------------------- (plusredZ_Z) --------
183− {hole0} : Z = Z
184−
185−Now we have to prove that ``Z`` equals ``Z``, which is easy to prove by
186−``Refl``. To apply a function, such as ``Refl``, we use ``refine`` which
187−introduces subgoals for each of the function’s explicit arguments
188−(``Refl`` has none):
189−
190−.. code-block:: idris
191−
192− -plusredZ_Z> refine Refl
193− plusredZ_Z: no more goals
194−
195−Here, we could also have used the ``trivial`` tactic, which tries to
196−refine by ``Refl``, and if that fails, tries to refine by each name in
197−the local context. When a proof is complete, we use the ``qed`` tactic
198−to add the proof to the global context, and remove the metavariable from
199−the unsolved metavariables list. This also outputs a trace of the proof:
200−
201−.. code-block:: idris
202−
203− -plusredZ_Z> qed
204− plusredZ_Z = proof
205− compute
206− refine Refl
207−
208−.. code-block:: idris
209−
210− *theorems> :m
211− Global metavariables:
212− [plusredZ_S]
213−
214−The ``:addproof`` command, at the interactive prompt, will add the proof
215−to the source file (effectively in an appendix). Let us now prove the
216−other required lemma, ``plusredZ_S``:
217−
218−.. code-block:: idris
219−
220− *theorems> :p plusredZ_S
221−
222− ---------------------------------- (plusredZ_S) --------
223− {hole0} : (k : Nat) -> (k = plus k Z) -> S k = plus (S k) Z
224−
225−In this case, the goal is a function type, using ``k`` (the argument
226−accessible by pattern matching) and ``ih`` — the local variable
227−containing the result of the recursive call. We can introduce these as
228−premisses using the ``intro`` tactic twice (or ``intros``, which
229−introduces all arguments as premisses). This gives:
230−
231−.. code-block:: idris
232−
233− k : Nat
234− ih : k = plus k Z
235− ---------------------------------- (plusredZ_S) --------
236− {hole2} : S k = plus (S k) Z
237−
238−Since plus is defined by recursion on its first argument, the term
239−``plus (S k) Z`` in the goal can be simplified, so we use ``compute``.
240−
241−.. code-block:: idris
242−
243− k : Nat
244− ih : k = plus k Z
245− ---------------------------------- (plusredZ_S) --------
246− {hole2} : S k = S (plus k Z)
247−
248−We know, from the type of ``ih``, that ``k = plus k Z``, so we would
249−like to use this knowledge to replace ``plus k Z`` in the goal with
250−``k``. We can achieve this with the ``rewrite`` tactic:
251−
252−.. code-block:: idris
253−
254− -plusredZ_S> rewrite ih
255−
256− k : Nat
257− ih : k = plus k Z
258− ---------------------------------- (plusredZ_S) --------
259− {hole3} : S k = S k
260−
261− -plusredZ_S>
262−
263−The ``rewrite`` tactic takes an equality proof as an argument, and tries
264−to rewrite the goal using that proof. Here, it results in an equality
265−which is trivially provable:
266−
267−.. code-block:: idris
268−
269− -plusredZ_S> trivial
270− plusredZ_S: no more goals
271− -plusredZ_S> qed
272− plusredZ_S = proof {
273− intros;
274− rewrite ih;
275− trivial;
276− }
277−
278−Again, we can add this proof to the end of our source file using the
279−``:addproof`` command at the interactive prompt.
123+an editor, see :ref:`proofs-index`.
280124
281125.. _sect-totality:
282126