ML antiquotation to instantiate logical entities.
*)
signature ML_INSTANTIATE = sig val make_ctyp: Proof.context -> typ -> ctyp val make_cterm: Proof.context -> term -> cterm type insts = ((indexname * sort) * typ) list * ((indexname * typ) * term) list type cinsts = ((indexname * sort) * ctyp) list * ((indexname * typ) * cterm) list val instantiate_typ: insts -> typ -> typ val instantiate_ctyp: Position.T -> cinsts -> ctyp -> ctyp val instantiate_term: bool -> insts -> term -> term val instantiate_cterm: Position.T -> bool -> cinsts -> cterm -> cterm val instantiate_thm: Position.T -> bool -> cinsts -> thm -> thm val instantiate_thms: Position.T -> bool -> cinsts -> thm list -> thm list val get_thms: Proof.context -> int -> thm list val get_thm: Proof.context -> int -> thm end;
structure ML_Instantiate: ML_INSTANTIATE = struct
(* exported operations *)
fun make_ctyp ctxt T = Thm.ctyp_of ctxt T |> Thm.trim_context_ctyp; fun make_cterm ctxt t = Thm.cterm_of ctxt t |> Thm.trim_context_cterm;
type insts = ((indexname * sort) * typ) list * ((indexname * typ) * term) list type cinsts = ((indexname * sort) * ctyp) list * ((indexname * typ) * cterm) list
fun instantiate_typ (insts: insts) =
Term_Subst.instantiateT (TVars.make (#1 insts));
fun instantiate_term beta (insts: insts) = let val instT = TVars.make (#1 insts); val instantiateT = Term_Subst.instantiateT instT; val inst = Vars.make ((map o apfst o apsnd) instantiateT (#2 insts)); in (if beta then Term_Subst.instantiate_beta else Term_Subst.instantiate) (instT, inst) end;
fun make_cinsts (cinsts: cinsts) = let val cinstT = TVars.make (#1 cinsts); val instantiateT = Term_Subst.instantiateT (TVars.map (K Thm.typ_of) cinstT); val cinst = Vars.make ((map o apfst o apsnd) instantiateT (#2 cinsts)); in (cinstT, cinst) end;
val ml = ML_Lex.tokenize_no_range; val ml_range = ML_Lex.tokenize_range; fun ml_parens x = ml "(" @ x @ ml ")"; fun ml_bracks x = ml "[" @ x @ ml "]"; fun ml_commas xs = flat (separate (ml ", ") xs); val ml_list = ml_bracks o ml_commas; fun ml_pair (x, y) = ml_parens (ml_commas [x, y]); val ml_list_pair = ml_list o ListPair.map ml_pair; val ml_here = ML_Syntax.atomic o ML_Syntax.print_position;
fun get_tfree envT (a, pos) =
(case AList.lookup (op =) envT a of
SOME S => (a, S)
| NONE => error ("No occurrence of type variable " ^ quote a ^ Position.here pos));
fun check_free ctxt env (x, pos) =
(case AList.lookup (op =) env x of
SOME T =>
(Context_Position.reports ctxt (map (pair pos) (Syntax_Phases.markup_free ctxt x)); (x, T))
| NONE => error ("No occurrence of variable " ^ quote x ^ Position.here pos));
fun missing_instT pos envT instT =
(case filter_out (fn (a, _) => exists (fn (b, _) => a = b) instT) envT of
[] => ()
| bad =>
error ("No instantiation for free type variable(s) " ^ commas_quote (map #1 bad) ^
Position.here pos));
fun missing_inst pos env inst =
(case filter_out (fn (a, _) => exists (fn (b, _) => a = b) inst) env of
[] => ()
| bad =>
error ("No instantiation for free variable(s) " ^ commas_quote (map #1 bad) ^
Position.here pos));
fun make_instT (a, pos) T =
(casetry (Term.dest_TVar o Logic.dest_type) T of
NONE => error ("Not a free type variable " ^ quote a ^ Position.here pos)
| SOME v => ml (ML_Syntax.print_pair ML_Syntax.print_indexname ML_Syntax.print_sort v));
fun make_inst (a, pos) t =
(casetry Term.dest_Var t of
NONE => error ("Not a free variable " ^ quote a ^ Position.here pos)
| SOME v => ml (ML_Syntax.print_pair ML_Syntax.print_indexname ML_Syntax.print_typ v));
fun make_env ts = let val envT = fold Term.add_tfrees ts []; val env = fold Term.add_frees ts []; in (envT, env) end;
fun prepare_insts pos {schematic} ctxt1 ctxt0 (instT, inst) ts = let val (envT, env) = make_env ts; val freesT = map (Logic.mk_type o TFree o get_tfree envT) instT; val frees = map (Free o check_free ctxt1 env) inst; val (ts', (varsT, vars)) =
Variable.export_terms ctxt1 ctxt0 (ts @ freesT @ frees)
|> chop (length ts) ||> chop (length freesT); val ml_insts = (map2 make_instT instT varsT, map2 make_inst inst vars); in if schematic then () else letval (envT', env') = make_env ts' in
missing_instT pos (subtract (eq_fst op =) envT' envT) instT;
missing_inst pos (subtract (eq_fst op =) env' env) inst end;
(ml_insts, ts') end;
fun prepare_ml range kind ml1 ml2 ml_val (ml_instT, ml_inst) ctxt = let val (ml_name, ctxt') = ML_Context.variant kind ctxt; val ml_env = ml ("val " ^ ml_name ^ " = ") @ ml ml1 @ ml_parens (ml ml_val) @ ml ";\n"; fun ml_body (ml_argsT, ml_args) =
ml_parens (ml ml2 @
ml_pair (ml_list_pair (ml_instT, ml_argsT), ml_list_pair (ml_inst, ml_args)) @
ml_range range (ML_Context.struct_name ctxt ^ "." ^ ml_name)); in ((ml_env, ml_body), ctxt') end;
fun prepare_beta {beta} = " " ^ Value.print_bool beta;
fun prepare_type range ((((kind, pos), ml1, ml2), schematic), s) insts ctxt = let val T = Syntax.read_typ ctxt s; val t = Logic.mk_type T; val ctxt1 = Proof_Context.augment t ctxt; val (ml_insts, T') =
prepare_insts pos schematic ctxt1 ctxt insts [t] ||> (the_single #> Logic.dest_type); in prepare_ml range kind ml1 ml2 (ML_Syntax.print_typ T') ml_insts ctxt end;
fun prepare_term read range ((((kind, pos), ml1, ml2), schematic), (s, fixes)) beta insts ctxt = let val ctxt' = #2 (Proof_Context.add_fixes_cmd fixes ctxt); val t = read ctxt' s; val ctxt1 = Proof_Context.augment t ctxt'; val (ml_insts, t') = prepare_insts pos schematic ctxt1 ctxt insts [t] ||> the_single; in prepare_ml range kind ml1 (ml2 ^ prepare_beta beta) (ML_Syntax.print_term t') ml_insts ctxt end;
fun prepare_lemma range ((pos, schematic), make_lemma) beta insts ctxt = let val (ths, (props, ctxt1)) = make_lemma ctxt val (i, thms_ctxt) = put_thms ths ctxt; val ml_insts = #1 (prepare_insts pos schematic ctxt1 ctxt insts props); val args = ml_here pos ^ prepare_beta beta; val (ml1, ml2) = if length ths = 1 then ("ML_Instantiate.get_thm ML_context", "ML_Instantiate.instantiate_thm " ^ args) else ("ML_Instantiate.get_thms ML_context", "ML_Instantiate.instantiate_thms " ^ args); in prepare_ml range "lemma" ml1 ml2 (ML_Syntax.print_int i) ml_insts thms_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.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.