thys2/Thm_inst.thy
changeset 25 a5f5b9336007
equal deleted inserted replaced
24:77daf1b85cf0 25:a5f5b9336007
       
     1 theory Thm_inst
       
     2 imports Term_pat
       
     3 begin
       
     4 
       
     5 section {* Monad for theorem instantiation based on bindings in proof contexts *}
       
     6 
       
     7 subsection {* Implementation *}
       
     8 
       
     9 ML {*
       
    10 local
       
    11 fun read_termTs ctxt schematic ts Ts =
       
    12   let
       
    13     val ts' =
       
    14       map2 (Type.constraint o Type_Infer.paramify_vars) Ts ts
       
    15       |> Syntax.check_terms ((schematic ? Proof_Context.set_mode Proof_Context.mode_schematic) ctxt)
       
    16       |> Variable.polymorphic ctxt;
       
    17     val Ts' = map Term.fastype_of ts';
       
    18     val tyenv = fold Type.raw_match (Ts ~~ Ts') Vartab.empty;
       
    19   in (ts', map (apsnd snd) (Vartab.dest tyenv)) end;
       
    20 
       
    21 fun make_inst f v =
       
    22   let
       
    23     val t = Var v;
       
    24     val t' = f t;
       
    25   in if t aconv t' then NONE else SOME (t, t') end;
       
    26 
       
    27 
       
    28 fun error_var msg xi = error (msg ^ quote (Term.string_of_vname xi));
       
    29 
       
    30 fun the_type vars (xi: indexname) =
       
    31   (case AList.lookup (op =) vars xi of
       
    32     SOME T => T
       
    33   | NONE => error_var "No such variable in theorem: " xi);
       
    34 
       
    35 fun instantiate inst =
       
    36   Term_Subst.instantiate ([], map (fn (xi, t) => ((xi, Term.fastype_of t), t)) inst) #>
       
    37   Envir.beta_norm;
       
    38 
       
    39 fun make_instT f v =
       
    40   let
       
    41     val T = TVar v;
       
    42     val T' = f T;
       
    43   in if T = T' then NONE else SOME (T, T') end;
       
    44 
       
    45 fun read_insts ctxt term_insts (tvars, vars) =
       
    46   let
       
    47     val thy = Proof_Context.theory_of ctxt;
       
    48     val cert = Thm.cterm_of thy;
       
    49     val certT = Thm.ctyp_of thy;
       
    50 
       
    51 
       
    52     (* type instantiations *)
       
    53 
       
    54     val instT1 = Term_Subst.instantiateT [];
       
    55     val vars1 = map (apsnd instT1) vars;
       
    56 
       
    57 
       
    58     (* term instantiations *)
       
    59 
       
    60     val (xs, ts) = split_list term_insts;
       
    61     val Ts = map (the_type vars1) xs;
       
    62     val (ts, inferred) = read_termTs ctxt false ts Ts;
       
    63 
       
    64     val instT2 = Term.typ_subst_TVars inferred;
       
    65     val vars2 = map (apsnd instT2) vars1;
       
    66     val inst2 = instantiate (xs ~~ ts);
       
    67 
       
    68 
       
    69     (* result *)
       
    70 
       
    71     val inst_tvars = map_filter (make_instT (instT2 o instT1)) tvars;
       
    72     val inst_vars = map_filter (make_inst inst2) vars2;
       
    73   in
       
    74     (map (pairself certT) inst_tvars, map (pairself cert) inst_vars)
       
    75   end
       
    76 
       
    77   val add_used =
       
    78   (Thm.fold_terms o fold_types o fold_atyps)
       
    79     (fn TFree (a, _) => insert (op =) a
       
    80       | TVar ((a, _), _) => insert (op =) a
       
    81       | _ => I)
       
    82 
       
    83 fun term_instantiate ctxt term_insts thm =
       
    84   let
       
    85     val ctxt' = ctxt
       
    86       |> Variable.declare_thm thm
       
    87       |> fold (fn a => Variable.declare_names (Logic.mk_type (TFree (a, dummyS)))) (add_used thm []); 
       
    88                  (* FIXME !? *)
       
    89     val tvars = Thm.fold_terms Term.add_tvars thm [];
       
    90     val vars = Thm.fold_terms Term.add_vars thm [];
       
    91     val insts = read_insts ctxt' term_insts (tvars, vars);
       
    92   in
       
    93     Drule.instantiate_normalize insts thm
       
    94     |> Rule_Cases.save thm
       
    95   end
       
    96 
       
    97 in
       
    98   fun ctxt_instantiate ctxt thm = let
       
    99      val binds = Variable.binds_of ctxt
       
   100      val vars = Thm.fold_terms Term.add_vars thm [] |> map fst
       
   101      val inst = map_filter ( Vartab.lookup_key binds) vars |> map (apsnd snd)
       
   102      val thm' = term_instantiate ctxt inst thm 
       
   103   in thm' end
       
   104 
       
   105   fun thm_instM thm = 
       
   106    liftM (lift (m0M (fn ctxt =>
       
   107     returnM (ctxt_instantiate ctxt thm)
       
   108    )) |> exnM err_trans)
       
   109 
       
   110 end
       
   111 *}
       
   112 
       
   113 subsection {* Examples *}
       
   114 
       
   115 lemma h: "x = x \<and> y = y"
       
   116   by simp
       
   117 
       
   118 ML {*
       
   119   val ctxt = @{context}
       
   120   val t = ctxt_instantiate ctxt @{thm h} |> prop_of
       
   121 *}
       
   122 
       
   123 ML {*
       
   124   val t =   [((), @{context})] |> @{match "?x"} @{term "[]::nat list"} |--
       
   125                                   @{match "?y"} @{term "1::nat"} |--
       
   126                                   thm_instM @{thm h}
       
   127 *}
       
   128  
       
   129 end
       
   130