(* Title: HoTT/Proj.thy Author: Josh Chen Date: Jun 2018 Projection functions \fst\ and \snd\ for the dependent sum type. *) theory Proj imports HoTT_Methods Prod Sum begin consts fst :: "[Term, 'a] \ Term" ("(1fst[/_,/ _])") snd :: "[Term, 'a] \ Term" ("(1snd[/_,/ _])") section \Overloaded syntax for dependent and nondependent pairs\ overloading fst_dep \ fst fst_nondep \ fst begin definition fst_dep :: "[Term, Typefam] \ Term" where "fst_dep A B \ \<^bold>\p: (\x:A. B x). ind\<^sub>\[A,B] (\_. A) (\x y. x) p" definition fst_nondep :: "[Term, Term] \ Term" where "fst_nondep A B \ \<^bold>\p: A \ B. ind\<^sub>\[A, \_. B] (\_. A) (\x y. x) p" end overloading snd_dep \ snd snd_nondep \ snd begin definition snd_dep :: "[Term, Typefam] \ Term" where "snd_dep A B \ \<^bold>\p: (\x:A. B x). ind\<^sub>\[A,B] (\q. B (fst[A,B]`q)) (\x y. y) p" definition snd_nondep :: "[Term, Term] \ Term" where "snd_nondep A B \ \<^bold>\p: A \ B. ind\<^sub>\[A, \_. B] (\_. B) (\x y. y) p" end section \Properties\ text "Typing judgments and computation rules for the dependent and non-dependent projection functions." lemma fst_dep_type: assumes "\x:A. B x : U(i)" and "p : \x:A. B x" shows "fst[A,B]`p : A" unfolding fst_dep_def proof show "lambda (Sum A B) (ind\<^sub>\[A, B] (\_. A) (\x y. x)) : (\x:A. B x) \ A" proof show "Sum A B : U(i)" by (rule assms) show "\p. p : Sum A B \ ind\<^sub>\[A, B] (\_. A) (\x y. x) p : A" proof show "A : U(i)" using assms(1) .. qed qed qed (rule assms) lemma fst_dep_comp: assumes "A : U(i)" and "B: A \ U(i)" and "a : A" and "b : B a" shows "fst[A,B]`(a,b) \ a" unfolding fst_dep_def proof (subst comp) show "\x. x : Sum A B \ ind\<^sub>\[A, B] (\_. A) (\x y. x) x : A" by (standard, rule assms(1), assumption+) show "(a,b) : Sum A B" using assms(2-4) .. show "ind\<^sub>\[A, B] (\_. A) (\x y. x) (a, b) \ a" proof oops \ \ (* Old proof *) proof - have "fst[A,B]`(a,b) \ indSum[A,B] (\_. A) (\x y. x) (a,b)" by (derive lems: assms unfolds: fst_dep_def) also have "indSum[A,B] (\_. A) (\x y. x) (a,b) \ a" by (derive lems: assms) finally show "fst[A,B]`(a,b) \ a" . qed \ \ \ (* Old lemma *) text "In proving results about the second dependent projection function we often use the following lemma." lemma lem: assumes "B: A \ U" and "x : A" and "y : B x" shows "y : B (fst[A,B]`(x,y))" proof - have "fst[A,B]`(x,y) \ x" using assms by (rule fst_dep_comp) then show "y : B (fst[A,B]`(x,y))" using assms by simp qed \ lemma snd_dep_type: assumes "\x:A. B x : U(i)" and "p : \x:A. B x" shows "snd[A,B]`p : B (fst[A,B]`p)" unfolding fst_dep_def snd_dep_def by (simplify lems: assms) \ \ (* Old proof *) proof (derive lems: assms unfolds: snd_dep_def) show "fst[A, B] : (\x:A. B x) \ A" by (derive lems: assms unfolds: fst_dep_def) fix x y assume asm: "x : A" "y : B x" have "B: A \ U" by (wellformed jdgmt: assms) then show "y : B (fst[A, B]`(x,y))" using asm by (rule lem) qed (assumption | rule assms)+ \ lemma snd_dep_comp: assumes "A : U(i)" and "B: A \ U(i)" and "a : A" and "b : B a" shows "snd[A,B]`(a,b) \ b" unfolding snd_dep_def fst_dep_def by (simplify lems: assms) \ \ (* Old proof *) proof - have "snd[A,B]`(a,b) \ indSum[A, B] (\q. B (fst[A,B]`q)) (\x y. y) (a,b)" proof (derive lems: assms unfolds: snd_dep_def) show "fst[A, B] : (\x:A. B x) \ A" by (derive lems: assms unfolds: fst_dep_def) fix x y assume asm: "x : A" "y : B x" with assms(1) show "y : B (fst[A, B]`(x,y))" by (rule lem) qed (assumption | derive lems: assms)+ also have "indSum[A, B] (\q. B (fst[A,B]`q)) (\x y. y) (a,b) \ b" proof (simple lems: assms) show "fst[A, B] : (\x:A. B x) \ A" by (derive lems: assms unfolds: fst_dep_def) fix x y assume "x : A" and "y : B x" with assms(1) show "y : B (fst[A,B]`(x,y))" by (rule lem) qed (assumption | rule assms)+ finally show "snd[A,B]`(a,b) \ b" . qed \ text "Nondependent projections:" lemma fst_nondep_type: assumes "A \ B : U(i)" and "p : A \ B" shows "fst[A,B]`p : A" unfolding fst_nondep_def by (derive lems: assms) lemma fst_nondep_comp: assumes "A : U(i)" and "B : U(i)" and "a : A" and "b : B" shows "fst[A,B]`(a,b) \ a" unfolding fst_nondep_def by (simplify lems: assms) \ \ (* Old proof *) proof - have "fst[A,B]`(a,b) \ indSum[A, \_. B] (\_. A) (\x y. x) (a,b)" by (derive lems: assms unfolds: fst_nondep_def) also have "indSum[A, \_. B] (\_. A) (\x y. x) (a,b) \ a" by (derive lems: assms) finally show "fst[A,B]`(a,b) \ a" . qed \ lemma snd_nondep_type: assumes "A \ B : U(i)" and "p : A \ B" shows "snd[A,B]`p : B" unfolding snd_nondep_def by (derive lems: assms) \ \ (* Old proof *) proof show "snd[A,B] : A \ B \ B" proof (derive unfolds: snd_nondep_def) fix q assume asm: "q : A \ B" show "indSum[A, \_. B] (\_. B) (\x y. y) q : B" by (derive lems: asm) qed (wellformed jdgmt: assms)+ qed (rule assms) \ lemma snd_nondep_comp: assumes "A : U(i)" and "B : U(i)" and "a : A" and "b : B" shows "snd[A,B]`(a,b) \ b" unfolding snd_nondep_def by (simplify lems: assms) \ \ (* Old proof *) proof - have "snd[A,B]`(a,b) \ indSum[A, \_. B] (\_. B) (\x y. y) (a,b)" by (derive lems: assms unfolds: snd_nondep_def) also have "indSum[A, \_. B] (\_. B) (\x y. y) (a,b) \ b" by (derive lems: assms) finally show "snd[A,B]`(a,b) \ b" . qed \ lemmas Proj_rules [intro] = fst_dep_type snd_dep_type fst_nondep_type snd_nondep_type fst_dep_comp snd_dep_comp fst_nondep_comp snd_nondep_comp lemmas Proj_comps [comp] = fst_dep_comp snd_dep_comp fst_nondep_comp snd_nondep_comp end