Exploring equality via homotopy and proof assistants - Day 2 - Equality in Coq
Note: You may use either the lab computers, or your laptop. Coq may not be installed on the Windows computers, you should use the Macs. If the Macs do not have CoqIDE installed, you can go to https://coq.inria.fr/coq-85, download CoqIDE_8.5beta2.dmg, open it, and run CoqIDE directly, without installing it.Tautologies
We can also write the colon on a line of its own; I set up this file in this way so that I can use a large font in my presentation.
Definition first_argument
: ∀ A B, A → (B → A)
:= admit.
Definition compose
: ∀ A B C,
(A → B) → (B → C) → (A → C)
:= admit.
We can also fill in the functions bit by bit, as follows:
These two are exercises to do individually or with the people sitting next to you.
Definition introduce_intermediate
: ∀ A B C,
(A → (B → C))
→ ((A → B) → (A → C))
:= admit.
Definition swap_args
: ∀ A B C,
(A → B → C) → (B → A → C)
:= admit.
Optional Homework Problems for More Practice
Definition second_argument
: ∀ A B, A → B → B
:= admit.
Definition id_either
: ∀ A, A → A → A
:= admit.
Definition third_argument
: ∀ A B C, A → B → C → C
:= admit.
This one is a bit different; one of the arguments has a ∀
Challenge Homework Problems
Come ask me about disjunction and negation during TAU if you are interested in playing with these.
Prove that the Law of Excluded Middle implies Double Negation Elimination
Prove that Double Negation Elimination implies Peirce's Law
Prove that Peirce's Law implies the Law of Excluded Middle
Interesting question: Are all proofs of equality themselves equal? Keep this in the back of your mind as we define what equality is. To do this we need to define two notions of equality: judgmental, and propositional.
Coq knows some things about equality. If Coq judges that two things are equal (and equally trivially), then you can prove them (propositionally) equal by reflexivity, with refl. In this case, we say that they are also judgmentally equal. For example:
Propositional equality is denoted as x = y.
Definition of judgmental equality, version 1: intuitively, x and y are judgmentally equal if there is a really stupid, trivial proof that x = y.
Definition of judgmental equality, version 2: x and y are judgmentally equal if (Coq says that) refl proves x = y.
Definition one_plus_one_equals_two
: 1 + 1 = 2
:= refl.
Definition two_plus_two_equals_four
: 2 + 2 = 4
:= refl.
Definition two_times_three_equals_six
: 2 × 3 = 6
:= refl.
Just so that you don't think Coq believes everything is equal:
This gives
The command has indeed failed with message:
=> Error: The term "refl" has type "?30 = ?30"
while it is expected to have type "1 = 0".
You can see the "normal form" of something with Compute:
Definition of judgmental equality, version 3: x and y are judgmentally equal if Compute gives you the same normal form for x and y. N.B. This is equivalent to what Coq is doing internally.
Note that equality is homogeneous; the things you're comparing for equality need to already have the same type. You can ask if a statement is valid using Check:
A note on syntax
Definition id'
: ∀ A, A → A
:= admit.
Definition id''
: ∀ (A : Type), A → A
:= admit.
Definition id'''
: ∀ (A : Type) (pf : A), A
:= admit.
: ∀ A, A → A
:= admit.
Definition id''
: ∀ (A : Type), A → A
:= admit.
Definition id'''
: ∀ (A : Type) (pf : A), A
:= admit.
Pattern matching is case analysis, on things that are defined by cases (like, bool, nat). This is a technical meaning for "pattern matching" or "case analysis", namely, "using a match ... with ... end statement in Coq".
Definition is_positive : nat → bool
:= admit.
Definition is_zero : nat → bool
:= admit.
Definition If_Then_Else
: ∀ (A : Type)
(b : bool)
(true_case : A)
(false_case : A),
A
:= admit.
unit is a type with one element.
But refl does not prove that all units are equal.
But we can pattern match
This should implement the truth table for "and":
A B │ A ∧ B ────┼────── T T │ T T F │ F F T │ F F F │ F
This should implement the truth table for "or":
A B │ A ∨ B ────┼────── T T │ T T F │ T F T │ T F F │ F
This should implement the truth table for "xor":
A B │ A ⊕ B ────┼────── T T │ F T F │ T F T │ T F F │ F
This should implement the truth table for "implication":
A B │ A → B ────┼────── T T │ T T F │ F F T │ T F F │ T
This should implement the truth table for "biconditional":
A B │ A ↔ B ────┼────── T T │ T T F │ F F T │ F F F │ T
Recall: Are all proofs of equality themselves equal? Here we define what equality is, i.e., how to use it.
We can prove the J-rule by pattern matching.
We start off with the simpler version, called the "non-dependent" version.
If you want to not always have to pass all of the arguments to J explicitly, you can uncomment the following lines, removing the and , to make A, x, and y be inferred automatically.
Recall the blackboard proof of symmetry, that x = y → y = x. Someone remind me how it goes.
First prove this by passing arguments to J_nondep.
Arguments J_nondep {A} {x} {y} H P _.
Now prove this by pattern matching.
First prove this by passing arguments to J_nondep.
Definition trans_J
: ∀ A (x y z : A),
x = y → y = z → x = z
:= admit.
Arguments trans_J {A x y z} p q, A x y z p q.
Now prove this by pattern matching.
Definition trans
: ∀ A (x y z : A),
x = y → y = z → x = z
:= admit.
Arguments trans {A x y z} p q, A x y z p q.
First prove this by passing arguments to J_nondep.
Definition ap_J
: ∀ A B (f : A → B) (x y : A),
x = y → f x = f y
:= admit.
Arguments ap_J {A B} f {x y} p, {A B} f x y p, A B f x y p.
First prove this by pattern matching.
Definition ap
: ∀ A B (f : A → B) (x y : A),
x = y → f x = f y
:= admit.
Arguments ap {A B} f {x y} p, {A B} f x y p, A B f x y p.
Now the version with more bells and whistles, again provable by pattern matching.
Definition J
: ∀
(A : Type) (x : A) (y : A)
(H : x = y)
(P : ∀ (y' : A)
(H' : x = y'),
Type),
P x refl → P y H
:= admit.
Definition J_nondep_computes
: ∀ (A : Type) (x : A)
(P : A → Type)
(k : P x),
J_nondep A x x refl P k = k
:= admit.
Definition J_computes
: ∀ (A : Type) (x : A)
(P : ∀ (y' : A) (H' : x = y'), Type)
(k : P x refl),
J A x x refl P k = k
:= admit.
If you want to not always have to pass all of the arguments to J explicitly, you can uncomment the following lines, removing the and , to make A, x, and y be inferred automatically.
First prove this by passing arguments to J.
Arguments J {A} {x} {y} H P _.
Arguments J_computes {A x} P k.
Arguments J_non_computes {A x} P k.
Now prove this by pattern matching.
Exercises to do individually, or with the people next to you.
First prove this by filling in arguments to J explicitly.
Definition sym_sym_J
: ∀ A (x y : A) (H : x = y),
sym_J (sym_J H) = H
:= admit.
Arguments sym_sym_J {A x y} H, A x y H.
Now prove this by pattern matching.
Definition sym_sym
: ∀ A (x y : A) (H : x = y),
sym (sym H) = H
:= admit.
Arguments sym_sym {A x y} H, A x y H.
Definition trans_1p_J
: ∀ A (x y : A) (H : x = y),
trans_J refl H = H
:= admit.
Definition trans_1p
: ∀ A (x y : A) (H : x = y),
trans refl H = H
:= admit.
Definition trans_p1_J
: ∀ A (x y : A) (H : x = y),
trans_J H refl = H
:= admit.
Definition trans_p1
: ∀ A (x y : A) (H : x = y),
trans H refl = H
:= admit.
Definition sym_refl_J
: ∀ A (x : A),
sym_J (refl x) = refl x
:= admit.
Definition sym_refl
: ∀ A (x : A),
sym (refl x) = refl x
:= admit.
Recall the informal proof from yesterday's homework, which "proved" that all proofs of x = y are themselves equal:
The J rule says informally that if you have a proof p of x = y, it suffices to assume that y is x (to substitute x for y in what you are trying to prove), and to assume that p is refl x (to substitute refl x for p in what you are trying to prove). Suppose we have a type A, two inhabitants x and y of type A, and two proofs p and q that x = y. By J, it suffices to assume that y is x, that p is refl x, and hence it suffices to prove that refl x = q, where q now has type x = x. To prove this, again by J, it suffices to assume that x is x (it already is) and that q is refl x, and hence it suffices to prove refl x = refl x. We can prove this by refl (refl x). Thus for any proofs p and q that x = y, we have p = q. Qed.
Try to formalize this proof in Coq, and see what goes wrong. It may help to use refine so that you can construct the proof sentence by sentence. If you are having trouble figuring out how to instantiate J for a proof of equality H : x = y, you can ask Coq to figure it out for you by running destruct H.. You can see what it did by typing Show Proof. afterwards.
Definition J_implies_UIP
: ∀ A (x y : A) (H0 H1 : x = y), H0 = H1.
Proof.
refine _.
refine admit.
Abort.
The rest of these are explicitly Homework; feel free to take a break now, or to keep going.
Recall from yesterday's homework that the K rule says:
Prove that K implies uniqueness of identity proofs. If you do this interactively with refine, you may find it useful to unfold K_rule_type in × to see the definition of K in your goals window.
Note that it's impossible to prove K from J. See if you can get any insight into this by attempting to construct a proof.
Hint: Think about what these things (and UIP) mean in the paths interpretation of equality, and remember that all of our functions are continuous.
Can you write down three "different" proofs of transitivity (they should all be judgmentally different; refl should not prove any two of them the same.
Definition trans1
: ∀ A (x y z : A),
x = y → y = z → x = z
:= admit1.
Definition trans2
: ∀ A (x y z : A),
x = y → y = z → x = z
:= admit2.
Definition trans3
: ∀ A (x y z : A),
x = y → y = z → x = z
:= admit3.
Now we have Coq check that they are not the same; these lines should compile unmodified.
Fail Check refl : trans1 = trans2.
Fail Check refl : trans2 = trans3.
Fail Check refl : trans1 = trans3.
Now prove that these are all equal (propositionally, but not judgmentally.
Definition trans_12
: ∀ A (x y z : A) (H0 : x = y) (H1 : y = z),
trans1 A x y z H0 H1 = trans2 A x y z H0 H1
:= admit.
Definition trans_23
: ∀ A (x y z : A) (H0 : x = y) (H1 : y = z),
trans2 A x y z H0 H1 = trans3 A x y z H0 H1
:= admit.
We can also prove associativity.
Definition trans_assoc
: ∀ A (x y z w : A) (H0 : x = y) (H1 : y = z) (H2 : z = w),
trans H0 (trans H1 H2) = trans (trans H0 H1) H2
:= admit.
Definition trans_Vp
: ∀ A (x y : A) (H : x = y),
trans (sym H) H = refl
:= admit.
Definition trans_sym
: ∀ A (x y z : A) (H0 : x = y) (H1 : y = z),
sym (trans H0 H1) = trans (sym H1) (sym H0)
:= admit.
Category theory
Action on composition:
Definition ap_trans
: ∀ {A B} (f : A → B) {x y z : A}
(H0 : x = y) (H1 : y = z),
ap f (trans H0 H1) = trans (ap f H0) (ap f H1)
:= admit.
Action on inverses (additional rule for groupoids):
Definition ap_sym
: ∀ {A B} (f : A → B) {x y : A}
(H : x = y),
ap f (sym H) = sym (ap f H)
:= admit.
Furthermore, every function that specifies the action of a natural transformation on objects is automatically natural:
Definition concat_Ap
: ∀ {A B} (f g : A → B)
(T : ∀ x, f x = g x),
∀ {x y : A} (m : x = y),
trans (ap f m) (T y) = trans (T x) (ap g m)
:= admit.