(* 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\ definition inv :: "Term \ Term" ("_\" [1000] 1000) where "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 lems: 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 lems: 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\. " definition rpathcomp :: Term where "rpathcomp \ \<^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 rpathcomp_type: assumes "A: U(i)" shows "rpathcomp: \x:A. \y:A. x =\<^sub>A y \ (\z:A. y =\<^sub>A z \ x =\<^sub>A z)" unfolding rpathcomp_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 lems: assms asm) qed (simple lems: assms) qed (rule assms) qed (simple lems: assms 1 2 3) qed (simple lems: 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 "rpathcomp`x`y`p`z`q: x =\<^sub>A z" by (simple lems: assms rpathcomp_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 rpathcomp_comp: assumes "A: U(i)" and "a: A" shows "rpathcomp`a`a`refl(a)`a`refl(a) \ refl(a)" unfolding rpathcomp_def proof compute { 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 lems: assms asm) qed (simple lems: assms) qed (rule assms) qed (simple lems: assms 1 2 3) qed (simple lems: 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 compute { 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 lems: assms 3 4) qed (simple lems: assms 3 4) qed fact qed (simple lems: assms 1 2) qed (simple lems: assms 1) } show "(\<^bold>\p. ind\<^sub>= (\_. \<^bold>\z. \<^bold>\q. ind\<^sub>= refl q) p)`refl(a)`a`refl(a) \ refl(a)" proof compute { 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 lems: assms 2 3) qed (simple lems: assms 2) qed fact qed (simple lems: assms 1) } show "(ind\<^sub>=(\_. \<^bold>\z q. ind\<^sub>= refl q)(refl(a)))`a`refl(a) \ refl(a)" proof compute { 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 lems: assms 1 2) qed (simple lems: assms 1) qed fact } show "(\<^bold>\z q. ind\<^sub>= refl q)`a`refl(a) \ refl(a)" proof compute { 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 lems: assms 1) qed (simple lems: assms 1) } show "(\<^bold>\q. ind\<^sub>= refl q)`refl(a) \ refl(a)" proof compute 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 lems: assms) show "ind\<^sub>= refl (refl(a)) \ refl(a)" proof show "\x. x: A \ refl(x): x =\<^sub>A x" .. qed (simple lems: assms) qed (simple lems: assms) qed fact qed (simple lems: assms) qed (simple lems: assms) qed fact qed fact text "The raw object lambda term is cumbersome to use, so we define a simpler constant instead." axiomatization pathcomp :: "[Term, Term] \ Term" (infixl "\" 60) where pathcomp_def: "\ A: U(i); x: A; y: A; z: A; p: x =\<^sub>A y; q: y =\<^sub>A z \ \ p \ q \ rpathcomp`x`y`p`z`q" lemma pathcomp_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 pathcomp_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 lems: assms rpathcomp_type) lemma pathcomp_comp: assumes "A : U(i)" and "a : A" shows "refl(a) \ refl(a) \ refl(a)" by (subst pathcomp_def) (simple lems: assms rpathcomp_comp) lemmas EqualProps_rules [intro] = inv_type pathcomp_type lemmas EqualProps_comps [comp] = inv_comp pathcomp_comp end