datatype ind_scheme = IndScheme of
{T: typ, (* sum of products *)
branches: scheme_branch list,
cases: scheme_case list}
fun ind_atomize ctxt = Simplifier.rewrite_wrt ctxt true @{thms induct_atomize} fun ind_rulify ctxt = Simplifier.rewrite_wrt ctxt true @{thms induct_rulify}
fun meta thm = thm RS eq_reflection
fun sum_prod_conv ctxt = Simplifier.rewrite_wrt ctxt true
(map meta (@{thm split_conv} :: @{thms sum.case}))
fun term_conv ctxt cv t =
cv (Thm.cterm_of ctxt t)
|> Thm.prop_of |> Logic.dest_equals |> snd
fun mk_relT T = HOLogic.mk_setT (HOLogic.mk_prodT (T, T))
fun dest_hhf ctxt t = let val ((params, imp), ctxt') = Variable.focus NONE t ctxt in
(ctxt', map #2 params, Logic.strip_imp_prems imp, Logic.strip_imp_concl imp) end
fun mk_scheme' ctxt cases concl = let fun mk_branch concl = let val (_, ws, Cs, _ $ Pxs) = dest_hhf ctxt concl val (P, xs) = strip_comb Pxs in
SchemeBranch { P=P, xs=map dest_Free xs, ws=ws, Cs=Cs } end
val (branches, cases') = (* correction *) case Logic.dest_conjunctions concl of
[conc] => let val _ $ Pxs = Logic.strip_assums_concl conc val (P, _) = strip_comb Pxs val (cases', conds) =
chop_prefix (Term.exists_subterm (curry op aconv P)) cases val concl' = fold_rev (curry Logic.mk_implies) conds conc in
([mk_branch concl'], cases') end
| concls => (map mk_branch concls, cases)
fun mk_case premise = let val (ctxt', qs, prems, _ $ Plhs) = dest_hhf ctxt premise val (P, lhs) = strip_comb Plhs
fun mk_wf R (IndScheme {T, ...}) =
HOLogic.mk_Trueprop (Const (\<^const_abbrev>\<open>wf\<close>, mk_relT T --> HOLogic.boolT) $ R)
fun mk_ineqs R thesisn (IndScheme {T, cases, branches}) = let fun inject i ts =
Sum_Tree.mk_inj T (length branches) (i + 1) (foldr1 HOLogic.mk_prod ts)
val thesis = Free (thesisn, HOLogic.boolT)
fun mk_pres bdx args = let val SchemeBranch { xs, ws, Cs, ... } = nth branches bdx fun replace (x, v) t = betapply (lambda (Free x) t, v) val Cs' = map (fold replace (xs ~~ args)) Cs val cse =
HOLogic.mk_Trueprop thesis
|> fold_rev (curry Logic.mk_implies) Cs'
|> fold_rev (Logic.all o Free) ws in
Logic.mk_implies (cse, HOLogic.mk_Trueprop thesis) end
fun f (SchemeCase {bidx, qs, oqnames, gs, lhs, rs, ...}) = let fun g (bidx', Gvs, Gas, rcarg) = letval export =
fold_rev (curry Logic.mk_implies) Gas
#> fold_rev (curry Logic.mk_implies) gs
#> fold_rev (Logic.all o Free) Gvs
#> fold_rev mk_forall_rename (oqnames ~~ map Free qs) in
(HOLogic.mk_mem (HOLogic.mk_prod (inject bidx' rcarg, inject bidx lhs), R)
|> HOLogic.mk_Trueprop
|> export,
mk_pres bidx' rcarg
|> export
|> Logic.all thesis) end in map g rs end in map f cases end
fun mk_ind_goal ctxt branches = let fun brnch (SchemeBranch { P, xs, ws, Cs, ... }) =
HOLogic.mk_Trueprop (list_comb (P, map Free xs))
|> fold_rev (curry Logic.mk_implies) Cs
|> fold_rev (Logic.all o Free) ws
|> term_conv ctxt (ind_atomize ctxt)
|> Object_Logic.drop_judgment ctxt
|> HOLogic.tupled_lambda (foldr1 HOLogic.mk_prod (map Free xs)) in
Sum_Tree.mk_sumcases HOLogic.boolT (map brnch branches) end
fun mk_induct_rule ctxt R x complete_thms wf_thm ineqss
(IndScheme {T, cases=scases, branches}) = let val n = length branches val scases_idx = map_index I scases
fun inject i ts =
Sum_Tree.mk_inj T n (i + 1) (foldr1 HOLogic.mk_prod ts) val P_of = nth (map (fn (SchemeBranch { P, ... }) => P) branches)
val P_comp = mk_ind_goal ctxt branches
(* Inductive Hypothesis: !!z. (z,x):R ==> P z *) val ihyp = Logic.all_const T $ Abs ("z", T,
Logic.mk_implies
(HOLogic.mk_Trueprop ( Const (\<^const_name>\<open>Set.member\<close>, HOLogic.mk_prodT (T, T) --> mk_relT T --> HOLogic.boolT)
$ (HOLogic.pair_const T T $ Bound 0 $ x)
$ R),
HOLogic.mk_Trueprop (P_comp $ Bound 0)))
|> Thm.cterm_of ctxt
val aihyp = Thm.assume ihyp
(* Rule for case splitting along the sum types *) val xss = map (fn (SchemeBranch { xs, ... }) => map Free xs) branches val pats = map_index (uncurry inject) xss val sum_split_rule =
Pat_Completeness.prove_completeness ctxt [x] (P_comp $ x) xss (map single pats)
fun prove_branch (bidx, (SchemeBranch { P, xs, ws, Cs, ... }, (complete_thm, pat))) = let val fxs = map Free xs val branch_hyp =
Thm.assume (Thm.cterm_of ctxt (HOLogic.mk_Trueprop (HOLogic.mk_eq (x, pat))))
val C_hyps = map (Thm.cterm_of ctxt #> Thm.assume) Cs
fun prove_case (cidx, SchemeCase {qs, gs, lhs, rs, ...}) ineq_press = let val case_hyps = map (Thm.assume o Thm.cterm_of ctxt o HOLogic.mk_Trueprop o HOLogic.mk_eq)
(fxs ~~ lhs)
val cqs = map (Thm.cterm_of ctxt o Free) qs val ags = map (Thm.assume o Thm.cterm_of ctxt) gs
val replace_x_simpset =
put_simpset HOL_basic_ss ctxt |> Simplifier.add_simps (branch_hyp :: case_hyps) val sih = full_simplify replace_x_simpset aihyp
fun mk_Prec (idx, Gvs, Gas, rcargs) (ineq, pres) = let val cGas = map (Thm.assume o Thm.cterm_of ctxt) Gas val cGvs = map (Thm.cterm_of ctxt o Free) Gvs val import = fold Thm.forall_elim (cqs @ cGvs)
#> fold Thm.elim_implies (ags @ cGas) val ipres = pres
|> Thm.forall_elim (Thm.cterm_of ctxt (list_comb (P_of idx, rcargs)))
|> import in
sih
|> Thm.forall_elim (Thm.cterm_of ctxt (inject idx rcargs))
|> Thm.elim_implies (import ineq) (* Psum rcargs *)
|> Conv.fconv_rule (sum_prod_conv ctxt)
|> Conv.fconv_rule (ind_rulify ctxt)
|> (fn th => th COMP ipres) (* P rs *)
|> fold_rev (Thm.implies_intr o Thm.cprop_of) cGas
|> fold_rev Thm.forall_intr cGvs end
val P_recs = map2 mk_Prec rs ineq_press (* [P rec1, P rec2, ... ] *)
val step = HOLogic.mk_Trueprop (list_comb (P, lhs))
|> fold_rev (curry Logic.mk_implies o Thm.prop_of) P_recs
|> fold_rev (curry Logic.mk_implies) gs
|> fold_rev (Logic.all o Free) qs
|> Thm.cterm_of ctxt
val Plhs_to_Pxs_conv =
foldl1 (uncurry Conv.combination_conv)
(Conv.all_conv :: map (fn ch => K (Thm.symmetric (ch RS eq_reflection))) case_hyps)
val res = Thm.assume step
|> fold Thm.forall_elim cqs
|> fold Thm.elim_implies ags
|> fold Thm.elim_implies P_recs (* P lhs *)
|> Conv.fconv_rule (Conv.arg_conv Plhs_to_Pxs_conv) (* P xs *)
|> fold_rev (Thm.implies_intr o Thm.cprop_of) (ags @ case_hyps)
|> fold_rev Thm.forall_intr cqs (* !!qs. Gas ==> xs = lhss ==> P xs *) in
(res, (cidx, step)) end
val (cases, steps) = split_list (map2 prove_case relevant_cases ineqss')
val bstep = complete_thm
|> Thm.forall_elim (Thm.cterm_of ctxt (list_comb (P, fxs)))
|> fold (Thm.forall_elim o Thm.cterm_of ctxt) (fxs @ map Free ws)
|> fold Thm.elim_implies C_hyps
|> fold Thm.elim_implies cases (* P xs *)
|> fold_rev (Thm.implies_intr o Thm.cprop_of) C_hyps
|> fold_rev (Thm.forall_intr o Thm.cterm_of ctxt o Free) ws
val Pxs =
Thm.cterm_of ctxt (HOLogic.mk_Trueprop (P_comp $ x))
|> Goal.init
|> (Simplifier.rewrite_goals_tac ctxt
(map meta (branch_hyp :: @{thm split_conv} :: @{thms sum.case})) THEN CONVERSION (ind_rulify ctxt) 1)
|> Seq.hd
|> Thm.elim_implies (Conv.fconv_rule Drule.beta_eta_conversion bstep)
|> Goal.finish ctxt
|> Thm.implies_intr (Thm.cprop_of branch_hyp)
|> fold_rev (Thm.forall_intr o Thm.cterm_of ctxt) fxs in
(Pxs, steps) end
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.14Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.