Skip to content

Instantly share code, notes, and snippets.

@tel
Created November 19, 2012 15:03
Show Gist options
  • Save tel/4111150 to your computer and use it in GitHub Desktop.
Save tel/4111150 to your computer and use it in GitHub Desktop.
intros b c H. destruct b.
simpl in H. rewrite -> H. reflexivity. simpl in H.
(** There are no hard and fast rules for how proofs should be
formatted in Coq -- in particular, where lines should be broken
and how sections of the proof should be indented to indicate their
nested structure. However, if the places where multiple subgoals
are generated are marked with explicit [Case] tactics placed at
the beginning of lines, then the proof will be readable almost no
matter what choices are made about other aspects of layout.
This is a good place to mention one other piece of (possibly
obvious) advice about line lengths. Beginning Coq users sometimes
tend to the extremes, either writing each tactic on its own line
or entire proofs on one line. Good style lies somewhere in the
middle. In particular, one reasonable convention is to limit
yourself to 80-character lines. Lines longer than this are hard
to read and can be inconvenient to display and print. Many
editors have features that help enforce this. *)
(* ###################################################################### *)
(** * Induction *)
(** We proved above that [0] is a neutral element for [+] on
the left using a simple partial evaluation argument. The fact
that it is also a neutral element on the _right_... *)
Theorem plus_0_r_firsttry : forall n:nat,
n + 0 = n.
(** ... cannot be proved in the same simple way. Just applying
[reflexivity] doesn't work: the [n] in [n + 0] is an arbitrary
unknown number, so the [match] in the definition of [+] can't be
simplified. And reasoning by cases using [destruct n] doesn't get
us much further: the branch of the case analysis where we assume [n
= 0] goes through, but in the branch where [n = S n'] for some [n']
we get stuck in exactly the same way. We could use [destruct n'] to
get one step further, but since [n] can be arbitrarily large, if we
try to keep on going this way we'll never be done. *)
Proof.
intros n.
simpl. (* Does nothing! *)
Admitted.
(** Case analysis gets us a little further, but not all the way: *)
Theorem plus_0_r_secondtry : forall n:nat,
n + 0 = n.
Proof.
intros n. destruct n as [| n'].
Case "n = 0".
reflexivity. (* so far so good... *)
Case "n = S n'".
simpl. (* ...but here we are stuck again *)
Admitted.
(** To prove such facts -- indeed, to prove most interesting
facts about numbers, lists, and other inductively defined sets --
we need a more powerful reasoning principle: _induction_.
Recall (from high school) the principle of induction over natural
numbers: If [P(n)] is some proposition involving a natural number
[n] and we want to show that P holds for _all_ numbers [n], we can
reason like this:
- show that [P(O)] holds;
- show that, for any [n'], if [P(n')] holds, then so does
[P(S n')];
- conclude that [P(n)] holds for all [n].
In Coq, the steps are the same but the order is backwards: we
begin with the goal of proving [P(n)] for all [n] and break it
down (by applying the [induction] tactic) into two separate
subgoals: first showing [P(O)] and then showing [P(n') -> P(S
n')]. Here's how this works for the theorem we are trying to
prove at the moment: *)
Theorem plus_0_r : forall n:nat, n + 0 = n.
Proof.
intros n. induction n as [| n'].
Case "n = 0". reflexivity.
Case "n = S n'". simpl. rewrite -> IHn'. reflexivity. Qed.
(** Like [destruct], the [induction] tactic takes an [as...]
clause that specifies the names of the variables to be introduced
in the subgoals. In the first branch, [n] is replaced by [0] and
the goal becomes [0 + 0 = 0], which follows by simplification. In
the second, [n] is replaced by [S n'] and the assumption [n' + 0 =
n'] is added to the context (with the name [IHn'], i.e., the
Induction Hypothesis for [n']). The goal in this case becomes [(S
n') + 0 = S n'], which simplifies to [S (n' + 0) = S n'], which in
turn follows from the induction hypothesis. *)
Theorem minus_diag : forall n,
minus n n = 0.
Proof.
(* WORKED IN CLASS *)
intros n. induction n as [| n'].
Case "n = 0".
simpl. reflexivity.
Case "n = S n'".
simpl. rewrite -> IHn'. reflexivity. Qed.
(** **** Exercise: 2 stars, recommended (basic_induction) *)
Theorem mult_0_r : forall n:nat,
n * 0 = 0.
Proof.
intros n.
induction n
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment