on master help sign in
Move tactic proofs out of main tutorial
035f24eEdwin Brady
docs/index.rst+1
@@ -88,6 +88,7 @@ Theorem Proving
88 proofs/pluscomm
88 proofs/pluscomm
89 proofs/inductive
89 proofs/inductive
90 proofs/patterns
90 proofs/patterns
91+ proofs/interactive
91
92
92.. _reference:
93.. _reference:
93
94
docs/proofs/index.rst+1
@@ -21,4 +21,5 @@ A tutorial on theorem proving in Idris.
21 pluscomm
21 pluscomm
22 inductive
22 inductive
23 patterns
23 patterns
24+ interactive
24
25
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’.
120
120
121Idris provides interactive editing capabilities, which can help with
121Idris provides interactive editing capabilities, which can help with
122building proofs. For more details on building proofs interactively in
122building proofs. For more details on building proofs interactively in
123−an editor, see :ref:`proofs-index`. In the rest of this section, we discuss
123+an editor, see :ref:`proofs-index`.
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.
280
124
281.. _sect-totality:
125.. _sect-totality:
282
126