text \Spartan type theory\ theory Spartan imports Pure "HOL-Eisbach.Eisbach" "HOL-Eisbach.Eisbach_Tools" keywords "Theorem" "Lemma" "Corollary" "Proposition" :: thy_goal_stmt and "focus" "\" "\<^item>" "\<^enum>" "~" :: prf_script_goal % "proof" and "derive" "prems" "vars":: quasi_command and "print_coercions" :: thy_decl begin section \Preamble\ declare [[eta_contract=false]] section \Metatype setup\ typedecl o section \Judgments\ judgment has_type :: \o \ o \ prop\ ("(2_:/ _)" 999) section \Universes\ typedecl lvl \ \Universe levels\ axiomatization O :: \lvl\ and S :: \lvl \ lvl\ and lt :: \lvl \ lvl \ prop\ (infix "<" 900) where O_min: "O < S i" and lt_S: "i < S i" and lt_trans: "i < j \ j < k \ i < k" axiomatization U :: \lvl \ o\ where U_hierarchy: "i < j \ U i: U j" and U_cumulative: "A: U i \ i < j \ A: U j" lemma U_in_U: "U i: U (S i)" by (rule U_hierarchy, rule lt_S) lemma lift_universe: "A: U i \ A: U (S i)" by (erule U_cumulative, rule lt_S) section \\-type\ axiomatization Pi :: \o \ (o \ o) \ o\ and lam :: \o \ (o \ o) \ o\ and app :: \o \ o \ o\ ("(1_ `_)" [120, 121] 120) syntax "_Pi" :: \idt \ o \ o \ o\ ("(2\_: _./ _)" 30) "_lam" :: \pttrns \ o \ o \ o\ ("(2\_: _./ _)" 30) "_lam2" :: \pttrns \ o \ o \ o\ translations "\x: A. B" \ "CONST Pi A (\x. B)" "\x xs: A. b" \ "CONST lam A (\x. _lam2 xs A b)" "_lam2 x A b" \ "\x: A. b" "\x: A. b" \ "CONST lam A (\x. b)" abbreviation Fn (infixr "\" 40) where "A \ B \ \_: A. B" axiomatization where PiF: "\\x. x: A \ B x: U i; A: U i\ \ \x: A. B x: U i" and PiI: "\\x. x: A \ b x: B x; A: U i\ \ \x: A. b x: \x: A. B x" and PiE: "\f: \x: A. B x; a: A\ \ f `a: B a" and beta: "\a: A; \x. x: A \ b x: B x\ \ (\x: A. b x) `a \ b a" and eta: "f: \x: A. B x \ \x: A. f `x \ f" and Pi_cong: "\ A: U i; \x. x: A \ B x: U i; \x. x: A \ B' x: U i; \x. x: A \ B x \ B' x \ \ \x: A. B x \ \x: A. B' x" and lam_cong: "\\x. x: A \ b x \ c x; A: U i\ \ \x: A. b x \ \x: A. c x" section \\-type\ axiomatization Sig :: \o \ (o \ o) \ o\ and pair :: \o \ o \ o\ ("(2<_,/ _>)") and SigInd :: \o \ (o \ o) \ (o \ o) \ (o \ o \ o) \ o \ o\ syntax "_Sum" :: \idt \ o \ o \ o\ ("(2\_: _./ _)" 20) translations "\x: A. B" \ "CONST Sig A (\x. B)" abbreviation Prod (infixl "\" 50) where "A \ B \ \_: A. B" axiomatization where SigF: "\\x. x: A \ B x: U i; A: U i\ \ \x: A. B x: U i" and SigI: "\\x. x: A \ B x: U i; a: A; b: B a\ \ : \x: A. B x" and SigE: "\ p: \x: A. B x; A: U i; \x. x : A \ B x: U i; \p. p: \x: A. B x \ C p: U i; \x y. \x: A; y: B x\ \ f x y: C \ \ SigInd A (\x. B x) (\p. C p) f p: C p" and Sig_comp: "\ a: A; b: B a; \x. x: A \ B x: U i; \p. p: \x: A. B x \ C p: U i; \x y. \x: A; y: B x\ \ f x y: C \ \ SigInd A (\x. B x) (\p. C p) f \ f a b" and Sig_cong: "\ \x. x: A \ B x \ B' x; A: U i; \x. x : A \ B x: U i; \x. x : A \ B' x: U i \ \ \x: A. B x \ \x: A. B' x" section \Proof commands\ named_theorems typechk ML_file \../lib/lib.ML\ ML_file \../lib/goals.ML\ ML_file \../lib/focus.ML\ section \Congruence automation\ (*Work in progress*) ML_file \../lib/congruence.ML\ section \Methods\ ML_file \../lib/elimination.ML\ \ \declares the [elims] attribute\ named_theorems intros and comps lemmas [intros] = PiF PiI SigF SigI and [elims] = PiE SigE and [comps] = beta Sig_comp and [cong] = Pi_cong lam_cong Sig_cong ML_file \../lib/tactics.ML\ method_setup assumptions = \Scan.succeed (fn ctxt => SIMPLE_METHOD ( CHANGED (TRYALL (assumptions_tac ctxt))))\ method_setup known = \Scan.succeed (fn ctxt => SIMPLE_METHOD ( CHANGED (TRYALL (known_tac ctxt))))\ method_setup intro = \Scan.succeed (fn ctxt => SIMPLE_METHOD (HEADGOAL (intro_tac ctxt)))\ method_setup intros = \Scan.succeed (fn ctxt => SIMPLE_METHOD (HEADGOAL (intros_tac ctxt)))\ method_setup elim = \Scan.option Args.term >> (fn tm => fn ctxt => SIMPLE_METHOD' (SIDE_CONDS (elims_tac tm ctxt) ctxt))\ method elims = elim+ (*This could possibly use additional simplification hints via a simp: modifier*) method_setup typechk = \Scan.succeed (fn ctxt => SIMPLE_METHOD ( CHANGED (ALLGOALS (TRY o typechk_tac ctxt))))\ method_setup rule = \Attrib.thms >> (fn ths => fn ctxt => SIMPLE_METHOD (HEADGOAL (rule_tac ths ctxt)))\ method_setup dest = \Scan.lift (Scan.option (Args.parens Parse.int)) -- Attrib.thms >> (fn (opt_n, ths) => fn ctxt => SIMPLE_METHOD (HEADGOAL (dest_tac opt_n ths ctxt)))\ subsection \Rewriting\ \ \\subst\ method\ 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" \ \\rewrite\ method\ consts rewrite_HOLE :: "'a::{}" ("\") lemma eta_expand: fixes f :: "'a::{} \ 'b::{}" shows "f \ \x. f x" . lemma rewr_imp: assumes "PROP A \ PROP B" shows "(PROP A \ PROP C) \ (PROP B \ PROP C)" apply (rule Pure.equal_intr_rule) apply (drule equal_elim_rule2[OF assms]; assumption) apply (drule equal_elim_rule1[OF assms]; assumption) done lemma imp_cong_eq: "(PROP A \ (PROP B \ PROP C) \ (PROP B' \ PROP C')) \ ((PROP B \ PROP A \ PROP C) \ (PROP B' \ PROP A \ PROP C'))" apply (Pure.intro Pure.equal_intr_rule) apply (drule (1) cut_rl; drule Pure.equal_elim_rule1 Pure.equal_elim_rule2; assumption)+ apply (drule Pure.equal_elim_rule1 Pure.equal_elim_rule2; assumption)+ done ML_file \~~/src/HOL/Library/cconv.ML\ ML_file \../lib/rewrite.ML\ \ \\reduce\ method computes terms via judgmental equalities\ setup \ map_theory_simpset (fn ctxt => ctxt addSolver (mk_solver "" typechk_tac)) \ method reduce uses add = (simp add: comps add | subst comps)+ section \Implicit notations\ text \ \?\ is used to mark implicit arguments in definitions, while \{}\ is expanded immediately for elaboration in statements. \ consts iarg :: \'a\ ("?") hole :: \'b\ ("{}") ML_file \../lib/implicits.ML\ attribute_setup implicit = \Scan.succeed Implicits.implicit_defs_attr\ ML \ val _ = Context.>> (Syntax_Phases.term_check 1 "" (fn ctxt => map (Implicits.make_holes ctxt))) \ text \Automatically insert inhabitation judgments where needed:\ consts inhabited :: \o \ prop\ ("(_)") translations "CONST inhabited A" \ "CONST has_type {} A" section \Lambda coercion\ \ \Coerce object lambdas to meta-lambdas\ abbreviation (input) lambda :: \o \ o \ o\ where "lambda f \ \x. f `x" ML_file \~~/src/Tools/subtyping.ML\ declare [[coercion_enabled, coercion lambda]] translations "f x" \ "f `x" section \Functions\ lemma eta_exp: assumes "f: \x: A. B x" shows "f \ \x: A. f x" by (rule eta[symmetric]) lemma lift_universe_codomain: assumes "A: U i" "f: A \ U j" shows "f: A \ U (S j)" apply (sub eta_exp) apply known apply (Pure.rule intros; rule lift_universe) done subsection \Function composition\ definition "funcomp A g f \ \x: A. g `(f `x)" syntax "_funcomp" :: \o \ o \ o \ o\ ("(2_ \\<^bsub>_\<^esub>/ _)" [111, 0, 110] 110) translations "g \\<^bsub>A\<^esub> f" \ "CONST funcomp A g f" lemma funcompI [typechk]: assumes "A: U i" "B: U i" "\x. x: B \ C x: U i" "f: A \ B" "g: \x: B. C x" shows "g \\<^bsub>A\<^esub> f: \x: A. C (f x)" unfolding funcomp_def by typechk lemma funcomp_assoc [comps]: assumes "f: A \ B" "g: B \ C" "h: \x: C. D x" "A: U i" shows "(h \\<^bsub>B\<^esub> g) \\<^bsub>A\<^esub> f \ h \\<^bsub>A\<^esub> g \\<^bsub>A\<^esub> f" unfolding funcomp_def by reduce lemma funcomp_lambda_comp [comps]: assumes "A: U i" "\x. x: A \ b x: B" "\x. x: B \ c x: C x" shows "(\x: B. c x) \\<^bsub>A\<^esub> (\x: A. b x) \ \x: A. c (b x)" unfolding funcomp_def by reduce lemma funcomp_apply_comp [comps]: assumes "f: A \ B" "g: \x: B. C x" "x: A" "A: U i" "B: U i" "\x y. x: B \ C x: U i" shows "(g \\<^bsub>A\<^esub> f) x \ g (f x)" unfolding funcomp_def by reduce text \Notation:\ definition funcomp_i (infixr "\" 120) where [implicit]: "funcomp_i g f \ g \\<^bsub>?\<^esub> f" translations "g \ f" \ "g \\<^bsub>A\<^esub> f" subsection \Identity function\ abbreviation id where "id A \ \x: A. x" lemma id_type[typechk]: "A: U i \ id A: A \ A" and id_comp [comps]: "x: A \ (id A) x \ x" \ \for the occasional manual rewrite\ by reduce lemma id_left [comps]: assumes "f: A \ B" "A: U i" "B: U i" shows "(id B) \\<^bsub>A\<^esub> f \ f" by (subst eta_exp[of f]) (reduce, rule eta) lemma id_right [comps]: assumes "f: A \ B" "A: U i" "B: U i" shows "f \\<^bsub>A\<^esub> (id A) \ f" by (subst eta_exp[of f]) (reduce, rule eta) lemma id_U [typechk]: "id (U i): U i \ U i" by typechk (fact U_in_U) section \Pairs\ definition "fst A B \ \p: \x: A. B x. SigInd A B (\_. A) (\x y. x) p" definition "snd A B \ \p: \x: A. B x. SigInd A B (\p. B (fst A B p)) (\x y. y) p" lemma fst_type [typechk]: assumes "A: U i" "\x. x: A \ B x: U i" shows "fst A B: (\x: A. B x) \ A" unfolding fst_def by typechk lemma fst_comp [comps]: assumes "a: A" "b: B a" "A: U i" "\x. x: A \ B x: U i" shows "fst A B \ a" unfolding fst_def by reduce lemma snd_type [typechk]: assumes "A: U i" "\x. x: A \ B x: U i" shows "snd A B: \p: \x: A. B x. B (fst A B p)" unfolding snd_def by typechk reduce lemma snd_comp [comps]: assumes "a: A" "b: B a" "A: U i" "\x. x: A \ B x: U i" shows "snd A B \ b" unfolding snd_def by reduce subsection \Notation\ definition fst_i ("fst") where [implicit]: "fst \ Spartan.fst ? ?" definition snd_i ("snd") where [implicit]: "snd \ Spartan.snd ? ?" translations "fst" \ "CONST Spartan.fst A B" "snd" \ "CONST Spartan.snd A B" subsection \Projections\ Lemma fst [typechk]: assumes "p: \x: A. B x" "A: U i" "\x. x: A \ B x: U i" shows "fst p: A" by typechk Lemma snd [typechk]: assumes "p: \x: A. B x" "A: U i" "\x. x: A \ B x: U i" shows "snd p: B (fst p)" by typechk method fst for p::o = rule fst[of p] method snd for p::o = rule snd[of p] subsection \Properties of \\ Lemma (derive) Sig_dist_exp: assumes "p: \x: A. B x \ C x" "A: U i" "\x. x: A \ B x: U i" "\x. x: A \ C x: U i" shows "(\x: A. B x) \ (\x: A. C x)" apply (elim p) focus vars x y apply intro \ apply intro apply assumption apply (fst y) done \ apply intro apply assumption apply (snd y) done done done end