signature BNF_GFP_GREC_SUGAR_UTIL = sig type s_parse_info =
{outer_buffer: BNF_GFP_Grec.buffer,
ctr_guards: term Symtab.table,
inner_buffer: BNF_GFP_Grec.buffer}
type rho_parse_info =
{pattern_ctrs: (term * term list) Symtab.table,
discs: term Symtab.table,
sels: term Symtab.table,
it: term,
mk_case: typ -> term}
exception UNNATURAL of unit
val generalize_types: int -> typ -> typ -> typ val mk_curry_uncurryN_balanced: Proof.context -> int -> thm val mk_const_transfer_goal: Proof.context -> string * typ -> term val mk_abs_transfer: Proof.context -> string -> thm val mk_rep_transfer: Proof.context -> string -> thm val mk_pointful_natural_from_transfer: Proof.context -> thm -> thm
val corec_parse_info_of: Proof.context -> typ list -> typ -> BNF_GFP_Grec.buffer -> s_parse_info val friend_parse_info_of: Proof.context -> typ list -> typ -> BNF_GFP_Grec.buffer ->
s_parse_info * rho_parse_info end;
open Ctr_Sugar open BNF_Util open BNF_Tactics open BNF_Def open BNF_Comp open BNF_FP_Util open BNF_FP_Def_Sugar open BNF_GFP_Grec open BNF_GFP_Grec_Tactics
val mk_case_sumN_balanced = Balanced_Tree.make mk_case_sum;
fun generalize_types max_j T U = let val vars = Unsynchronized.ref [];
fun var_of T U =
(case AList.lookup (op =) (!vars) (T, U) of
SOME V => V
| NONE => letval V = TVar ((Name.aT, length (!vars) + max_j), \<^sort>\<open>type\<close>) in
vars := ((T, U), V) :: !vars; V end);
fun gen (T as Type (s, Ts)) (U as Type (s', Us)) = if s = s' then Type (s, map2 gen Ts Us) else var_of T U
| gen T U = if T = U then T else var_of T U; in
gen T U end;
fun mk_curry_uncurryN_balanced_raw ctxt n = let val ((As, B), names_ctxt) = ctxt
|> mk_TFrees (n + 1)
|>> split_last;
val num_curry_uncurryN_balanced_precomp = 8; val curry_uncurryN_balanced_precomp = map (mk_curry_uncurryN_balanced_raw \<^context>) (0 upto num_curry_uncurryN_balanced_precomp);
fun mk_curry_uncurryN_balanced ctxt n = if n <= num_curry_uncurryN_balanced_precomp then nth curry_uncurryN_balanced_precomp n else mk_curry_uncurryN_balanced_raw ctxt n;
fun mk_const_transfer_goal ctxt (s, var_T) = let val var_As = Term.add_tvarsT var_T [];
val (Rs, _) = names_ctxt
|> mk_Frees "R" (map2 mk_pred2T As Bs);
val T = Term.typ_subst_TVars (map fst var_As ~~ As) var_T; val U = Term.typ_subst_TVars (map fst var_As ~~ Bs) var_T; in
mk_parametricity_goal ctxt Rs (Const (s, T)) (Const (s, U))
|> tap (fn goal => can type_of goal orelse
error ("Cannot transfer constant " ^ quote (Syntax.string_of_term ctxt (Const (s, T))) ^ " from type " ^ quote (Syntax.string_of_typ ctxt T) ^ " to " ^
quote (Syntax.string_of_typ ctxt U))) end;
fun mk_abs_transfer ctxt fpT_name = let val SOME {pre_bnf, absT_info = {absT, repT, abs, type_definition, ...}, live_nesting_bnfs,...} =
fp_sugar_of ctxt fpT_name; in if absT = repT then raise Fail "no abs/rep" else let val rel_def = rel_def_of_bnf pre_bnf; val live_nesting_rel_eqs = map rel_eq_of_bnf live_nesting_bnfs;
val goal = mk_const_transfer_goal ctxt (dest_Const (mk_abs absT abs)) in
Variable.add_free_names ctxt goal []
|> (fn vars => Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} =>
unfold_thms_tac ctxt (rel_def :: live_nesting_rel_eqs) THEN
HEADGOAL (rtac ctxt refl ORELSE'
rtac ctxt (@{thm Abs_transfer} OF [type_definition, type_definition])))) end end;
fun mk_rep_transfer ctxt fpT_name = let val SOME {pre_bnf, absT_info = {absT, repT, rep, ...}, live_nesting_bnfs, ...} =
fp_sugar_of ctxt fpT_name; in if absT = repT then raise Fail "no abs/rep" else let val rel_def = rel_def_of_bnf pre_bnf; val live_nesting_rel_eqs = map rel_eq_of_bnf live_nesting_bnfs;
val ((xs, fs), _) = names_ctxt
|> mk_Frees "x" (binder_types TA)
||>> mk_Frees "f" (map2 (curry (op -->)) As Bs);
val AB_fs = (As ~~ Bs) ~~ fs;
fun build_applied_map TU t = if op = TU then
t else
(casetry (build_map ctxt [] [] (the o AList.lookup (op =) AB_fs)) TU of
SOME mapx => mapx $ t
| NONE => raise UNNATURAL ());
fun unextensionalize (f $ (x as Free _), rhs) = unextensionalize (f, lambda x rhs)
| unextensionalize tu = tu;
val TB = typ_subst_atomic (var_As ~~ Bs) var_T;
val (binder_TAs, body_TA) = strip_type TA; val (binder_TBs, body_TB) = strip_type TB;
val n = length var_As; val m = length binder_TAs;
val A_nesting_bnfs = nesting_bnfs ctxt [[body_TA :: binder_TAs]] As; val A_nesting_map_ids = map map_id_of_bnf A_nesting_bnfs; val A_nesting_rel_Grps = map rel_Grp_of_bnf A_nesting_bnfs;
val ta = Const (s, TA); val tb = Const (s, TB); val xfs = @{map 3} (curry build_applied_map) binder_TAs binder_TBs xs;
val _ = if can type_of goal then () elseraise UNNATURAL ();
val vars = map (fst o dest_Free) (xs @ fs); in
Goal.prove_sorry ctxt vars [] goal (fn {context = ctxt, prems = _} =>
mk_natural_from_transfer_tac ctxt m (replicate n true) transfer A_nesting_map_ids
A_nesting_rel_Grps [])
|> Thm.close_derivation \<^here> end;
type s_parse_info =
{outer_buffer: BNF_GFP_Grec.buffer,
ctr_guards: term Symtab.table,
inner_buffer: BNF_GFP_Grec.buffer};
type rho_parse_info =
{pattern_ctrs: (term * term list) Symtab.table,
discs: term Symtab.table,
sels: term Symtab.table,
it: term,
mk_case: typ -> term};
fun curry_friend (T, t) = let val prod_T = domain_type (fastype_of t); val Ts = dest_tupleT_balanced (num_binder_types T) prod_T; val xs = map_index (fn (i, T) => Free ("x" ^ string_of_int i, T)) Ts; val body = mk_tuple_balanced xs; in
(T, fold_rev Term.lambda xs (t $ body)) end;
val VLeaf0_T = fastype_of VLeaf0; val Y = domain_type VLeaf0_T;
val raw_buffer = specialize_buffer_types raw_buffer0;
val As_rho = tvar_subst thy [fpT] [res_T];
val substAT = Term.typ_subst_TVars As_rho; val substA = Term.subst_TVars As_rho; val substYT = Tsubst Y tupled_arg_T; val substY = substT Y tupled_arg_T;
val Ys_rho_inner = if friend then [] else [(Y, tupled_arg_T)]; val substYT_inner = substAT o Term.typ_subst_atomic Ys_rho_inner; val substY_inner = substA o Term.subst_atomic_types Ys_rho_inner;
val mid_T = substYT_inner (range_type VLeaf0_T);
val substXT_mid = Tsubst X mid_T;
val XifyT = typ_subst_nonatomic [(res_T, X)]; val YifyT = typ_subst_nonatomic [(res_T, Y)];
val substXYT = Tsubst X Y;
val ctor0 = nth ctors0 fp_res_index; val ctor = enforce_type ctxt range_type res_T ctor0; val preT = YifyT (domain_type (fastype_of ctor));
val n = length ctrs0; val ks = 1 upto n;
fun mk_ctr_guards () = let val ctr_Tss = map (map (substXT_mid o substAT)) ctrXs_Tss; val preT = XifyT (domain_type (fastype_of ctor)); val mid_preT = substXT_mid preT; val abs = enforce_type ctxt range_type mid_preT abs0; val absT = range_type (fastype_of abs);
fun mk_ctr_guard k ctr_Ts (Const (s, _)) = let val xs = map_index (fn (i, T) => Free ("x" ^ string_of_int i, T)) ctr_Ts; val body = mk_absumprod absT abs n k xs; in
(s, fold_rev Term.lambda xs body) end; in
Symtab.make (@{map 3} mk_ctr_guard ks ctr_Tss ctrs0) end;
val substYT_mid = substYT o Tsubst Y mid_T;
val outer_T = substYT_mid preT;
val substY_outer = substY o substT Y outer_T;
val outer_buffer = curry_friends (map_buffer substY_outer raw_buffer); val ctr_guards = mk_ctr_guards (); val inner_buffer = curry_friends (map_buffer substY_inner raw_buffer);
fun mk_disc_sels_pair disc sels = if forall is_some sels then SOME (disc, map the sels) else NONE;
val pattern_ctrs = (ctrs0, selss0)
||> map (map (try dest_Const_name #> Option.mapPartial (Symtab.lookup sels)))
||> @{map 2} mk_disc_sels_pair all_discs
|>> map dest_Const_name
|> op ~~
|> map_filter (fn (s, opt) => if is_some opt then SOME (s, the opt) else NONE)
|> Symtab.make;
val it = HOLogic.mk_comp (VLeaf0, fst_const YpreT);
val mk_case = let val abs_fun_tms = case0
|> fastype_of
|> substAT
|> XifyT
|> binder_fun_types
|> map_index (fn (i, T) => Free ("f" ^ string_of_int (i + 1), T)); val arg_Uss = abs_fun_tms
|> map fastype_of
|> map binder_types; val arg_Tss = arg_Uss
|> map (map substXYT); val case0 =
arg_Tss
|> map (map_index (fn (i, T) => Free ("x" ^ string_of_int (i + 1), T)))
|> `(map mk_tuple_balanced)
||> @{map 3} (@{map 3} encapsulate_nested) arg_Uss arg_Tss
|> uncurry (@{map 3} mk_tupled_fun abs_fun_tms)
|> mk_case_sumN_balanced
|> (fn tm => Library.foldl1 HOLogic.mk_comp [tm, rep, snd_const YpreT])
|> fold_rev lambda abs_fun_tms
|> map_types (substAT o substXT_mid); in
fn U => case0
|> substT (body_type (fastype_of case0)) U
|> Syntax.check_term ctxt end; in
{pattern_ctrs = pattern_ctrs, discs = discs, sels = sels, it = it, mk_case = mk_case} end; in
(s_parse_info, mk_friend_spec) end;
fun corec_parse_info_of ctxt =
fst ooo generic_spec_of false ctxt;
fun friend_parse_info_of ctxt =
apsnd (fn f => f ()) ooo generic_spec_of true ctxt;
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.13Bemerkung:
(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.