src/Pure/Tools/rule_insts.ML
changeset 59759 cb1966f3a92b
parent 59755 f8d164ab0dc1
child 59761 558acf0426f1
equal deleted inserted replaced
59756:96abba46955f 59759:cb1966f3a92b
    46 val partition_insts = List.partition (fn (((x, _), _), _) => String.isPrefix "'" x);
    46 val partition_insts = List.partition (fn (((x, _), _), _) => String.isPrefix "'" x);
    47 
    47 
    48 fun error_var msg (xi, pos) =
    48 fun error_var msg (xi, pos) =
    49   error (msg ^ quote (Term.string_of_vname xi) ^ Position.here pos);
    49   error (msg ^ quote (Term.string_of_vname xi) ^ Position.here pos);
    50 
    50 
    51 local
       
    52 
       
    53 fun the_sort tvars (xi, pos) : sort =
    51 fun the_sort tvars (xi, pos) : sort =
    54   (case AList.lookup (op =) tvars xi of
    52   (case AList.lookup (op =) tvars xi of
    55     SOME S => S
    53     SOME S => S
    56   | NONE => error_var "No such type variable in theorem: " (xi, pos));
    54   | NONE => error_var "No such type variable in theorem: " (xi, pos));
    57 
    55 
    58 fun the_type vars (xi, pos) : typ =
    56 fun the_type vars (xi, pos) : typ =
    59   (case AList.lookup (op =) vars xi of
    57   (case AList.lookup (op =) vars xi of
    60     SOME T => T
    58     SOME T => T
    61   | NONE => error_var "No such variable in theorem: " (xi, pos));
    59   | NONE => error_var "No such variable in theorem: " (xi, pos));
    62 
    60 
       
    61 local
       
    62 
    63 fun instantiate inst =
    63 fun instantiate inst =
    64   Term_Subst.instantiate ([], map (fn (xi, t) => ((xi, Term.fastype_of t), t)) inst) #>
    64   Term_Subst.instantiate ([], map (fn (xi, t) => ((xi, Term.fastype_of t), t)) inst) #>
    65   Envir.beta_norm;
    65   Envir.beta_norm;
    66 
    66 
    67 fun make_instT f v =
    67 fun make_instT f v =
    75     val t = Var v;
    75     val t = Var v;
    76     val t' = f t;
    76     val t' = f t;
    77   in if t aconv t' then NONE else SOME (t, t') end;
    77   in if t aconv t' then NONE else SOME (t, t') end;
    78 
    78 
    79 in
    79 in
       
    80 
       
    81 fun readT ctxt tvars ((xi, pos), s) =
       
    82   let
       
    83     val S = the_sort tvars (xi, pos);
       
    84     val T = Syntax.read_typ ctxt s;
       
    85   in
       
    86     if Sign.of_sort (Proof_Context.theory_of ctxt) (T, S) then ((xi, S), T)
       
    87     else error_var "Incompatible sort for typ instantiation of " (xi, pos)
       
    88   end;
    80 
    89 
    81 fun read_termTs ctxt ss Ts =
    90 fun read_termTs ctxt ss Ts =
    82   let
    91   let
    83     fun parse T = if T = propT then Syntax.parse_prop ctxt else Syntax.parse_term ctxt;
    92     fun parse T = if T = propT then Syntax.parse_prop ctxt else Syntax.parse_term ctxt;
    84     val ts = map2 parse Ts ss;
    93     val ts = map2 parse Ts ss;
    86       map2 (Type.constraint o Type_Infer.paramify_vars) Ts ts
    95       map2 (Type.constraint o Type_Infer.paramify_vars) Ts ts
    87       |> Syntax.check_terms ctxt
    96       |> Syntax.check_terms ctxt
    88       |> Variable.polymorphic ctxt;
    97       |> Variable.polymorphic ctxt;
    89     val Ts' = map Term.fastype_of ts';
    98     val Ts' = map Term.fastype_of ts';
    90     val tyenv = fold Type.raw_match (Ts ~~ Ts') Vartab.empty;
    99     val tyenv = fold Type.raw_match (Ts ~~ Ts') Vartab.empty;
    91   in (ts', map (apsnd snd) (Vartab.dest tyenv)) end;
   100     val tyenv' = Vartab.fold (fn (xi, (S, T)) => cons ((xi, S), T)) tyenv [];
    92 
   101   in (ts', tyenv') end;
    93 fun read_insts ctxt mixed_insts (tvars, vars) =
   102 
    94   let
   103 fun read_insts ctxt (tvars, vars) mixed_insts =
    95     val thy = Proof_Context.theory_of ctxt;
   104   let
    96 
       
    97     val (type_insts, term_insts) = partition_insts mixed_insts;
   105     val (type_insts, term_insts) = partition_insts mixed_insts;
    98 
   106 
    99 
   107 
   100     (* type instantiations *)
   108     (* type instantiations *)
   101 
   109 
   102     fun readT ((xi, pos), s) =
   110     val instT1 = Term_Subst.instantiateT (map (readT ctxt tvars) type_insts);
   103       let
       
   104         val S = the_sort tvars (xi, pos);
       
   105         val T = Syntax.read_typ ctxt s;
       
   106       in
       
   107         if Sign.of_sort thy (T, S) then ((xi, S), T)
       
   108         else error_var "Incompatible sort for typ instantiation of " (xi, pos)
       
   109       end;
       
   110 
       
   111     val instT1 = Term_Subst.instantiateT (map readT type_insts);
       
   112     val vars1 = map (apsnd instT1) vars;
   111     val vars1 = map (apsnd instT1) vars;
   113 
   112 
   114 
   113 
   115     (* term instantiations *)
   114     (* term instantiations *)
   116 
   115 
   117     val (xs, ss) = split_list term_insts;
   116     val (xs, ss) = split_list term_insts;
   118     val Ts = map (the_type vars1) xs;
   117     val Ts = map (the_type vars1) xs;
   119     val (ts, inferred) = read_termTs ctxt ss Ts;
   118     val (ts, inferred) = read_termTs ctxt ss Ts;
   120 
   119 
   121     val instT2 = Term.typ_subst_TVars inferred;
   120     val instT2 = Term_Subst.instantiateT inferred;
   122     val vars2 = map (apsnd instT2) vars1;
   121     val vars2 = map (apsnd instT2) vars1;
   123     val inst2 = instantiate (map #1 xs ~~ ts);
   122     val inst2 = instantiate (map #1 xs ~~ ts);
   124 
   123 
   125 
   124 
   126     (* result *)
   125     (* result *)
   137     val ctxt' = ctxt
   136     val ctxt' = ctxt
   138       |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes |> #2
   137       |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes |> #2
   139       |> Variable.declare_thm thm;
   138       |> Variable.declare_thm thm;
   140     val tvars = Thm.fold_terms Term.add_tvars thm [];
   139     val tvars = Thm.fold_terms Term.add_tvars thm [];
   141     val vars = Thm.fold_terms Term.add_vars thm [];
   140     val vars = Thm.fold_terms Term.add_vars thm [];
   142     val insts = read_insts ctxt' mixed_insts (tvars, vars);
   141     val insts = read_insts ctxt' (tvars, vars) mixed_insts;
   143   in
   142   in
   144     Drule.instantiate_normalize insts thm
   143     Drule.instantiate_normalize insts thm
   145     |> singleton (Proof_Context.export ctxt' ctxt)
   144     |> singleton (Proof_Context.export ctxt' ctxt)
   146     |> Rule_Cases.save thm
   145     |> Rule_Cases.save thm
   147   end;
   146   end;
   210 
   209 
   211 (* resolution after lifting and instantiation; may refer to parameters of the subgoal *)
   210 (* resolution after lifting and instantiation; may refer to parameters of the subgoal *)
   212 
   211 
   213 fun bires_inst_tac bires_flag ctxt mixed_insts thm i st = CSUBGOAL (fn (cgoal, _) =>
   212 fun bires_inst_tac bires_flag ctxt mixed_insts thm i st = CSUBGOAL (fn (cgoal, _) =>
   214   let
   213   let
   215     val thy = Proof_Context.theory_of ctxt;
       
   216 
       
   217     val (Tinsts, tinsts) = partition_insts mixed_insts;
   214     val (Tinsts, tinsts) = partition_insts mixed_insts;
       
   215 
       
   216 
       
   217     (* goal context *)
       
   218 
   218     val goal = Thm.term_of cgoal;
   219     val goal = Thm.term_of cgoal;
   219 
       
   220     val params =
   220     val params =
   221       Logic.strip_params goal
   221       Logic.strip_params goal
   222       (*as they are printed: bound variables with the same name are renamed*)
   222       (*as they are printed: bound variables with the same name are renamed*)
   223       |> Term.rename_wrt_term goal
   223       |> Term.rename_wrt_term goal
   224       |> rev;
   224       |> rev;
   226       |> Variable.declare_thm thm
   226       |> Variable.declare_thm thm
   227       |> Thm.fold_terms Variable.declare_constraints st
   227       |> Thm.fold_terms Variable.declare_constraints st
   228       |> Proof_Context.add_fixes (map (fn (x, T) => (Binding.name x, SOME T, NoSyn)) params);
   228       |> Proof_Context.add_fixes (map (fn (x, T) => (Binding.name x, SOME T, NoSyn)) params);
   229 
   229 
   230 
   230 
   231     (* process type insts: Tinsts_env *)
   231     (* preprocess rule *)
   232 
   232 
   233     val (rtypes, rsorts) = Drule.types_sorts thm;
   233     val tvars = Thm.fold_terms Term.add_tvars thm [];
   234     fun readT ((xi, pos), s) =
   234     val vars = Thm.fold_terms Term.add_vars thm [];
   235       let
   235 
   236         val S =
   236     val Tinsts_env = map (readT ctxt' tvars) Tinsts;
   237           (case rsorts xi of
       
   238             SOME S => S
       
   239           | NONE => error_var "No such type variable in theorem: " (xi, pos));
       
   240         val T = Syntax.read_typ ctxt' s;
       
   241         val U = TVar (xi, S);
       
   242       in
       
   243         if Sign.typ_instance thy (T, U) then (U, T)
       
   244         else error_var "Cannot instantiate: " (xi, pos)
       
   245       end;
       
   246     val Tinsts_env = map readT Tinsts;
       
   247 
       
   248 
       
   249     (* preprocess rule: extract vars and their types, apply Tinsts *)
       
   250 
       
   251     fun get_typ (xi, pos) =
       
   252       (case rtypes xi of
       
   253         SOME T => typ_subst_atomic Tinsts_env T
       
   254       | NONE => error_var "No such variable in theorem: " (xi, pos) xi);
       
   255     val (xis, ss) = split_list tinsts;
   237     val (xis, ss) = split_list tinsts;
   256     val Ts = map get_typ xis;
   238     val Ts = map (Term_Subst.instantiateT Tinsts_env o the_type vars) xis;
   257 
   239 
   258     val (ts, envT) =
   240     val (ts, envT) =
   259       read_termTs (Proof_Context.set_mode Proof_Context.mode_schematic ctxt') ss Ts;
   241       read_termTs (Proof_Context.set_mode Proof_Context.mode_schematic ctxt') ss Ts;
   260     val envT' =
   242     val envT' = map (fn (v, T) => (TVar v, T)) (envT @ Tinsts_env);
   261       map (fn (xi, T) => (TVar (xi, the (rsorts xi)), T)) envT @ Tinsts_env;
       
   262     val cenv =
   243     val cenv =
   263       map (fn ((xi, _), t) => apply2 (Thm.cterm_of ctxt') (Var (xi, fastype_of t), t))
   244       map (fn ((xi, _), t) => apply2 (Thm.cterm_of ctxt') (Var (xi, fastype_of t), t))
   264         (distinct
   245         (distinct
   265           (fn ((x1, t1), (x2, t2)) => x1 = x2 andalso t1 aconv t2)
   246           (fn ((x1, t1), (x2, t2)) => x1 = x2 andalso t1 aconv t2)
   266           (xis ~~ ts));
   247           (xis ~~ ts));