diff options
Diffstat (limited to 'spartan')
-rw-r--r-- | spartan/core/Spartan.thy (renamed from spartan/theories/Spartan.thy) | 18 | ||||
-rw-r--r-- | spartan/core/congruence.ML (renamed from spartan/lib/congruence.ML) | 0 | ||||
-rw-r--r-- | spartan/core/elimination.ML (renamed from spartan/lib/elimination.ML) | 0 | ||||
-rw-r--r-- | spartan/core/eqsubst.ML (renamed from spartan/lib/eqsubst.ML) | 0 | ||||
-rw-r--r-- | spartan/core/equality.ML (renamed from spartan/lib/equality.ML) | 0 | ||||
-rw-r--r-- | spartan/core/focus.ML (renamed from spartan/lib/focus.ML) | 0 | ||||
-rw-r--r-- | spartan/core/goals.ML (renamed from spartan/lib/goals.ML) | 0 | ||||
-rw-r--r-- | spartan/core/implicits.ML (renamed from spartan/lib/implicits.ML) | 0 | ||||
-rw-r--r-- | spartan/core/lib.ML (renamed from spartan/lib/lib.ML) | 0 | ||||
-rw-r--r-- | spartan/core/rewrite.ML (renamed from spartan/lib/rewrite.ML) | 0 | ||||
-rw-r--r-- | spartan/core/tactics.ML (renamed from spartan/lib/tactics.ML) | 0 | ||||
-rw-r--r-- | spartan/data/List.thy | 6 | ||||
-rw-r--r-- | spartan/theories/Equivalence.thy | 416 | ||||
-rw-r--r-- | spartan/theories/Identity.thy | 464 |
14 files changed, 15 insertions, 889 deletions
diff --git a/spartan/theories/Spartan.thy b/spartan/core/Spartan.thy index d235041..b4f7772 100644 --- a/spartan/theories/Spartan.thy +++ b/spartan/core/Spartan.thy @@ -142,20 +142,20 @@ section \<open>Proof commands\<close> named_theorems typechk -ML_file \<open>../lib/lib.ML\<close> -ML_file \<open>../lib/goals.ML\<close> -ML_file \<open>../lib/focus.ML\<close> +ML_file \<open>lib.ML\<close> +ML_file \<open>goals.ML\<close> +ML_file \<open>focus.ML\<close> section \<open>Congruence automation\<close> (*Potential to be retired*) -ML_file \<open>../lib/congruence.ML\<close> +ML_file \<open>congruence.ML\<close> section \<open>Methods\<close> -ML_file \<open>../lib/elimination.ML\<close> \<comment> \<open>declares the [elims] attribute\<close> +ML_file \<open>elimination.ML\<close> \<comment> \<open>declares the [elims] attribute\<close> named_theorems intros and comps lemmas @@ -165,7 +165,7 @@ lemmas [comps] = beta Sig_comp and [cong] = Pi_cong lam_cong Sig_cong -ML_file \<open>../lib/tactics.ML\<close> +ML_file \<open>tactics.ML\<close> method_setup assumptions = \<open>Scan.succeed (fn ctxt => SIMPLE_METHOD ( @@ -227,7 +227,7 @@ ML_file "~~/src/Tools/misc_legacy.ML" ML_file "~~/src/Tools/IsaPlanner/isand.ML" ML_file "~~/src/Tools/IsaPlanner/rw_inst.ML" ML_file "~~/src/Tools/IsaPlanner/zipper.ML" -ML_file "../lib/eqsubst.ML" +ML_file "eqsubst.ML" \<comment> \<open>\<open>rewrite\<close> method\<close> consts rewrite_HOLE :: "'a::{}" ("\<hole>") @@ -254,7 +254,7 @@ lemma imp_cong_eq: done ML_file \<open>~~/src/HOL/Library/cconv.ML\<close> -ML_file \<open>../lib/rewrite.ML\<close> +ML_file \<open>rewrite.ML\<close> \<comment> \<open>\<open>reduce\<close> computes terms via judgmental equalities\<close> setup \<open>map_theory_simpset (fn ctxt => ctxt addSolver (mk_solver "" typechk_tac))\<close> @@ -273,7 +273,7 @@ consts iarg :: \<open>'a\<close> ("?") hole :: \<open>'b\<close> ("{}") -ML_file \<open>../lib/implicits.ML\<close> +ML_file \<open>implicits.ML\<close> attribute_setup implicit = \<open>Scan.succeed Implicits.implicit_defs_attr\<close> diff --git a/spartan/lib/congruence.ML b/spartan/core/congruence.ML index bb7348c..bb7348c 100644 --- a/spartan/lib/congruence.ML +++ b/spartan/core/congruence.ML diff --git a/spartan/lib/elimination.ML b/spartan/core/elimination.ML index 617f83e..617f83e 100644 --- a/spartan/lib/elimination.ML +++ b/spartan/core/elimination.ML diff --git a/spartan/lib/eqsubst.ML b/spartan/core/eqsubst.ML index ea6f098..ea6f098 100644 --- a/spartan/lib/eqsubst.ML +++ b/spartan/core/eqsubst.ML diff --git a/spartan/lib/equality.ML b/spartan/core/equality.ML index 023147b..023147b 100644 --- a/spartan/lib/equality.ML +++ b/spartan/core/equality.ML diff --git a/spartan/lib/focus.ML b/spartan/core/focus.ML index 1d8de78..1d8de78 100644 --- a/spartan/lib/focus.ML +++ b/spartan/core/focus.ML diff --git a/spartan/lib/goals.ML b/spartan/core/goals.ML index 9f394f0..9f394f0 100644 --- a/spartan/lib/goals.ML +++ b/spartan/core/goals.ML diff --git a/spartan/lib/implicits.ML b/spartan/core/implicits.ML index 04fc825..04fc825 100644 --- a/spartan/lib/implicits.ML +++ b/spartan/core/implicits.ML diff --git a/spartan/lib/lib.ML b/spartan/core/lib.ML index 615f601..615f601 100644 --- a/spartan/lib/lib.ML +++ b/spartan/core/lib.ML diff --git a/spartan/lib/rewrite.ML b/spartan/core/rewrite.ML index f9c5d8e..f9c5d8e 100644 --- a/spartan/lib/rewrite.ML +++ b/spartan/core/rewrite.ML diff --git a/spartan/lib/tactics.ML b/spartan/core/tactics.ML index f23bfee..f23bfee 100644 --- a/spartan/lib/tactics.ML +++ b/spartan/core/tactics.ML diff --git a/spartan/data/List.thy b/spartan/data/List.thy new file mode 100644 index 0000000..71a879b --- /dev/null +++ b/spartan/data/List.thy @@ -0,0 +1,6 @@ +theory List +imports Spartan + +begin + +end diff --git a/spartan/theories/Equivalence.thy b/spartan/theories/Equivalence.thy deleted file mode 100644 index 2975738..0000000 --- a/spartan/theories/Equivalence.thy +++ /dev/null @@ -1,416 +0,0 @@ -theory Equivalence -imports Identity - -begin - -section \<open>Homotopy\<close> - -definition "homotopy A B f g \<equiv> \<Prod>x: A. f `x =\<^bsub>B x\<^esub> g `x" - -definition homotopy_i (infix "~" 100) - where [implicit]: "f ~ g \<equiv> homotopy ? ? f g" - -translations "f ~ g" \<leftharpoondown> "CONST homotopy A B f g" - -Lemma homotopy_type [typechk]: - assumes - "A: U i" - "\<And>x. x: A \<Longrightarrow> B x: U i" - "f: \<Prod>x: A. B x" "g: \<Prod>x: A. B x" - shows "f ~ g: U i" - unfolding homotopy_def by typechk - -Lemma (derive) homotopy_refl [refl]: - assumes - "A: U i" - "f: \<Prod>x: A. B x" - shows "f ~ f" - unfolding homotopy_def by intros - -Lemma (derive) hsym: - assumes - "f: \<Prod>x: A. B x" - "g: \<Prod>x: A. B x" - "A: U i" - "\<And>x. x: A \<Longrightarrow> B x: U i" - shows "H: f ~ g \<Longrightarrow> g ~ f" - unfolding homotopy_def - apply intros - apply (rule pathinv) - \<guillemotright> by (elim H) - \<guillemotright> by typechk - done - -Lemma (derive) htrans: - assumes - "f: \<Prod>x: A. B x" - "g: \<Prod>x: A. B x" - "h: \<Prod>x: A. B x" - "A: U i" - "\<And>x. x: A \<Longrightarrow> B x: U i" - shows "\<lbrakk>H1: f ~ g; H2: g ~ h\<rbrakk> \<Longrightarrow> f ~ h" - unfolding homotopy_def - apply intro - \<guillemotright> vars x - apply (rule pathcomp[where ?y="g x"]) - \<^item> by (elim H1) - \<^item> by (elim H2) - done - \<guillemotright> by typechk - done - -text \<open>For calculations:\<close> - -lemmas - homotopy_sym [sym] = hsym[rotated 4] and - homotopy_trans [trans] = htrans[rotated 5] - -Lemma (derive) commute_homotopy: - assumes - "A: U i" "B: U i" - "x: A" "y: A" - "p: x =\<^bsub>A\<^esub> y" - "f: A \<rightarrow> B" "g: A \<rightarrow> B" - "H: homotopy A (\<lambda>_. B) f g" - shows "(H x) \<bullet> g[p] = f[p] \<bullet> (H y)" - \<comment> \<open>Need this assumption unfolded for typechecking:\<close> - supply assms(8)[unfolded homotopy_def] - apply (eq p) - focus vars x - apply reduce - \<comment> \<open>Here it would really be nice to have automation for transport and - propositional equality.\<close> - apply (rule use_transport[where ?y="H x \<bullet> refl (g x)"]) - \<guillemotright> by (rule pathcomp_right_refl) - \<guillemotright> by (rule pathinv) (rule pathcomp_left_refl) - \<guillemotright> by typechk - done - done - -Corollary (derive) commute_homotopy': - assumes - "A: U i" - "x: A" - "f: A \<rightarrow> A" - "H: homotopy A (\<lambda>_. A) f (id A)" - shows "H (f x) = f [H x]" -oops - -Lemma homotopy_id_left [typechk]: - assumes "A: U i" "B: U i" "f: A \<rightarrow> B" - shows "homotopy_refl A f: (id B) \<circ> f ~ f" - unfolding homotopy_refl_def homotopy_def by reduce - -Lemma homotopy_id_right [typechk]: - assumes "A: U i" "B: U i" "f: A \<rightarrow> B" - shows "homotopy_refl A f: f \<circ> (id A) ~ f" - unfolding homotopy_refl_def homotopy_def by reduce - -Lemma homotopy_funcomp_left: - assumes - "H: homotopy B C g g'" - "f: A \<rightarrow> B" - "g: \<Prod>x: B. C x" - "g': \<Prod>x: B. C x" - "A: U i" "B: U i" - "\<And>x. x: B \<Longrightarrow> C x: U i" - shows "homotopy A {} (g \<circ>\<^bsub>A\<^esub> f) (g' \<circ>\<^bsub>A\<^esub> f)" - unfolding homotopy_def - apply (intro; reduce) - apply (insert \<open>H: _\<close>[unfolded homotopy_def]) - apply (elim H) - done - -Lemma homotopy_funcomp_right: - assumes - "H: homotopy A (\<lambda>_. B) f f'" - "f: A \<rightarrow> B" - "f': A \<rightarrow> B" - "g: B \<rightarrow> C" - "A: U i" "B: U i" "C: U i" - shows "homotopy A {} (g \<circ>\<^bsub>A\<^esub> f) (g \<circ>\<^bsub>A\<^esub> f')" - unfolding homotopy_def - apply (intro; reduce) - apply (insert \<open>H: _\<close>[unfolded homotopy_def]) - apply (dest PiE, assumption) - apply (rule ap, assumption) - done - - -section \<open>Quasi-inverse and bi-invertibility\<close> - -subsection \<open>Quasi-inverses\<close> - -definition "qinv A B f \<equiv> \<Sum>g: B \<rightarrow> A. - homotopy A (\<lambda>_. A) (g \<circ>\<^bsub>A\<^esub> f) (id A) \<times> homotopy B (\<lambda>_. B) (f \<circ>\<^bsub>B\<^esub> g) (id B)" - -lemma qinv_type [typechk]: - assumes "A: U i" "B: U i" "f: A \<rightarrow> B" - shows "qinv A B f: U i" - unfolding qinv_def by typechk - -definition qinv_i ("qinv") - where [implicit]: "qinv f \<equiv> Equivalence.qinv ? ? f" - -translations "qinv f" \<leftharpoondown> "CONST Equivalence.qinv A B f" - -Lemma (derive) id_qinv: - assumes "A: U i" - shows "qinv (id A)" - unfolding qinv_def - apply intro defer - apply intro defer - apply (rule homotopy_id_right) - apply (rule homotopy_id_left) - done - -Lemma (derive) quasiinv_qinv: - assumes "A: U i" "B: U i" "f: A \<rightarrow> B" - shows "prf: qinv f \<Longrightarrow> qinv (fst prf)" - unfolding qinv_def - apply intro - \<guillemotright> by (rule \<open>f:_\<close>) - \<guillemotright> apply (elim "prf") - focus vars g HH - apply intro - \<^item> by reduce (snd HH) - \<^item> by reduce (fst HH) - done - done - done - -Lemma (derive) funcomp_qinv: - assumes - "A: U i" "B: U i" "C: U i" - "f: A \<rightarrow> B" "g: B \<rightarrow> C" - shows "qinv f \<rightarrow> qinv g \<rightarrow> qinv (g \<circ> f)" - apply (intros, unfold qinv_def, elims) - focus - prems prms - vars _ _ finv _ ginv _ HfA HfB HgB HgC - - apply intro - apply (rule funcompI[where ?f=ginv and ?g=finv]) - - text \<open>Now a whole bunch of rewrites and we're done.\<close> -oops - -subsection \<open>Bi-invertible maps\<close> - -definition "biinv A B f \<equiv> - (\<Sum>g: B \<rightarrow> A. homotopy A (\<lambda>_. A) (g \<circ>\<^bsub>A\<^esub> f) (id A)) - \<times> (\<Sum>g: B \<rightarrow> A. homotopy B (\<lambda>_. B) (f \<circ>\<^bsub>B\<^esub> g) (id B))" - -lemma biinv_type [typechk]: - assumes "A: U i" "B: U i" "f: A \<rightarrow> B" - shows "biinv A B f: U i" - unfolding biinv_def by typechk - -definition biinv_i ("biinv") - where [implicit]: "biinv f \<equiv> Equivalence.biinv ? ? f" - -translations "biinv f" \<leftharpoondown> "CONST Equivalence.biinv A B f" - -Lemma (derive) qinv_imp_biinv: - assumes - "A: U i" "B: U i" - "f: A \<rightarrow> B" - shows "?prf: qinv f \<rightarrow> biinv f" - apply intros - unfolding qinv_def biinv_def - by (rule Sig_dist_exp) - -text \<open> - Show that bi-invertible maps are quasi-inverses, as a demonstration of how to - work in this system. -\<close> - -Lemma (derive) biinv_imp_qinv: - assumes "A: U i" "B: U i" "f: A \<rightarrow> B" - shows "biinv f \<rightarrow> qinv f" - - text \<open>Split the hypothesis \<^term>\<open>biinv f\<close> into its components:\<close> - apply intro - unfolding biinv_def - apply elims - - text \<open>Name the components:\<close> - focus prems vars _ _ _ g H1 h H2 - thm \<open>g:_\<close> \<open>h:_\<close> \<open>H1:_\<close> \<open>H2:_\<close> - - text \<open> - \<^term>\<open>g\<close> is a quasi-inverse to \<^term>\<open>f\<close>, so the proof will be a triple - \<^term>\<open><g, <?H1, ?H2>>\<close>. - \<close> - unfolding qinv_def - apply intro - \<guillemotright> by (rule \<open>g: _\<close>) - \<guillemotright> apply intro - text \<open>The first part \<^prop>\<open>?H1: g \<circ> f ~ id A\<close> is given by \<^term>\<open>H1\<close>.\<close> - apply (rule \<open>H1: _\<close>) - - text \<open> - It remains to prove \<^prop>\<open>?H2: f \<circ> g ~ id B\<close>. First show that \<open>g ~ h\<close>, - then the result follows from @{thm \<open>H2: f \<circ> h ~ id B\<close>}. Here a proof - block is used to calculate "forward". - \<close> - proof - - have "g ~ g \<circ> (id B)" by reduce refl - also have "g \<circ> (id B) ~ g \<circ> f \<circ> h" - by (rule homotopy_funcomp_right) (rule \<open>H2:_\<close>[symmetric]) - also have "g \<circ> f \<circ> h ~ (id A) \<circ> h" - by (subst funcomp_assoc[symmetric]) - (rule homotopy_funcomp_left, rule \<open>H1:_\<close>) - also have "(id A) \<circ> h ~ h" by reduce refl - finally have "g ~ h" by this - - then have "f \<circ> g ~ f \<circ> h" by (rule homotopy_funcomp_right) - - with \<open>H2:_\<close> - show "f \<circ> g ~ id B" - by (rule homotopy_trans) (assumption+, typechk) - qed - done - done - -Lemma (derive) id_biinv: - "A: U i \<Longrightarrow> biinv (id A)" - by (rule qinv_imp_biinv) (rule id_qinv) - -Lemma (derive) funcomp_biinv: - assumes - "A: U i" "B: U i" "C: U i" - "f: A \<rightarrow> B" "g: B \<rightarrow> C" - shows "biinv f \<rightarrow> biinv g \<rightarrow> biinv (g \<circ> f)" - apply intros - focus vars biinv\<^sub>f biinv\<^sub>g - - text \<open>Follows from \<open>funcomp_qinv\<close>.\<close> -oops - - -section \<open>Equivalence\<close> - -text \<open> - Following the HoTT book, we first define equivalence in terms of - bi-invertibility. -\<close> - -definition equivalence (infix "\<simeq>" 110) - where "A \<simeq> B \<equiv> \<Sum>f: A \<rightarrow> B. Equivalence.biinv A B f" - -lemma equivalence_type [typechk]: - assumes "A: U i" "B: U i" - shows "A \<simeq> B: U i" - unfolding equivalence_def by typechk - -Lemma (derive) equivalence_refl: - assumes "A: U i" - shows "A \<simeq> A" - unfolding equivalence_def - apply intro defer - apply (rule qinv_imp_biinv) defer - apply (rule id_qinv) - done - -text \<open> - The following could perhaps be easier with transport (but then I think we need - univalence?)... -\<close> - -Lemma (derive) equivalence_symmetric: - assumes "A: U i" "B: U i" - shows "A \<simeq> B \<rightarrow> B \<simeq> A" - apply intros - unfolding equivalence_def - apply elim - \<guillemotright> vars _ f "prf" - apply (dest (4) biinv_imp_qinv) - apply intro - \<^item> unfolding qinv_def by (rule fst[of "(biinv_imp_qinv A B f) prf"]) - \<^item> by (rule qinv_imp_biinv) (rule quasiinv_qinv) - done - done - -Lemma (derive) equivalence_transitive: - assumes "A: U i" "B: U i" "C: U i" - shows "A \<simeq> B \<rightarrow> B \<simeq> C \<rightarrow> A \<simeq> C" - apply intros - unfolding equivalence_def - - text \<open>Use \<open>funcomp_biinv\<close>.\<close> -oops - -text \<open> - Equal types are equivalent. We give two proofs: the first by induction, and - the second by following the HoTT book and showing that transport is an - equivalence. -\<close> - -Lemma - assumes - "A: U i" "B: U i" "p: A =\<^bsub>U i\<^esub> B" - shows "A \<simeq> B" - by (eq p) (rule equivalence_refl) - -text \<open> - The following proof is wordy because (1) the typechecker doesn't rewrite, and - (2) we don't yet have universe automation. -\<close> - -Lemma (derive) id_imp_equiv: - assumes - "A: U i" "B: U i" "p: A =\<^bsub>U i\<^esub> B" - shows "<trans (id (U i)) p, ?isequiv>: A \<simeq> B" - unfolding equivalence_def - apply intros defer - - \<comment> \<open>Switch off auto-typechecking, which messes with universe levels\<close> - supply [[auto_typechk=false]] - - \<guillemotright> apply (eq p, typechk) - \<^item> prems vars A B - apply (rewrite at A in "A \<rightarrow> B" id_comp[symmetric]) - apply (rewrite at B in "_ \<rightarrow> B" id_comp[symmetric]) - apply (rule transport, rule U_in_U) - apply (rule lift_universe_codomain, rule U_in_U) - apply (typechk, rule U_in_U) - done - \<^item> prems vars A - apply (subst transport_comp) - \<^enum> by (rule U_in_U) - \<^enum> by reduce (rule lift_universe) - \<^enum> by reduce (rule id_biinv) - done - done - - \<guillemotright> \<comment> \<open>Similar proof as in the first subgoal above\<close> - apply (rewrite at A in "A \<rightarrow> B" id_comp[symmetric]) - apply (rewrite at B in "_ \<rightarrow> B" id_comp[symmetric]) - apply (rule transport, rule U_in_U) - apply (rule lift_universe_codomain, rule U_in_U) - apply (typechk, rule U_in_U) - done - done - -(*Uncomment this to see all implicits from here on. -no_translations - "f x" \<leftharpoondown> "f `x" - "x = y" \<leftharpoondown> "x =\<^bsub>A\<^esub> y" - "g \<circ> f" \<leftharpoondown> "g \<circ>\<^bsub>A\<^esub> f" - "p\<inverse>" \<leftharpoondown> "CONST pathinv A x y p" - "p \<bullet> q" \<leftharpoondown> "CONST pathcomp A x y z p q" - "fst" \<leftharpoondown> "CONST Spartan.fst A B" - "snd" \<leftharpoondown> "CONST Spartan.snd A B" - "f[p]" \<leftharpoondown> "CONST ap A B x y f p" - "trans P p" \<leftharpoondown> "CONST transport A P x y p" - "trans_const B p" \<leftharpoondown> "CONST transport_const A B x y p" - "lift P p u" \<leftharpoondown> "CONST pathlift A P x y p u" - "apd f p" \<leftharpoondown> "CONST Identity.apd A P f x y p" - "f ~ g" \<leftharpoondown> "CONST homotopy A B f g" - "qinv f" \<leftharpoondown> "CONST Equivalence.qinv A B f" - "biinv f" \<leftharpoondown> "CONST Equivalence.biinv A B f" -*) - - -end diff --git a/spartan/theories/Identity.thy b/spartan/theories/Identity.thy deleted file mode 100644 index 3a982f6..0000000 --- a/spartan/theories/Identity.thy +++ /dev/null @@ -1,464 +0,0 @@ -chapter \<open>The identity type\<close> - -text \<open> - The identity type, the higher groupoid structure of types, - and type families as fibrations. -\<close> - -theory Identity -imports Spartan - -begin - -axiomatization - Id :: \<open>o \<Rightarrow> o \<Rightarrow> o \<Rightarrow> o\<close> and - refl :: \<open>o \<Rightarrow> o\<close> and - IdInd :: \<open>o \<Rightarrow> (o \<Rightarrow> o \<Rightarrow> o \<Rightarrow> o) \<Rightarrow> (o \<Rightarrow> o) \<Rightarrow> o \<Rightarrow> o \<Rightarrow> o \<Rightarrow> o\<close> - -syntax "_Id" :: \<open>o \<Rightarrow> o \<Rightarrow> o \<Rightarrow> o\<close> ("(2_ =\<^bsub>_\<^esub>/ _)" [111, 0, 111] 110) - -translations "a =\<^bsub>A\<^esub> b" \<rightleftharpoons> "CONST Id A a b" - -axiomatization where - IdF: "\<lbrakk>A: U i; a: A; b: A\<rbrakk> \<Longrightarrow> a =\<^bsub>A\<^esub> b: U i" and - - IdI: "a: A \<Longrightarrow> refl a: a =\<^bsub>A\<^esub> a" and - - IdE: "\<lbrakk> - p: a =\<^bsub>A\<^esub> b; - a: A; - b: A; - \<And>x y p. \<lbrakk>p: x =\<^bsub>A\<^esub> y; x: A; y: A\<rbrakk> \<Longrightarrow> C x y p: U i; - \<And>x. x: A \<Longrightarrow> f x: C x x (refl x) - \<rbrakk> \<Longrightarrow> IdInd A (\<lambda>x y p. C x y p) f a b p: C a b p" and - - Id_comp: "\<lbrakk> - a: A; - \<And>x y p. \<lbrakk>x: A; y: A; p: x =\<^bsub>A\<^esub> y\<rbrakk> \<Longrightarrow> C x y p: U i; - \<And>x. x: A \<Longrightarrow> f x: C x x (refl x) - \<rbrakk> \<Longrightarrow> IdInd A (\<lambda>x y p. C x y p) f a a (refl a) \<equiv> f a" - -lemmas - [intros] = IdF IdI and - [elims "?p" "?a" "?b"] = IdE and - [comps] = Id_comp and - [refl] = IdI - - -section \<open>Path induction\<close> - -method_setup eq = \<open> -Args.term >> (fn tm => fn ctxt => CONTEXT_METHOD (K ( - CONTEXT_SUBGOAL (fn (goal, i) => - let - val facts = Proof_Context.facts_of ctxt - val prems = Logic.strip_assums_hyp goal - val template = \<^const>\<open>has_type\<close> - $ tm - $ (\<^const>\<open>Id\<close> $ Var (("*?A", 0), \<^typ>\<open>o\<close>) - $ Var (("*?x", 0), \<^typ>\<open>o\<close>) - $ Var (("*?y", 0), \<^typ>\<open>o\<close>)) - val types = - map (Thm.prop_of o #1) (Facts.could_unify facts template) - @ filter (fn prem => Term.could_unify (template, prem)) prems - |> map Lib.type_of_typing - in case types of - (\<^const>\<open>Id\<close> $ _ $ x $ y)::_ => - elim_context_tac [tm, x, y] ctxt i - | _ => Context_Tactic.CONTEXT_TACTIC no_tac - end) 1))) -\<close> - - -section \<open>Symmetry and transitivity\<close> - -Lemma (derive) pathinv: - assumes "A: U i" "x: A" "y: A" "p: x =\<^bsub>A\<^esub> y" - shows "y =\<^bsub>A\<^esub> x" - by (eq p) intro - -lemma pathinv_comp [comps]: - assumes "x: A" "A: U i" - shows "pathinv A x x (refl x) \<equiv> refl x" - unfolding pathinv_def by reduce - -Lemma (derive) pathcomp: - assumes - "A: U i" "x: A" "y: A" "z: A" - "p: x =\<^bsub>A\<^esub> y" "q: y =\<^bsub>A\<^esub> z" - shows - "x =\<^bsub>A\<^esub> z" - apply (eq p) - focus prems vars x p - apply (eq p) - apply intro - done - done - -lemma pathcomp_comp [comps]: - assumes "a: A" "A: U i" - shows "pathcomp A a a a (refl a) (refl a) \<equiv> refl a" - unfolding pathcomp_def by reduce - - -section \<open>Notation\<close> - -definition Id_i (infix "=" 110) - where [implicit]: "Id_i x y \<equiv> x =\<^bsub>?\<^esub> y" - -definition pathinv_i ("_\<inverse>" [1000]) - where [implicit]: "pathinv_i p \<equiv> pathinv ? ? ? p" - -definition pathcomp_i (infixl "\<bullet>" 121) - where [implicit]: "pathcomp_i p q \<equiv> pathcomp ? ? ? ? p q" - -translations - "x = y" \<leftharpoondown> "x =\<^bsub>A\<^esub> y" - "p\<inverse>" \<leftharpoondown> "CONST pathinv A x y p" - "p \<bullet> q" \<leftharpoondown> "CONST pathcomp A x y z p q" - - -section \<open>Calculational reasoning\<close> - -consts rhs :: \<open>'a\<close> ("''''") - -ML \<open> -local fun last_rhs ctxt = - let - val this_name = Name_Space.full_name (Proof_Context.naming_of ctxt) - (Binding.name Auto_Bind.thisN) - val this = #thms (the (Proof_Context.lookup_fact ctxt this_name)) - handle Option => [] - val rhs = case map Thm.prop_of this of - [\<^const>\<open>has_type\<close> $ _ $ (\<^const>\<open>Id\<close> $ _ $ _ $ y)] => y - | _ => Term.dummy - in - map_aterms (fn t => case t of Const (\<^const_name>\<open>rhs\<close>, _) => rhs | _ => t) - end -in val _ = Context.>> - (Syntax_Phases.term_check 5 "" (fn ctxt => map (last_rhs ctxt))) -end -\<close> - -lemmas - [sym] = pathinv[rotated 3] and - [trans] = pathcomp[rotated 4] - - -section \<open>Basic propositional equalities\<close> - -Lemma (derive) pathcomp_left_refl: - assumes "A: U i" "x: A" "y: A" "p: x =\<^bsub>A\<^esub> y" - shows "(refl x) \<bullet> p = p" - apply (eq p) - apply (reduce; intros) - done - -Lemma (derive) pathcomp_right_refl: - assumes "A: U i" "x: A" "y: A" "p: x =\<^bsub>A\<^esub> y" - shows "p \<bullet> (refl y) = p" - apply (eq p) - apply (reduce; intros) - done - -Lemma (derive) pathcomp_left_inv: - assumes "A: U i" "x: A" "y: A" "p: x =\<^bsub>A\<^esub> y" - shows "p\<inverse> \<bullet> p = refl y" - apply (eq p) - apply (reduce; intros) - done - -Lemma (derive) pathcomp_right_inv: - assumes "A: U i" "x: A" "y: A" "p: x =\<^bsub>A\<^esub> y" - shows "p \<bullet> p\<inverse> = refl x" - apply (eq p) - apply (reduce; intros) - done - -Lemma (derive) pathinv_pathinv: - assumes "A: U i" "x: A" "y: A" "p: x =\<^bsub>A\<^esub> y" - shows "p\<inverse>\<inverse> = p" - apply (eq p) - apply (reduce; intros) - done - -Lemma (derive) pathcomp_assoc: - assumes - "A: U i" "x: A" "y: A" "z: A" "w: A" - "p: x =\<^bsub>A\<^esub> y" "q: y =\<^bsub>A\<^esub> z" "r: z =\<^bsub>A\<^esub> w" - shows "p \<bullet> (q \<bullet> r) = p \<bullet> q \<bullet> r" - apply (eq p) - focus prems vars x p - apply (eq p) - focus prems vars x p - apply (eq p) - apply (reduce; intros) - done - done - done - - -section \<open>Functoriality of functions\<close> - -Lemma (derive) ap: - assumes - "A: U i" "B: U i" - "x: A" "y: A" - "f: A \<rightarrow> B" - "p: x =\<^bsub>A\<^esub> y" - shows "f x = f y" - apply (eq p) - apply intro - done - -definition ap_i ("_[_]" [1000, 0]) - where [implicit]: "ap_i f p \<equiv> ap ? ? ? ? f p" - -translations "f[p]" \<leftharpoondown> "CONST ap A B x y f p" - -Lemma ap_refl [comps]: - assumes "f: A \<rightarrow> B" "x: A" "A: U i" "B: U i" - shows "f[refl x] \<equiv> refl (f x)" - unfolding ap_def by reduce - -Lemma (derive) ap_pathcomp: - assumes - "A: U i" "B: U i" - "x: A" "y: A" "z: A" - "f: A \<rightarrow> B" - "p: x =\<^bsub>A\<^esub> y" "q: y =\<^bsub>A\<^esub> z" - shows - "f[p \<bullet> q] = f[p] \<bullet> f[q]" - apply (eq p) - focus prems vars x p - apply (eq p) - apply (reduce; intro) - done - done - -Lemma (derive) ap_pathinv: - assumes - "A: U i" "B: U i" - "x: A" "y: A" - "f: A \<rightarrow> B" - "p: x =\<^bsub>A\<^esub> y" - shows "f[p\<inverse>] = f[p]\<inverse>" - by (eq p) (reduce; intro) - -text \<open>The next two proofs currently use some low-level rewriting.\<close> - -Lemma (derive) ap_funcomp: - assumes - "A: U i" "B: U i" "C: U i" - "x: A" "y: A" - "f: A \<rightarrow> B" "g: B \<rightarrow> C" - "p: x =\<^bsub>A\<^esub> y" - shows "(g \<circ> f)[p] = g[f[p]]" - apply (eq p) - apply (simp only: funcomp_apply_comp[symmetric]) - apply (reduce; intro) - done - -Lemma (derive) ap_id: - assumes "A: U i" "x: A" "y: A" "p: x =\<^bsub>A\<^esub> y" - shows "(id A)[p] = p" - apply (eq p) - apply (rewrite at "\<hole> = _" id_comp[symmetric]) - apply (rewrite at "_ = \<hole>" id_comp[symmetric]) - apply (reduce; intros) - done - - -section \<open>Transport\<close> - -Lemma (derive) transport: - assumes - "A: U i" - "\<And>x. x: A \<Longrightarrow> P x: U i" - "x: A" "y: A" - "p: x =\<^bsub>A\<^esub> y" - shows "P x \<rightarrow> P y" - by (eq p) intro - -definition transport_i ("trans") - where [implicit]: "trans P p \<equiv> transport ? P ? ? p" - -translations "trans P p" \<leftharpoondown> "CONST transport A P x y p" - -Lemma transport_comp [comps]: - assumes - "a: A" - "A: U i" - "\<And>x. x: A \<Longrightarrow> P x: U i" - shows "trans P (refl a) \<equiv> id (P a)" - unfolding transport_def by reduce - -\<comment> \<open>TODO: Build transport automation!\<close> - -Lemma use_transport: - assumes - "p: y =\<^bsub>A\<^esub> x" - "u: P x" - "x: A" "y: A" - "A: U i" - "\<And>x. x: A \<Longrightarrow> P x: U i" - shows "trans P p\<inverse> u: P y" - by typechk - -Lemma (derive) transport_left_inv: - assumes - "A: U i" - "\<And>x. x: A \<Longrightarrow> P x: U i" - "x: A" "y: A" - "p: x =\<^bsub>A\<^esub> y" - shows "(trans P p\<inverse>) \<circ> (trans P p) = id (P x)" - by (eq p) (reduce; intro) - -Lemma (derive) transport_right_inv: - assumes - "A: U i" - "\<And>x. x: A \<Longrightarrow> P x: U i" - "x: A" "y: A" - "p: x =\<^bsub>A\<^esub> y" - shows "(trans P p) \<circ> (trans P p\<inverse>) = id (P y)" - by (eq p) (reduce; intros) - -Lemma (derive) transport_pathcomp: - assumes - "A: U i" - "\<And>x. x: A \<Longrightarrow> P x: U i" - "x: A" "y: A" "z: A" - "u: P x" - "p: x =\<^bsub>A\<^esub> y" "q: y =\<^bsub>A\<^esub> z" - shows "trans P q (trans P p u) = trans P (p \<bullet> q) u" - apply (eq p) - focus prems vars x p - apply (eq p) - apply (reduce; intros) - done - done - -Lemma (derive) transport_compose_typefam: - assumes - "A: U i" "B: U i" - "\<And>x. x: B \<Longrightarrow> P x: U i" - "f: A \<rightarrow> B" - "x: A" "y: A" - "p: x =\<^bsub>A\<^esub> y" - "u: P (f x)" - shows "trans (\<lambda>x. P (f x)) p u = trans P f[p] u" - by (eq p) (reduce; intros) - -Lemma (derive) transport_function_family: - assumes - "A: U i" - "\<And>x. x: A \<Longrightarrow> P x: U i" - "\<And>x. x: A \<Longrightarrow> Q x: U i" - "f: \<Prod>x: A. P x \<rightarrow> Q x" - "x: A" "y: A" - "u: P x" - "p: x =\<^bsub>A\<^esub> y" - shows "trans Q p ((f x) u) = (f y) (trans P p u)" - by (eq p) (reduce; intros) - -Lemma (derive) transport_const: - assumes - "A: U i" "B: U i" - "x: A" "y: A" - "p: x =\<^bsub>A\<^esub> y" - shows "\<Prod>b: B. trans (\<lambda>_. B) p b = b" - by (intro, eq p) (reduce; intro) - -definition transport_const_i ("trans'_const") - where [implicit]: "trans_const B p \<equiv> transport_const ? B ? ? p" - -translations "trans_const B p" \<leftharpoondown> "CONST transport_const A B x y p" - -Lemma transport_const_comp [comps]: - assumes - "x: A" "b: B" - "A: U i" "B: U i" - shows "trans_const B (refl x) b\<equiv> refl b" - unfolding transport_const_def by reduce - -Lemma (derive) pathlift: - assumes - "A: U i" - "\<And>x. x: A \<Longrightarrow> P x: U i" - "x: A" "y: A" - "p: x =\<^bsub>A\<^esub> y" - "u: P x" - shows "<x, u> = <y, trans P p u>" - by (eq p) (reduce; intros) - -definition pathlift_i ("lift") - where [implicit]: "lift P p u \<equiv> pathlift ? P ? ? p u" - -translations "lift P p u" \<leftharpoondown> "CONST pathlift A P x y p u" - -Lemma pathlift_comp [comps]: - assumes - "u: P x" - "x: A" - "\<And>x. x: A \<Longrightarrow> P x: U i" - "A: U i" - shows "lift P (refl x) u \<equiv> refl <x, u>" - unfolding pathlift_def by reduce - -Lemma (derive) pathlift_fst: - assumes - "A: U i" - "\<And>x. x: A \<Longrightarrow> P x: U i" - "x: A" "y: A" - "u: P x" - "p: x =\<^bsub>A\<^esub> y" - shows "fst[lift P p u] = p" - apply (eq p) - text \<open>Some rewriting needed here:\<close> - \<guillemotright> vars x y - (*Here an automatic reordering tactic would be helpful*) - apply (rewrite at x in "x = y" fst_comp[symmetric]) - prefer 4 - apply (rewrite at y in "_ = y" fst_comp[symmetric]) - done - \<guillemotright> by reduce intro - done - - -section \<open>Dependent paths\<close> - -Lemma (derive) apd: - assumes - "A: U i" - "\<And>x. x: A \<Longrightarrow> P x: U i" - "f: \<Prod>x: A. P x" - "x: A" "y: A" - "p: x =\<^bsub>A\<^esub> y" - shows "trans P p (f x) = f y" - by (eq p) (reduce; intros; typechk) - -definition apd_i ("apd") - where [implicit]: "apd f p \<equiv> Identity.apd ? ? f ? ? p" - -translations "apd f p" \<leftharpoondown> "CONST Identity.apd A P f x y p" - -Lemma dependent_map_comp [comps]: - assumes - "f: \<Prod>x: A. P x" - "x: A" - "A: U i" - "\<And>x. x: A \<Longrightarrow> P x: U i" - shows "apd f (refl x) \<equiv> refl (f x)" - unfolding apd_def by reduce - -Lemma (derive) apd_ap: - assumes - "A: U i" "B: U i" - "f: A \<rightarrow> B" - "x: A" "y: A" - "p: x =\<^bsub>A\<^esub> y" - shows "apd f p = trans_const B p (f x) \<bullet> f[p]" - by (eq p) (reduce; intro) - - -end |