| author | wenzelm | 
| Sun, 29 Mar 2015 17:43:03 +0200 | |
| changeset 59836 | 5e77a35adc67 | 
| parent 59835 | 97872c658a44 | 
| child 59839 | 62d69ffa639f | 
| permissions | -rw-r--r-- | 
| 53707 | 1 | (* Title: Pure/Tools/rule_insts.ML | 
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 2 | Author: Makarius | 
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 3 | |
| 53708 | 4 | Rule instantiations -- operations within implicit rule / subgoal context. | 
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 5 | *) | 
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 6 | |
| 59763 | 7 | signature RULE_INSTS = | 
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 8 | sig | 
| 59763 | 9 | val where_rule: Proof.context -> | 
| 10 | ((indexname * Position.T) * string) list -> | |
| 11 | (binding * string option * mixfix) list -> thm -> thm | |
| 12 | val of_rule: Proof.context -> string option list * string option list -> | |
| 13 | (binding * string option * mixfix) list -> thm -> thm | |
| 14 | val read_instantiate: Proof.context -> | |
| 15 | ((indexname * Position.T) * string) list -> string list -> thm -> thm | |
| 59827 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 wenzelm parents: 
59825diff
changeset | 16 | val read_term: string -> Proof.context -> term * Proof.context | 
| 59801 | 17 | val schematic: bool Config.T | 
| 59829 | 18 | val goal_context: term -> Proof.context -> (string * typ) list * Proof.context | 
| 59755 | 19 | val res_inst_tac: Proof.context -> | 
| 59780 | 20 | ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> thm -> | 
| 21 | int -> tactic | |
| 59755 | 22 | val eres_inst_tac: Proof.context -> | 
| 59780 | 23 | ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> thm -> | 
| 24 | int -> tactic | |
| 59755 | 25 | val cut_inst_tac: Proof.context -> | 
| 59780 | 26 | ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> thm -> | 
| 27 | int -> tactic | |
| 59755 | 28 | val forw_inst_tac: Proof.context -> | 
| 59780 | 29 | ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> thm -> | 
| 30 | int -> tactic | |
| 59755 | 31 | val dres_inst_tac: Proof.context -> | 
| 59780 | 32 | ((indexname * Position.T) * string) list -> (binding * string option * mixfix) list -> thm -> | 
| 33 | int -> tactic | |
| 34 | val thin_tac: Proof.context -> string -> (binding * string option * mixfix) list -> | |
| 35 | int -> tactic | |
| 36 | val subgoal_tac: Proof.context -> string -> (binding * string option * mixfix) list -> | |
| 37 | int -> tactic | |
| 58950 
d07464875dd4
optional proof context for unify operations, for the sake of proper local options;
 wenzelm parents: 
58027diff
changeset | 38 | val make_elim_preserve: Proof.context -> thm -> thm | 
| 59755 | 39 | val method: | 
| 59780 | 40 | (Proof.context -> ((indexname * Position.T) * string) list -> | 
| 41 | (binding * string option * mixfix) list -> thm -> int -> tactic) -> | |
| 53708 | 42 | (Proof.context -> thm list -> int -> tactic) -> (Proof.context -> Proof.method) context_parser | 
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 43 | end; | 
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 44 | |
| 42806 | 45 | structure Rule_Insts: RULE_INSTS = | 
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 46 | struct | 
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 47 | |
| 59771 
c6e60787ffe2
read instantiations uniformly for rules and tactics;
 wenzelm parents: 
59770diff
changeset | 48 | (** read instantiations **) | 
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 49 | |
| 59771 
c6e60787ffe2
read instantiations uniformly for rules and tactics;
 wenzelm parents: 
