How do we go from a proof in Coq to something we might write on paper, or even show to another person? That is, how do we take a formal proof with tactics, like:

Lemma complement_involutive : forall (b : base),
    complement (complement b) = b.
Proof.
  intros b. destruct b eqn:E.
  - reflexivity.
  - reflexivity.
  - reflexivity.
  - reflexivity.
Qed.

And generate a careful "paper" proof that a human might want to look at?

Theorem: complement is involutive, i.e., $\forall b,~ \texttt{complement}(\texttt{complement}(b)) = b$.

Proof: Let a base $b$ be given; we go by cases on $b$.

QED

In the long term, you'll want to be able to write proofs without any reference to Coq or tactics at all. In the near term, however, it'll be helpful to make explicit reference to the formal proof techniques you already know. The core ideas from formal proof are directly portable to an informal, paper-proof setting; many tactics have more or less direct translations.

Transliteration vs. translation

Jewish prayer books often come with three kinds of text: the Hebrew text, its translation into English, and one more thing: a transliteration of the Hebrew into English phonetics. Transliteration lets those who can't read Hebrew sing along, even if they don't know what they're saying.

We are in the business of translation, not transliteration. There is no direct, one-to-one mapping of Coq concepts to informal proof, and Coq tactics do not belong in an informal proof. Your proof should not be a description of what happens to the context or goal, but rather some rigorous prose that should convince your readers.

We'll go through five proofs that we've done before in Coq, talking about how to translate from Coq tactics to proofs. In addition to what we show here, you should consider using the how to prove it sheet as a guide.

A note about definitions

Unless we've defined it on paper, the definitions we're reasoning about are the ones we gave in Coq. You're free to use whatever lemmas we've proved (other than the one you might be translating, naturally), but it's not okay to assert that, say, $n + S m = S (n + m)$ by definition. That equality holds, but only because we proved it---with plus_n_Sm, so be sure to reference that lemma when you do that reasoning.

If you're not sure if your reasoning is valid, please just ask!

First proof: equality is transitive

From day 11:

Theorem trans_eq : forall (X:Type) (n m o : X),
  n = m -> m = o -> n = o.
Proof.
  intros X n m o eq1 eq2. rewrite -> eq1. rewrite -> eq2.
  reflexivity.  Qed.

Theorem: Equality is transitive, i.e., $\forall n m o, n = m \wedge m = o \Rightarrow n = o$.

Translated proof: Let $n$, $m$, and $o$ be given such that $n = m$ and $m = o$. We must show that $n = o$. But since $n = m$ by our first assumption, it suffices to show $m = o$---which we have immediately by our second assumption. QED

More idiomatic proof: Let $n$, $m$, and $o$ be given such that $n = m$ and $m = o$. We have to prove that $n = o$. Substituting $o$ for $m$ in the first equation yields $n = o$, as desired. QED

Stating your goal

Coq manages your context and goal for you. In an informal proof, the reader will manage their own context and goal---but you should help them. Notice how we state the goal. It's often helpful to restate the goal every time it appears or changes.

Universal quantification a/k/a $\forall$ (intros)

Informal proofs manipulate propositions in different ways than they talk about variables.

First, note how intros corresponds to "let such-and-such be given such that so-and-so", where the "such-and-such" are the variables and the "so-and-so" are any properties about them.

