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.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.