theory HoTT imports Pure begin section \Setup\ text "For ML files, routines and setup." section \Basic definitions\ text "A single meta-level type \Term\ suffices to implement the object-level types and terms. We do not implement universes, but simply follow the informal notation in the HoTT book." typedecl Term section \Judgments\ consts is_a_type :: "Term \ prop" ("(_ : U)" [0] 1000) is_of_type :: "[Term, Term] \ prop" ("(3_ :/ _)" [0, 0] 1000) section \Definitional equality\ text "We take the meta-equality \\\, defined by the Pure framework for any of its terms, and use it additionally for definitional/judgmental equality of types and terms in our theory. Note that the Pure framework already provides axioms and results for various properties of \\\, which we make use of and extend where necessary." theorem equal_types: assumes "A \ B" and "A : U" shows "B : U" using assms by simp theorem equal_type_element: assumes "A \ B" and "x : A" shows "x : B" using assms by simp lemmas type_equality [intro, simp] = equal_types equal_types[rotated] equal_type_element equal_type_element[rotated] section \Type families\ text "Type families are implemented using meta-level lambda expressions \P::Term \ Term\ that further satisfy the following property." abbreviation is_type_family :: "[Term \ Term, Term] \ prop" ("(3_:/ _ \ U)") where "P: A \ U \ (\x::Term. x : A \ P(x) : U)" section \Types\ subsection \Dependent function/product\ axiomatization Prod :: "[Term, Term \ Term] \ Term" and lambda :: "[Term, Term \ Term] \ Term" syntax "_PROD" :: "[idt, Term, Term] \ Term" ("(3\_:_./ _)" 30) "_LAMBDA" :: "[idt, Term, Term] \ Term" ("(3\<^bold>\_:_./ _)" 30) "_PROD_ASCII" :: "[idt, Term, Term] \ Term" ("(3PROD _:_./ _)" 30) "_LAMBDA_ASCII" :: "[idt, Term, Term] \ Term" ("(3%%_:_./ _)" 30) translations "\x:A. B" \ "CONST Prod A (\x. B)" "\<^bold>\x:A. b" \ "CONST lambda A (\x. b)" "PROD x:A. B" \ "CONST Prod A (\x. B)" "%%x:A. b" \ "CONST lambda A (\x. b)" (* The above syntax translations bind the x in the expressions B, b. *) abbreviation Function :: "[Term, Term] \ Term" (infixr "\" 40) where "A\B \ \_:A. B" axiomatization appl :: "[Term, Term] \ Term" (infixl "`" 60) where Prod_form: "\(A::Term) (B::Term \ Term). \A : U; B : A \ U\ \ \x:A. B(x) : U" and Prod_intro [intro]: "\(A::Term) (B::Term \ Term) (b::Term \ Term). (\x::Term. x : A \ b(x) : B(x)) \ \<^bold>\x:A. b(x) : \x:A. B(x)" and Prod_elim [elim]: "\(A::Term) (B::Term \ Term) (f::Term) (a::Term). \f : \x:A. B(x); a : A\ \ f`a : B(a)" and Prod_comp [simp]: "\(A::Term) (b::Term \ Term) (a::Term). a : A \ (\<^bold>\x:A. b(x))`a \ b(a)" and Prod_uniq [simp]: "\A f::Term. \<^bold>\x:A. (f`x) \ f" lemmas Prod_formation [intro] = Prod_form Prod_form[rotated] text "Note that the syntax \\<^bold>\\ (bold lambda) used for dependent functions clashes with the proof term syntax (cf. \
2.5.2 of the Isabelle/Isar Implementation)." subsection \Dependent pair/sum\ axiomatization Sum :: "[Term, Term \ Term] \ Term" syntax "_SUM" :: "[idt, Term, Term] \ Term" ("(3\_:_./ _)" 20) "_SUM_ASCII" :: "[idt, Term, Term] \ Term" ("(3SUM _:_./ _)" 20) translations "\x:A. B" \ "CONST Sum A (\x. B)" "SUM x:A. B" \ "CONST Sum A (\x. B)" abbreviation Pair :: "[Term, Term] \ Term" (infixr "\" 50) where "A\B \ \_:A. B" axiomatization pair :: "[Term, Term] \ Term" ("(1'(_,/ _'))") and indSum :: "(Term \ Term) \ Term" where Sum_form: "\(A::Term) (B::Term \ Term). \A : U; B: A \ U\ \ \x:A. B(x) : U" and Sum_intro [intro]: "\(A::Term) (B::Term \ Term) (a::Term) (b::Term). \a : A; b : B(a)\ \ (a, b) : \x:A. B(x)" and Sum_elim [elim]: "\(A::Term) (B::Term \ Term) (C::Term \ Term) (f::Term) (p::Term). \C: \x:A. B(x) \ U; f : \x:A. \y:B(x). C((x,y)); p : \x:A. B(x)\ \ indSum(C)`f`p : C(p)" and Sum_comp [simp]: "\(C::Term \ Term) (f::Term) (a::Term) (b::Term). indSum(C)`f`(a,b) \ f`a`b" lemmas Sum_formation [intro] = Sum_form Sum_form[rotated] text "We choose to formulate the elimination rule by using the object-level function type and function application as much as possible. Hence only the type family \C\ is left as a meta-level argument to the inductor indSum." subsubsection \Projections\ consts fst :: "[Term, 'a] \ Term" ("(1fst[/_,/ _])") snd :: "[Term, 'a] \ Term" ("(1snd[/_,/ _])") overloading fst_dep \ fst snd_dep \ snd fst_nondep \ fst snd_nondep \ snd begin definition fst_dep :: "[Term, Term \ Term] \ Term" where "fst_dep A B \ indSum(\_. A)`(\<^bold>\x:A. \<^bold>\y:B(x). x)" definition snd_dep :: "[Term, Term \ Term] \ Term" where "snd_dep A B \ indSum(\_. A)`(\<^bold>\x:A. \<^bold>\y:B(x). y)" definition fst_nondep :: "[Term, Term] \ Term" where "fst_nondep A B \ indSum(\_. A)`(\<^bold>\x:A. \<^bold>\y:B. x)" definition snd_nondep :: "[Term, Term] \ Term" where "snd_nondep A B \ indSum(\_. A)`(\<^bold>\x:A. \<^bold>\y:B. y)" end lemma fst_dep_comp: "\a : A; b : B(a)\ \ fst[A,B]`(a,b) \ a" unfolding fst_dep_def by simp lemma snd_dep_comp: "\a : A; b : B(a)\ \ snd[A,B]`(a,b) \ b" unfolding snd_dep_def by simp lemma fst_nondep_comp: "\a : A; b : B\ \ fst[A,B]`(a,b) \ a" unfolding fst_nondep_def by simp lemma snd_nondep_comp: "\a : A; b : B\ \ snd[A,B]`(a,b) \ b" unfolding snd_nondep_def by simp \ \Simplification rules for projections\ lemmas fst_snd_simps [simp] = fst_dep_comp snd_dep_comp fst_nondep_comp snd_nondep_comp subsection \Equality type\ axiomatization Equal :: "[Term, Term, Term] \ Term" syntax "_EQUAL" :: "[Term, Term, Term] \ Term" ("(3_ =\<^sub>_/ _)" [101, 101] 100) "_EQUAL_ASCII" :: "[Term, Term, Term] \ Term" ("(3_ =[_]/ _)" [101, 101] 100) translations "a =\<^sub>A b" \ "CONST Equal A a b" "a =[A] b" \ "CONST Equal A a b" axiomatization refl :: "Term \ Term" and indEqual :: "[Term, [Term, Term, Term] \ Term] \ Term" ("(indEqual[_])") where Equal_form: "\A a b::Term. \A : U; a : A; b : A\ \ a =\<^sub>A b : U" (* Should I write a permuted version \\A : U; b : A; a : A\ \ \\? *) and Equal_intro [intro]: "\A x::Term. x : A \ refl(x) : x =\<^sub>A x" and Equal_elim [elim]: "\(A::Term) (C::[Term, Term, Term] \ Term) (f::Term) (a::Term) (b::Term) (p::Term). \ \x y::Term. \x : A; y : A\ \ C(x)(y): x =\<^sub>A y \ U; f : \x:A. C(x)(x)(refl(x)); a : A; b : A; p : a =\<^sub>A b \ \ indEqual[A](C)`f`a`b`p : C(a)(b)(p)" and Equal_comp [simp]: "\(A::Term) (C::[Term, Term, Term] \ Term) (f::Term) (a::Term). indEqual[A](C)`f`a`a`refl(a) \ f`a" lemmas Equal_formation [intro] = Equal_form Equal_form[rotated 1] Equal_form[rotated 2] subsubsection \Properties of equality\ text "Symmetry/Path inverse" definition inv :: "[Term, Term, Term] \ Term" ("(1inv[_,/ _,/ _])") where "inv[A,x,y] \ indEqual[A](\x y _. y =\<^sub>A x)`(\<^bold>\x:A. refl(x))`x`y" lemma inv_comp: "\A a::Term. a : A \ inv[A,a,a]`refl(a) \ refl(a)" unfolding inv_def by simp text "Transitivity/Path composition" definition compose' :: "Term \ Term" ("(1compose''[_])") where "compose'[A] \ indEqual[A](\x y _. \z:A. \q: y =\<^sub>A z. x =\<^sub>A z)`(indEqual[A](\x z _. x =\<^sub>A z)`(\<^bold>\x:A. refl(x)))" lemma compose'_comp: "a : A \ compose'[A]`a`a`refl(a)`a`refl(a) \ refl(a)" unfolding compose'_def by simp end (* subsubsection \Empty type\ axiomatization Null :: Term and ind_Null :: "Term \ Term \ Term" ("(ind'_Null'(_,/ _'))") where Null_form: "Null : U" and Null_elim: "\C x a. \x : Null \ C(x) : U; a : Null\ \ ind_Null(C(x), a) : C(a)" subsubsection \Natural numbers\ axiomatization Nat :: Term and zero :: Term ("0") and succ :: "Term \ Term" and (* how to enforce \succ : Nat\Nat\? *) ind_Nat :: "Term \ Term \ Term \ Term \ Term" where Nat_form: "Nat : U" and Nat_intro1: "0 : Nat" and Nat_intro2: "\n. n : Nat \ succ n : Nat" (* computation rules *) *)