src/Pure/Tools/rule_insts.ML
changeset 59796 f05ef8c62e4f
parent 59790 85c572d089fc
child 59800 af3e0919603f
equal deleted inserted replaced
59795:d453c69596cc 59796:f05ef8c62e4f
    66   in
    66   in
    67     if Sign.of_sort (Proof_Context.theory_of ctxt) (T, S) then ((xi, S), T)
    67     if Sign.of_sort (Proof_Context.theory_of ctxt) (T, S) then ((xi, S), T)
    68     else error_var "Bad sort for instantiation of type variable: " (xi, pos)
    68     else error_var "Bad sort for instantiation of type variable: " (xi, pos)
    69   end;
    69   end;
    70 
    70 
    71 fun read_terms ctxt ss Ts =
    71 fun read_terms ss Ts ctxt =
    72   let
    72   let
    73     fun parse T = if T = propT then Syntax.parse_prop ctxt else Syntax.parse_term ctxt;
    73     fun parse T = if T = propT then Syntax.parse_prop ctxt else Syntax.parse_term ctxt;
    74     val ts = map2 parse Ts ss;
    74     val (ts, ctxt') = fold_map Variable.fix_dummy_patterns (map2 parse Ts ss) ctxt;
    75     val ts' =
    75     val ts' =
    76       map2 (Type.constraint o Type_Infer.paramify_vars) Ts ts
    76       map2 (Type.constraint o Type_Infer.paramify_vars) Ts ts
    77       |> Syntax.check_terms ctxt
    77       |> Syntax.check_terms ctxt'
    78       |> Variable.polymorphic ctxt;
    78       |> Variable.polymorphic ctxt';
    79     val Ts' = map Term.fastype_of ts';
    79     val Ts' = map Term.fastype_of ts';
    80     val tyenv = fold Type.raw_match (Ts ~~ Ts') Vartab.empty;
    80     val tyenv = fold Type.raw_match (Ts ~~ Ts') Vartab.empty;
    81     val tyenv' = Vartab.fold (fn (xi, (S, T)) => cons ((xi, S), T)) tyenv [];
    81     val tyenv' = Vartab.fold (fn (xi, (S, T)) => cons ((xi, S), T)) tyenv [];
    82   in (ts', tyenv') end;
    82   in ((ts', tyenv'), ctxt') end;
    83 
    83 
    84 fun make_instT f v =
    84 fun make_instT f v =
    85   let
    85   let
    86     val T = TVar v;
    86     val T = TVar v;
    87     val T' = f T;
    87     val T' = f T;
    93     val t' = f t;
    93     val t' = f t;
    94   in if t aconv t' then NONE else SOME (v, t') end;
    94   in if t aconv t' then NONE else SOME (v, t') end;
    95 
    95 
    96 in
    96 in
    97 
    97 
    98 fun read_insts ctxt mixed_insts thm =
    98 fun read_insts thm mixed_insts ctxt =
    99   let
    99   let
   100     val (type_insts, term_insts) =
   100     val (type_insts, term_insts) =
   101       List.partition (fn (((x, _), _), _) => String.isPrefix "'" x) mixed_insts;
   101       List.partition (fn (((x, _), _), _) => String.isPrefix "'" x) mixed_insts;
   102 
   102 
   103     val tvars = Thm.fold_terms Term.add_tvars thm [];
   103     val tvars = Thm.fold_terms Term.add_tvars thm [];
   108     val vars1 = map (apsnd instT1) vars;
   108     val vars1 = map (apsnd instT1) vars;
   109 
   109 
   110     (*term instantiations*)
   110     (*term instantiations*)
   111     val (xs, ss) = split_list term_insts;
   111     val (xs, ss) = split_list term_insts;
   112     val Ts = map (the_type vars1) xs;
   112     val Ts = map (the_type vars1) xs;
   113     val (ts, inferred) = read_terms ctxt ss Ts;
   113     val ((ts, inferred), ctxt') = read_terms ss Ts ctxt;
   114 
   114 
   115     (*implicit type instantiations*)
   115     (*implicit type instantiations*)
   116     val instT2 = Term_Subst.instantiateT inferred;
   116     val instT2 = Term_Subst.instantiateT inferred;
   117     val vars2 = map (apsnd instT2) vars1;
   117     val vars2 = map (apsnd instT2) vars1;
   118     val inst2 =
   118     val inst2 =
   119       Term_Subst.instantiate ([], map2 (fn (xi, _) => fn t => ((xi, Term.fastype_of t), t)) xs ts)
   119       Term_Subst.instantiate ([], map2 (fn (xi, _) => fn t => ((xi, Term.fastype_of t), t)) xs ts)
   120       #> Envir.beta_norm;
   120       #> Envir.beta_norm;
   121 
   121 
   122     val inst_tvars = map_filter (make_instT (instT2 o instT1)) tvars;
   122     val inst_tvars = map_filter (make_instT (instT2 o instT1)) tvars;
   123     val inst_vars = map_filter (make_inst inst2) vars2;
   123     val inst_vars = map_filter (make_inst inst2) vars2;
   124   in (inst_tvars, inst_vars) end;
   124   in ((inst_tvars, inst_vars), ctxt') end;
   125 
   125 
   126 end;
   126 end;
   127 
   127 
   128 
   128 
   129 
   129 
   132 fun where_rule ctxt mixed_insts fixes thm =
   132 fun where_rule ctxt mixed_insts fixes thm =
   133   let
   133   let
   134     val ctxt' = ctxt
   134     val ctxt' = ctxt
   135       |> Variable.declare_thm thm
   135       |> Variable.declare_thm thm
   136       |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes |> #2;
   136       |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes |> #2;
   137     val (inst_tvars, inst_vars) = read_insts ctxt' mixed_insts thm;
   137     val ((inst_tvars, inst_vars), ctxt'') = read_insts thm mixed_insts ctxt';
   138   in
   138   in
   139     thm
   139     thm
   140     |> Drule.instantiate_normalize
   140     |> Drule.instantiate_normalize
   141       (map (apply2 (Thm.ctyp_of ctxt) o apfst TVar) inst_tvars,
   141       (map (apply2 (Thm.ctyp_of ctxt'') o apfst TVar) inst_tvars,
   142        map (apply2 (Thm.cterm_of ctxt) o apfst Var) inst_vars)
   142        map (apply2 (Thm.cterm_of ctxt'') o apfst Var) inst_vars)
   143     |> singleton (Variable.export ctxt' ctxt)
   143     |> singleton (Variable.export ctxt'' ctxt)
   144     |> Rule_Cases.save thm
   144     |> Rule_Cases.save thm
   145   end;
   145   end;
   146 
   146 
   147 fun of_rule ctxt (args, concl_args) fixes thm =
   147 fun of_rule ctxt (args, concl_args) fixes thm =
   148   let
   148   let
   223     (* local fixes *)
   223     (* local fixes *)
   224 
   224 
   225     val (fixed, fixes_ctxt) = param_ctxt
   225     val (fixed, fixes_ctxt) = param_ctxt
   226       |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes;
   226       |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes;
   227 
   227 
   228     val (inst_tvars, inst_vars) = read_insts fixes_ctxt mixed_insts thm;
   228     val ((inst_tvars, inst_vars), inst_ctxt) = read_insts thm mixed_insts fixes_ctxt;
   229 
   229 
   230 
   230 
   231     (* lift and instantiate rule *)
   231     (* lift and instantiate rule *)
   232 
   232 
   233     val inc = Thm.maxidx_of st + 1;
   233     val inc = Thm.maxidx_of st + 1;
   236     fun lift_term t =
   236     fun lift_term t =
   237       fold_rev Term.absfree (param_names ~~ paramTs)
   237       fold_rev Term.absfree (param_names ~~ paramTs)
   238         (Logic.incr_indexes (fixed, paramTs, inc) t);
   238         (Logic.incr_indexes (fixed, paramTs, inc) t);
   239 
   239 
   240     val inst_tvars' = inst_tvars
   240     val inst_tvars' = inst_tvars
   241       |> map (apply2 (Thm.ctyp_of fixes_ctxt o Logic.incr_tvar inc) o apfst TVar);
   241       |> map (apply2 (Thm.ctyp_of inst_ctxt o Logic.incr_tvar inc) o apfst TVar);
   242     val inst_vars' = inst_vars
   242     val inst_vars' = inst_vars
   243       |> map (fn (v, t) => apply2 (Thm.cterm_of fixes_ctxt) (lift_var v, lift_term t));
   243       |> map (fn (v, t) => apply2 (Thm.cterm_of inst_ctxt) (lift_var v, lift_term t));
   244 
   244 
   245     val thm' =
   245     val thm' =
   246       Drule.instantiate_normalize (inst_tvars', inst_vars')
   246       Drule.instantiate_normalize (inst_tvars', inst_vars')
   247         (Thm.lift_rule cgoal thm)
   247         (Thm.lift_rule cgoal thm)
   248       |> singleton (Variable.export fixes_ctxt param_ctxt);
   248       |> singleton (Variable.export inst_ctxt param_ctxt);
   249   in
   249   in
   250     compose_tac param_ctxt (bires_flag, thm', Thm.nprems_of thm) i
   250     compose_tac param_ctxt (bires_flag, thm', Thm.nprems_of thm) i
   251   end) i st;
   251   end) i st;
   252 
   252 
   253 val res_inst_tac = bires_inst_tac false;
   253 val res_inst_tac = bires_inst_tac false;