(* Title: HoTT/EqualProps.thy Author: Josh Chen Date: Aug 2018 Properties of equality. *) theory EqualProps imports HoTT_Methods Equal Prod begin section \Symmetry / Path inverse\ axiomatization inv :: "Term \ Term" ("_\" [1000] 1000) where inv_def: "inv \ \p. ind\<^sub>= (\x. refl(x)) p" text " In the proof below we begin by using path induction on \p\ with the application of \rule Equal_elim\, telling Isabelle the specific substitutions to use. The proof is finished with a standard application of the relevant type rules. " lemma inv_type: assumes "A : U(i)" and "x : A" and "y : A" and "p: x =\<^sub>A y" shows "p\: y =\<^sub>A x" unfolding inv_def by (rule Equal_elim[where ?x=x and ?y=y]) (simple lem: assms) \ \The type doesn't depend on \p\ so we don't need to specify \?p\ in the \where\ clause above.\ text " The next proof requires explicitly telling Isabelle what to substitute on the RHS of the typing judgment after the initial application of the type rules. (If viewing this inside Isabelle, place the cursor after the \proof\ statement and observe the second subgoal.) " lemma inv_comp: assumes "A : U(i)" and "a : A" shows "(refl a)\ \ refl(a)" unfolding inv_def proof show "\x. x: A \ refl x: x =\<^sub>A x" .. qed (simple lem: assms) section \Transitivity / Path composition\ text " Raw composition function, of type \\x:A. \y:A. x =\<^sub>A y \ (\z:A. y =\<^sub>A z \ x =\<^sub>A z)\ polymorphic over the type \A\. " axiomatization rcompose :: Term where rcompose_def: "rcompose \ \<^bold>\x y p. ind\<^sub>= (\_. \<^bold>\z q. ind\<^sub>= (\x. refl(x)) q) p" text " More complicated proofs---the nested path inductions require more explicit step-by-step rule applications: " lemma rcompose_type: assumes "A: U(i)" shows "rcompose: \x:A. \y:A. x =\<^sub>A y \ (\z:A. y =\<^sub>A z \ x =\<^sub>A z)" unfolding rcompose_def proof fix x assume 1: "x: A" show "\<^bold>\y p. ind\<^sub>= (\_. \<^bold>\z q. ind\<^sub>= refl q) p: \y:A. x =\<^sub>A y \ (\z:A. y =\<^sub>A z \ x =\<^sub>A z)" proof fix y assume 2: "y: A" show "\<^bold>\p. ind\<^sub>= (\_. \<^bold>\z q. ind\<^sub>= refl q) p: x =\<^sub>A y \ (\z:A. y =\<^sub>A z \ x =\<^sub>A z)" proof fix p assume 3: "p: x =\<^sub>A y" show "ind\<^sub>= (\_. \<^bold>\z q. ind\<^sub>= refl q) p: \z:A. y =\<^sub>A z \ x =\<^sub>A z" proof (rule Equal_elim[where ?x=x and ?y=y]) show "\u. u: A \ \<^bold>\z q. ind\<^sub>= refl q: \z:A. u =\<^sub>A z \ u =\<^sub>A z" proof show "\u z. \u: A; z: A\ \ \<^bold>\q. ind\<^sub>= refl q: u =\<^sub>A z \ u =\<^sub>A z" proof fix u z q assume asm: "u: A" "z: A" "q: u =\<^sub>A z" show "ind\<^sub>= refl q: u =\<^sub>A z" by (rule Equal_elim[where ?x=u and ?y=z]) (simple lem: assms asm) qed (simple lem: assms) qed (rule assms) qed (simple lem: assms 1 2 3) qed (simple lem: assms 1 2) qed (rule assms) qed fact corollary assumes "A: U(i)" "x: A" "y: A" "z: A" "p: x =\<^sub>A y" "q: y =\<^sub>A z" shows "rcompose`x`y`p`z`q: x =\<^sub>A z" by (simple lem: assms rcompose_type) text " The following proof is very long, chiefly because for every application of \`\ we have to show the wellformedness of the type family appearing in the equality computation rule. " lemma rcompose_comp: assumes "A: U(i)" and "a: A" shows "rcompose`a`a`refl(a)`a`refl(a) \ refl(a)" unfolding rcompose_def proof (subst comp) { fix x assume 1: "x: A" show "\<^bold>\y p. ind\<^sub>= (\_. \<^bold>\z q. ind\<^sub>= refl q) p: \y:A. x =\<^sub>A y \ (\z:A. y =\<^sub>A z \ x =\<^sub>A z)" proof fix y assume 2: "y: A" show "\<^bold>\p. ind\<^sub>= (\_. \<^bold>\z q. ind\<^sub>= refl q) p: x =\<^sub>A y \ (\z:A. y =\<^sub>A z \ x =\<^sub>A z)" proof fix p assume 3: "p: x =\<^sub>A y" show "ind\<^sub>= (\_. \<^bold>\z q. ind\<^sub>= refl q) p: \z:A. y =\<^sub>A z \ x =\<^sub>A z" proof (rule Equal_elim[where ?x=x and ?y=y]) show "\u. u: A \ \<^bold>\z q. ind\<^sub>= refl q: \z:A. u =\<^sub>A z \ u =\<^sub>A z" proof show "\u z. \u: A; z: A\ \ \<^bold>\q. ind\<^sub>= refl q: u =\<^sub>A z \ u =\<^sub>A z" proof fix u z assume asm: "u: A" "z: A" show "\q. q: u =\<^sub>A z \ ind\<^sub>= refl q: u =\<^sub>A z" by (rule Equal_elim[where ?x=u and ?y=z]) (simple lem: assms asm) qed (simple lem: assms) qed (rule assms) qed (simple lem: assms 1 2 3) qed (simple lem: assms 1 2) qed (rule assms) } show "(\<^bold>\y p. ind\<^sub>= (\_. \<^bold>\z q. ind\<^sub>= refl q) p)`a`refl(a)`a`refl(a) \ refl(a)" proof (subst comp) { fix y assume 1: "y: A" show "\<^bold>\p. ind\<^sub>= (\_. \<^bold>\z q. ind\<^sub>= refl q) p: a =\<^sub>A y \ (\z:A. y =\<^sub>A z \ a =\<^sub>A z)" proof fix p assume 2: "p: a =\<^sub>A y" show "ind\<^sub>= (\_. \<^bold>\z q. ind\<^sub>= refl q) p: \z:A. y =\<^sub>A z \ a =\<^sub>A z" proof (rule Equal_elim[where ?x=a and ?y=y]) fix u assume 3: "u: A" show "\<^bold>\z q. ind\<^sub>= refl q: \z:A. u =[A] z \ u =[A] z" proof fix z assume 4: "z: A" show "\<^bold>\q. ind\<^sub>= refl q: u =\<^sub>A z \ u =\<^sub>A z" proof show "\q. q: u =\<^sub>A z \ ind\<^sub>= refl q: u =\<^sub>A z" by (rule Equal_elim[where ?x=u and ?y=z]) (simple lem: assms 3 4) qed (simple lem: assms 3 4) qed fact qed (simple lem: assms 1 2) qed (simple lem: assms 1) } show "(\<^bold>\p. ind\<^sub>= (\_. \<^bold>\z. \<^bold>\q. ind\<^sub>= refl q) p)`refl(a)`a`refl(a) \ refl(a)" proof (subst comp) { fix p assume 1: "p: a =\<^sub>A a" show "ind\<^sub>= (\_. \<^bold>\z. \<^bold>\q. ind\<^sub>= refl q) p: \z:A. a =\<^sub>A a \ a =\<^sub>A z" proof (rule Equal_elim[where ?x=a and ?y=a]) fix u assume 2: "u: A" show "\<^bold>\z q. ind\<^sub>= refl q: \z:A. u =\<^sub>A u\ u =\<^sub>A z" proof fix z assume 3: "z: A" show "\<^bold>\q. ind\<^sub>= refl q: u =\<^sub>A u \ u =\<^sub>A z" proof show "\q. q: u =\<^sub>A u \ ind\<^sub>= refl q: u =\<^sub>A z" by (rule Equal_elim[where ?x=u and ?y=z]) (simple lem: assms 2 3) qed (simple lem: assms 2) qed fact qed (simple lem: assms 1) } show "(ind\<^sub>=(\_. \<^bold>\z q. ind\<^sub>= refl q)(refl(a)))`a`refl(a) \ refl(a)" proof (subst comp) { fix u assume 1: "u: A" show "\<^bold>\z q. ind\<^sub>= refl q: \z:A. u =\<^sub>A u\ u =\<^sub>A z" proof fix z assume 2: "z: A" show "\<^bold>\q. ind\<^sub>= refl q: u =\<^sub>A u \ u =\<^sub>A z" proof show "\q. q: u =\<^sub>A u \ ind\<^sub>= refl q: u =\<^sub>A z" by (rule Equal_elim[where ?x=u and ?y=z]) (simple lem: assms 1 2) qed (simple lem: assms 1) qed fact } show "(\<^bold>\z q. ind\<^sub>= refl q)`a`refl(a) \ refl(a)" proof (subst comp) { fix a assume 1: "a: A" show "\<^bold>\q. ind\<^sub>= refl q: a =\<^sub>A a \ a =\<^sub>A a" proof show "\q. q: a =\<^sub>A a \ ind\<^sub>= refl q: a =\<^sub>A a" by (rule Equal_elim[where ?x=a and ?y=a]) (simple lem: assms 1) qed (simple lem: assms 1) } show "(\<^bold>\q. ind\<^sub>= refl q)`refl(a) \ refl(a)" proof (subst comp) show "\p. p: a =\<^sub>A a \ ind\<^sub>= refl p: a =\<^sub>A a" by (rule Equal_elim[where ?x=a and ?y=a]) (simple lem: assms) show "ind\<^sub>= refl (refl(a)) \ refl(a)" proof show "\x. x: A \ refl(x): x =\<^sub>A x" .. qed (simple lem: assms) qed (simple lem: assms) qed fact qed (simple lem: assms) qed (simple lem: assms) qed fact qed fact text "The raw object lambda term is cumbersome to use, so we define a simpler constant instead." axiomatization compose :: "[Term, Term] \ Term" (infixl "\" 60) where compose_def: "\ A: U(i); x: A; y: A; z: A; p: x =\<^sub>A y; q: y =\<^sub>A z \ \ p \ q \ rcompose`x`y`p`z`q" lemma compose_type: assumes "A: U(i)" "x: A" "y: A" "z: A" "p: x =\<^sub>A y" "q: y =\<^sub>A z" shows "p \ q: x =\<^sub>A z" proof (subst compose_def) show "A: U(i)" "x: A" "y: A" "z: A" "p: x =\<^sub>A y" "q: y =\<^sub>A z" by fact+ qed (simple lem: assms rcompose_type) lemma compose_comp: assumes "A : U(i)" and "a : A" shows "refl(a) \ refl(a) \ refl(a)" by (subst compose_def) (simple lem: assms rcompose_comp) lemmas EqualProps_rules [intro] = inv_type compose_type lemmas EqualProps_comps [comp] = inv_comp compose_comp end