59770diff
changeset | 50 | local | 
| 59755 | 51 | |
| 52 | fun error_var msg (xi, pos) = | |
| 53 | error (msg ^ quote (Term.string_of_vname xi) ^ Position.here pos); | |
| 59754 | 54 | |
| 59755 | 55 | fun the_sort tvars (xi, pos) : sort = | 
| 45611 | 56 | (case AList.lookup (op =) tvars xi of | 
| 57 | SOME S => S | |
| 59755 | 58 | | NONE => error_var "No such type variable in theorem: " (xi, pos)); | 
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 59 | |
| 59755 | 60 | fun the_type vars (xi, pos) : typ = | 
| 45611 | 61 | (case AList.lookup (op =) vars xi of | 
| 62 | SOME T => T | |
| 59755 | 63 | | NONE => error_var "No such variable in theorem: " (xi, pos)); | 
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 64 | |
| 59774 | 65 | fun read_type ctxt tvars ((xi, pos), s) = | 
| 59759 | 66 | let | 
| 67 | val S = the_sort tvars (xi, pos); | |
| 68 | val T = Syntax.read_typ ctxt s; | |
| 69 | in | |
| 70 | if Sign.of_sort (Proof_Context.theory_of ctxt) (T, S) then ((xi, S), T) | |
| 59768 | 71 | else error_var "Bad sort for instantiation of type variable: " (xi, pos) | 
| 59759 | 72 | end; | 
| 73 | ||
| 59827 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 wenzelm parents: 
59825diff
changeset | 74 | fun make_instT f v = | 
| 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 wenzelm parents: 
59825diff
changeset | 75 | let | 
| 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 wenzelm parents: 
59825diff
changeset | 76 | val T = TVar v; | 
| 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 wenzelm parents: 
59825diff
changeset | 77 | val T' = f T; | 
| 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 wenzelm parents: 
59825diff
changeset | 78 | in if T = T' then NONE else SOME (v, T') end; | 
| 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 wenzelm parents: 
59825diff
changeset | 79 | |
| 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 wenzelm parents: 
59825diff
changeset | 80 | fun make_inst f v = | 
| 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 wenzelm parents: 
59825diff
changeset | 81 | let | 
| 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 wenzelm parents: 
59825diff
changeset | 82 | val t = Var v; | 
| 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 wenzelm parents: 
59825diff
changeset | 83 | val t' = f t; | 
| 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 wenzelm parents: 
59825diff
changeset | 84 | in if t aconv t' then NONE else SOME (v, t') end; | 
| 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 wenzelm parents: 
59825diff
changeset | 85 | |
| 59796 | 86 | fun read_terms ss Ts ctxt = | 
| 25329 | 87 | let | 
| 88 | fun parse T = if T = propT then Syntax.parse_prop ctxt else Syntax.parse_term ctxt; | |
| 59796 | 89 | val (ts, ctxt') = fold_map Variable.fix_dummy_patterns (map2 parse Ts ss) ctxt; | 
| 25329 | 90 | val ts' = | 
| 39288 | 91 | map2 (Type.constraint o Type_Infer.paramify_vars) Ts ts | 
| 59796 | 92 | |> Syntax.check_terms ctxt' | 
| 93 | |> Variable.polymorphic ctxt'; | |
| 25329 | 94 | val Ts' = map Term.fastype_of ts'; | 
| 95 | val tyenv = fold Type.raw_match (Ts ~~ Ts') Vartab.empty; | |
| 59759 | 96 | val tyenv' = Vartab.fold (fn (xi, (S, T)) => cons ((xi, S), T)) tyenv []; | 
| 59796 | 97 | in ((ts', tyenv'), ctxt') end; | 
| 25329 | 98 | |
| 59827 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 wenzelm parents: 
59825diff
changeset | 99 | in | 
| 59771 
c6e60787ffe2
read instantiations uniformly for rules and tactics;
 wenzelm parents: 
59770diff
changeset | 100 | |
| 59827 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 wenzelm parents: 
59825diff
changeset | 101 | fun read_term s ctxt = | 
| 59771 
c6e60787ffe2
read instantiations uniformly for rules and tactics;
 wenzelm parents: 
59770diff
changeset | 102 | let | 
| 59827 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 wenzelm parents: 
59825diff
changeset | 103 | val (t, ctxt') = Variable.fix_dummy_patterns (Syntax.parse_term ctxt s) ctxt; | 
| 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 wenzelm parents: 
59825diff
changeset | 104 | val t' = Syntax.check_term ctxt' t; | 
| 
04e569577c18
proper Rule_Insts.read_term, e.g. to enable case_tac using "_";
 wenzelm parents: 
59825diff
changeset | 105 | in (t', ctxt') end; | 
| 59771 
c6e60787ffe2
read instantiations uniformly for rules and tactics;
 wenzelm parents: 
59770diff
changeset | 106 | |
| 59796 | 107 | fun read_insts thm mixed_insts ctxt = | 
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 108 | let | 
| 59771 
c6e60787ffe2
read instantiations uniformly for rules and tactics;
 wenzelm parents: 
59770diff
changeset | 109 | val (type_insts, term_insts) = | 
| 
c6e60787ffe2
read instantiations uniformly for rules and tactics;
 wenzelm parents: 
59770diff
changeset | 110 | List.partition (fn (((x, _), _), _) => String.isPrefix "'" x) mixed_insts; | 
| 59768 | 111 | |
| 59825 | 112 | (*thm context*) | 
| 113 | val ctxt1 = Variable.declare_thm thm ctxt; | |
| 59769 | 114 | val tvars = Thm.fold_terms Term.add_tvars thm []; | 
| 115 | val vars = Thm.fold_terms Term.add_vars thm []; | |
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 116 | |
| 59771 
c6e60787ffe2
read instantiations uniformly for rules and tactics;
 wenzelm parents: 
59770diff
changeset | 117 | (*explicit type instantiations*) | 
| 59825 | 118 | val instT1 = Term_Subst.instantiateT (map (read_type ctxt1 tvars) type_insts); | 
| 20343 
e093a54bf25e
reworked read_instantiate -- separate read_insts;
 wenzelm parents: 
20336diff
changeset | 119 | val vars1 = map (apsnd instT1) vars; | 
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 120 | |
| 59771 
c6e60787ffe2
read instantiations uniformly for rules and tactics;
 wenzelm parents: 
59770diff
changeset | 121 | (*term instantiations*) | 
| 45613 
70e5b43535cd
simplified read_instantiate -- no longer need to assign values, since rule attributes are now static;
 wenzelm parents: 
45611diff
changeset | 122 | val (xs, ss) = split_list term_insts; | 
| 
70e5b43535cd
simplified read_instantiate -- no longer need to assign values, since rule attributes are now static;
 wenzelm parents: 
45611diff
changeset | 123 | val Ts = map (the_type vars1) xs; | 
| 59825 | 124 | val ((ts, inferred), ctxt2) = read_terms ss Ts ctxt1; | 
| 45613 
70e5b43535cd
simplified read_instantiate -- no longer need to assign values, since rule attributes are now static;
 wenzelm parents: 
45611diff
changeset | 125 | |
| 59771 
c6e60787ffe2
read instantiations uniformly for rules and tactics;
 wenzelm parents: 
59770diff
changeset | 126 | (*implicit type instantiations*) | 
| 59759 | 127 | val instT2 = Term_Subst.instantiateT inferred; | 
| 20343 
e093a54bf25e
reworked read_instantiate -- separate read_insts;
 wenzelm parents: 
20336diff
changeset | 128 | val vars2 = map (apsnd instT2) vars1; | 
| 59774 | 129 | val inst2 = | 
| 130 | Term_Subst.instantiate ([], map2 (fn (xi, _) => fn t => ((xi, Term.fastype_of t), t)) xs ts) | |
| 131 | #> Envir.beta_norm; | |
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 132 | |
| 45613 
70e5b43535cd
simplified read_instantiate -- no longer need to assign values, since rule attributes are now static;
 wenzelm parents: 
45611diff
changeset | 133 | val inst_tvars = map_filter (make_instT (instT2 o instT1)) tvars; | 
| 
70e5b43535cd
simplified read_instantiate -- no longer need to assign values, since rule attributes are now static;
 wenzelm parents: 
45611diff
changeset | 134 | val inst_vars = map_filter (make_inst inst2) vars2; | 
| 59825 | 135 | in ((inst_tvars, inst_vars), ctxt2) end; | 
| 20343 
e093a54bf25e
reworked read_instantiate -- separate read_insts;
 wenzelm parents: 
20336diff
changeset | 136 | |
| 59771 
c6e60787ffe2
read instantiations uniformly for rules and tactics;
 wenzelm parents: 
59770diff
changeset | 137 | end; | 
| 
c6e60787ffe2
read instantiations uniformly for rules and tactics;
 wenzelm parents: 
59770diff
changeset | 138 | |
| 
c6e60787ffe2
read instantiations uniformly for rules and tactics;
 wenzelm parents: 
59770diff
changeset | 139 | |
| 
c6e60787ffe2
read instantiations uniformly for rules and tactics;
 wenzelm parents: 
59770diff
changeset | 140 | |
| 
c6e60787ffe2
read instantiations uniformly for rules and tactics;
 wenzelm parents: 
59770diff
changeset | 141 | (** forward rules **) | 
| 
c6e60787ffe2
read instantiations uniformly for rules and tactics;
 wenzelm parents: 
59770diff
changeset | 142 | |
| 55143 
04448228381d
explicit eigen-context for attributes "where", "of", and corresponding read_instantiate, instantiate_tac;
 wenzelm parents: 
55111diff
changeset | 143 | fun where_rule ctxt mixed_insts fixes thm = | 
| 20343 
e093a54bf25e
reworked read_instantiate -- separate read_insts;
 wenzelm parents: 
20336diff
changeset | 144 | let | 
| 59825 | 145 | val ctxt' = ctxt |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes |> #2; | 
| 59796 | 146 | val ((inst_tvars, inst_vars), ctxt'') = read_insts thm mixed_insts ctxt'; | 
| 20343 
e093a54bf25e
reworked read_instantiate -- separate read_insts;
 wenzelm parents: 
20336diff
changeset | 147 | in | 
| 59769 | 148 | thm | 
| 149 | |> Drule.instantiate_normalize | |
| 59796 | 150 | (map (apply2 (Thm.ctyp_of ctxt'') o apfst TVar) inst_tvars, | 
| 151 | map (apply2 (Thm.cterm_of ctxt'') o apfst Var) inst_vars) | |
| 152 | |> singleton (Variable.export ctxt'' ctxt) | |
| 45613 
70e5b43535cd
simplified read_instantiate -- no longer need to assign values, since rule attributes are now static;
 wenzelm parents: 
45611diff
changeset | 153 | |> Rule_Cases.save thm | 
| 20343 
e093a54bf25e
reworked read_instantiate -- separate read_insts;
 wenzelm parents: 
20336diff
changeset | 154 | end; | 
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 155 | |
| 55143 
04448228381d
explicit eigen-context for attributes "where", "of", and corresponding read_instantiate, instantiate_tac;
 wenzelm parents: 
55111diff
changeset | 156 | fun of_rule ctxt (args, concl_args) fixes thm = | 
| 20343 
e093a54bf25e
reworked read_instantiate -- separate read_insts;
 wenzelm parents: 
20336diff
changeset | 157 | let | 
| 
e093a54bf25e
reworked read_instantiate -- separate read_insts;
 wenzelm parents: 
20336diff
changeset | 158 | fun zip_vars _ [] = [] | 
| 45613 
70e5b43535cd
simplified read_instantiate -- no longer need to assign values, since rule attributes are now static;
 wenzelm parents: 
45611diff
changeset | 159 | | zip_vars (_ :: xs) (NONE :: rest) = zip_vars xs rest | 
| 59755 | 160 | | zip_vars ((x, _) :: xs) (SOME t :: rest) = ((x, Position.none), t) :: zip_vars xs rest | 
| 20343 
e093a54bf25e
reworked read_instantiate -- separate read_insts;
 wenzelm parents: 
20336diff
changeset | 161 | | zip_vars [] _ = error "More instantiations than variables in theorem"; | 
| 
e093a54bf25e
reworked read_instantiate -- separate read_insts;
 wenzelm parents: 
20336diff
changeset | 162 | val insts = | 
| 
e093a54bf25e
reworked read_instantiate -- separate read_insts;
 wenzelm parents: 
20336diff
changeset | 163 | zip_vars (rev (Term.add_vars (Thm.full_prop_of thm) [])) args @ | 
| 
e093a54bf25e
reworked read_instantiate -- separate read_insts;
 wenzelm parents: 
20336diff
changeset | 164 | zip_vars (rev (Term.add_vars (Thm.concl_of thm) [])) concl_args; | 
| 55143 
04448228381d
explicit eigen-context for attributes "where", "of", and corresponding read_instantiate, instantiate_tac;
 wenzelm parents: 
55111diff
changeset | 165 | in where_rule ctxt insts fixes thm end; | 
| 27236 | 166 | |
| 55143 
04448228381d
explicit eigen-context for attributes "where", "of", and corresponding read_instantiate, instantiate_tac;
 wenzelm parents: 
55111diff
changeset | 167 | fun read_instantiate ctxt insts xs = | 
| 
04448228381d
explicit eigen-context for attributes "where", "of", and corresponding read_instantiate, instantiate_tac;
 wenzelm parents: 
55111diff
changeset | 168 | where_rule ctxt insts (map (fn x => (Binding.name x, NONE, NoSyn)) xs); | 
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 169 | |
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 170 | |
| 20343 
e093a54bf25e
reworked read_instantiate -- separate read_insts;
 wenzelm parents: 
20336diff
changeset | 171 | |
| 
e093a54bf25e
reworked read_instantiate -- separate read_insts;
 wenzelm parents: 
20336diff
changeset | 172 | (** attributes **) | 
| 
e093a54bf25e
reworked read_instantiate -- separate read_insts;
 wenzelm parents: 
20336diff
changeset | 173 | |
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 174 | (* where: named instantiation *) | 
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 175 | |
| 53171 | 176 | val _ = Theory.setup | 
| 53708 | 177 |   (Attrib.setup @{binding "where"}
 | 
| 55143 
04448228381d
explicit eigen-context for attributes "where", "of", and corresponding read_instantiate, instantiate_tac;
 wenzelm parents: 
55111diff
changeset | 178 | (Scan.lift | 
| 59755 | 179 | (Parse.and_list (Parse.position Args.var -- (Args.$$$ "=" |-- Args.name_inner_syntax)) | 
| 180 | -- Parse.for_fixes) >> (fn (insts, fixes) => | |
| 181 | Thm.rule_attribute (fn context => where_rule (Context.proof_of context) insts fixes))) | |
| 53171 | 182 | "named instantiation of theorem"); | 
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 183 | |
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 184 | |
| 20343 
e093a54bf25e
reworked read_instantiate -- separate read_insts;
 wenzelm parents: 
20336diff
changeset | 185 | (* of: positional instantiation (terms only) *) | 
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 186 | |
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 187 | local | 
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 188 | |
| 55111 | 189 | val inst = Args.maybe Args.name_inner_syntax; | 
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 190 | val concl = Args.$$$ "concl" -- Args.colon; | 
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 191 | |
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 192 | val insts = | 
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 193 | Scan.repeat (Scan.unless concl inst) -- | 
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 194 | Scan.optional (concl |-- Scan.repeat inst) []; | 
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 195 | |
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 196 | in | 
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 197 | |
| 53171 | 198 | val _ = Theory.setup | 
| 53708 | 199 |   (Attrib.setup @{binding "of"}
 | 
| 55143 
04448228381d
explicit eigen-context for attributes "where", "of", and corresponding read_instantiate, instantiate_tac;
 wenzelm parents: 
55111diff
changeset | 200 | (Scan.lift (insts -- Parse.for_fixes) >> (fn (args, fixes) => | 
| 
04448228381d
explicit eigen-context for attributes "where", "of", and corresponding read_instantiate, instantiate_tac;
 wenzelm parents: 
55111diff
changeset | 201 | Thm.rule_attribute (fn context => of_rule (Context.proof_of context) args fixes))) | 
| 53171 | 202 | "positional instantiation of theorem"); | 
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 203 | |
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 204 | end; | 
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 205 | |
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 206 | |
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 207 | |
| 27245 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 208 | (** tactics **) | 
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 209 | |
| 59825 | 210 | (* goal context *) | 
| 211 | ||
| 59835 
97872c658a44
rule_insts_schematic is considered legacy and false by default;
 wenzelm parents: 
59834diff
changeset | 212 | (*legacy*) | 
| 
97872c658a44
rule_insts_schematic is considered legacy and false by default;
 wenzelm parents: 
59834diff
changeset | 213 | val schematic = Attrib.setup_config_bool @{binding rule_insts_schematic} (K false);
 | 
| 59800 | 214 | |
| 59829 | 215 | fun goal_context goal ctxt = | 
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 216 | let | 
| 59828 
0e9baaf0e0bb
prefer Variable.focus, despite subtle differences of Logic.strip_params vs. Term.strip_all_vars;
 wenzelm parents: 
59827diff
changeset | 217 | val ((_, params), ctxt') = ctxt | 
| 59829 | 218 | |> Variable.declare_constraints goal | 
| 59790 | 219 | |> Variable.improper_fixes | 
| 59828 
0e9baaf0e0bb
prefer Variable.focus, despite subtle differences of Logic.strip_params vs. Term.strip_all_vars;
 wenzelm parents: 
59827diff
changeset | 220 | |> Variable.focus_params goal | 
| 59790 | 221 | ||> Variable.restore_proper_fixes ctxt | 
| 59801 | 222 | ||> Config.get ctxt schematic ? Proof_Context.set_mode Proof_Context.mode_schematic; | 
| 59828 
0e9baaf0e0bb
prefer Variable.focus, despite subtle differences of Logic.strip_params vs. Term.strip_all_vars;
 wenzelm parents: 
59827diff
changeset | 223 | in (params, ctxt') end; | 
| 59825 | 224 | |
| 225 | ||
| 226 | (* resolution after lifting and instantiation; may refer to parameters of the subgoal *) | |
| 227 | ||
| 228 | fun bires_inst_tac bires_flag ctxt mixed_insts fixes thm i st = CSUBGOAL (fn (cgoal, _) => | |
| 229 | let | |
| 230 | (* goal context *) | |
| 231 | ||
| 59834 | 232 | val (params, goal_ctxt) = goal_context (Thm.term_of cgoal) ctxt; | 
| 59825 | 233 | val paramTs = map #2 params; | 
| 59754 | 234 | |
| 235 | ||
| 59835 
97872c658a44
rule_insts_schematic is considered legacy and false by default;
 wenzelm parents: 
59834diff
changeset | 236 | (* instantiation context *) | 
| 59754 | 237 | |
| 59834 | 238 | val ((inst_tvars, inst_vars), inst_ctxt) = goal_ctxt | 
| 239 | |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes |> #2 | |
| 240 | |> read_insts thm mixed_insts; | |
| 59780 | 241 | |
| 59834 | 242 | fun add_fixed (Free (x, _)) = Variable.newly_fixed inst_ctxt goal_ctxt x ? insert (op =) x | 
| 59805 | 243 | | add_fixed _ = I; | 
| 244 | val fixed = fold (Term.fold_aterms add_fixed o #2) inst_vars []; | |
| 245 | ||
| 59780 | 246 | |
| 247 | (* lift and instantiate rule *) | |
| 59754 | 248 | |
| 59774 | 249 | val inc = Thm.maxidx_of st + 1; | 
| 59825 | 250 | val lift_type = Logic.incr_tvar inc; | 
| 59834 | 251 | fun lift_var ((a, j), T) = Var ((a, j + inc), paramTs ---> lift_type T); | 
| 59825 | 252 | fun lift_term t = fold_rev Term.absfree params (Logic.incr_indexes (fixed, paramTs, inc) t); | 
| 59754 | 253 | |
| 59771 
c6e60787ffe2
read instantiations uniformly for rules and tactics;
 wenzelm parents: 
59770diff
changeset | 254 | val inst_tvars' = inst_tvars | 
| 59825 | 255 | |> map (apply2 (Thm.ctyp_of inst_ctxt o lift_type) o apfst TVar); | 
| 59771 
c6e60787ffe2
read instantiations uniformly for rules and tactics;
 wenzelm parents: 
59770diff
changeset | 256 | val inst_vars' = inst_vars | 
| 59796 | 257 | |> map (fn (v, t) => apply2 (Thm.cterm_of inst_ctxt) (lift_var v, lift_term t)); | 
| 59771 
c6e60787ffe2
read instantiations uniformly for rules and tactics;
 wenzelm parents: 
59770diff
changeset | 258 | |
| 59825 | 259 | val thm' = Thm.lift_rule cgoal thm | 
| 260 | |> Drule.instantiate_normalize (inst_tvars', inst_vars') | |
| 59836 | 261 | |> singleton (Variable.export inst_ctxt ctxt); | 
| 262 | in compose_tac ctxt (bires_flag, thm', Thm.nprems_of thm) i end) i st; | |
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 263 | |
| 27120 | 264 | val res_inst_tac = bires_inst_tac false; | 
| 265 | val eres_inst_tac = bires_inst_tac true; | |
| 266 | ||
| 267 | ||
| 27245 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 268 | (* forward resolution *) | 
| 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 269 | |
| 58950 
d07464875dd4
optional proof context for unify operations, for the sake of proper local options;
 wenzelm parents: 
58027diff
changeset | 270 | fun make_elim_preserve ctxt rl = | 
| 27245 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 271 | let | 
| 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 272 | val maxidx = Thm.maxidx_of rl; | 
| 59623 | 273 | fun cvar xi = Thm.cterm_of ctxt (Var (xi, propT)); | 
| 27245 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 274 | val revcut_rl' = | 
| 43333 
2bdec7f430d3
renamed Drule.instantiate to Drule.instantiate_normalize to emphasize its meaning as opposed to plain Thm.instantiate;
 wenzelm parents: 
42806diff
changeset | 275 |       Drule.instantiate_normalize ([], [(cvar ("V", 0), cvar ("V", maxidx + 1)),
 | 
| 27245 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 276 |         (cvar ("W", 0), cvar ("W", maxidx + 1))]) Drule.revcut_rl;
 | 
| 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 277 | in | 
| 52223 
5bb6ae8acb87
tuned signature -- more explicit flags for low-level Thm.bicompose;
 wenzelm parents: 
46476diff
changeset | 278 | (case Seq.list_of | 
| 58950 
d07464875dd4
optional proof context for unify operations, for the sake of proper local options;
 wenzelm parents: 
58027diff
changeset | 279 |       (Thm.bicompose (SOME ctxt) {flatten = true, match = false, incremented = false}
 | 
| 52223 
5bb6ae8acb87
tuned signature -- more explicit flags for low-level Thm.bicompose;
 wenzelm parents: 
46476diff
changeset | 280 | (false, rl, Thm.nprems_of rl) 1 revcut_rl') | 
| 
5bb6ae8acb87
tuned signature -- more explicit flags for low-level Thm.bicompose;
 wenzelm parents: 
46476diff
changeset | 281 | of | 
| 27245 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 282 | [th] => th | 
| 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 283 |     | _ => raise THM ("make_elim_preserve", 1, [rl]))
 | 
| 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 284 | end; | 
| 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 285 | |
| 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 286 | (*instantiate and cut -- for atomic fact*) | 
| 59780 | 287 | fun cut_inst_tac ctxt insts fixes rule = | 
| 288 | res_inst_tac ctxt insts fixes (make_elim_preserve ctxt rule); | |
| 27245 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 289 | |
| 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 290 | (*forward tactic applies a rule to an assumption without deleting it*) | 
| 59780 | 291 | fun forw_inst_tac ctxt insts fixes rule = | 
| 292 | cut_inst_tac ctxt insts fixes rule THEN' assume_tac ctxt; | |
| 27245 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 293 | |
| 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 294 | (*dresolve tactic applies a rule to replace an assumption*) | 
| 59780 | 295 | fun dres_inst_tac ctxt insts fixes rule = | 
| 296 | eres_inst_tac ctxt insts fixes (make_elim_preserve ctxt rule); | |
| 27245 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 297 | |
| 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 298 | |
| 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 299 | (* derived tactics *) | 
| 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 300 | |
| 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 301 | (*deletion of an assumption*) | 
| 59780 | 302 | fun thin_tac ctxt s fixes = | 
| 303 |   eres_inst_tac ctxt [((("V", 0), Position.none), s)] fixes Drule.thin_rl;
 | |
| 27245 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 304 | |
| 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 305 | (*Introduce the given proposition as lemma and subgoal*) | 
| 59780 | 306 | fun subgoal_tac ctxt A fixes = | 
| 307 |   DETERM o res_inst_tac ctxt [((("psi", 0), Position.none), A)] fixes cut_rl;
 | |
| 27245 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 308 | |
| 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 309 | |
| 53708 | 310 | (* method wrapper *) | 
| 27245 
817d34377170
added instantiate_tac, cut_inst_tac, forw_inst_tac, dres_inst_tac, make_elim_preserve (from tactic.ML);
 wenzelm parents: 
27236diff
changeset | 311 | |
| 30545 | 312 | fun method inst_tac tac = | 
| 30515 | 313 | Args.goal_spec -- | 
| 314 | Scan.optional (Scan.lift | |
| 59780 | 315 | (Parse.and_list1 | 
| 316 | (Parse.position Args.var -- (Args.$$$ "=" |-- Parse.!!! Args.name_inner_syntax)) -- | |
| 317 | Parse.for_fixes --| Args.$$$ "in")) ([], []) -- | |
| 30515 | 318 | Attrib.thms >> | 
| 59780 | 319 | (fn ((quant, (insts, fixes)), thms) => fn ctxt => METHOD (fn facts => | 
| 320 | if null insts andalso null fixes | |
| 321 | then quant (Method.insert_tac facts THEN' tac ctxt thms) | |
| 30515 | 322 | else | 
| 323 | (case thms of | |
| 59780 | 324 | [thm] => quant (Method.insert_tac facts THEN' inst_tac ctxt insts fixes thm) | 
| 30515 | 325 | | _ => error "Cannot have instantiations with multiple rules"))); | 
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 326 | |
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 327 | |
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 328 | (* setup *) | 
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 329 | |
| 53708 | 330 | (*warning: rule_tac etc. refer to dynamic subgoal context!*) | 
| 331 | ||
| 53171 | 332 | val _ = Theory.setup | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59058diff
changeset | 333 |  (Method.setup @{binding rule_tac} (method res_inst_tac resolve_tac)
 | 
| 53708 | 334 | "apply rule (dynamic instantiation)" #> | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59058diff
changeset | 335 |   Method.setup @{binding erule_tac} (method eres_inst_tac eresolve_tac)
 | 
| 30515 | 336 | "apply rule in elimination manner (dynamic instantiation)" #> | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59058diff
changeset | 337 |   Method.setup @{binding drule_tac} (method dres_inst_tac dresolve_tac)
 | 
| 30515 | 338 | "apply rule in destruct manner (dynamic instantiation)" #> | 
| 59498 
50b60f501b05
proper context for resolve_tac, eresolve_tac, dresolve_tac, forward_tac etc.;
 wenzelm parents: 
59058diff
changeset | 339 |   Method.setup @{binding frule_tac} (method forw_inst_tac forward_tac)
 | 
| 30515 | 340 | "apply rule in forward manner (dynamic instantiation)" #> | 
| 53708 | 341 |   Method.setup @{binding cut_tac} (method cut_inst_tac (K cut_rules_tac))
 | 
| 342 | "cut rule (dynamic instantiation)" #> | |
| 343 |   Method.setup @{binding subgoal_tac}
 | |
| 59780 | 344 | (Args.goal_spec -- Scan.lift (Scan.repeat1 Args.name_inner_syntax -- Parse.for_fixes) >> | 
| 345 | (fn (quant, (props, fixes)) => fn ctxt => | |
| 346 | SIMPLE_METHOD'' quant (EVERY' (map (fn prop => subgoal_tac ctxt prop fixes) props)))) | |
| 30515 | 347 | "insert subgoal (dynamic instantiation)" #> | 
| 53708 | 348 |   Method.setup @{binding thin_tac}
 | 
| 59780 | 349 | (Args.goal_spec -- Scan.lift (Args.name_inner_syntax -- Parse.for_fixes) >> | 
| 350 | (fn (quant, (prop, fixes)) => fn ctxt => SIMPLE_METHOD'' quant (thin_tac ctxt prop fixes))) | |
| 351 | "remove premise (dynamic instantiation)"); | |
| 20336 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 352 | |
| 
aac494583949
Rule instantiations -- operations within a rule/subgoal context.
 wenzelm parents: diff
changeset | 353 | end; |