fun mk_relT aT bT = aT --> bT --> HOLogic.boolT; fun mk_relcompp r s = let val (rT, sT) = apply2 fastype_of (r, s); val ((xT, _), (_, zTs)) = apply2 dest_funT (rT, sT); val T = rT --> sT --> mk_relT xT (fst (dest_funT zTs)); inConst (@{const_name relcompp}, T) $ r $ s end; val mk_OO = fold_rev mk_relcompp;
(* option from sum *) fun mk_MaybeT T = mk_sumT (HOLogic.unitT, T); fun mk_Nothing T = BNF_FP_Util.mk_Inl T HOLogic.unit; val Just_const = BNF_FP_Util.Inr_const HOLogic.unitT; fun mk_Just tm = Just_const (fastype_of tm) $ tm; fun Maybe_map_const T = letval (xT, yT) = dest_funT T in Const (@{const_name map_sum}, (HOLogic.unitT --> HOLogic.unitT) --> T --> mk_MaybeT xT --> mk_MaybeT yT) $
HOLogic.id_const HOLogic.unitT end; fun mk_Maybe_map tm = Maybe_map_const (fastype_of tm) $ tm; fun fromJust_const T = Const (@{const_name sum.projr}, mk_MaybeT T --> T)
fun rel_Maybe_const T U = Const (@{const_name rel_sum}, (HOLogic.unitT --> HOLogic.unitT --> HOLogic.boolT) -->
(T --> U --> HOLogic.boolT) --> mk_MaybeT T --> mk_MaybeT U --> HOLogic.boolT) $
HOLogic.eq_const HOLogic.unitT fun set_Maybe_const T = Const (@{const_name Basic_BNFs.setr}, mk_MaybeT T --> HOLogic.mk_setT T)
fun Inf_const T = Const (@{const_name Inf}, HOLogic.mk_setT T --> T);
fun Image_const T = let val relT = HOLogic.mk_setT (HOLogic.mk_prodT (T, T)); val setT = HOLogic.mk_setT T; inConst (@{const_name Image}, relT --> setT --> setT) end;
fun bot_const T = Const (@{const_name bot}, T);
fun mk_insert x S = Const (@{const_name Set.insert}, fastype_of x --> fastype_of S --> fastype_of S) $ x $ S;
fun mk_vimage f s = letval (xT, yT) = dest_funT (fastype_of f) in Const (@{const_name vimage}, (xT --> yT) --> HOLogic.mk_setT yT --> HOLogic.mk_setT xT) $ f $ s end;
fun mk_case_prod (x, y) tm = let val ((x, xT), (y, yT)) = apply2 dest_Free (x, y); val prodT = HOLogic.mk_prodT (xT, yT); in HOLogic.Collect_const prodT $ (Const (@{const_name case_prod},
(xT --> yT --> HOLogic.boolT) --> prodT --> HOLogic.boolT) $ absfree (x, xT)
(absfree (y, yT) tm)) end;
fun mk_Trueprop_implies (ps, c) =
Logic.list_implies (map HOLogic.mk_Trueprop ps, HOLogic.mk_Trueprop c);
fun mk_Collect (v, tm) = letval (n, T) = dest_Free v in
HOLogic.mk_Collect (n, T, tm) end;
(** witnesses **) fun prepare_wits is_quotient RepT wits opts alphas wits_F var_as var_as' sets lthy = let fun binder_types_until_eq V T = let fun strip (TU as Type ("fun", [T, U])) = if V = TU then [] else T :: strip U
| strip T = if V = T then [] else
error ("Bad type for witness: " ^ quote (Syntax.string_of_typ lthy T)); in strip T end;
val Iwits = the_default wits_F (Option.map (map (`(map (fn T =>
find_index (fn U => T = U) alphas) o binder_types_until_eq RepT o fastype_of))) wits);
val Iwits = if is_quotient then let val subsumed_Iwits = filter (fn (J, _) => exists (fn (I, _) => subset (op =) (I, J)) wits_F) Iwits; val _ = if null subsumed_Iwits orelse exists (fn No_Warn_Wits => true | _ => false) opts then () else let val (suffix1, suffix2, be) =
(if length subsumed_Iwits = 1 then ("", "", "is") else ("s", "es", "are")) in
subsumed_Iwits
|> map (Syntax.pretty_typ lthy o fastype_of o snd)
|> Pretty.big_list
("The following type" ^ suffix1 ^ " of nonemptiness witness" ^ suffix2 ^ " of the raw type's BNF " ^ be ^ " subsumed by the existing raw witnesses:")
|> (fn pt => Pretty.chunks [pt,
Pretty.para ("You do not need to lift these subsumed witnesses.")])
|> Pretty.string_of
|> warning end; in
filter_out (fn (J, _) => exists (fn (I, _) => subset (op =) (I, J)) wits_F) Iwits end else Iwits;
val wit_goals = maps (BNF_Def.mk_wit_goals var_as var_as' sets) Iwits;
val lost_wits = if is_quotient then [] else
filter_out (fn (J, _) => exists (fn (I, _) => subset (op =) (I, J)) Iwits) wits_F;
val _ = if null lost_wits orelse exists (fn No_Warn_Wits => true | _ => false) opts then () else let val what = (if is_quotient then"quotient type"else"typedef"); val (suffix1, suffix2, be) =
(if length lost_wits = 1 then ("", "", "was") else ("s", "es", "were")) in
lost_wits
|> map (Syntax.pretty_typ lthy o fastype_of o snd)
|> Pretty.big_list
("The following type" ^ suffix1 ^ " of nonemptiness witness" ^ suffix2 ^ " of the raw type's BNF " ^ be ^ " lost:")
|> (fn pt => Pretty.chunks [pt,
Pretty.para ("You can specify a liftable witness (e.g., a term of one of the above types\
\ that satisfies the " ^ what ^ "'s invariant)\
\ using the annotation [wits: <term>].")])
|> Pretty.string_of
|> warning end; in (Iwits, wit_goals) end;
(** transfer theorems **)
fun mk_transfer_thms' bnf_F bnf_G name consts Tss crel_def pcrel_def defs lthy = let
(* get the "pcrel :: args_raw => rep => abs \<Rightarrow> bool" term and instantiate types *) val (args_raw, (rep, abs)) = pcrel_tm
|> fastype_of
|> binder_types
|> last2; val thy = Proof_Context.theory_of lthy; val tyenv_match = Vartab.empty
|> Sign.typ_match thy ((rep, #rep Tss))
|> Sign.typ_match thy ((abs, #abs Tss)); val args = map (Envir.subst_type tyenv_match) args_raw; val (pcrel_a, pcrel_b) = Envir.subst_term (tyenv_match, Vartab.empty) pcrel_tm
|> `(subst_atomic_types (#alphas Tss @ #betas Tss ~~ #gammas Tss @ #deltas Tss));
(* match "crel :: ?a F \<Rightarrow> {a G} \<Rightarrow> bool" with "a G" *) val tyenv_match = Vartab.empty |> Sign.typ_match thy
(crel_tm |> fastype_of |> binder_types |> tl |> hd, #abs Tss); val crel_b = Envir.subst_term (tyenv_match, Vartab.empty) crel_tm
|> subst_atomic_types (#alphas Tss ~~ #betas Tss); val crel_d = subst_atomic_types (#betas Tss ~~ #deltas Tss) crel_b;
(* instantiate pcrel with Qs and Rs*) val dead_args = map binder_types args
|> map (fn [T,U] => if T = U then SOME T else NONE | _ => NONE); val parametrize = let fun go (SOME T :: dTs) tms = HOLogic.eq_const T :: go dTs tms
| go (_ :: dTs) (tm :: tms) = tm :: go dTs tms
| go (_ :: dTs) tms = go dTs tms
| go _ _ = []; in go dead_args end; val pcrel_Qs = list_comb (pcrel_b, parametrize var_Qs); val pcrel_Rs = list_comb (pcrel_a, parametrize var_Rs);
(* get the order of the dead variables right *) val Ds0 = Library.union (op =) (maps the_list dead_args) (#Ds0 Tss); val permute_Ds = (mk_T_of_bnf Ds0 (#betas Tss) bnf_G, nth (binder_types (type_of pcrel_Qs)) 1)
|> apply2 (fn Type (_, Ts) => Ts | _ => []) |> op~~ |> typ_subst_atomic; val Ds0 = map permute_Ds Ds0;
(* terms for sets of the set_transfer thms *) val rel_sets_Q = @{map 3} (fn aT => fn bT => fn Q =>
mk_rel 1 [aT] [bT] @{term rel_set} $ Q) (#alphas Tss) (#betas Tss) var_Qs;
(* rewrite rules for pcrel and BNF's relator: "pcrel Q = rel_F OO crel" *) fun mk_pcr_rel_F_eq Ts Us pcrel vs crel = let val thm = HOLogic.mk_Trueprop (HOLogic.mk_eq (pcrel, mk_relcompp (list_comb
(mk_rel_of_bnf (#deads Tss) (Ts Tss) (Us Tss) bnf_F, vs)) crel)); fun tac ctxt = unfold_thms_tac ctxt (pcrel_def :: defs @ @{thm id_bnf_apply} ::
Transfer.get_relator_eq ctxt) THEN (HEADGOAL (rtac ctxt refl)) in prove lthy vs thm tac |> mk_abs_def end;
(* create transfer-relations from term('s type) *) fun mk_transfer_rel' i tm = let fun go T' (n, q) = case T'of Type ("fun", [T as Type ("fun", _), U]) =>
go U (n+1, q) |>> mk_rel_fun (fst (go T (n, q)))
| Type ("fun", [T, U]) =>
go T (n, q) |-> (fn x => fn st => go U st |>> mk_rel_fun x)
| Type (@{type_name bool}, _) => (HOLogic.eq_const HOLogic.boolT, (n, q))
| Type (@{type_name set}, _) => (nth rel_sets_Q n, (n, q))
| Type _ => (if q then pcrel_Qs else pcrel_Rs, (n, not q))
| TFree _ => (nth (if q then var_Qs else var_Rs) n, (n, not q))
| _ => raiseMatch in go (fastype_of tm) (i, true) |> fst end;
(* prove transfer rules *) fun prove_transfer_thm' i vars new_tm const = let val tm = HOLogic.mk_Trueprop (mk_transfer_rel' i new_tm $ #raw const $ new_tm); val tac = (fn ctxt => unfold_thms_tac ctxt (pcr_rel_F_eqs @ [crel_def]) THEN
#tac const {Rs=var_Rs,Qs=var_Qs} ctxt); in prove lthy vars tm tac end; val prove_transfer_thm = prove_transfer_thm' 0; (* map transfer: "((Q ===> R) ===> pcr_G Q ===> pcr_G R) map_F' map_G" *) val map_G = mk_map_of_bnf Ds0 (#betas Tss) (#deltas Tss) bnf_G; val map_transfer = prove_transfer_thm (var_Qs @ var_Rs) map_G (#map consts); (* pred_transfer: "((Q ===> (=)) ===> pcr_G Q ===> (=)) pred_F' pred_G" *) val pred_G = mk_pred_of_bnf Ds0 (#betas Tss) bnf_G; val pred_transfer = #pred consts |> Option.map (fn p =>
("pred", [prove_transfer_thm (var_Qs @ var_Rs) pred_G p])); (* rel_transfer: "((Q ===> R ===> (=)) ===> pcr_G Q ===> pcr_G R ===> (=)) rel_F' rel_G" *) val rel_G = mk_rel_of_bnf Ds0 (#betas Tss) (#deltas Tss) bnf_G; val rel_transfer = prove_transfer_thm (var_Qs @ var_Rs) rel_G (#rel consts); (* set_transfer: "(pcr_G Q ===> rel_set Q) set_F' set_G" *) val sets_G = mk_sets_of_bnf (replicate live Ds0) (replicate live (#betas Tss)) bnf_G; fun mk_set_transfer i set_G raw tac = prove_transfer_thm' i var_Qs set_G {raw=raw, tac=tac}; val sets_transfer = @{map 4} mk_set_transfer
(0 upto (live-1)) sets_G (#raws (#sets consts)) (#tacs (#sets consts)); (* export transfer theorems *) val transform = Morphism.thm (Morphism.thm_morphism "BNF" (unfold_thms lthy defs)) |> map; val b = Binding.qualified_name name; val qualify = letval qs = Binding.path_of b; in fold_rev (fn (s, mand) => Binding.qualify mand s) qs end; fun mk_binding n = Binding.name (n ^ "_transfer_raw")
|> Binding.qualify true (Binding.name_of b) |> qualify; val notes = [("map", [map_transfer]), ("rel", [rel_transfer])] @ the_list pred_transfer @
[("set", sets_transfer)] |> map (fn (n, thms) =>
((mk_binding n, []), [(transform thms, @{attributes [transfer_rule]})]));
in lthy |> Local_Theory.notes notes |> snd end;
(* transfer theorems for map, pred (in case of a typedef), rel and sets *) fun mk_transfer_thms quiet bnf_F bnf_G name consts thm Tss defs lthy = let
fun mk_crel_def quot_thm =
(case thm of
Quotient equiv => @{thm Quotient_crel_quotient} OF [quot_thm, equiv]
| Typedef => hd ([quot_thm] RL @{thms Quotient_crel_typedef Quotient_crel_typecopy})); fun no_quotient _ = [Pretty.para ("No quotient theorem has been registered for " ^
Binding.name_of (name_of_bnf bnf_G) ^ "."),
Pretty.para "Use setup_lifting to register a quotient or type definition theorem."]; fun wrong_quotient T lthy = [Pretty.para ("A wrong quotient theorem has been registered for " ^
Binding.name_of (name_of_bnf bnf_G) ^ "."),
Pretty.para ("Expected raw type " ^
Pretty.string_of (Syntax.pretty_typ lthy (T_of_bnf bnf_F)) ^ " but the quotient theorem has raw type " ^
Pretty.string_of (Syntax.pretty_typ lthy T) ^ "."),
Pretty.para "Use setup_lifting to register a different quotient or type definition theorem."]; fun pcr_why _ = [Pretty.para ("The pcr_" ^ Binding.name_of (name_of_bnf bnf_G) ^ " relator has not been defined.")]; fun warn_transfer why lthy =
(Pretty.para "The transfer theorems can't be generated:" :: why lthy)
|> Pretty.chunks |> Pretty.string_of |> warning |> K lthy; fun maybe_warn_transfer why = not quiet ? warn_transfer why; in case Lifting_Info.lookup_quotients lthy name of
SOME {pcr_info, quot_thm} =>
(let val crel_def = mk_crel_def quot_thm; val rty = Lifting_Util.quot_thm_rty_qty quot_thm |> fst; val thy = Proof_Context.theory_of lthy; in if Sign.typ_instance thy (rty, T_of_bnf bnf_F) then
(case pcr_info of
SOME {pcrel_def, ...} =>
mk_transfer_thms' bnf_F bnf_G name consts Tss crel_def pcrel_def defs lthy
| _ => maybe_warn_transfer pcr_why lthy) else maybe_warn_transfer (wrong_quotient rty) lthy end)
| _ => maybe_warn_transfer no_quotient lthy end;
(** typedef_bnf **)
fun mk_typedef_transfer_tacs bnf_F bnf_G thms old_defs
map_raw rel_raw pred_raw sets_raw = let
val live = live_of_bnf bnf_G; val Abs_G_inverse = @{thm type_definition.Abs_inverse} OF [#typedef thms]; val Rep_G = @{thm type_definition.Rep} OF [#typedef thms];
fun common_tac addefs tac = (fn _ => fn ctxt =>
HEADGOAL (EVERY' [SELECT_GOAL (unfold_thms_tac ctxt addefs),
REPEAT_DETERM o rtac ctxt rel_funI,
SELECT_GOAL (unfold_thms_tac ctxt @{thms o_apply}),
REPEAT_DETERM o eresolve_tac ctxt @{thms relcomppE exE conjE},
hyp_subst_tac ctxt]) THEN tac ctxt)
fun map_tac ctxt = (HEADGOAL o EVERY')
[rtac ctxt @{thm relcomppI},
etac ctxt (mk_rel_funDN (live+1) (map_transfer_of_bnf bnf_F)),
REPEAT_DETERM_N live o assume_tac ctxt,
SELECT_GOAL (unfold_thms_tac ctxt [Abs_G_inverse OF [#map_closed thms] OF [Rep_G]]),
REPEAT_DETERM o rtac ctxt refl]; val map_tac = common_tac [#map old_defs] map_tac;
fun rel_tac ctxt =
HEADGOAL (etac ctxt (mk_rel_funDN (live+2) (rel_transfer_of_bnf bnf_F)) THEN'
REPEAT_DETERM_N (live+1) o assume_tac ctxt); val rel_tac = common_tac (#rel old_defs :: @{thms vimage2p_def}) rel_tac;
fun pred_tac ctxt =
HEADGOAL (etac ctxt (mk_rel_funDN (live+1) (pred_transfer_of_bnf bnf_F)) THEN'
REPEAT_DETERM_N live o (assume_tac ctxt)); val pred_tac = common_tac [#pred old_defs] pred_tac;
fun set_tac set_transfer_thm ctxt =
HEADGOAL (etac ctxt (rel_funD OF [set_transfer_thm])); fun mk_set_tac set_def set_transfer = common_tac [set_def] (set_tac set_transfer); val set_tacs = map2 mk_set_tac (#sets old_defs) (set_transfer_of_bnf bnf_F);
in {map={raw=map_raw,tac=map_tac},rel={raw=rel_raw,tac=rel_tac},
sets={raws=sets_raw,tacs=set_tacs},pred=SOME{raw=pred_raw,tac=pred_tac}} end;
fun typedef_bnf thm wits specs map_b rel_b pred_b opts lthy = let val plugins =
get_first (fn Plugins_Option f => SOME (f lthy) | _ => NONE) (rev opts)
|> the_default Plugin_Name.default_filter;
(* extract Rep Abs F RepT AbsT *) val (Rep_G, Abs_G, F) = strip3 thm; val typ_Abs_G = dest_funT (fastype_of Abs_G); val RepT = fst typ_Abs_G; (* F *) val AbsT = snd typ_Abs_G; (* G *) val AbsT_name = dest_Type_name AbsT; val tvs = AbsT |> dest_Type_args |> map (fst o dest_TVar); val alpha0s = map (TFree o snd) specs;
val _ = length tvs = length alpha0s orelse
error ("Expected " ^ string_of_int (length tvs) ^ " type argument(s) to " ^ quote AbsT_name);
(* instantiate the new type variables newtvs to oldtvs *) val subst = subst_TVars (tvs ~~ alpha0s); val typ_subst = typ_subst_TVars (tvs ~~ alpha0s);
val Rep_G = subst Rep_G; val Abs_G = subst Abs_G; val F = subst F; val RepT = typ_subst RepT; val AbsT = typ_subst AbsT;
fun flatten_tyargs Ass = map dest_TFree alpha0s
|> filter (fn T => exists (fn Ts => member op= Ts T) Ass);
val Ds0 = filter (is_none o fst) specs |> map snd;
(* get the bnf for RepT *) val ((bnf_F, (deads, alphas)), ((_, unfolds), lthy)) =
bnf_of_typ true Hardly_Inline (Binding.qualify true AbsT_name) flatten_tyargs []
Ds0 RepT ((empty_comp_cache, empty_unfolds), lthy);
val set_bs = map (fn T => find_index (fn U => T = U) alpha0s) alphas
|> map (the_default Binding.empty o fst o nth specs);
val _ = (case alphas of [] => error "No live variables" | _ => ());
(* val wit_closed_F = @{term "wit_F a \<in> F"}; *) val (var_as, names_lthy) = mk_Frees "a" alphas names_lthy; val (var_bs, _) = mk_Frees "a" alphas names_lthy; val sets = mk_sets_of_bnf (replicate live deads) (replicate live alphas) bnf_F; val (Iwits, wit_goals) =
prepare_wits false RepT wits opts alphas wits_F var_as var_bs sets lthy; val wit_closed_Fs =
Iwits |> map (fn (I, wit_F) => let val vars = map (nth var_as) I; val wit_a = list_comb (wit_F, vars); in fold_rev Logic.all vars (HOLogic.mk_Trueprop (HOLogic.mk_mem (wit_a, aF_set))) end);
val goals = [map_closed_F, zip_closed_F] @ wit_closed_Fs @
(case wits of NONE => [] | _ => wit_goals);
fun after_qed ([map_closed_thm] :: [zip_closed_thm] :: wit_thmss) lthy = let val (wit_closed_thms, wit_thms) =
(case wits of
NONE => (map the_single wit_thmss, wit_thms_of_bnf bnf_F)
| _ => chop (length wit_closed_Fs) (map the_single wit_thmss))
(* construct map set bd rel wit *) (* val map_G = @{term "\<lambda>f. Abs_G o map_F f o Rep_G"}; *) val Abs_Gb = subst_b Abs_G; val map_G = fold_rev lambda var_fs
(HOLogic.mk_comp (HOLogic.mk_comp (Abs_Gb, map_f), Rep_G)); val map_raw = fold_rev lambda var_fs map_f;
(* val sets_G = [@{term "set_F o Rep_G"}]; *) val sets_F = mk_sets_of_bnf (replicate live deads) (replicate live alphas) bnf_F; val sets_G = map (fn set_F => HOLogic.mk_comp (set_F, Rep_G)) sets_F;
(* val bd_G = @{term "bd_F"}; *) val bd_F = mk_bd_of_bnf deads alphas bnf_F; val bd_G = bd_F;
(* val rel_G = @{term "\<lambda>R. BNF_Def.vimage2p Rep_G Rep_G (rel_F R)"}; *) val rel_F = mk_rel_of_bnf deads alphas betas bnf_F; val (typ_Rs, _) = strip_typeN live (fastype_of rel_F);
val (var_Rs, names_lthy) = mk_Frees "R" typ_Rs lthy; val Rep_Gb = subst_b Rep_G; val rel_G = fold_rev absfree (map dest_Free var_Rs)
(mk_vimage2p Rep_G Rep_Gb $ list_comb (rel_F, var_Rs)); val rel_raw = fold_rev absfree (map dest_Free var_Rs) (list_comb (rel_F, var_Rs));
(* val pred_G = @{term "\<lambda>P. pred_F P o Rep_G"}; *) val pred_F = mk_pred_of_bnf deads alphas bnf_F; val (typ_Ps, _) = strip_typeN live (fastype_of pred_F);
fun quotient_bnf (equiv_thm, quot_thm) wits specs map_b rel_b pred_b opts lthy = let (* extract rep_G and abs_G *) val (equiv_rel, abs_G, rep_G) = strip3 quot_thm; val (repT, absT) = dest_funT (fastype_of abs_G); (* ("?'a F", "?'a G") *) val absT_name = dest_Type_name absT;
val tvs = map (fst o dest_TVar) (dest_Type_args absT); val _ = length tvs = length specs orelse
error ("Expected " ^ string_of_int (length tvs) ^ " type argument" ^ (if (length tvs) = 1 then""else"s") ^ " to " ^ quote absT_name);
(* instantiate TVars *) val alpha0s = map (TFree o snd) specs; val typ_subst = typ_subst_TVars (tvs ~~ alpha0s); val (repT, absT) = apply2 typ_subst (repT, absT);
(* get the bnf for RepT *) val Ds0 = filter (is_none o fst) specs |> map snd;
fun flatten_tyargs Ass = map dest_TFree alpha0s |> filter (fn T => exists (fn Ts => member op= Ts T) Ass);
val ((bnf_F, (deads, alphas)), ((_, unfolds), lthy)) =
bnf_of_typ true Hardly_Inline (Binding.qualify true absT_name) flatten_tyargs
[] Ds0 repT ((empty_comp_cache, empty_unfolds), lthy); val live = length alphas; val _ = (if live = 0 then error "No live variables"else ());
val defs = #map_unfolds unfolds @ flat (#set_unfoldss unfolds) @ #rel_unfolds unfolds; val set_bs = map (fn T => find_index (fn U => T = U) alpha0s) alphas
|> map (the_default Binding.empty o fst o nth specs);
(* create and instantiate all the needed type variables *) val subst = subst_TVars (tvs ~~ alpha0s); val (abs_G, rep_G) = apply2 subst (abs_G, rep_G);
(* create local definitions `b = tm` with n arguments *) fun suffix tm s = Long_Name.base_name (dest_Const_name tm) ^ s; fun define lthy b n tm = let val b = Binding.qualify true absT_name (Binding.qualified_name b); val ((tm, (_, def)), (lthy, lthy_old)) = lthy
|> (snd o Local_Theory.begin_nested)
|> Local_Theory.define_internal (((Binding.concealed b, NoSyn), (Binding.empty_atts, tm)))
||> `Local_Theory.end_nested; val phi = Proof_Context.export_morphism lthy_old lthy; val tm = Term.subst_atomic_types
(map (`(Morphism.typ phi)) (alphas @ betas @ gammas @ map TFree Ds0))
(Morphism.term phi tm); val def = mk_unabs_def n (HOLogic.mk_obj_eq (Morphism.thm phi def)); in ({def=def, tm=tm}, lthy) end;
(* internally use REL, not the user-provided definition *) val (REL, lthy) = define lthy "REL" 0 equiv_rel_a; val REL_def = sym RS eq_reflection OF [#def REL]; fun REL_rewr_all ctxt thm = Conv.fconv_rule
(Conv.top_conv (fn _ => Conv.try_conv (Conv.rewr_conv REL_def)) ctxt) thm;
val equiv_rel_a' = equiv_rel_a; val equiv_rel_a = #tm REL; val (equiv_rel_b, equiv_rel_c) = apply2 (subst_Ts equiv_rel_a) (betas, gammas);
(* rel_pos_distr: @{term "\<And>A B.
A \<circ>\<circ> B \<noteq> bot \<Longrightarrow> REL \<circ>\<circ> rel_F A \<circ>\<circ> REL \<circ>\<circ> rel_F B \<circ>\<circ> REL \<le> REL \<circ>\<circ> rel_F (A \<circ>\<circ> B) \<circ>\<circ> REL"} *) fun compp_not_bot comp aT cT = let val T = mk_relT aT cT; val mk_eq = HOLogic.eq_const T; in HOLogic.mk_not (mk_eq $ comp $ bot_const T) end; val ab_comps = map2 mk_relcompp var_Ps var_Qs; val ne_comps = (@{map 3} compp_not_bot ab_comps alphas gammas); val ab_prem = foldr1 HOLogic.mk_conj ne_comps;
val REL_pos_distrI_tm = let val le_relcomps = map2 mk_leq ab_comps var_Rs; val assm = mk_OO [equiv_rel_a, list_comb (rel_F_ab, var_Ps),
equiv_rel_b, list_comb (rel_F_bc, var_Qs)] equiv_rel_c; val concl = mk_OO [equiv_rel_a, list_comb (rel_F_ac, var_Rs)] equiv_rel_c; in
mk_Trueprop_implies
([assm $ var_x $ var_y'] @ ne_comps @ le_relcomps, concl $ var_x $ var_y') end;
(* {(x, y) . REL x y} *) fun mk_rel_pairs rel = mk_case_prod (var_x, var_x') (rel $ var_x $ var_x') val rel_pairs = mk_rel_pairs equiv_rel_a;
(* rel_Inter: \<And>S. \<lbrakk> S \<noteq> {}; \<Inter>S \<noteq> {} \<rbrakk> \<Longrightarrow>
(\<Inter>A\<in>S. {(x, y). REL x y} `` {x. set_F x \<subseteq> A}) \<subseteq> {(x, y). REL x y} `` {x. set_F x \<subseteq> \<Inter>S} *) fun rel_Inter_from_set_F (var_A, var_S) set_F = let
val typ_aset = fastype_of var_A;
(* \<Inter>S *) val inter_S = Inf_const typ_aset $ var_S;
(* [S \<noteq> {}, \<Inter>S \<noteq> {}] *) fun not_empty x = letval ty = fastype_of x in HOLogic.mk_not (HOLogic.mk_eq (x, bot_const ty)) end; val prems = map (HOLogic.mk_Trueprop o not_empty) [var_S, inter_S];
(* {x. set_F x \<subseteq> A} *) val setF_sub_A = mk_in [var_A] [set_F] typ_aF;
(* {x. set_F x \<subseteq> \<Inter>S} *) val setF_sub_S = mk_in [inter_S] [set_F] typ_aF;
val goals = rel_pos_distr :: rel_Inters @
(case wits of NONE => [] | _ => wit_goals);
val plugins =
get_first (fn Plugins_Option f => SOME (f lthy) | _ => NONE) (rev opts) |>
the_default Plugin_Name.default_filter;
fun after_qed thmss lthy =
(case thmss of [rel_pos_distr_thm0] :: thmss => let val equiv_thm' = REL_rewr_all lthy equiv_thm; val rel_pos_distr_thm =
@{thm equivp_add_relconj} OF [equiv_thm', equiv_thm', rel_pos_distr_thm0];
val (rel_Inter_thms, wit_thmss) = apply2 (fn f => flat (f live thmss)) (take, drop);
(* construct map_G, sets_G, bd_G, rel_G and wits_G *)
(* map_G f = abs_G o map_F f o rep_G *) val map_G = fold_rev lambda var_fs (HOLogic.mk_comp (HOLogic.mk_comp
(subst_Ts abs_G betas, list_comb (map_F, var_fs)), rep_G)); val map_raw = fold_rev lambda var_fs (list_comb (map_F, var_fs))
|> subst_atomic_types (betas ~~ gammas);
(* Define set_G and the three auxiliary definitions (set_F', F_in, F_in') *) fun mk_set_G var_A set_F lthy = let val typ_a = HOLogic.dest_setT (fastype_of var_A); val set_F'_tm = mk_set_F'_tm typ_a set_F
(* map_F_in_F_in'I: x \<in> F_in' B \<Longrightarrow> map_F f x \<in> F_in' (f ` B) *) val map_F_in_F_in'I_tm = mk_Trueprop_implies ([HOLogic.mk_mem (var_x, #tm F_in' $ var_A')],
HOLogic.mk_mem (map_F_fs_x, subst_b (#tm F_in') $ (mk_image var_f $ var_A'))); fun map_F_in_F_in'I_tac ctxt =
Local_Defs.unfold_tac ctxt (#def F_in' :: #def F_in :: @{thms Bex_def vimage_def Image_iff}) THEN
HEADGOAL (EVERY'
--> --------------------
--> maximum size reached
--> --------------------
¤ 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.34Bemerkung:
(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.