| author | nipkow | 
| Thu, 29 Sep 2005 15:31:34 +0200 | |
| changeset 17719 | 2e75155c5ed5 | 
| parent 17004 | 6a0d8ecf65f1 | 
| child 17723 | ee5b42e3cbb4 | 
| permissions | -rw-r--r-- | 
| 16014 | 1 | (* Title: Pure/simplifier.ML | 
| 2 | ID: $Id$ | |
| 3 | Author: Tobias Nipkow and Markus Wenzel, TU Muenchen | |
| 4 | ||
| 5 | Generic simplifier, suitable for most logics (see also | |
| 6 | meta_simplifier.ML for the actual meta-level rewriting engine). | |
| 7 | *) | |
| 8 | ||
| 9 | signature BASIC_SIMPLIFIER = | |
| 10 | sig | |
| 11 | include BASIC_META_SIMPLIFIER | |
| 12 | type context_solver | |
| 13 | val mk_context_solver: string -> (Proof.context -> thm list -> int -> tactic) | |
| 14 | -> context_solver | |
| 15 | type context_simproc | |
| 16 | val mk_context_simproc: string -> cterm list -> | |
| 17 | (Proof.context -> simpset -> term -> thm option) -> context_simproc | |
| 18 | val print_simpset: theory -> unit | |
| 16458 | 19 | val simpset_ref_of_sg: theory -> simpset ref (*obsolete*) | 
| 16014 | 20 | val simpset_ref_of: theory -> simpset ref | 
| 16458 | 21 | val simpset_of_sg: theory -> simpset (*obsolete*) | 
| 16014 | 22 | val simpset_of: theory -> simpset | 
| 23 | val SIMPSET: (simpset -> tactic) -> tactic | |
| 24 | val SIMPSET': (simpset -> 'a -> tactic) -> 'a -> tactic | |
| 25 | val simpset: unit -> simpset | |
| 26 | val simpset_ref: unit -> simpset ref | |
| 27 | val Addsimps: thm list -> unit | |
| 28 | val Delsimps: thm list -> unit | |
| 29 | val Addsimprocs: simproc list -> unit | |
| 30 | val Delsimprocs: simproc list -> unit | |
| 31 | val Addcongs: thm list -> unit | |
| 32 | val Delcongs: thm list -> unit | |
| 33 | val local_simpset_of: Proof.context -> simpset | |
| 34 | val safe_asm_full_simp_tac: simpset -> int -> tactic | |
| 35 | val simp_tac: simpset -> int -> tactic | |
| 36 | val asm_simp_tac: simpset -> int -> tactic | |
| 37 | val full_simp_tac: simpset -> int -> tactic | |
| 38 | val asm_lr_simp_tac: simpset -> int -> tactic | |
| 39 | val asm_full_simp_tac: simpset -> int -> tactic | |
| 40 | val Simp_tac: int -> tactic | |
| 41 | val Asm_simp_tac: int -> tactic | |
| 42 | val Full_simp_tac: int -> tactic | |
| 43 | val Asm_lr_simp_tac: int -> tactic | |
| 44 | val Asm_full_simp_tac: int -> tactic | |
| 45 | val simplify: simpset -> thm -> thm | |
| 46 | val asm_simplify: simpset -> thm -> thm | |
| 47 | val full_simplify: simpset -> thm -> thm | |
| 48 | val asm_lr_simplify: simpset -> thm -> thm | |
| 49 | val asm_full_simplify: simpset -> thm -> thm | |
| 50 | end; | |
| 51 | ||
| 52 | signature SIMPLIFIER = | |
| 53 | sig | |
| 54 | include BASIC_SIMPLIFIER | |
| 17004 | 55 | val clear_ss: simpset -> simpset | 
| 56 | val inherit_bounds: simpset -> simpset -> simpset | |
| 16458 | 57 | val simproc_i: theory -> string -> term list | 
| 58 | -> (theory -> simpset -> term -> thm option) -> simproc | |
| 59 | val simproc: theory -> string -> string list | |
| 60 | -> (theory -> simpset -> term -> thm option) -> simproc | |
| 61 | val context_simproc_i: theory -> string -> term list | |
| 16014 | 62 | -> (Proof.context -> simpset -> term -> thm option) -> context_simproc | 
| 16458 | 63 | val context_simproc: theory -> string -> string list | 
| 16014 | 64 | -> (Proof.context -> simpset -> term -> thm option) -> context_simproc | 
| 65 | val rewrite: simpset -> cterm -> thm | |
| 66 | val asm_rewrite: simpset -> cterm -> thm | |
| 67 | val full_rewrite: simpset -> cterm -> thm | |
| 68 | val asm_lr_rewrite: simpset -> cterm -> thm | |
| 69 | val asm_full_rewrite: simpset -> cterm -> thm | |
| 70 | val add_context_simprocs: context_simproc list -> theory -> theory | |
| 71 | val del_context_simprocs: context_simproc list -> theory -> theory | |
| 72 | val set_context_subgoaler: (Proof.context -> simpset -> int -> tactic) -> theory -> theory | |
| 73 | val reset_context_subgoaler: theory -> theory | |
| 74 | val add_context_looper: string * (Proof.context -> int -> Tactical.tactic) -> | |
| 75 | theory -> theory | |
| 76 | val del_context_looper: string -> theory -> theory | |
| 77 | val add_context_unsafe_solver: context_solver -> theory -> theory | |
| 78 | val add_context_safe_solver: context_solver -> theory -> theory | |
| 79 | val print_local_simpset: Proof.context -> unit | |
| 80 | val get_local_simpset: Proof.context -> simpset | |
| 81 | val put_local_simpset: simpset -> Proof.context -> Proof.context | |
| 82 | val change_global_ss: (simpset * thm list -> simpset) -> theory attribute | |
| 83 | val change_local_ss: (simpset * thm list -> simpset) -> Proof.context attribute | |
| 84 | val simp_add_global: theory attribute | |
| 85 | val simp_del_global: theory attribute | |
| 86 | val simp_add_local: Proof.context attribute | |
| 87 | val simp_del_local: Proof.context attribute | |
| 88 | val cong_add_global: theory attribute | |
| 89 | val cong_del_global: theory attribute | |
| 90 | val cong_add_local: Proof.context attribute | |
| 91 | val cong_del_local: Proof.context attribute | |
| 92 | val change_simpset_of: (simpset * 'a -> simpset) -> 'a -> theory -> theory | |
| 93 | val simp_modifiers: (Args.T list -> (Method.modifier * Args.T list)) list | |
| 94 | val method_setup: (Args.T list -> (Method.modifier * Args.T list)) list | |
| 95 | -> (theory -> theory) list | |
| 96 | val easy_setup: thm -> thm list -> (theory -> theory) list | |
| 97 | end; | |
| 98 | ||
| 99 | structure Simplifier: SIMPLIFIER = | |
| 100 | struct | |
| 101 | ||
| 102 | open MetaSimplifier; | |
| 103 | ||
| 104 | ||
| 105 | (** context dependent simpset components **) | |
| 106 | ||
| 107 | (* datatype context_solver *) | |
| 108 | ||
| 109 | datatype context_solver = | |
| 110 | ContextSolver of (string * (Proof.context -> thm list -> int -> tactic)) * stamp; | |
| 111 | ||
| 112 | fun mk_context_solver name f = ContextSolver ((name, f), stamp ()); | |
| 113 | fun eq_context_solver (ContextSolver (_, id1), ContextSolver (_, id2)) = (id1 = id2); | |
| 114 | val merge_context_solvers = gen_merge_lists eq_context_solver; | |
| 115 | ||
| 116 | ||
| 117 | (* datatype context_simproc *) | |
| 118 | ||
| 119 | datatype context_simproc = ContextSimproc of | |
| 120 | (string * cterm list * (Proof.context -> simpset -> term -> thm option)) * stamp; | |
| 121 | ||
| 122 | fun mk_context_simproc name lhss f = ContextSimproc ((name, lhss, f), stamp ()); | |
| 123 | fun eq_context_simproc (ContextSimproc (_, id1), ContextSimproc (_, id2)) = (id1 = id2); | |
| 124 | val merge_context_simprocs = gen_merge_lists eq_context_simproc; | |
| 125 | ||
| 16458 | 126 | fun context_simproc_i thy name = | 
| 127 | mk_context_simproc name o map (Thm.cterm_of thy o Logic.varify); | |
| 16014 | 128 | |
| 16458 | 129 | fun context_simproc thy name = | 
| 16806 | 130 | context_simproc_i thy name o map (Sign.read_term thy); | 
| 16014 | 131 | |
| 132 | ||
| 133 | (* datatype context_ss *) | |
| 134 | ||
| 135 | datatype context_ss = ContextSS of | |
| 136 |  {simprocs: context_simproc list,
 | |
| 137 | subgoal_tac: (Proof.context -> simpset -> int -> tactic) option, | |
| 138 | loop_tacs: (string * (Proof.context -> int -> tactic)) list, | |
| 139 | unsafe_solvers: context_solver list, | |
| 140 | solvers: context_solver list}; | |
| 141 | ||
| 142 | fun context_ss ctxt ss ctxt_ss = | |
| 143 | let | |
| 144 |     val ContextSS {simprocs, subgoal_tac, loop_tacs, unsafe_solvers, solvers} = ctxt_ss;
 | |
| 145 | fun prep_simproc (ContextSimproc ((name, lhss, f), _)) = | |
| 146 | mk_simproc name lhss (K (f ctxt)); | |
| 147 | fun add_loop (name, f) simpset = simpset addloop (name, f ctxt); | |
| 148 | fun add_solver add (ContextSolver ((name, f), _)) simpset = | |
| 149 | add (simpset, mk_solver name (f ctxt)); | |
| 150 | in | |
| 151 | ((case subgoal_tac of NONE => ss | SOME tac => ss setsubgoaler tac ctxt) | |
| 152 | addsimprocs map prep_simproc simprocs) | |
| 153 | |> fold_rev add_loop loop_tacs | |
| 154 | |> fold_rev (add_solver (op addSolver)) unsafe_solvers | |
| 155 | |> fold_rev (add_solver (op addSSolver)) solvers | |
| 156 | end; | |
| 157 | ||
| 158 | fun make_context_ss (simprocs, subgoal_tac, loop_tacs, unsafe_solvers, solvers) = | |
| 159 |   ContextSS {simprocs = simprocs, subgoal_tac = subgoal_tac, loop_tacs = loop_tacs,
 | |
| 160 | unsafe_solvers = unsafe_solvers, solvers = solvers}; | |
| 161 | ||
| 162 | val empty_context_ss = make_context_ss ([], NONE, [], [], []); | |
| 163 | ||
| 164 | fun merge_context_ss (ctxt_ss1, ctxt_ss2) = | |
| 165 | let | |
| 166 |     val ContextSS {simprocs = simprocs1, subgoal_tac = subgoal_tac1, loop_tacs = loop_tacs1,
 | |
| 167 | unsafe_solvers = unsafe_solvers1, solvers = solvers1} = ctxt_ss1; | |
| 168 |     val ContextSS {simprocs = simprocs2, subgoal_tac = subgoal_tac2, loop_tacs = loop_tacs2,
 | |
| 169 | unsafe_solvers = unsafe_solvers2, solvers = solvers2} = ctxt_ss2; | |
| 170 | ||
| 171 | val simprocs' = merge_context_simprocs simprocs1 simprocs2; | |
| 172 | val subgoal_tac' = (case subgoal_tac1 of NONE => subgoal_tac2 | some => some); | |
| 173 | val loop_tacs' = merge_alists loop_tacs1 loop_tacs2; | |
| 174 | val unsafe_solvers' = merge_context_solvers unsafe_solvers1 unsafe_solvers2; | |
| 175 | val solvers' = merge_context_solvers solvers1 solvers2; | |
| 176 | in make_context_ss (simprocs', subgoal_tac', loop_tacs', unsafe_solvers', solvers') end; | |
| 177 | ||
| 178 | ||
| 179 | ||
| 180 | (** global and local simpset data **) | |
| 181 | ||
| 182 | (* theory data kind 'Pure/simpset' *) | |
| 183 | ||
| 16458 | 184 | structure GlobalSimpset = TheoryDataFun | 
| 185 | (struct | |
| 16014 | 186 | val name = "Pure/simpset"; | 
| 187 | type T = simpset ref * context_ss; | |
| 188 | ||
| 189 | val empty = (ref empty_ss, empty_context_ss); | |
| 190 | fun copy (ref ss, ctxt_ss) = (ref ss, ctxt_ss): T; (*create new reference!*) | |
| 16458 | 191 | val extend = copy; | 
| 192 | fun merge _ ((ref ss1, ctxt_ss1), (ref ss2, ctxt_ss2)) = | |
| 16014 | 193 | (ref (merge_ss (ss1, ss2)), merge_context_ss (ctxt_ss1, ctxt_ss2)); | 
| 194 | fun print _ (ref ss, _) = print_ss ss; | |
| 16458 | 195 | end); | 
| 16014 | 196 | |
| 197 | val _ = Context.add_setup [GlobalSimpset.init]; | |
| 198 | val print_simpset = GlobalSimpset.print; | |
| 199 | ||
| 200 | val simpset_ref_of = #1 o GlobalSimpset.get; | |
| 16458 | 201 | val simpset_ref_of_sg = simpset_ref_of; | 
| 16014 | 202 | val get_context_ss = #2 o GlobalSimpset.get o ProofContext.theory_of; | 
| 203 | ||
| 204 | fun map_context_ss f = GlobalSimpset.map (apsnd | |
| 205 |   (fn ContextSS {simprocs, subgoal_tac, loop_tacs, unsafe_solvers, solvers} =>
 | |
| 206 | make_context_ss (f (simprocs, subgoal_tac, loop_tacs, unsafe_solvers, solvers)))); | |
| 207 | ||
| 208 | ||
| 209 | (* access global simpset *) | |
| 210 | ||
| 16458 | 211 | val simpset_of = ! o simpset_ref_of; | 
| 212 | val simpset_of_sg = simpset_of; | |
| 16014 | 213 | |
| 16458 | 214 | fun SIMPSET tacf state = tacf (simpset_of (Thm.theory_of_thm state)) state; | 
| 215 | fun SIMPSET' tacf i state = tacf (simpset_of (Thm.theory_of_thm state)) i state; | |
| 16014 | 216 | |
| 217 | val simpset = simpset_of o Context.the_context; | |
| 16458 | 218 | val simpset_ref = simpset_ref_of o Context.the_context; | 
| 16014 | 219 | |
| 220 | ||
| 221 | (* change global simpset *) | |
| 222 | ||
| 223 | fun change_simpset_of f x thy = | |
| 224 | let val r = simpset_ref_of thy | |
| 225 | in r := f (! r, x); thy end; | |
| 226 | ||
| 227 | fun change_simpset f x = (change_simpset_of f x (Context.the_context ()); ()); | |
| 228 | ||
| 229 | val Addsimps = change_simpset (op addsimps); | |
| 230 | val Delsimps = change_simpset (op delsimps); | |
| 231 | val Addsimprocs = change_simpset (op addsimprocs); | |
| 232 | val Delsimprocs = change_simpset (op delsimprocs); | |
| 233 | val Addcongs = change_simpset (op addcongs); | |
| 234 | val Delcongs = change_simpset (op delcongs); | |
| 235 | ||
| 236 | ||
| 237 | (* change context dependent components *) | |
| 238 | ||
| 239 | fun add_context_simprocs procs = | |
| 240 | map_context_ss (fn (simprocs, subgoal_tac, loop_tacs, unsafe_solvers, solvers) => | |
| 241 | (merge_context_simprocs procs simprocs, subgoal_tac, loop_tacs, | |
| 242 | unsafe_solvers, solvers)); | |
| 243 | ||
| 244 | fun del_context_simprocs procs = | |
| 245 | map_context_ss (fn (simprocs, subgoal_tac, loop_tacs, unsafe_solvers, solvers) => | |
| 246 | (gen_rems eq_context_simproc (simprocs, procs), subgoal_tac, loop_tacs, | |
| 247 | unsafe_solvers, solvers)); | |
| 248 | ||
| 249 | fun set_context_subgoaler tac = | |
| 250 | map_context_ss (fn (simprocs, _, loop_tacs, unsafe_solvers, solvers) => | |
| 251 | (simprocs, SOME tac, loop_tacs, unsafe_solvers, solvers)); | |
| 252 | ||
| 253 | val reset_context_subgoaler = | |
| 254 | map_context_ss (fn (simprocs, _, loop_tacs, unsafe_solvers, solvers) => | |
| 255 | (simprocs, NONE, loop_tacs, unsafe_solvers, solvers)); | |
| 256 | ||
| 257 | fun add_context_looper (name, tac) = | |
| 258 | map_context_ss (fn (simprocs, subgoal_tac, loop_tacs, unsafe_solvers, solvers) => | |
| 259 | (simprocs, subgoal_tac, merge_alists [(name, tac)] loop_tacs, | |
| 260 | unsafe_solvers, solvers)); | |
| 261 | ||
| 262 | fun del_context_looper name = | |
| 263 | map_context_ss (fn (simprocs, subgoal_tac, loop_tacs, unsafe_solvers, solvers) => | |
| 264 | (simprocs, subgoal_tac, filter_out (equal name o #1) loop_tacs, | |
| 265 | unsafe_solvers, solvers)); | |
| 266 | ||
| 267 | fun add_context_unsafe_solver solver = | |
| 268 | map_context_ss (fn (simprocs, subgoal_tac, loop_tacs, unsafe_solvers, solvers) => | |
| 269 | (simprocs, subgoal_tac, loop_tacs, | |
| 270 | merge_context_solvers [solver] unsafe_solvers, solvers)); | |
| 271 | ||
| 272 | fun add_context_safe_solver solver = | |
| 273 | map_context_ss (fn (simprocs, subgoal_tac, loop_tacs, unsafe_solvers, solvers) => | |
| 274 | (simprocs, subgoal_tac, loop_tacs, unsafe_solvers, | |
| 275 | merge_context_solvers [solver] solvers)); | |
| 276 | ||
| 277 | ||
| 278 | (* proof data kind 'Pure/simpset' *) | |
| 279 | ||
| 16458 | 280 | structure LocalSimpset = ProofDataFun | 
| 281 | (struct | |
| 16014 | 282 | val name = "Pure/simpset"; | 
| 283 | type T = simpset; | |
| 284 | val init = simpset_of; | |
| 285 | fun print ctxt ss = print_ss (context_ss ctxt ss (get_context_ss ctxt)); | |
| 16458 | 286 | end); | 
| 16014 | 287 | |
| 288 | val _ = Context.add_setup [LocalSimpset.init]; | |
| 289 | val print_local_simpset = LocalSimpset.print; | |
| 290 | ||
| 291 | val get_local_simpset = LocalSimpset.get; | |
| 292 | val put_local_simpset = LocalSimpset.put; | |
| 293 | fun map_local_simpset f ctxt = put_local_simpset (f (get_local_simpset ctxt)) ctxt; | |
| 294 | ||
| 295 | fun local_simpset_of ctxt = | |
| 296 | context_ss ctxt (get_local_simpset ctxt) (get_context_ss ctxt); | |
| 297 | ||
| 298 | ||
| 299 | (* attributes *) | |
| 300 | ||
| 301 | fun change_global_ss f (thy, th) = | |
| 302 | let val r = simpset_ref_of thy | |
| 303 | in r := f (! r, [th]); (thy, th) end; | |
| 304 | ||
| 305 | fun change_local_ss f (ctxt, th) = | |
| 306 | let val ss = f (get_local_simpset ctxt, [th]) | |
| 307 | in (put_local_simpset ss ctxt, th) end; | |
| 308 | ||
| 309 | val simp_add_global = change_global_ss (op addsimps); | |
| 310 | val simp_del_global = change_global_ss (op delsimps); | |
| 16806 | 311 | val simp_add_local = change_local_ss (op addsimps); | 
| 16014 | 312 | val simp_del_local = change_local_ss (op delsimps); | 
| 313 | ||
| 314 | val cong_add_global = change_global_ss (op addcongs); | |
| 315 | val cong_del_global = change_global_ss (op delcongs); | |
| 316 | val cong_add_local = change_local_ss (op addcongs); | |
| 317 | val cong_del_local = change_local_ss (op delcongs); | |
| 318 | ||
| 319 | ||
| 16806 | 320 | (* tactics *) | 
| 321 | ||
| 16014 | 322 | val simp_tac = generic_simp_tac false (false, false, false); | 
| 323 | val asm_simp_tac = generic_simp_tac false (false, true, false); | |
| 324 | val full_simp_tac = generic_simp_tac false (true, false, false); | |
| 325 | val asm_lr_simp_tac = generic_simp_tac false (true, true, false); | |
| 326 | val asm_full_simp_tac = generic_simp_tac false (true, true, true); | |
| 327 | val safe_asm_full_simp_tac = generic_simp_tac true (true, true, true); | |
| 328 | ||
| 329 | (*the abstraction over the proof state delays the dereferencing*) | |
| 330 | fun Simp_tac i st = simp_tac (simpset ()) i st; | |
| 331 | fun Asm_simp_tac i st = asm_simp_tac (simpset ()) i st; | |
| 332 | fun Full_simp_tac i st = full_simp_tac (simpset ()) i st; | |
| 333 | fun Asm_lr_simp_tac i st = asm_lr_simp_tac (simpset ()) i st; | |
| 334 | fun Asm_full_simp_tac i st = asm_full_simp_tac (simpset ()) i st; | |
| 335 | ||
| 16806 | 336 | |
| 337 | (* conversions *) | |
| 338 | ||
| 16014 | 339 | val simplify = simp_thm (false, false, false); | 
| 340 | val asm_simplify = simp_thm (false, true, false); | |
| 341 | val full_simplify = simp_thm (true, false, false); | |
| 342 | val asm_lr_simplify = simp_thm (true, true, false); | |
| 343 | val asm_full_simplify = simp_thm (true, true, true); | |
| 344 | ||
| 345 | val rewrite = simp_cterm (false, false, false); | |
| 346 | val asm_rewrite = simp_cterm (false, true, false); | |
| 347 | val full_rewrite = simp_cterm (true, false, false); | |
| 348 | val asm_lr_rewrite = simp_cterm (true, true, false); | |
| 349 | val asm_full_rewrite = simp_cterm (true, true, true); | |
| 350 | ||
| 351 | ||
| 352 | ||
| 353 | (** concrete syntax of attributes **) | |
| 354 | ||
| 355 | (* add / del *) | |
| 356 | ||
| 357 | val simpN = "simp"; | |
| 358 | val congN = "cong"; | |
| 359 | val addN = "add"; | |
| 360 | val delN = "del"; | |
| 361 | val onlyN = "only"; | |
| 362 | val no_asmN = "no_asm"; | |
| 363 | val no_asm_useN = "no_asm_use"; | |
| 364 | val no_asm_simpN = "no_asm_simp"; | |
| 365 | val asm_lrN = "asm_lr"; | |
| 366 | ||
| 367 | val simp_attr = | |
| 368 | (Attrib.add_del_args simp_add_global simp_del_global, | |
| 369 | Attrib.add_del_args simp_add_local simp_del_local); | |
| 370 | ||
| 371 | val cong_attr = | |
| 372 | (Attrib.add_del_args cong_add_global cong_del_global, | |
| 373 | Attrib.add_del_args cong_add_local cong_del_local); | |
| 374 | ||
| 375 | ||
| 376 | (* conversions *) | |
| 377 | ||
| 378 | local | |
| 379 | ||
| 380 | fun conv_mode x = | |
| 381 | ((Args.parens (Args.$$$ no_asmN) >> K simplify || | |
| 382 | Args.parens (Args.$$$ no_asm_simpN) >> K asm_simplify || | |
| 383 | Args.parens (Args.$$$ no_asm_useN) >> K full_simplify || | |
| 384 | Scan.succeed asm_full_simplify) |> Scan.lift) x; | |
| 385 | ||
| 386 | fun simplified_att get args = | |
| 387 | Attrib.syntax (conv_mode -- args >> (fn (f, ths) => | |
| 388 | Drule.rule_attribute (fn x => f ((if null ths then I else clear_ss) (get x) addsimps ths)))); | |
| 389 | ||
| 390 | in | |
| 391 | ||
| 392 | val simplified_attr = | |
| 393 | (simplified_att simpset_of Attrib.global_thmss, | |
| 394 | simplified_att local_simpset_of Attrib.local_thmss); | |
| 395 | ||
| 396 | end; | |
| 397 | ||
| 398 | ||
| 399 | (* setup attributes *) | |
| 400 | ||
| 401 | val _ = Context.add_setup | |
| 402 | [Attrib.add_attributes | |
| 403 | [(simpN, simp_attr, "declaration of simplification rule"), | |
| 404 | (congN, cong_attr, "declaration of Simplifier congruence rule"), | |
| 405 |     ("simplified", simplified_attr, "simplified rule")]];
 | |
| 406 | ||
| 407 | ||
| 408 | ||
| 409 | (** proof methods **) | |
| 410 | ||
| 411 | (* simplification *) | |
| 412 | ||
| 413 | val simp_options = | |
| 414 | (Args.parens (Args.$$$ no_asmN) >> K simp_tac || | |
| 415 | Args.parens (Args.$$$ no_asm_simpN) >> K asm_simp_tac || | |
| 416 | Args.parens (Args.$$$ no_asm_useN) >> K full_simp_tac || | |
| 417 | Args.parens (Args.$$$ asm_lrN) >> K asm_lr_simp_tac || | |
| 418 | Scan.succeed asm_full_simp_tac); | |
| 419 | ||
| 16685 | 420 | fun simp_flags x = (Scan.repeat | 
| 16684 
7b58002668c0
methods: added simp_flags argument, added "depth_limit" flag;
 wenzelm parents: 
16458diff
changeset | 421 | (Args.parens (Args.$$$ "depth_limit" -- Args.colon |-- Args.nat) | 
| 
7b58002668c0
methods: added simp_flags argument, added "depth_limit" flag;
 wenzelm parents: 
16458diff
changeset | 422 | >> setmp MetaSimplifier.simp_depth_limit) | 
| 16709 | 423 | >> (curry (Library.foldl op o) I o rev)) x; | 
| 16684 
7b58002668c0
methods: added simp_flags argument, added "depth_limit" flag;
 wenzelm parents: 
16458diff
changeset | 424 | |
| 16014 | 425 | val cong_modifiers = | 
| 426 | [Args.$$$ congN -- Args.colon >> K ((I, cong_add_local):Method.modifier), | |
| 427 | Args.$$$ congN -- Args.add -- Args.colon >> K (I, cong_add_local), | |
| 428 | Args.$$$ congN -- Args.del -- Args.colon >> K (I, cong_del_local)]; | |
| 429 | ||
| 430 | val simp_modifiers = | |
| 431 | [Args.$$$ simpN -- Args.colon >> K (I, simp_add_local), | |
| 432 | Args.$$$ simpN -- Args.add -- Args.colon >> K (I, simp_add_local), | |
| 433 | Args.$$$ simpN -- Args.del -- Args.colon >> K (I, simp_del_local), | |
| 434 | Args.$$$ simpN -- Args.$$$ onlyN -- Args.colon >> K (map_local_simpset clear_ss, simp_add_local)] | |
| 435 | @ cong_modifiers; | |
| 436 | ||
| 437 | val simp_modifiers' = | |
| 438 | [Args.add -- Args.colon >> K (I, simp_add_local), | |
| 439 | Args.del -- Args.colon >> K (I, simp_del_local), | |
| 440 | Args.$$$ onlyN -- Args.colon >> K (map_local_simpset clear_ss, simp_add_local)] | |
| 441 | @ cong_modifiers; | |
| 442 | ||
| 443 | fun simp_args more_mods = | |
| 16684 
7b58002668c0
methods: added simp_flags argument, added "depth_limit" flag;
 wenzelm parents: 
16458diff
changeset | 444 | Method.sectioned_args (Args.bang_facts -- Scan.lift simp_options -- Scan.lift simp_flags) | 
| 
7b58002668c0
methods: added simp_flags argument, added "depth_limit" flag;
 wenzelm parents: 
16458diff
changeset | 445 | (more_mods @ simp_modifiers'); | 
| 16014 | 446 | |
| 16684 
7b58002668c0
methods: added simp_flags argument, added "depth_limit" flag;
 wenzelm parents: 
16458diff
changeset | 447 | fun simp_method ((prems, tac), FLAGS) ctxt = Method.METHOD (fn facts => | 
| 16014 | 448 | ALLGOALS (Method.insert_tac (prems @ facts)) THEN | 
| 16684 
7b58002668c0
methods: added simp_flags argument, added "depth_limit" flag;
 wenzelm parents: 
16458diff
changeset | 449 | (FLAGS o CHANGED_PROP o ALLGOALS o tac) (local_simpset_of ctxt)); | 
| 16014 | 450 | |
| 16684 
7b58002668c0
methods: added simp_flags argument, added "depth_limit" flag;
 wenzelm parents: 
16458diff
changeset | 451 | fun simp_method' ((prems, tac), FLAGS) ctxt = Method.METHOD (fn facts => | 
| 16014 | 452 | HEADGOAL (Method.insert_tac (prems @ facts) THEN' | 
| 16684 
7b58002668c0
methods: added simp_flags argument, added "depth_limit" flag;
 wenzelm parents: 
16458diff
changeset | 453 | ((FLAGS o CHANGED_PROP) oo tac) (local_simpset_of ctxt))); | 
| 16014 | 454 | |
| 455 | ||
| 456 | (* setup methods *) | |
| 457 | ||
| 458 | fun setup_methods more_mods = Method.add_methods | |
| 459 | [(simpN, simp_args more_mods simp_method', "simplification"), | |
| 460 |   ("simp_all", simp_args more_mods simp_method, "simplification (all goals)")];
 | |
| 461 | ||
| 462 | fun method_setup mods = [setup_methods mods]; | |
| 463 | ||
| 464 | ||
| 465 | (** easy_setup **) | |
| 466 | ||
| 467 | fun easy_setup reflect trivs = | |
| 468 | let | |
| 469 | val trivialities = Drule.reflexive_thm :: trivs; | |
| 470 | ||
| 471 | fun unsafe_solver_tac prems = FIRST' [resolve_tac (trivialities @ prems), assume_tac]; | |
| 472 | val unsafe_solver = mk_solver "easy unsafe" unsafe_solver_tac; | |
| 473 | ||
| 474 | (*no premature instantiation of variables during simplification*) | |
| 475 | fun safe_solver_tac prems = FIRST' [match_tac (trivialities @ prems), eq_assume_tac]; | |
| 476 | val safe_solver = mk_solver "easy safe" safe_solver_tac; | |
| 477 | ||
| 478 | fun mk_eq thm = | |
| 479 | if Logic.is_equals (Thm.concl_of thm) then [thm] | |
| 480 | else [thm RS reflect] handle THM _ => []; | |
| 481 | ||
| 482 | fun mksimps thm = mk_eq (Drule.forall_elim_vars (#maxidx (Thm.rep_thm thm) + 1) thm); | |
| 483 | ||
| 484 | fun init_ss thy = | |
| 485 | (simpset_ref_of thy := | |
| 486 | empty_ss setsubgoaler asm_simp_tac | |
| 487 | setSSolver safe_solver | |
| 488 | setSolver unsafe_solver | |
| 489 | setmksimps mksimps; thy); | |
| 490 | in method_setup [] @ [init_ss] end; | |
| 491 | ||
| 492 | end; | |
| 493 | ||
| 494 | structure BasicSimplifier: BASIC_SIMPLIFIER = Simplifier; | |
| 495 | open BasicSimplifier; |