comparison src/Match.v @ 141:ce4cc7fa9b2b

Templatize Match
author Adam Chlipala <adamc@hcoop.net>
date Mon, 27 Oct 2008 10:31:57 -0400
parents 8cce3247496b
children cbf2f74a5130
comparison
equal deleted inserted replaced
140:8cce3247496b 141:ce4cc7fa9b2b
38 The basic hints for [auto] and [eauto] are [Hint Immediate lemma], asking to try solving a goal immediately by applying the premise-free lemma; [Resolve lemma], which does the same but may add new premises that are themselves to be subjects of proof search; [Constructor type], which acts like [Resolve] applied to every constructor of an inductive type; and [Unfold ident], which tries unfolding [ident] when it appears at the head of a proof goal. Each of these [Hint] commands may be used with a suffix, as in [Hint Resolve lemma : my_db]. This adds the hint only to the specified database, so that it would only be used by, for instance, [auto with my_db]. An additional argument to [auto] specifies the maximum depth of proof trees to search in depth-first order, as in [auto 8] or [auto 8 with my_db]. The default depth is 5. 38 The basic hints for [auto] and [eauto] are [Hint Immediate lemma], asking to try solving a goal immediately by applying the premise-free lemma; [Resolve lemma], which does the same but may add new premises that are themselves to be subjects of proof search; [Constructor type], which acts like [Resolve] applied to every constructor of an inductive type; and [Unfold ident], which tries unfolding [ident] when it appears at the head of a proof goal. Each of these [Hint] commands may be used with a suffix, as in [Hint Resolve lemma : my_db]. This adds the hint only to the specified database, so that it would only be used by, for instance, [auto with my_db]. An additional argument to [auto] specifies the maximum depth of proof trees to search in depth-first order, as in [auto 8] or [auto 8 with my_db]. The default depth is 5.
39 39
40 All of these [Hint] commands can be issued alternatively with a more primitive hint kind, [Extern]. A few examples should do best to explain how [Hint Extern] works. *) 40 All of these [Hint] commands can be issued alternatively with a more primitive hint kind, [Extern]. A few examples should do best to explain how [Hint Extern] works. *)
41 41
42 Theorem bool_neq : true <> false. 42 Theorem bool_neq : true <> false.
43 (* begin thide *)
43 auto. 44 auto.
44 (** [crush] would have discharged this goal, but the default hint database for [auto] contains no hint that applies. *) 45 (** [crush] would have discharged this goal, but the default hint database for [auto] contains no hint that applies. *)
45 Abort. 46 Abort.
46 47
47 (** It is hard to come up with a [bool]-specific hint that is not just a restatement of the theorem we mean to prove. Luckily, a simpler form suffices. *) 48 (** It is hard to come up with a [bool]-specific hint that is not just a restatement of the theorem we mean to prove. Luckily, a simpler form suffices. *)
49 Hint Extern 1 (_ <> _) => congruence. 50 Hint Extern 1 (_ <> _) => congruence.
50 51
51 Theorem bool_neq : true <> false. 52 Theorem bool_neq : true <> false.
52 auto. 53 auto.
53 Qed. 54 Qed.
55 (* end thide *)
54 56
55 (** Our hint says: "whenever the conclusion matches the pattern [_ <> _], try applying [congruence]." The [1] is a cost for this rule. During proof search, whenever multiple rules apply, rules are tried in increasing cost order, so it pays to assign high costs to relatively expensive [Extern] hints. 57 (** Our hint says: "whenever the conclusion matches the pattern [_ <> _], try applying [congruence]." The [1] is a cost for this rule. During proof search, whenever multiple rules apply, rules are tried in increasing cost order, so it pays to assign high costs to relatively expensive [Extern] hints.
56 58
57 [Extern] hints may be implemented with the full Ltac language. This example shows a case where a hint uses a [match]. *) 59 [Extern] hints may be implemented with the full Ltac language. This example shows a case where a hint uses a [match]. *)
58 60
61 Variables P Q : A -> Prop. 63 Variables P Q : A -> Prop.
62 64
63 Hypothesis both : forall x, P x /\ Q x. 65 Hypothesis both : forall x, P x /\ Q x.
64 66
65 Theorem forall_and : forall z, P z. 67 Theorem forall_and : forall z, P z.
68 (* begin thide *)
66 crush. 69 crush.
67 (** [crush] makes no progress beyond what [intros] would have accomplished. [auto] will not apply the hypothesis [both] to prove the goal, because the conclusion of [both] does not unify with the conclusion of the goal. However, we can teach [auto] to handle this kind of goal. *) 70 (** [crush] makes no progress beyond what [intros] would have accomplished. [auto] will not apply the hypothesis [both] to prove the goal, because the conclusion of [both] does not unify with the conclusion of the goal. However, we can teach [auto] to handle this kind of goal. *)
68 71
69 Hint Extern 1 (P ?X) => 72 Hint Extern 1 (P ?X) =>
70 match goal with 73 match goal with
71 | [ H : forall x, P x /\ _ |- _ ] => apply (proj1 (H X)) 74 | [ H : forall x, P x /\ _ |- _ ] => apply (proj1 (H X))
72 end. 75 end.
73 76
74 auto. 77 auto.
75 Qed. 78 Qed.
79 (* end thide *)
76 80
77 (** We see that an [Extern] pattern may bind unification variables that we use in the associated tactic. [proj1] is a function from the standard library for extracting a proof of [R] from a proof of [R /\ S]. *) 81 (** We see that an [Extern] pattern may bind unification variables that we use in the associated tactic. [proj1] is a function from the standard library for extracting a proof of [R] from a proof of [R /\ S]. *)
78 End forall_and. 82 End forall_and.
79 83
80 (** After our success on this example, we might get more ambitious and seek to generalize the hint to all possible predicates [P]. 84 (** After our success on this example, we might get more ambitious and seek to generalize the hint to all possible predicates [P].
161 165
162 Section garden_path. 166 Section garden_path.
163 Variable P : A -> Prop. 167 Variable P : A -> Prop.
164 Variable g : A -> A. 168 Variable g : A -> A.
165 Hypothesis f_g : forall x, P x -> f x = g x. 169 Hypothesis f_g : forall x, P x -> f x = g x.
170 (* begin thide *)
166 Hint Rewrite f_g using assumption : my_db. 171 Hint Rewrite f_g using assumption : my_db.
172 (* end thide *)
167 173
168 Lemma f_f_f' : forall x, f (f (f x)) = f x. 174 Lemma f_f_f' : forall x, f (f (f x)) = f x.
175 (* begin thide *)
169 intros; autorewrite with my_db; reflexivity. 176 intros; autorewrite with my_db; reflexivity.
170 Qed. 177 Qed.
178 (* end thide *)
171 179
172 (** [autorewrite] will still use [f_g] when the generated premise is among our assumptions. *) 180 (** [autorewrite] will still use [f_g] when the generated premise is among our assumptions. *)
173 181
174 Lemma f_f_f_g : forall x, P x -> f (f x) = g x. 182 Lemma f_f_f_g : forall x, P x -> f (f x) = g x.
183 (* begin thide *)
175 intros; autorewrite with my_db; reflexivity. 184 intros; autorewrite with my_db; reflexivity.
185 (* end thide *)
176 Qed. 186 Qed.
177 End garden_path. 187 End garden_path.
178 188
179 (** It can also be useful to use the [autorewrite with db in *] form, which does rewriting in hypotheses, as well as in the conclusion. *) 189 (** It can also be useful to use the [autorewrite with db in *] form, which does rewriting in hypotheses, as well as in the conclusion. *)
180 190
181 Lemma in_star : forall x y, f (f (f (f x))) = f (f y) 191 Lemma in_star : forall x y, f (f (f (f x))) = f (f y)
182 -> f x = f (f (f y)). 192 -> f x = f (f (f y)).
193 (* begin thide *)
183 intros; autorewrite with my_db in *; assumption. 194 intros; autorewrite with my_db in *; assumption.
195 (* end thide *)
184 Qed. 196 Qed.
185 197
186 End autorewrite. 198 End autorewrite.
187 199
188 200
190 202
191 (** We have already seen many examples of Ltac programs. In the rest of this chapter, we attempt to give a more principled introduction to the important features and design patterns. 203 (** We have already seen many examples of Ltac programs. In the rest of this chapter, we attempt to give a more principled introduction to the important features and design patterns.
192 204
193 One common use for [match] tactics is identification of subjects for case analysis, as we see in this tactic definition. *) 205 One common use for [match] tactics is identification of subjects for case analysis, as we see in this tactic definition. *)
194 206
207 (* begin thide *)
195 Ltac find_if := 208 Ltac find_if :=
196 match goal with 209 match goal with
197 | [ |- if ?X then _ else _ ] => destruct X 210 | [ |- if ?X then _ else _ ] => destruct X
198 end. 211 end.
212 (* end thide *)
199 213
200 (** The tactic checks if the conclusion is an [if], [destruct]ing the test expression if so. Certain classes of theorem are trivial to prove automatically with such a tactic. *) 214 (** The tactic checks if the conclusion is an [if], [destruct]ing the test expression if so. Certain classes of theorem are trivial to prove automatically with such a tactic. *)
201 215
202 Theorem hmm : forall (a b c : bool), 216 Theorem hmm : forall (a b c : bool),
203 if a 217 if a
205 then True 219 then True
206 else True 220 else True
207 else if c 221 else if c
208 then True 222 then True
209 else True. 223 else True.
224 (* begin thide *)
210 intros; repeat find_if; constructor. 225 intros; repeat find_if; constructor.
211 Qed. 226 Qed.
227 (* end thide *)
212 228
213 (** The [repeat] that we use here is called a %\textit{%#<i>#tactical#</i>#%}%, or tactic combinator. The behavior of [repeat t] is to loop through running [t], running [t] on all generated subgoals, running [t] on %\textit{%#<i>#their#</i>#%}% generated subgoals, and so on. When [t] fails at any point in this search tree, that particular subgoal is left to be handled by later tactics. Thus, it is important never to use [repeat] with a tactic that always succeeds. 229 (** The [repeat] that we use here is called a %\textit{%#<i>#tactical#</i>#%}%, or tactic combinator. The behavior of [repeat t] is to loop through running [t], running [t] on all generated subgoals, running [t] on %\textit{%#<i>#their#</i>#%}% generated subgoals, and so on. When [t] fails at any point in this search tree, that particular subgoal is left to be handled by later tactics. Thus, it is important never to use [repeat] with a tactic that always succeeds.
214 230
215 Another very useful Ltac building block is %\textit{%#<i>#context patterns#</i>#%}%. *) 231 Another very useful Ltac building block is %\textit{%#<i>#context patterns#</i>#%}%. *)
216 232
233 (* begin thide *)
217 Ltac find_if_inside := 234 Ltac find_if_inside :=
218 match goal with 235 match goal with
219 | [ |- context[if ?X then _ else _] ] => destruct X 236 | [ |- context[if ?X then _ else _] ] => destruct X
220 end. 237 end.
238 (* end thide *)
221 239
222 (** The behavior of this tactic is to find any subterm of the conclusion that is an [if] and then [destruct] the test expression. This version subsumes [find_if]. *) 240 (** The behavior of this tactic is to find any subterm of the conclusion that is an [if] and then [destruct] the test expression. This version subsumes [find_if]. *)
223 241
224 Theorem hmm' : forall (a b c : bool), 242 Theorem hmm' : forall (a b c : bool),
225 if a 243 if a
227 then True 245 then True
228 else True 246 else True
229 else if c 247 else if c
230 then True 248 then True
231 else True. 249 else True.
250 (* begin thide *)
232 intros; repeat find_if_inside; constructor. 251 intros; repeat find_if_inside; constructor.
233 Qed. 252 Qed.
253 (* end thide *)
234 254
235 (** We can also use [find_if_inside] to prove goals that [find_if] does not simplify sufficiently. *) 255 (** We can also use [find_if_inside] to prove goals that [find_if] does not simplify sufficiently. *)
236 256
237 Theorem duh2 : forall (a b : bool), 257 Theorem hmm2 : forall (a b : bool),
238 (if a then 42 else 42) = (if b then 42 else 42). 258 (if a then 42 else 42) = (if b then 42 else 42).
259 (* begin thide *)
239 intros; repeat find_if_inside; reflexivity. 260 intros; repeat find_if_inside; reflexivity.
240 Qed. 261 Qed.
262 (* end thide *)
241 263
242 (** Many decision procedures can be coded in Ltac via "[repeat match] loops." For instance, we can implement a subset of the functionality of [tauto]. *) 264 (** Many decision procedures can be coded in Ltac via "[repeat match] loops." For instance, we can implement a subset of the functionality of [tauto]. *)
243 265
266 (* begin thide *)
244 Ltac my_tauto := 267 Ltac my_tauto :=
245 repeat match goal with 268 repeat match goal with
246 | [ H : ?P |- ?P ] => exact H 269 | [ H : ?P |- ?P ] => exact H
247 270
248 | [ |- True ] => constructor 271 | [ |- True ] => constructor
255 278
256 | [ H1 : ?P -> ?Q, H2 : ?P |- _ ] => 279 | [ H1 : ?P -> ?Q, H2 : ?P |- _ ] =>
257 let H := fresh "H" in 280 let H := fresh "H" in
258 generalize (H1 H2); clear H1; intro H 281 generalize (H1 H2); clear H1; intro H
259 end. 282 end.
283 (* end thide *)
260 284
261 (** Since [match] patterns can share unification variables between hypothesis and conclusion patterns, it is easy to figure out when the conclusion matches a hypothesis. The [exact] tactic solves a goal completely when given a proof term of the proper type. 285 (** Since [match] patterns can share unification variables between hypothesis and conclusion patterns, it is easy to figure out when the conclusion matches a hypothesis. The [exact] tactic solves a goal completely when given a proof term of the proper type.
262 286
263 It is also trivial to implement the "introduction rules" for a few of the connectives. Implementing elimination rules is only a little more work, since we must bind a name for a hypothesis to [destruct]. 287 It is also trivial to implement the "introduction rules" for a few of the connectives. Implementing elimination rules is only a little more work, since we must bind a name for a hypothesis to [destruct].
264 288
266 290
267 Section propositional. 291 Section propositional.
268 Variables P Q R : Prop. 292 Variables P Q R : Prop.
269 293
270 Theorem propositional : (P \/ Q \/ False) /\ (P -> Q) -> True /\ Q. 294 Theorem propositional : (P \/ Q \/ False) /\ (P -> Q) -> True /\ Q.
295 (* begin thide *)
271 my_tauto. 296 my_tauto.
272 Qed. 297 Qed.
298 (* end thide *)
273 End propositional. 299 End propositional.
274 300
275 (** It was relatively easy to implement modus ponens, because we do not lose information by clearing every implication that we use. If we want to implement a similarly-complete procedure for quantifier instantiation, we need a way to ensure that a particular proposition is not already included among our hypotheses. To do that effectively, we first need to learn a bit more about the semantics of [match]. 301 (** It was relatively easy to implement modus ponens, because we do not lose information by clearing every implication that we use. If we want to implement a similarly-complete procedure for quantifier instantiation, we need a way to ensure that a particular proposition is not already included among our hypotheses. To do that effectively, we first need to learn a bit more about the semantics of [match].
276 302
277 It is tempting to assume that [match] works like it does in ML. In fact, there are a few critical differences in its behavior. One is that we may include arbitrary expressions in patterns, instead of being restricted to variables and constructors. Another is that the same variable may appear multiple times, inducing an implicit equality constraint. 303 It is tempting to assume that [match] works like it does in ML. In fact, there are a few critical differences in its behavior. One is that we may include arbitrary expressions in patterns, instead of being restricted to variables and constructors. Another is that the same variable may appear multiple times, inducing an implicit equality constraint.
283 Theorem m1 : True. 309 Theorem m1 : True.
284 match goal with 310 match goal with
285 | [ |- _ ] => intro 311 | [ |- _ ] => intro
286 | [ |- True ] => constructor 312 | [ |- True ] => constructor
287 end. 313 end.
288 Qed. 314 (* begin thide *)
315 Qed.
316 (* end thide *)
289 317
290 (** The first case matches trivially, but its body tactic fails, since the conclusion does not begin with a quantifier or implication. In a similar ML match, that would mean that the whole pattern-match fails. In Coq, we backtrack and try the next pattern, which also matches. Its body tactic succeeds, so the overall tactic succeeds as well. 318 (** The first case matches trivially, but its body tactic fails, since the conclusion does not begin with a quantifier or implication. In a similar ML match, that would mean that the whole pattern-match fails. In Coq, we backtrack and try the next pattern, which also matches. Its body tactic succeeds, so the overall tactic succeeds as well.
291 319
292 The example shows how failure can move to a different pattern within a [match]. Failure can also trigger an attempt to find %\textit{%#<i>#a different way of matching a single pattern#</i>#%}%. Consider another example: *) 320 The example shows how failure can move to a different pattern within a [match]. Failure can also trigger an attempt to find %\textit{%#<i>#a different way of matching a single pattern#</i>#%}%. Consider another example: *)
293 321
302 Q 330 Q
303 ]] 331 ]]
304 332
305 By applying [pose], a convenient debugging tool for "leaking information out of [match]es," we see that this [match] first tries binding [H] to [H1], which cannot be used to prove [Q]. Nonetheless, the following variation on the tactic succeeds at proving the goal: *) 333 By applying [pose], a convenient debugging tool for "leaking information out of [match]es," we see that this [match] first tries binding [H] to [H1], which cannot be used to prove [Q]. Nonetheless, the following variation on the tactic succeeds at proving the goal: *)
306 334
335 (* begin thide *)
307 match goal with 336 match goal with
308 | [ H : _ |- _ ] => exact H 337 | [ H : _ |- _ ] => exact H
309 end. 338 end.
310 Qed. 339 Qed.
340 (* end thide *)
311 341
312 (** The tactic first unifies [H] with [H1], as before, but [exact H] fails in that case, so the tactic engine searches for more possible values of [H]. Eventually, it arrives at the correct value, so that [exact H] and the overall tactic succeed. *) 342 (** The tactic first unifies [H] with [H1], as before, but [exact H] fails in that case, so the tactic engine searches for more possible values of [H]. Eventually, it arrives at the correct value, so that [exact H] and the overall tactic succeed. *)
313 343
314 (** Now we are equipped to implement a tactic for checking that a proposition is not among our hypotheses: *) 344 (** Now we are equipped to implement a tactic for checking that a proposition is not among our hypotheses: *)
315 345
346 (* begin thide *)
316 Ltac notHyp P := 347 Ltac notHyp P :=
317 match goal with 348 match goal with
318 | [ _ : P |- _ ] => fail 1 349 | [ _ : P |- _ ] => fail 1
319 | _ => 350 | _ =>
320 match P with 351 match P with
321 | ?P1 /\ ?P2 => first [ notHyp P1 | notHyp P2 | fail 2 ] 352 | ?P1 /\ ?P2 => first [ notHyp P1 | notHyp P2 | fail 2 ]
322 | _ => idtac 353 | _ => idtac
323 end 354 end
324 end. 355 end.
356 (* end thide *)
325 357
326 (** We use the equality checking that is built into pattern-matching to see if there is a hypothesis that matches the proposition exactly. If so, we use the [fail] tactic. Without arguments, [fail] signals normal tactic failure, as you might expect. When [fail] is passed an argument [n], [n] is used to count outwards through the enclosing cases of backtracking search. In this case, [fail 1] says "fail not just in this pattern-matching branch, but for the whole [match]." The second case will never be tried when the [fail 1] is reached. 358 (** We use the equality checking that is built into pattern-matching to see if there is a hypothesis that matches the proposition exactly. If so, we use the [fail] tactic. Without arguments, [fail] signals normal tactic failure, as you might expect. When [fail] is passed an argument [n], [n] is used to count outwards through the enclosing cases of backtracking search. In this case, [fail 1] says "fail not just in this pattern-matching branch, but for the whole [match]." The second case will never be tried when the [fail 1] is reached.
327 359
328 This second case, used when [P] matches no hypothesis, checks if [P] is a conjunction. Other simplifications may have split conjunctions into their component formulas, so we need to check that at least one of those components is also not represented. To achieve this, we apply the [first] tactical, which takes a list of tactics and continues down the list until one of them does not fail. The [fail 2] at the end says to [fail] both the [first] and the [match] wrapped around it. 360 This second case, used when [P] matches no hypothesis, checks if [P] is a conjunction. Other simplifications may have split conjunctions into their component formulas, so we need to check that at least one of those components is also not represented. To achieve this, we apply the [first] tactical, which takes a list of tactics and continues down the list until one of them does not fail. The [fail 2] at the end says to [fail] both the [first] and the [match] wrapped around it.
329 361
330 The body of the [?P1 /\ ?P2] case guarantees that, if it is reached, we either succeed completely or fail completely. Thus, if we reach the wildcard case, [P] is not a conjunction. We use [idtac], a tactic that would be silly to apply on its own, since its effect is to succeed at doing nothing. Nonetheless, [idtac] is a useful placeholder for cases like what we see here. 362 The body of the [?P1 /\ ?P2] case guarantees that, if it is reached, we either succeed completely or fail completely. Thus, if we reach the wildcard case, [P] is not a conjunction. We use [idtac], a tactic that would be silly to apply on its own, since its effect is to succeed at doing nothing. Nonetheless, [idtac] is a useful placeholder for cases like what we see here.
331 363
332 With the non-presence check implemented, it is easy to build a tactic that takes as input a proof term and adds its conclusion as a new hypothesis, only if that conclusion is not already present, failing otherwise. *) 364 With the non-presence check implemented, it is easy to build a tactic that takes as input a proof term and adds its conclusion as a new hypothesis, only if that conclusion is not already present, failing otherwise. *)
333 365
366 (* begin thide *)
334 Ltac extend pf := 367 Ltac extend pf :=
335 let t := type of pf in 368 let t := type of pf in
336 notHyp t; generalize pf; intro. 369 notHyp t; generalize pf; intro.
370 (* end thide *)
337 371
338 (** We see the useful [type of] operator of Ltac. This operator could not be implemented in Gallina, but it is easy to support in Ltac. We end up with [t] bound to the type of [pf]. We check that [t] is not already present. If so, we use a [generalize]/[intro] combo to add a new hypothesis proved by [pf]. 372 (** We see the useful [type of] operator of Ltac. This operator could not be implemented in Gallina, but it is easy to support in Ltac. We end up with [t] bound to the type of [pf]. We check that [t] is not already present. If so, we use a [generalize]/[intro] combo to add a new hypothesis proved by [pf].
339 373
340 With these tactics defined, we can write a tactic [completer] for adding to the context all consequences of a set of simple first-order formulas. *) 374 With these tactics defined, we can write a tactic [completer] for adding to the context all consequences of a set of simple first-order formulas. *)
341 375
376 (* begin thide *)
342 Ltac completer := 377 Ltac completer :=
343 repeat match goal with 378 repeat match goal with
344 | [ |- _ /\ _ ] => constructor 379 | [ |- _ /\ _ ] => constructor
345 | [ H : _ /\ _ |- _ ] => destruct H 380 | [ H : _ /\ _ |- _ ] => destruct H
346 | [ H : ?P -> ?Q, H' : ?P |- _ ] => 381 | [ H : ?P -> ?Q, H' : ?P |- _ ] =>
348 | [ |- forall x, _ ] => intro 383 | [ |- forall x, _ ] => intro
349 384
350 | [ H : forall x, ?P x -> _, H' : ?P ?X |- _ ] => 385 | [ H : forall x, ?P x -> _, H' : ?P ?X |- _ ] =>
351 extend (H X H') 386 extend (H X H')
352 end. 387 end.
388 (* end thide *)
353 389
354 (** We use the same kind of conjunction and implication handling as previously. Note that, since [->] is the special non-dependent case of [forall], the fourth rule handles [intro] for implications, too. 390 (** We use the same kind of conjunction and implication handling as previously. Note that, since [->] is the special non-dependent case of [forall], the fourth rule handles [intro] for implications, too.
355 391
356 In the fifth rule, when we find a [forall] fact [H] with a premise matching one of our hypotheses, we add the appropriate instantiation of [H]'s conclusion, if we have not already added it. 392 In the fifth rule, when we find a [forall] fact [H] with a premise matching one of our hypotheses, we add the appropriate instantiation of [H]'s conclusion, if we have not already added it.
357 393
363 399
364 Hypothesis H1 : forall x, P x -> Q x /\ R x. 400 Hypothesis H1 : forall x, P x -> Q x /\ R x.
365 Hypothesis H2 : forall x, R x -> S x. 401 Hypothesis H2 : forall x, R x -> S x.
366 402
367 Theorem fo : forall x, P x -> S x. 403 Theorem fo : forall x, P x -> S x.
404 (* begin thide *)
368 completer. 405 completer.
369 (** [[ 406 (** [[
370 407
371 x : A 408 x : A
372 H : P x 409 H : P x
377 S x 414 S x
378 ]] *) 415 ]] *)
379 416
380 assumption. 417 assumption.
381 Qed. 418 Qed.
419 (* end thide *)
382 End firstorder. 420 End firstorder.
383 421
384 (** We narrowly avoided a subtle pitfall in our definition of [completer]. Let us try another definition that even seems preferable to the original, to the untrained eye. *) 422 (** We narrowly avoided a subtle pitfall in our definition of [completer]. Let us try another definition that even seems preferable to the original, to the untrained eye. *)
385 423
424 (* begin thide *)
386 Ltac completer' := 425 Ltac completer' :=
387 repeat match goal with 426 repeat match goal with
388 | [ |- _ /\ _ ] => constructor 427 | [ |- _ /\ _ ] => constructor
389 | [ H : _ /\ _ |- _ ] => destruct H 428 | [ H : _ /\ _ |- _ ] => destruct H
390 | [ H : ?P -> _, H' : ?P |- _ ] => 429 | [ H : ?P -> _, H' : ?P |- _ ] =>
392 | [ |- forall x, _ ] => intro 431 | [ |- forall x, _ ] => intro
393 432
394 | [ H : forall x, ?P x -> _, H' : ?P ?X |- _ ] => 433 | [ H : forall x, ?P x -> _, H' : ?P ?X |- _ ] =>
395 extend (H X H') 434 extend (H X H')
396 end. 435 end.
436 (* end thide *)
397 437
398 (** The only difference is in the modus ponens rule, where we have replaced an unused unification variable [?Q] with a wildcard. Let us try our example again with this version: *) 438 (** The only difference is in the modus ponens rule, where we have replaced an unused unification variable [?Q] with a wildcard. Let us try our example again with this version: *)
399 439
400 Section firstorder'. 440 Section firstorder'.
401 Variable A : Set. 441 Variable A : Set.
403 443
404 Hypothesis H1 : forall x, P x -> Q x /\ R x. 444 Hypothesis H1 : forall x, P x -> Q x /\ R x.
405 Hypothesis H2 : forall x, R x -> S x. 445 Hypothesis H2 : forall x, R x -> S x.
406 446
407 Theorem fo' : forall x, P x -> S x. 447 Theorem fo' : forall x, P x -> S x.
448 (* begin thide *)
408 (** [[ 449 (** [[
409 450
410 completer'. 451 completer'.
411 452
412 Coq loops forever at this point. What went wrong? *) 453 Coq loops forever at this point. What went wrong? *)
413 Abort. 454 Abort.
455 (* end thide *)
414 End firstorder'. 456 End firstorder'.
415 457
416 (** A few examples should illustrate the issue. Here we see a [match]-based proof that works fine: *) 458 (** A few examples should illustrate the issue. Here we see a [match]-based proof that works fine: *)
417 459
418 Theorem t1 : forall x : nat, x = x. 460 Theorem t1 : forall x : nat, x = x.
419 match goal with 461 match goal with
420 | [ |- forall x, _ ] => trivial 462 | [ |- forall x, _ ] => trivial
421 end. 463 end.
422 Qed. 464 (* begin thide *)
465 Qed.
466 (* end thide *)
423 467
424 (** This one fails. *) 468 (** This one fails. *)
425 469
470 (* begin thide *)
426 Theorem t1' : forall x : nat, x = x. 471 Theorem t1' : forall x : nat, x = x.
427 (** [[ 472 (** [[
428 473
429 match goal with 474 match goal with
430 | [ |- forall x, ?P ] => trivial 475 | [ |- forall x, ?P ] => trivial
432 477
433 [[ 478 [[
434 User error: No matching clauses for match goal 479 User error: No matching clauses for match goal
435 ]] *) 480 ]] *)
436 Abort. 481 Abort.
482 (* end thide *)
437 483
438 (** The problem is that unification variables may not contain locally-bound variables. In this case, [?P] would need to be bound to [x = x], which contains the local quantified variable [x]. By using a wildcard in the earlier version, we avoided this restriction. 484 (** The problem is that unification variables may not contain locally-bound variables. In this case, [?P] would need to be bound to [x = x], which contains the local quantified variable [x]. By using a wildcard in the earlier version, we avoided this restriction.
439 485
440 The Coq 8.2 release includes a special pattern form for a unification variable with an explicit set of free variables. That unification variable is then bound to a function from the free variables to the "real" value. In Coq 8.1 and earlier, there is no such workaround. 486 The Coq 8.2 release includes a special pattern form for a unification variable with an explicit set of free variables. That unification variable is then bound to a function from the free variables to the "real" value. In Coq 8.1 and earlier, there is no such workaround.
441 487
442 No matter which version you use, it is important to be aware of this restriction. As we have alluded to, the restriction is the culprit behind the infinite-looping behavior of [completer']. We unintentionally match quantified facts with the modus ponens rule, circumventing the "already present" check and leading to different behavior. *) 488 No matter which version you use, it is important to be aware of this restriction. As we have alluded to, the restriction is the culprit behind the infinite-looping behavior of [completer']. We unintentionally match quantified facts with the modus ponens rule, circumventing the "already present" check and leading to different behavior. *)
443 489
444 490
445 (** * Functional Programming in Ltac *) 491 (** * Functional Programming in Ltac *)
492
493 (* EX: Write a list length function in Ltac. *)
446 494
447 (** Ltac supports quite convenient functional programming, with a Lisp-with-syntax kind of flavor. However, there are a few syntactic conventions involved in getting programs to be accepted. The Ltac syntax is optimized for tactic-writing, so one has to deal with some inconveniences in writing more standard functional programs. 495 (** Ltac supports quite convenient functional programming, with a Lisp-with-syntax kind of flavor. However, there are a few syntactic conventions involved in getting programs to be accepted. The Ltac syntax is optimized for tactic-writing, so one has to deal with some inconveniences in writing more standard functional programs.
448 496
449 To illustrate, let us try to write a simple list length function. We start out writing it just like in Gallina, simply replacing [Fixpoint] (and its annotations) with [Ltac]. 497 To illustrate, let us try to write a simple list length function. We start out writing it just like in Gallina, simply replacing [Fixpoint] (and its annotations) with [Ltac].
450 498
472 Error: The reference S was not found in the current environment 520 Error: The reference S was not found in the current environment
473 ]] 521 ]]
474 522
475 The problem is that Ltac treats the expression [S (length ls')] as an invocation of a tactic [S] with argument [length ls']. We need to use a special annotation to "escape into" the Gallina parsing nonterminal. *) 523 The problem is that Ltac treats the expression [S (length ls')] as an invocation of a tactic [S] with argument [length ls']. We need to use a special annotation to "escape into" the Gallina parsing nonterminal. *)
476 524
525 (* begin thide *)
477 Ltac length ls := 526 Ltac length ls :=
478 match ls with 527 match ls with
479 | nil => O 528 | nil => O
480 | _ :: ?ls' => constr:(S (length ls')) 529 | _ :: ?ls' => constr:(S (length ls'))
481 end. 530 end.
514 n := 3 : nat 563 n := 3 : nat
515 ============================ 564 ============================
516 False 565 False
517 ]] *) 566 ]] *)
518 Abort. 567 Abort.
568 (* end thide *)
569
570 (* EX: Write a list map function in Ltac. *)
519 571
520 (** We can also use anonymous function expressions and local function definitions in Ltac, as this example of a standard list [map] function shows. *) 572 (** We can also use anonymous function expressions and local function definitions in Ltac, as this example of a standard list [map] function shows. *)
521 573
574 (* begin thide *)
522 Ltac map T f := 575 Ltac map T f :=
523 let rec map' ls := 576 let rec map' ls :=
524 match ls with 577 match ls with
525 | nil => constr:(@nil T) 578 | nil => constr:(@nil T)
526 | ?x :: ?ls' => 579 | ?x :: ?ls' =>
542 l := (1, 1) :: (2, 2) :: (3, 3) :: nil : list (nat * nat) 595 l := (1, 1) :: (2, 2) :: (3, 3) :: nil : list (nat * nat)
543 ============================ 596 ============================
544 False 597 False
545 ]] *) 598 ]] *)
546 Abort. 599 Abort.
600 (* end thide *)
547 601
548 602
549 (** * Recursive Proof Search *) 603 (** * Recursive Proof Search *)
550 604
551 (** Deciding how to instantiate quantifiers is one of the hardest parts of automated first-order theorem proving. For a given problem, we can consider all possible bounded-length sequences of quantifier instantiations, applying only propositional reasoning at the end. This is probably a bad idea for almost all goals, but it makes for a nice example of recursive proof search procedures in Ltac. 605 (** Deciding how to instantiate quantifiers is one of the hardest parts of automated first-order theorem proving. For a given problem, we can consider all possible bounded-length sequences of quantifier instantiations, applying only propositional reasoning at the end. This is probably a bad idea for almost all goals, but it makes for a nice example of recursive proof search procedures in Ltac.
552 606
553 We can consider the maximum "dependency chain" length for a first-order proof. We define the chain length for a hypothesis to be 0, and the chain length for an instantiation of a quantified fact to be one greater than the length for that fact. The tactic [inster n] is meant to try all possible proofs with chain length at most [n]. *) 607 We can consider the maximum "dependency chain" length for a first-order proof. We define the chain length for a hypothesis to be 0, and the chain length for an instantiation of a quantified fact to be one greater than the length for that fact. The tactic [inster n] is meant to try all possible proofs with chain length at most [n]. *)
554 608
609 (* begin thide *)
555 Ltac inster n := 610 Ltac inster n :=
556 intuition; 611 intuition;
557 match n with 612 match n with
558 | S ?n' => 613 | S ?n' =>
559 match goal with 614 match goal with
560 | [ H : forall x : ?T, _, x : ?T |- _ ] => generalize (H x); inster n' 615 | [ H : forall x : ?T, _, x : ?T |- _ ] => generalize (H x); inster n'
561 end 616 end
562 end. 617 end.
618 (* end thide *)
563 619
564 (** [inster] begins by applying propositional simplification. Next, it checks if any chain length remains. If so, it tries all possible ways of instantiating quantified hypotheses with properly-typed local variables. It is critical to realize that, if the recursive call [inster n'] fails, then the [match goal] just seeks out another way of unifying its pattern against proof state. Thus, this small amount of code provides an elegant demonstration of how backtracking [match] enables exhaustive search. 620 (** [inster] begins by applying propositional simplification. Next, it checks if any chain length remains. If so, it tries all possible ways of instantiating quantified hypotheses with properly-typed local variables. It is critical to realize that, if the recursive call [inster n'] fails, then the [match goal] just seeks out another way of unifying its pattern against proof state. Thus, this small amount of code provides an elegant demonstration of how backtracking [match] enables exhaustive search.
565 621
566 We can verify the efficacy of [inster] with two short examples. The built-in [firstorder] tactic (with no extra arguments) is able to prove the first but not the second. *) 622 We can verify the efficacy of [inster] with two short examples. The built-in [firstorder] tactic (with no extra arguments) is able to prove the first but not the second. *)
567 623
647 imp. 703 imp.
648 Qed. 704 Qed.
649 705
650 (** The first order of business in crafting our [matcher] tactic will be auxiliary support for searching through formula trees. The [search_prem] tactic implements running its tactic argument [tac] on every subformula of an [imp] premise. As it traverses a tree, [search_prem] applies some of the above lemmas to rewrite the goal to bring different subformulas to the head of the goal. That is, for every subformula [P] of the implication premise, we want [P] to "have a turn," where the premise is rearranged into the form [P /\ Q] for some [Q]. The tactic [tac] should expect to see a goal in this form and focus its attention on the first conjunct of the premise. *) 706 (** The first order of business in crafting our [matcher] tactic will be auxiliary support for searching through formula trees. The [search_prem] tactic implements running its tactic argument [tac] on every subformula of an [imp] premise. As it traverses a tree, [search_prem] applies some of the above lemmas to rewrite the goal to bring different subformulas to the head of the goal. That is, for every subformula [P] of the implication premise, we want [P] to "have a turn," where the premise is rearranged into the form [P /\ Q] for some [Q]. The tactic [tac] should expect to see a goal in this form and focus its attention on the first conjunct of the premise. *)
651 707
708 (* begin thide *)
652 Ltac search_prem tac := 709 Ltac search_prem tac :=
653 let rec search P := 710 let rec search P :=
654 tac 711 tac
655 || (apply and_True_prem; tac) 712 || (apply and_True_prem; tac)
656 || match P with 713 || match P with
729 intros; 786 intros;
730 repeat search_prem ltac:(apply False_prem || (apply ex_prem; intro)); 787 repeat search_prem ltac:(apply False_prem || (apply ex_prem; intro));
731 repeat search_conc ltac:(apply True_conc || eapply ex_conc 788 repeat search_conc ltac:(apply True_conc || eapply ex_conc
732 || search_prem ltac:(apply Match)); 789 || search_prem ltac:(apply Match));
733 try apply imp_True. 790 try apply imp_True.
791 (* end thide *)
734 792
735 (** Our tactic succeeds at proving a simple example. *) 793 (** Our tactic succeeds at proving a simple example. *)
736 794
737 Theorem t2 : forall P Q : Prop, 795 Theorem t2 : forall P Q : Prop,
738 Q /\ (P /\ False) /\ P --> P /\ Q. 796 Q /\ (P /\ False) /\ P --> P /\ Q.
785 (ex_conc (fun x0 : nat => P x0) x 843 (ex_conc (fun x0 : nat => P x0) x
786 (Match (P:=P x) (imp_True (P:=True)))))))) 844 (Match (P:=P x) (imp_True (P:=True))))))))
787 : forall (P : nat -> Prop) (Q : Prop), 845 : forall (P : nat -> Prop) (Q : Prop),
788 (exists x : nat, P x /\ Q) --> Q /\ (exists x : nat, P x) 846 (exists x : nat, P x /\ Q) --> Q /\ (exists x : nat, P x)
789 ]] *) 847 ]] *)
790
791