(** We have defined another arbitrary notion of tree splicing, similar to before, and we can prove an analogous theorem about its relationship with tree size. We start with a useful lemma about addition. *)
(** We have defined another arbitrary notion of tree splicing, similar to before, and we can prove an analogous theorem about its relationship with tree size. We start with a useful lemma about addition. *)
(* begin thide *)
Lemma plus_S : forall n1 n2 : nat,
Lemma plus_S : forall n1 n2 : nat,
plus n1 (S n2) = S (plus n1 n2).
plus n1 (S n2) = S (plus n1 n2).
induction n1; crush.
induction n1; crush.
Qed.
Qed.
(* end thide *)
(** Now we begin the proof of the theorem, adding the lemma [plus_S] as a hint. *)
(** Now we begin the proof of the theorem, adding the lemma [plus_S] as a hint. *)
(** We know that the standard induction principle is insufficient for the task, so we need to provide a [using] clause for the [induction] tactic to specify our alternate principle. *)
(** We know that the standard induction principle is insufficient for the task, so we need to provide a [using] clause for the [induction] tactic to specify our alternate principle. *)
(** We will go into great detail on hints in a later chapter, but the only important thing to note here is that we register a pattern that describes a conclusion we expect to encounter during the proof. The pattern may contain unification variables, whose names are prefixed with question marks, and we may refer to those bound variables in a tactic that we ask to have run whenever the pattern matches.
(** We will go into great detail on hints in a later chapter, but the only important thing to note here is that we register a pattern that describes a conclusion we expect to encounter during the proof. The pattern may contain unification variables, whose names are prefixed with question marks, and we may refer to those bound variables in a tactic that we ask to have run whenever the pattern matches.
...
@@ -1022,6 +1057,7 @@ The advantage of using the hint is not very clear here, because the original pro
...
@@ -1022,6 +1057,7 @@ The advantage of using the hint is not very clear here, because the original pro
(** It can be useful to understand how tactics like [discriminate] and [injection] work, so it is worth stepping through a manual proof of each kind. We will start with a proof fit for [discriminate]. *)
(** It can be useful to understand how tactics like [discriminate] and [injection] work, so it is worth stepping through a manual proof of each kind. We will start with a proof fit for [discriminate]. *)
Theorem true_neq_false : true <> false.
Theorem true_neq_false : true <> false.
(* begin thide *)
(** We begin with the tactic [red], which is short for "onestepofreduction," to unfold the definition of logical negation. *)
(** We begin with the tactic [red], which is short for "onestepofreduction," to unfold the definition of logical negation. *)
red.
red.
...
@@ -1077,6 +1113,7 @@ We are almost done. Just how close we are to done is revealed by computational
...
@@ -1077,6 +1113,7 @@ We are almost done. Just how close we are to done is revealed by computational
trivial.
trivial.
Qed.
Qed.
(* end thide *)
(** I have no trivial automated version of this proof to suggest, beyond using [discriminate] or [congruence] in the first place.
(** I have no trivial automated version of this proof to suggest, beyond using [discriminate] or [congruence] in the first place.
...
@@ -1085,11 +1122,13 @@ Qed.
...
@@ -1085,11 +1122,13 @@ Qed.
We can perform a similar manual proof of injectivity of the constructor [S]. I leave a walk-through of the details to curious readers who want to run the proof script interactively. *)
We can perform a similar manual proof of injectivity of the constructor [S]. I leave a walk-through of the details to curious readers who want to run the proof script interactively. *)
Theorem S_inj' : forall n m : nat, S n = S m -> n = m.
Theorem S_inj' : forall n m : nat, S n = S m -> n = m.