How to read this blog
Many of the pages in this blog have Coq proofs embedded in them, like this:
even_Even_fp:forall n0 : nat, even n0 = true <-> Even n0n:nateven n = true <-> Even neven_Even_fp:forall n0 : nat, even n0 = true <-> Even n0n:nateven n = true <-> Even neven_Even_fp:forall n : nat, even n = true <-> Even neven 0 = true <-> Even 0even_Even_fp:forall n : nat, even n = true <-> Even neven 1 = true <-> Even 1even_Even_fp:forall n0 : nat, even n0 = true <-> Even n0n:nateven (S (S n)) = true <-> Even (S (S n))even_Even_fp:forall n : nat, even n = true <-> Even ntrue = true <-> Even 0even_Even_fp:forall n : nat, even n = true <-> Even nfalse = true <-> Even 1even_Even_fp:forall n0 : nat, even n0 = true <-> Even n0n:nateven n = true <-> Even (S (S n))even_Even_fp:forall n : nat, even n = true <-> Even ntrue = true <-> Even 0all: constructor.even_Even_fp:forall n : nat, even n = true <-> Even nH:true = trueEven 0even_Even_fp:forall n : nat, even n = true <-> Even nH:Even 0true = trueeven_Even_fp:forall n : nat, even n = true <-> Even nfalse = true <-> Even 1all: inversion 1.even_Even_fp:forall n : nat, even n = true <-> Even nfalse = true -> Even 1even_Even_fp:forall n : nat, even n = true <-> Even nEven 1 -> false = trueeven_Even_fp:forall n0 : nat, even n0 = true <-> Even n0n:nateven n = true <-> Even (S (S n))even_Even_fp:forall n0 : nat, even n0 = true <-> Even n0n:nateven n = true -> Even (S (S n))even_Even_fp:forall n0 : nat, even n0 = true <-> Even n0n:natEven (S (S n)) -> even n = trueeven_Even_fp:forall n0 : nat, even n0 = true <-> Even n0n:natH:even n = trueEven neven_Even_fp:forall n1 : nat, even n1 = true <-> Even n1n:natH:Even (S (S n))n0:natH1:Even nH0:n0 = neven n = trueall: assumption. Qed.even_Even_fp:forall n0 : nat, even n0 = true <-> Even n0n:natH:even n = trueeven n = trueeven_Even_fp:forall n1 : nat, even n1 = true <-> Even n1n:natH:Even (S (S n))n0:natH1:Even nH0:n0 = nEven n
Coq is a Proof Assistant that makes heavy use of tactics to create proofs. As a result, Coq proofs are usually not so readable without seeing the intermediate goals that Coq normally displays.
On this website, you'll notice small bubbles (like this ) next to some of the code. These bubbles indicate Coq fragments (sentences) that you can interact with. Try hovering over the sentences below:
Clicking on a sentence will inline Coq's output and make it persistently visible. This is convenient when comparing steps of a proof. Try it on the unnecessarily long sequence of proof steps below:
forall n : nat, 2 * sum n = n * (n + 1)forall n : nat, 2 * sum n = n * (n + 1)n:nat2 * sum n = n * (n + 1)2 * sum 0 = 0 * (0 + 1)n:natIHn:2 * sum n = n * (n + 1)2 * sum (S n) = S n * (S n + 1)reflexivity.2 * sum 0 = 0 * (0 + 1)n:natIHn:2 * sum n = n * (n + 1)2 * sum (S n) = S n * (S n + 1)n:natIHn:2 * sum n = n * (n + 1)2 * (S n + sum n) = S n * (S n + 1)n:natIHn:2 * sum n = n * (n + 1)2 * S n + 2 * sum n = S n * (S n + 1)n:natIHn:2 * sum n = n * (n + 1)2 * S n + n * (n + 1) = S n * (S n + 1)n:natIHn:2 * sum n = n * (n + 1)2 * (1 + n) + n * (n + 1) = (1 + n) * (1 + n + 1)n:natIHn:2 * sum n = n * (n + 1)2 * 1 + 2 * n + (n * n + n * 1) = 1 * 1 + n * 1 + (1 * n + n * n) + (1 * 1 + n * 1)n:natIHn:2 * sum n = n * (n + 1)1 + 1 + (n + n) + (n * n + n) = 1 + n + (n + n * n) + (1 + n)n:natIHn:2 * sum n = n * (n + 1)1 + 1 + n + n + n * n + n = 1 + n + n + n * n + 1 + nn:natIHn:2 * sum n = n * (n + 1)2 + n + n + n * n + n = 1 + n + n + n * n + 1 + nn:natIHn:2 * sum n = n * (n + 1)2 + n + n + n * n + n = 1 + 1 + n + n + n * n + nn:natIHn:2 * sum n = n * (n + 1)2 + n + n + n * n + n = 2 + n + n + n * n + nreflexivity. Qed.
One final way to interact with the proofs is using the keyboard, in a style similar to Proof General or CoqIDE. Try pressing Ctrl+↓ and Ctrl+↑; you will be taken back to the beginning of this article and shown goals and responses at each step. You can also click on a sentence while holding Ctrl (or Cmd on macOS) to focus on a given goal.
I plan to write about the system that powers this blog in the future. For now, happy hacking!