Second, note how we name the variables, but omit the type (it could be anything, so it's not necessarily worth mentioning). We also leave the assumptions anonymous, using the order they were mentioned rather than names.

Using assumptions (rewrite, apply)

The first proof follows the logic in Coq closely, using backward reasoning ("it suffices to show"). The second proof works by forward reasoning, manipulating the $n = m$ assumption directly.

Closing it out

It's nice to let your readers know when you're done. Writing QED or $\square$ at the end of the proof is helpful. It's also nice to use language that recalls the goal to the reader ("as desired").

Second proof: complement is involutive

From day 12:

Lemma complement_involutive : forall (b : base),
    complement (complement b) = b.
Proof.
  intros b. destruct b eqn:E.
  - reflexivity.
  - reflexivity.
  - reflexivity.
  - reflexivity.
Qed.

Theorem: complement is involutive, i.e., $\forall b,~ \texttt{complement}(\texttt{complement}(b)) = b$.

Proof: Let a base $b$ be given; we go by cases on $b$.

QED

Not a lot would make this more idiomatic. A mathematician might abbreviate the last three cases even more, writing "similar" or "as for $C$, mutatis mutandis". (Mutatis mutandis is Latin for "changing that which needs to be changed", which is... not wrong, but not always helpful.)

Reasoning by cases (destruct)

Case analysis in proofs aligns neatly with Coq's destruct tactic. One "goes by cases on $b$" or "by cases on how $b$ was formed". If we were to test whether or not a number was even, (i.e., destruct (evenb n)), we might say, "by cases on whether or not $n$ is even".

Equational reasoning (simpl, unfold, fold, reflexivity)

Coq has a variety of tactics for computation... but that's about holding Coq's symbolic hand. Humans know what you mean much more clearly.

I particularly like the "chained equations" style used in this proof: start with a complex term, and then slowly rewrite to the thing you're interested in. Just be sure to show appropriate size steps, changing only one thing at a time in an equation.

Third proof: 0 is a right identity for addition

Theorem plus_n_O : forall n:nat, n = n + 0.
Proof.
  intros n. induction n as [| n' IHn'].
  - (* n = 0 *)    reflexivity.
  - (* n = S n' *) simpl. rewrite <- IHn'. reflexivity.  Qed.

Theorem: $\forall n \in \mathbb{N}, n = n + 0$

Proof: By induction on $n$.

Proofs by induction (induction)

Induction in informal proof more or less follows the approach in Coq. Just like in Coq, it's quite common to not bother introducing a variable you're about to do induction on.

It's not in general necessary to use outlines, though I think they make for clear proofs. In any inductive case, it's important that early on you (a) state your goal, and (b) state your IH.

It's also important that you explicitly call out your IH when you use it. It helps us for grading, but it's also signaling a key moment in your proof.

Finally, notice that we write $n = S(n')$, but it's just as well to write $n = 1+n'$ or $n=n'+1$.

Fourth proof: double is injective

Theorem double_injective : forall n m,
     double n = double m ->
     n = m.
Proof.
  intros n. induction n as [| n'].
  - intros m eq. simpl in eq. destruct m as [| m'].
    + reflexivity.
    + discriminate eq.
  - intros m eq. simpl in eq. destruct m as [| m'].
    + discriminate eq.
    + simpl in eq. injection eq as eq'. apply IHn' in eq'. rewrite eq'. reflexivity.
Qed.

Theorem: double is injective, i.e., $\forall n m \in \mathbb{N}, \mathit{double}(n) = \mathit{double}(m) \Rightarrow n = m$.

Proof: By induction on $n$, leaving $m$ general.

Cases (destruct)

Not every case needs outlines. The base case considers both possibilities for $m$, but keeps things short. The inductive case goes into more detail, but it could have dropped the outline too.

Continuing to outline is nice when there's a lot of structure in each case, but if some cases are simple (as is the case here), it's often better to keep it short.

Varying the IH (generalize dependent, intros or the lack thereof)

First, notice how we vary the IH: we simply say what we want to leave general. We introduce $m$ and the assumption explicitly in the base case, but less so in the inductive case. We are careful to state the general IH, though. Furthermore, we have the IH quantify over a variable name that suggests what we'll be doing later: applying the IH at $m'$.

Coq automatically infers instantiations for many of our quantifiers, but it's polite to help your readers out little when you can.

Equational reasoning (injection, discriminate, inversion)

Our proof freely talks about the consequences of various equalities: $0 = S(S(\dots))$ being contradictory in the base case, or canceling pairs of successors in the inductive case.

But, it's important to be careful with the phrase "it must be case": don't say it if isn't well and truly clear that it must be the case! Avoid words like "obvious" or "clearly": if it's not clear to your reader, they'll just be annoyed.

Fifth proof: In_map_iff

From day 15:

Lemma In_map_iff :
  forall (A B : Type) (f : A -> B) (l : list A) (y : B),
    In y (map f l) <->
    exists x, f x = y /\ In x l.
Proof.
  intros A B f l y. split.
  { induction l as [|x l' IHl'].
    - simpl. intros [].
    - simpl. intros [H | H].
      + exists x. split.
        * apply H.
        * left. reflexivity.
      + assert (H' : exists x', f x' = y /\ In x' l').
        { apply IHl'. apply H. }
        destruct H' as [x' [H1 H2]].
        exists x'. split.
        * apply H1.
        * right. apply H2. }
  { intros [x [H1 H2]].  induction l as [|x' l' IHl'].
  - destruct H2.
  - simpl. destruct H2 as [Heq | Hin].
    + left. rewrite Heq. apply H1.
    + right. apply IHl'. apply Hin. }
Qed.

Theorem: $y$ is in the list $\texttt{map}(f, l)$ iff there exists some $x$ in $l$ such that $f(x) = y$.

Proof: We prove each direction separately.

QED.

Informal mathematics

Constructors and functions

I prefer to use [] over $\mathit{nil}$, but both are good. Notice how I write $\texttt{map}$ like a more conventional math function, taking both of its arguments at once. Mathematicians tend to not like partial applications so much, instead opting to name whatever intermediate function they might care about.

Naming variables

The Coq proof plays fast and loose with $x$ and $x'$, but it's good to be a bit more careful in informal proofs. For one, Coq isn't checking your work, and a tiny typo can cause a lot of confusion and frustration in your reader! Choose fresh names when you it's not intrusive: since the original existential uses $x$, I'm careful to continue calling it that throughout the proof.

Talking about propositions

Finally, we don't bother using In x l at all, instead writing out the explicit phrase "$x$ is in the list $l$". Choosing words over notation leads to a proof that's a bit easier to read, but you must be careful: even if the language is informal, the definition is not. When we say "$x$ is in the list $z :: l$", we mean In x (z::l'), which is just the same as z = x \/ In x l', i.e., "$z = x$ or $x$ is in the list $l'$.

Logical reasoning (destruct, split, left, right)

Notice how various tactics play out in prose. The initial split turns into "prove each direction separately". We casually break apart existentials without much comment ("suppose there is some $x$"). We never really make explicit left or right decisions, treating the definition of In implicitly. Similarly, we just prove both parts of a conjunction as we go.

It's possible to do too little logical reasoning, though, and have your reader get confused. If you're not sure, maybe err on the side of explicitness, and we'll tell you when to back off.

Existential quantification a/k/a $\exists$ (exists)

While we aren't always explicit about logical reasoning, you must be explicit about existentials. In the first subcase of the inductive case of the left-to-right direction of the proof, the exists shows up as "we choose $z$ itself as our $x$". The second subcase is less explicit, because it reuses the exists from the IH.

Forward vs. backward reasoning (assert, replace, ... in ...)

The informal proof is almost entirely in a forward reasoning style, while most of the Coq proof reasons backwards. Some of the explicit forward reasoning that stands out in the Coq proof (assert) corresponds to entirely unremarkable phrasing in the informal proof ("our IH gives us").