| author | paulson | 
| Tue, 15 Jan 2002 10:23:58 +0100 | |
| changeset 12762 | a0c0a1e3a53a | 
| parent 12311 | ce5f9e61c037 | 
| child 13462 | 56610e2ba220 | 
| permissions | -rw-r--r-- | 
| 1243 | 1 | (* Title: Provers/simplifier.ML | 
| 1 | 2 | ID: $Id$ | 
| 3557 | 3 | Author: Tobias Nipkow and Markus Wenzel, TU Muenchen | 
| 1 | 4 | |
| 10412 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 5 | Generic simplifier, suitable for most logics. See Pure/meta_simplifier.ML | 
| 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 6 | for the actual meta-level rewriting engine. | 
| 1 | 7 | *) | 
| 1260 | 8 | |
| 3551 | 9 | infix 4 | 
| 4682 | 10 | setsubgoaler setloop addloop delloop setSSolver addSSolver setSolver | 
| 9715 | 11 | addSolver addsimps delsimps addeqcongs deleqcongs addcongs delcongs | 
| 12 | setmksimps setmkeqTrue setmkcong setmksym settermless addsimprocs delsimprocs; | |
| 2567 | 13 | |
| 4795 | 14 | signature BASIC_SIMPLIFIER = | 
| 0 | 15 | sig | 
| 2509 | 16 | type simproc | 
| 3577 
9715b6e3ec5f
added prems argument to simplification procedures;
 wenzelm parents: 
3557diff
changeset | 17 | val mk_simproc: string -> cterm list | 
| 
9715b6e3ec5f
added prems argument to simplification procedures;
 wenzelm parents: 
3557diff
changeset | 18 | -> (Sign.sg -> thm list -> term -> thm option) -> simproc | 
| 7568 | 19 | type solver | 
| 20 | val mk_solver: string -> (thm list -> int -> tactic) -> solver | |
| 0 | 21 | type simpset | 
| 2503 | 22 | val empty_ss: simpset | 
| 3551 | 23 | val rep_ss: simpset -> | 
| 11669 | 24 |    {mss: MetaSimplifier.meta_simpset,
 | 
| 9715 | 25 | mk_cong: thm -> thm, | 
| 26 | subgoal_tac: simpset -> int -> tactic, | |
| 27 | loop_tacs: (string * (int -> tactic)) list, | |
| 7568 | 28 | unsafe_solvers: solver list, | 
| 9715 | 29 | solvers: solver list}; | 
| 3551 | 30 | val print_ss: simpset -> unit | 
| 4366 | 31 | val print_simpset: theory -> unit | 
| 2629 | 32 | val setsubgoaler: simpset * (simpset -> int -> tactic) -> simpset | 
| 33 | val setloop: simpset * (int -> tactic) -> simpset | |
| 4668 
131989b78417
Little reorganization. Loop tactics have names now.
 nipkow parents: 
4612diff
changeset | 34 | val addloop: simpset * (string * (int -> tactic)) -> simpset | 
| 4682 | 35 | val delloop: simpset * string -> simpset | 
| 7568 | 36 | val setSSolver: simpset * solver -> simpset | 
| 37 | val addSSolver: simpset * solver -> simpset | |
| 38 | val setSolver: simpset * solver -> simpset | |
| 39 | val addSolver: simpset * solver -> simpset | |
| 3577 
9715b6e3ec5f
added prems argument to simplification procedures;
 wenzelm parents: 
3557diff
changeset | 40 | val setmksimps: simpset * (thm -> thm list) -> simpset | 
| 4677 | 41 | val setmkeqTrue: simpset * (thm -> thm option) -> simpset | 
| 9715 | 42 | val setmkcong: simpset * (thm -> thm) -> simpset | 
| 4677 | 43 | val setmksym: simpset * (thm -> thm option) -> simpset | 
| 3577 
9715b6e3ec5f
added prems argument to simplification procedures;
 wenzelm parents: 
3557diff
changeset | 44 | val settermless: simpset * (term * term -> bool) -> simpset | 
| 
9715b6e3ec5f
added prems argument to simplification procedures;
 wenzelm parents: 
3557diff
changeset | 45 | val addsimps: simpset * thm list -> simpset | 
| 
9715b6e3ec5f
added prems argument to simplification procedures;
 wenzelm parents: 
3557diff
changeset | 46 | val delsimps: simpset * thm list -> simpset | 
| 
9715b6e3ec5f
added prems argument to simplification procedures;
 wenzelm parents: 
3557diff
changeset | 47 | val addeqcongs: simpset * thm list -> simpset | 
| 
9715b6e3ec5f
added prems argument to simplification procedures;
 wenzelm parents: 
3557diff
changeset | 48 | val deleqcongs: simpset * thm list -> simpset | 
| 9715 | 49 | val addcongs: simpset * thm list -> simpset | 
| 50 | val delcongs: simpset * thm list -> simpset | |
| 3577 
9715b6e3ec5f
added prems argument to simplification procedures;
 wenzelm parents: 
3557diff
changeset | 51 | val addsimprocs: simpset * simproc list -> simpset | 
| 
9715b6e3ec5f
added prems argument to simplification procedures;
 wenzelm parents: 
3557diff
changeset | 52 | val delsimprocs: simpset * simproc list -> simpset | 
| 
9715b6e3ec5f
added prems argument to simplification procedures;
 wenzelm parents: 
3557diff
changeset | 53 | val merge_ss: simpset * simpset -> simpset | 
| 
9715b6e3ec5f
added prems argument to simplification procedures;
 wenzelm parents: 
3557diff
changeset | 54 | val prems_of_ss: simpset -> thm list | 
| 4080 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 55 | val simpset_ref_of_sg: Sign.sg -> simpset ref | 
| 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 56 | val simpset_ref_of: theory -> simpset ref | 
| 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 57 | val simpset_of_sg: Sign.sg -> simpset | 
| 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 58 | val simpset_of: theory -> simpset | 
| 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 59 | val SIMPSET: (simpset -> tactic) -> tactic | 
| 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 60 | val SIMPSET': (simpset -> 'a -> tactic) -> 'a -> tactic | 
| 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 61 | val simpset: unit -> simpset | 
| 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 62 | val simpset_ref: unit -> simpset ref | 
| 1243 | 63 | val Addsimps: thm list -> unit | 
| 64 | val Delsimps: thm list -> unit | |
| 2509 | 65 | val Addsimprocs: simproc list -> unit | 
| 66 | val Delsimprocs: simproc list -> unit | |
| 9715 | 67 | val Addcongs: thm list -> unit | 
| 68 | val Delcongs: thm list -> unit | |
| 8879 | 69 | val generic_simp_tac: bool -> bool * bool * bool -> simpset -> int -> tactic | 
| 10004 | 70 | val safe_asm_full_simp_tac: simpset -> int -> tactic | 
| 2629 | 71 | val simp_tac: simpset -> int -> tactic | 
| 72 | val asm_simp_tac: simpset -> int -> tactic | |
| 73 | val full_simp_tac: simpset -> int -> tactic | |
| 4722 
d2e44673c21e
The new asm_lr_simp_tac is the old asm_full_simp_tac.
 nipkow parents: 
4713diff
changeset | 74 | val asm_lr_simp_tac: simpset -> int -> tactic | 
| 2629 | 75 | val asm_full_simp_tac: simpset -> int -> tactic | 
| 76 | val Simp_tac: int -> tactic | |
| 77 | val Asm_simp_tac: int -> tactic | |
| 78 | val Full_simp_tac: int -> tactic | |
| 4722 
d2e44673c21e
The new asm_lr_simp_tac is the old asm_full_simp_tac.
 nipkow parents: 
4713diff
changeset | 79 | val Asm_lr_simp_tac: int -> tactic | 
| 2629 | 80 | val Asm_full_simp_tac: int -> tactic | 
| 3557 | 81 | val simplify: simpset -> thm -> thm | 
| 82 | val asm_simplify: simpset -> thm -> thm | |
| 83 | val full_simplify: simpset -> thm -> thm | |
| 84 | val asm_full_simplify: simpset -> thm -> thm | |
| 0 | 85 | end; | 
| 86 | ||
| 4795 | 87 | signature SIMPLIFIER = | 
| 88 | sig | |
| 89 | include BASIC_SIMPLIFIER | |
| 5082 | 90 | val rewrite: simpset -> cterm -> thm | 
| 91 | val asm_rewrite: simpset -> cterm -> thm | |
| 92 | val full_rewrite: simpset -> cterm -> thm | |
| 93 | val asm_full_rewrite: simpset -> cterm -> thm | |
| 5842 | 94 | val print_local_simpset: Proof.context -> unit | 
| 95 | val get_local_simpset: Proof.context -> simpset | |
| 96 | val put_local_simpset: simpset -> Proof.context -> Proof.context | |
| 8467 | 97 | val change_global_ss: (simpset * thm list -> simpset) -> theory attribute | 
| 98 | val change_local_ss: (simpset * thm list -> simpset) -> Proof.context attribute | |
| 4855 | 99 | val simp_add_global: theory attribute | 
| 100 | val simp_del_global: theory attribute | |
| 5842 | 101 | val simp_add_local: Proof.context attribute | 
| 102 | val simp_del_local: Proof.context attribute | |
| 9715 | 103 | val cong_add_global: theory attribute | 
| 104 | val cong_del_global: theory attribute | |
| 105 | val cong_add_local: Proof.context attribute | |
| 106 | val cong_del_local: Proof.context attribute | |
| 7177 | 107 | val change_simpset_of: (simpset * 'a -> simpset) -> 'a -> theory -> theory | 
| 7273 | 108 | val simp_modifiers: (Args.T list -> (Method.modifier * Args.T list)) list | 
| 5842 | 109 | val setup: (theory -> theory) list | 
| 8467 | 110 | val method_setup: (Args.T list -> (Method.modifier * Args.T list)) list | 
| 111 | -> (theory -> theory) list | |
| 8228 | 112 | val easy_setup: thm -> thm list -> (theory -> theory) list | 
| 4795 | 113 | end; | 
| 2503 | 114 | |
| 115 | structure Simplifier: SIMPLIFIER = | |
| 0 | 116 | struct | 
| 117 | ||
| 2509 | 118 | |
| 119 | (** simplification procedures **) | |
| 120 | ||
| 121 | (* datatype simproc *) | |
| 122 | ||
| 123 | datatype simproc = | |
| 3577 
9715b6e3ec5f
added prems argument to simplification procedures;
 wenzelm parents: 
3557diff
changeset | 124 | Simproc of string * cterm list * (Sign.sg -> thm list -> term -> thm option) * stamp; | 
| 2509 | 125 | |
| 3557 | 126 | fun mk_simproc name lhss proc = | 
| 127 | Simproc (name, map (Thm.cterm_fun Logic.varify) lhss, proc, stamp ()); | |
| 128 | ||
| 3551 | 129 | fun rep_simproc (Simproc args) = args; | 
| 2509 | 130 | |
| 8467 | 131 | |
| 132 | ||
| 7568 | 133 | (** solvers **) | 
| 2509 | 134 | |
| 7568 | 135 | datatype solver = Solver of string * (thm list -> int -> tactic) * stamp; | 
| 136 | ||
| 12282 | 137 | fun mk_solver name solver = Solver (name, solver, stamp()); | 
| 138 | fun eq_solver (Solver (_, _, s1), Solver(_, _, s2)) = s1 = s2; | |
| 7568 | 139 | |
| 12282 | 140 | val merge_solvers = gen_merge_lists eq_solver; | 
| 7568 | 141 | |
| 142 | fun app_sols [] _ _ = no_tac | |
| 143 | | app_sols (Solver(_,solver,_)::sols) thms i = | |
| 144 | solver thms i ORELSE app_sols sols thms i; | |
| 2509 | 145 | |
| 8467 | 146 | |
| 147 | ||
| 2503 | 148 | (** simplification sets **) | 
| 149 | ||
| 150 | (* type simpset *) | |
| 151 | ||
| 0 | 152 | datatype simpset = | 
| 2503 | 153 |   Simpset of {
 | 
| 11669 | 154 | mss: MetaSimplifier.meta_simpset, | 
| 9715 | 155 | mk_cong: thm -> thm, | 
| 156 | subgoal_tac: simpset -> int -> tactic, | |
| 157 | loop_tacs: (string * (int -> tactic)) list, | |
| 7568 | 158 | unsafe_solvers: solver list, | 
| 9715 | 159 | solvers: solver list}; | 
| 2503 | 160 | |
| 9715 | 161 | fun make_ss mss mk_cong subgoal_tac loop_tacs unsafe_solvers solvers = | 
| 162 |   Simpset {mss = mss, mk_cong = mk_cong, subgoal_tac = subgoal_tac,
 | |
| 163 | loop_tacs = loop_tacs, unsafe_solvers = unsafe_solvers, solvers = solvers}; | |
| 0 | 164 | |
| 165 | val empty_ss = | |
| 10412 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 166 | let val mss = MetaSimplifier.set_mk_sym (MetaSimplifier.empty_mss, Some o symmetric_fun) | 
| 9715 | 167 | in make_ss mss I (K (K no_tac)) [] [] [] end; | 
| 3551 | 168 | |
| 169 | fun rep_ss (Simpset args) = args; | |
| 10412 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 170 | fun prems_of_ss (Simpset {mss, ...}) = MetaSimplifier.prems_of_mss mss;
 | 
| 3551 | 171 | |
| 172 | ||
| 173 | (* print simpsets *) | |
| 2503 | 174 | |
| 3551 | 175 | fun print_ss ss = | 
| 176 | let | |
| 177 |     val Simpset {mss, ...} = ss;
 | |
| 10412 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 178 |     val {simps, procs, congs} = MetaSimplifier.dest_mss mss;
 | 
| 2503 | 179 | |
| 3551 | 180 | val pretty_thms = map Display.pretty_thm; | 
| 181 | fun pretty_proc (name, lhss) = | |
| 182 | Pretty.big_list (name ^ ":") (map Display.pretty_cterm lhss); | |
| 183 | in | |
| 8727 | 184 | [Pretty.big_list "simplification rules:" (pretty_thms simps), | 
| 185 | Pretty.big_list "simplification procedures:" (map pretty_proc procs), | |
| 186 | Pretty.big_list "congruences:" (pretty_thms congs)] | |
| 187 | |> Pretty.chunks |> Pretty.writeln | |
| 3551 | 188 | end; | 
| 2503 | 189 | |
| 190 | ||
| 191 | (* extend simpsets *) | |
| 192 | ||
| 9715 | 193 | fun (Simpset {mss, mk_cong, subgoal_tac = _, loop_tacs, unsafe_solvers, solvers})
 | 
| 3551 | 194 | setsubgoaler subgoal_tac = | 
| 9715 | 195 | make_ss mss mk_cong subgoal_tac loop_tacs unsafe_solvers solvers; | 
| 2629 | 196 | |
| 9715 | 197 | fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs = _, unsafe_solvers, solvers})
 | 
| 4668 
131989b78417
Little reorganization. Loop tactics have names now.
 nipkow parents: 
4612diff
changeset | 198 | setloop tac = | 
| 9715 | 199 |   make_ss mss mk_cong subgoal_tac [("", tac)] unsafe_solvers solvers;
 | 
| 2503 | 200 | |
| 9715 | 201 | fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers})
 | 
| 202 | addloop tac = make_ss mss mk_cong subgoal_tac | |
| 203 | (case assoc_string (loop_tacs, (#1 tac)) of None => () | Some x => | |
| 204 |         warning ("overwriting looper " ^ quote (#1 tac)); overwrite (loop_tacs, tac))
 | |
| 205 | unsafe_solvers solvers; | |
| 2567 | 206 | |
| 9715 | 207 | fun (ss as Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers})
 | 
| 7214 
381d6987f68d
exchanged finish_tac and unsafe_finish_tac (the more important one) in simpset
 oheimb parents: 
7177diff
changeset | 208 | delloop name = | 
| 6911 | 209 | let val (del, rest) = partition (fn (n, _) => n = name) loop_tacs in | 
| 210 |     if null del then (warning ("No such looper in simpset: " ^ name); ss)
 | |
| 9715 | 211 | else make_ss mss mk_cong subgoal_tac rest unsafe_solvers solvers | 
| 4682 | 212 | end; | 
| 213 | ||
| 9715 | 214 | fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, ...})
 | 
| 7568 | 215 | setSSolver solver = | 
| 9715 | 216 | make_ss mss mk_cong subgoal_tac loop_tacs unsafe_solvers [solver]; | 
| 2503 | 217 | |
| 9715 | 218 | fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers})
 | 
| 7568 | 219 | addSSolver sol = | 
| 9715 | 220 | make_ss mss mk_cong subgoal_tac loop_tacs unsafe_solvers (merge_solvers solvers [sol]); | 
| 2503 | 221 | |
| 9715 | 222 | fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers = _, solvers})
 | 
| 7568 | 223 | setSolver unsafe_solver = | 
| 9715 | 224 | make_ss mss mk_cong subgoal_tac loop_tacs [unsafe_solver] solvers; | 
| 7568 | 225 | |
| 9715 | 226 | fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers})
 | 
| 7568 | 227 | addSolver sol = | 
| 9715 | 228 | make_ss mss mk_cong subgoal_tac loop_tacs (merge_solvers unsafe_solvers [sol]) solvers; | 
| 2503 | 229 | |
| 9715 | 230 | fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers})
 | 
| 3551 | 231 | setmksimps mk_simps = | 
| 10412 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 232 | make_ss (MetaSimplifier.set_mk_rews (mss, mk_simps)) mk_cong subgoal_tac loop_tacs unsafe_solvers solvers; | 
| 2509 | 233 | |
| 9715 | 234 | fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers})
 | 
| 4677 | 235 | setmkeqTrue mk_eq_True = | 
| 10412 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 236 | make_ss (MetaSimplifier.set_mk_eq_True (mss, mk_eq_True)) mk_cong subgoal_tac loop_tacs | 
| 9715 | 237 | unsafe_solvers solvers; | 
| 4677 | 238 | |
| 9715 | 239 | fun (Simpset {mss, mk_cong = _, subgoal_tac, loop_tacs, unsafe_solvers, solvers})
 | 
| 240 | setmkcong mk_cong = | |
| 241 | make_ss mss mk_cong subgoal_tac loop_tacs unsafe_solvers solvers; | |
| 242 | ||
| 243 | fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers})
 | |
| 4677 | 244 | setmksym mksym = | 
| 10412 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 245 | make_ss (MetaSimplifier.set_mk_sym (mss, mksym)) mk_cong subgoal_tac loop_tacs unsafe_solvers solvers; | 
| 4677 | 246 | |
| 9715 | 247 | fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs,  unsafe_solvers, solvers})
 | 
| 3551 | 248 | settermless termless = | 
| 10412 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 249 | make_ss (MetaSimplifier.set_termless (mss, termless)) mk_cong subgoal_tac loop_tacs | 
| 9715 | 250 | unsafe_solvers solvers; | 
| 3551 | 251 | |
| 9715 | 252 | fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers})
 | 
| 3551 | 253 | addsimps rews = | 
| 10412 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 254 | make_ss (MetaSimplifier.add_simps (mss, rews)) mk_cong subgoal_tac loop_tacs unsafe_solvers solvers; | 
| 2503 | 255 | |
| 9715 | 256 | fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers})
 | 
| 3551 | 257 | delsimps rews = | 
| 10412 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 258 | make_ss (MetaSimplifier.del_simps (mss, rews)) mk_cong subgoal_tac loop_tacs unsafe_solvers solvers; | 
| 2503 | 259 | |
| 9715 | 260 | fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers})
 | 
| 3551 | 261 | addeqcongs newcongs = | 
| 10412 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 262 | make_ss (MetaSimplifier.add_congs (mss, newcongs)) mk_cong subgoal_tac loop_tacs unsafe_solvers solvers; | 
| 9715 | 263 | |
| 264 | fun (Simpset {mss, subgoal_tac, mk_cong, loop_tacs, unsafe_solvers, solvers})
 | |
| 265 | deleqcongs oldcongs = | |
| 10412 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 266 | make_ss (MetaSimplifier.del_congs (mss, oldcongs)) mk_cong subgoal_tac loop_tacs unsafe_solvers solvers; | 
| 2509 | 267 | |
| 9715 | 268 | fun (ss as Simpset {mk_cong, ...}) addcongs newcongs =
 | 
| 269 | ss addeqcongs map mk_cong newcongs; | |
| 2629 | 270 | |
| 9715 | 271 | fun (ss as Simpset {mk_cong, ...}) delcongs oldcongs =
 | 
| 272 | ss deleqcongs map mk_cong oldcongs; | |
| 273 | ||
| 274 | fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers})
 | |
| 3551 | 275 | addsimprocs simprocs = | 
| 10412 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 276 | make_ss (MetaSimplifier.add_simprocs (mss, map rep_simproc simprocs)) mk_cong subgoal_tac loop_tacs | 
| 9715 | 277 | unsafe_solvers solvers; | 
| 2509 | 278 | |
| 9715 | 279 | fun (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers})
 | 
| 3551 | 280 | delsimprocs simprocs = | 
| 10412 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 281 | make_ss (MetaSimplifier.del_simprocs (mss, map rep_simproc simprocs)) mk_cong subgoal_tac | 
| 9715 | 282 | loop_tacs unsafe_solvers solvers; | 
| 2503 | 283 | |
| 9715 | 284 | fun clear_ss (Simpset {mss, mk_cong, subgoal_tac, loop_tacs = _, unsafe_solvers, solvers}) =
 | 
| 10412 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 285 | make_ss (MetaSimplifier.clear_mss mss) mk_cong subgoal_tac [] unsafe_solvers solvers; | 
| 6911 | 286 | |
| 2503 | 287 | |
| 7568 | 288 | (* merge simpsets *) | 
| 8467 | 289 | |
| 290 | (*ignores subgoal_tac of 2nd simpset!*) | |
| 2503 | 291 | |
| 3551 | 292 | fun merge_ss | 
| 9715 | 293 |    (Simpset {mss = mss1, mk_cong, loop_tacs = loop_tacs1, subgoal_tac,
 | 
| 7568 | 294 | unsafe_solvers = unsafe_solvers1, solvers = solvers1}, | 
| 9715 | 295 |     Simpset {mss = mss2, mk_cong = _, loop_tacs = loop_tacs2, subgoal_tac = _,
 | 
| 296 | unsafe_solvers = unsafe_solvers2, solvers = solvers2}) = | |
| 10412 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 297 | make_ss (MetaSimplifier.merge_mss (mss1, mss2)) mk_cong subgoal_tac | 
| 9715 | 298 | (merge_alists loop_tacs1 loop_tacs2) | 
| 299 | (merge_solvers unsafe_solvers1 unsafe_solvers2) | |
| 300 | (merge_solvers solvers1 solvers2); | |
| 2503 | 301 | |
| 3557 | 302 | |
| 8467 | 303 | |
| 5024 | 304 | (** global and local simpset data **) | 
| 4080 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 305 | |
| 5842 | 306 | (* theory data kind 'Provers/simpset' *) | 
| 4795 | 307 | |
| 5842 | 308 | structure GlobalSimpsetArgs = | 
| 5024 | 309 | struct | 
| 5842 | 310 | val name = "Provers/simpset"; | 
| 5024 | 311 | type T = simpset ref; | 
| 0 | 312 | |
| 5024 | 313 | val empty = ref empty_ss; | 
| 6556 | 314 | fun copy (ref ss) = (ref ss): T; (*create new reference!*) | 
| 315 | val prep_ext = copy; | |
| 5024 | 316 | fun merge (ref ss1, ref ss2) = ref (merge_ss (ss1, ss2)); | 
| 317 | fun print _ (ref ss) = print_ss ss; | |
| 318 | end; | |
| 4080 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 319 | |
| 5842 | 320 | structure GlobalSimpset = TheoryDataFun(GlobalSimpsetArgs); | 
| 321 | val print_simpset = GlobalSimpset.print; | |
| 322 | val simpset_ref_of_sg = GlobalSimpset.get_sg; | |
| 323 | val simpset_ref_of = GlobalSimpset.get; | |
| 4080 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 324 | |
| 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 325 | |
| 4795 | 326 | (* access global simpset *) | 
| 0 | 327 | |
| 4080 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 328 | val simpset_of_sg = ! o simpset_ref_of_sg; | 
| 6391 | 329 | val simpset_of = simpset_of_sg o Theory.sign_of; | 
| 4080 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 330 | |
| 6391 | 331 | fun SIMPSET tacf state = tacf (simpset_of_sg (Thm.sign_of_thm state)) state; | 
| 332 | fun SIMPSET' tacf i state = tacf (simpset_of_sg (Thm.sign_of_thm state)) i state; | |
| 0 | 333 | |
| 5028 | 334 | val simpset = simpset_of o Context.the_context; | 
| 6391 | 335 | val simpset_ref = simpset_ref_of_sg o Theory.sign_of o Context.the_context; | 
| 4080 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 336 | |
| 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 337 | |
| 4795 | 338 | (* change global simpset *) | 
| 4080 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 339 | |
| 7177 | 340 | fun change_simpset_of f x thy = | 
| 341 | let val r = simpset_ref_of thy | |
| 342 | in r := f (! r, x); thy end; | |
| 343 | ||
| 344 | fun change_simpset f x = (change_simpset_of f x (Context.the_context ()); ()); | |
| 4080 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 345 | |
| 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 346 | val Addsimps = change_simpset (op addsimps); | 
| 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 347 | val Delsimps = change_simpset (op delsimps); | 
| 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 348 | val Addsimprocs = change_simpset (op addsimprocs); | 
| 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 349 | val Delsimprocs = change_simpset (op delsimprocs); | 
| 9715 | 350 | val Addcongs = change_simpset (op addcongs); | 
| 351 | val Delcongs = change_simpset (op delcongs); | |
| 2509 | 352 | |
| 0 | 353 | |
| 5842 | 354 | (* proof data kind 'Provers/simpset' *) | 
| 4795 | 355 | |
| 5842 | 356 | structure LocalSimpsetArgs = | 
| 357 | struct | |
| 358 | val name = "Provers/simpset"; | |
| 359 | type T = simpset; | |
| 360 | val init = simpset_of; | |
| 361 | fun print _ ss = print_ss ss; | |
| 362 | end; | |
| 4795 | 363 | |
| 5842 | 364 | structure LocalSimpset = ProofDataFun(LocalSimpsetArgs); | 
| 365 | val print_local_simpset = LocalSimpset.print; | |
| 366 | val get_local_simpset = LocalSimpset.get; | |
| 367 | val put_local_simpset = LocalSimpset.put; | |
| 7273 | 368 | fun map_local_simpset f ctxt = put_local_simpset (f (get_local_simpset ctxt)) ctxt; | 
| 4795 | 369 | |
| 370 | ||
| 5886 | 371 | (* attributes *) | 
| 372 | ||
| 373 | fun change_global_ss f (thy, th) = | |
| 374 | let val r = simpset_ref_of thy | |
| 6096 | 375 | in r := f (! r, [th]); (thy, th) end; | 
| 5886 | 376 | |
| 377 | fun change_local_ss f (ctxt, th) = | |
| 6096 | 378 | let val ss = f (get_local_simpset ctxt, [th]) | 
| 5886 | 379 | in (put_local_simpset ss ctxt, th) end; | 
| 380 | ||
| 381 | val simp_add_global = change_global_ss (op addsimps); | |
| 382 | val simp_del_global = change_global_ss (op delsimps); | |
| 383 | val simp_add_local = change_local_ss (op addsimps); | |
| 384 | val simp_del_local = change_local_ss (op delsimps); | |
| 385 | ||
| 9715 | 386 | val cong_add_global = change_global_ss (op addcongs); | 
| 387 | val cong_del_global = change_global_ss (op delcongs); | |
| 388 | val cong_add_local = change_local_ss (op addcongs); | |
| 389 | val cong_del_local = change_local_ss (op delcongs); | |
| 390 | ||
| 5886 | 391 | |
| 3557 | 392 | |
| 2503 | 393 | (** simplification tactics **) | 
| 0 | 394 | |
| 9715 | 395 | fun solve_all_tac (mk_cong, subgoal_tac, loop_tacs, unsafe_solvers) mss = | 
| 3557 | 396 | let | 
| 397 | val ss = | |
| 9715 | 398 | make_ss mss mk_cong subgoal_tac loop_tacs unsafe_solvers unsafe_solvers; | 
| 4612 | 399 | val solve1_tac = (subgoal_tac ss THEN_ALL_NEW (K no_tac)) 1 | 
| 3557 | 400 | in DEPTH_SOLVE solve1_tac end; | 
| 401 | ||
| 4668 
131989b78417
Little reorganization. Loop tactics have names now.
 nipkow parents: 
4612diff
changeset | 402 | fun loop_tac loop_tacs = FIRST'(map snd loop_tacs); | 
| 3557 | 403 | |
| 8879 | 404 | (*note: may instantiate unknowns that appear also in other subgoals*) | 
| 405 | fun generic_simp_tac safe mode = | |
| 9715 | 406 |   fn (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, solvers, ...}) =>
 | 
| 3551 | 407 | let | 
| 8879 | 408 | val solvs = app_sols (if safe then solvers else unsafe_solvers); | 
| 4612 | 409 | fun simp_loop_tac i = | 
| 410 | asm_rewrite_goal_tac mode | |
| 9715 | 411 | (solve_all_tac (mk_cong, subgoal_tac, loop_tacs, unsafe_solvers)) | 
| 4612 | 412 | mss i | 
| 11669 | 413 | THEN (solvs (MetaSimplifier.prems_of_mss mss) i ORELSE | 
| 4668 
131989b78417
Little reorganization. Loop tactics have names now.
 nipkow parents: 
4612diff
changeset | 414 | TRY ((loop_tac loop_tacs THEN_ALL_NEW simp_loop_tac) i)) | 
| 4612 | 415 | in simp_loop_tac end; | 
| 0 | 416 | |
| 10004 | 417 | val simp_tac = generic_simp_tac false (false, false, false); | 
| 418 | val asm_simp_tac = generic_simp_tac false (false, true, false); | |
| 419 | val full_simp_tac = generic_simp_tac false (true, false, false); | |
| 420 | val asm_lr_simp_tac = generic_simp_tac false (true, true, false); | |
| 421 | val asm_full_simp_tac = generic_simp_tac false (true, true, true); | |
| 422 | val safe_asm_full_simp_tac = generic_simp_tac true (true, true, true); | |
| 0 | 423 | |
| 2629 | 424 | |
| 4795 | 425 | (*the abstraction over the proof state delays the dereferencing*) | 
| 4080 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 426 | fun Simp_tac i st = simp_tac (simpset ()) i st; | 
| 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 427 | fun Asm_simp_tac i st = asm_simp_tac (simpset ()) i st; | 
| 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 428 | fun Full_simp_tac i st = full_simp_tac (simpset ()) i st; | 
| 4722 
d2e44673c21e
The new asm_lr_simp_tac is the old asm_full_simp_tac.
 nipkow parents: 
4713diff
changeset | 429 | fun Asm_lr_simp_tac i st = asm_lr_simp_tac (simpset ()) i st; | 
| 4080 
7dce11095b0a
new implicit simpset mechanism based on Sign.sg anytype data;
 wenzelm parents: 
3728diff
changeset | 430 | fun Asm_full_simp_tac i st = asm_full_simp_tac (simpset ()) i st; | 
| 406 | 431 | |
| 3557 | 432 | |
| 4795 | 433 | |
| 5082 | 434 | (** simplification rules and conversions **) | 
| 3557 | 435 | |
| 9715 | 436 | fun simp rew mode | 
| 437 |      (Simpset {mss, mk_cong, subgoal_tac, loop_tacs, unsafe_solvers, ...}) thm =
 | |
| 3557 | 438 | let | 
| 9715 | 439 | val tacf = solve_all_tac (mk_cong, subgoal_tac, loop_tacs, unsafe_solvers); | 
| 4271 
3a82492e70c5
changed Pure/Sequence interface -- isatool fixseq;
 wenzelm parents: 
4259diff
changeset | 440 | fun prover m th = apsome fst (Seq.pull (tacf m th)); | 
| 5082 | 441 | in rew mode prover mss thm end; | 
| 442 | ||
| 10412 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 443 | val simp_thm = simp MetaSimplifier.rewrite_thm; | 
| 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 444 | val simp_cterm = simp MetaSimplifier.rewrite_cterm; | 
| 3557 | 445 | |
| 5082 | 446 | val simplify = simp_thm (false, false, false); | 
| 447 | val asm_simplify = simp_thm (false, true, false); | |
| 448 | val full_simplify = simp_thm (true, false, false); | |
| 449 | val asm_full_simplify = simp_thm (true, true, false); | |
| 450 | ||
| 451 | val rewrite = simp_cterm (false, false, false); | |
| 452 | val asm_rewrite = simp_cterm (false, true, false); | |
| 453 | val full_rewrite = simp_cterm (true, false, false); | |
| 454 | val asm_full_rewrite = simp_cterm (true, true, false); | |
| 3557 | 455 | |
| 456 | ||
| 4795 | 457 | |
| 5886 | 458 | (** concrete syntax of attributes **) | 
| 5842 | 459 | |
| 5886 | 460 | (* add / del *) | 
| 5842 | 461 | |
| 5928 | 462 | val simpN = "simp"; | 
| 9715 | 463 | val congN = "cong"; | 
| 10412 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 464 | val addN = "add"; | 
| 
1a1b4c1b2b7c
Moved meta simplification stuff from Thm to MetaSimplifier.
 berghofe parents: 
10034diff
changeset | 465 | val delN = "del"; | 
| 6911 | 466 | val onlyN = "only"; | 
| 9899 | 467 | val no_asmN = "no_asm"; | 
| 468 | val no_asm_useN = "no_asm_use"; | |
| 469 | val no_asm_simpN = "no_asm_simp"; | |
| 5842 | 470 | |
| 8634 | 471 | val simp_attr = | 
| 472 | (Attrib.add_del_args simp_add_global simp_del_global, | |
| 473 | Attrib.add_del_args simp_add_local simp_del_local); | |
| 5842 | 474 | |
| 9715 | 475 | val cong_attr = | 
| 476 | (Attrib.add_del_args cong_add_global cong_del_global, | |
| 477 | Attrib.add_del_args cong_add_local cong_del_local); | |
| 478 | ||
| 5842 | 479 | |
| 480 | (* conversions *) | |
| 481 | ||
| 9899 | 482 | local | 
| 483 | ||
| 484 | fun conv_mode x = | |
| 485 | ((Args.parens (Args.$$$ no_asmN) >> K simplify || | |
| 486 | Args.parens (Args.$$$ no_asm_simpN) >> K asm_simplify || | |
| 487 | Args.parens (Args.$$$ no_asm_useN) >> K full_simplify || | |
| 488 | Scan.succeed asm_full_simplify) |> Scan.lift) x; | |
| 489 | ||
| 11938 | 490 | fun simplified_att get args = | 
| 491 | Attrib.syntax (conv_mode -- args >> (fn (f, ths) => | |
| 492 | Drule.rule_attribute (fn x => f ((if null ths then I else clear_ss) (get x) addsimps ths)))); | |
| 9899 | 493 | |
| 494 | in | |
| 495 | ||
| 496 | val simplified_attr = | |
| 11938 | 497 | (simplified_att simpset_of Attrib.global_thmss, | 
| 498 | simplified_att get_local_simpset Attrib.local_thmss); | |
| 9899 | 499 | |
| 500 | end; | |
| 5842 | 501 | |
| 502 | ||
| 503 | (* setup_attrs *) | |
| 504 | ||
| 505 | val setup_attrs = Attrib.add_attributes | |
| 9899 | 506 | [(simpN, simp_attr, "declaration of simplification rule"), | 
| 507 | (congN, cong_attr, "declaration of Simplifier congruence rule"), | |
| 508 |   ("simplified", simplified_attr, "simplified rule")];
 | |
| 5842 | 509 | |
| 510 | ||
| 511 | ||
| 512 | (** proof methods **) | |
| 513 | ||
| 514 | (* simplification *) | |
| 515 | ||
| 8700 | 516 | val simp_options = | 
| 9899 | 517 | (Args.parens (Args.$$$ no_asmN) >> K simp_tac || | 
| 518 | Args.parens (Args.$$$ no_asm_simpN) >> K asm_simp_tac || | |
| 519 | Args.parens (Args.$$$ no_asm_useN) >> K full_simp_tac || | |
| 8700 | 520 | Scan.succeed asm_full_simp_tac); | 
| 521 | ||
| 9715 | 522 | val cong_modifiers = | 
| 9720 | 523 | [Args.$$$ congN -- Args.colon >> K ((I, cong_add_local):Method.modifier), | 
| 10034 | 524 | Args.$$$ congN -- Args.add -- Args.colon >> K (I, cong_add_local), | 
| 525 | Args.$$$ congN -- Args.del -- Args.colon >> K (I, cong_del_local)]; | |
| 9715 | 526 | |
| 5928 | 527 | val simp_modifiers = | 
| 8815 | 528 | [Args.$$$ simpN -- Args.colon >> K (I, simp_add_local), | 
| 10034 | 529 | Args.$$$ simpN -- Args.add -- Args.colon >> K (I, simp_add_local), | 
| 530 | Args.$$$ simpN -- Args.del -- Args.colon >> K (I, simp_del_local), | |
| 9861 | 531 | Args.$$$ simpN -- Args.$$$ onlyN -- Args.colon >> K (map_local_simpset clear_ss, simp_add_local)] | 
| 532 | @ cong_modifiers; | |
| 5928 | 533 | |
| 534 | val simp_modifiers' = | |
| 10034 | 535 | [Args.add -- Args.colon >> K (I, simp_add_local), | 
| 536 | Args.del -- Args.colon >> K (I, simp_del_local), | |
| 9861 | 537 | Args.$$$ onlyN -- Args.colon >> K (map_local_simpset clear_ss, simp_add_local)] | 
| 538 | @ cong_modifiers; | |
| 5928 | 539 | |
| 8700 | 540 | fun simp_args more_mods = | 
| 541 | Method.sectioned_args (Args.bang_facts -- Scan.lift simp_options) (more_mods @ simp_modifiers'); | |
| 542 | ||
| 8170 | 543 | |
| 8700 | 544 | fun simp_method (prems, tac) ctxt = Method.METHOD (fn facts => | 
| 545 | ALLGOALS (Method.insert_tac (prems @ facts)) THEN | |
| 10821 | 546 | (CHANGED_PROP o ALLGOALS o tac) (get_local_simpset ctxt)); | 
| 8700 | 547 | |
| 548 | fun simp_method' (prems, tac) ctxt = Method.METHOD (fn facts => | |
| 10821 | 549 | HEADGOAL (Method.insert_tac (prems @ facts) THEN' | 
| 550 | (CHANGED_PROP oo tac) (get_local_simpset ctxt))); | |
| 9715 | 551 | |
| 5842 | 552 | |
| 553 | (* setup_methods *) | |
| 554 | ||
| 8467 | 555 | fun setup_methods more_mods = Method.add_methods | 
| 8700 | 556 | [(simpN, simp_args more_mods simp_method', "simplification"), | 
| 557 |   ("simp_all", simp_args more_mods simp_method, "simplification (all goals)")];
 | |
| 5842 | 558 | |
| 559 | ||
| 560 | ||
| 4795 | 561 | (** theory setup **) | 
| 562 | ||
| 8467 | 563 | val setup = [GlobalSimpset.init, LocalSimpset.init, setup_attrs]; | 
| 564 | fun method_setup mods = [setup_methods mods]; | |
| 4795 | 565 | |
| 8228 | 566 | fun easy_setup reflect trivs = | 
| 567 | let | |
| 568 | val trivialities = Drule.reflexive_thm :: trivs; | |
| 569 | ||
| 570 | fun unsafe_solver_tac prems = FIRST' [resolve_tac (trivialities @ prems), assume_tac]; | |
| 571 | val unsafe_solver = mk_solver "easy unsafe" unsafe_solver_tac; | |
| 572 | ||
| 573 | (*no premature instantiation of variables during simplification*) | |
| 574 | fun safe_solver_tac prems = FIRST' [match_tac (trivialities @ prems), eq_assume_tac]; | |
| 575 | val safe_solver = mk_solver "easy safe" safe_solver_tac; | |
| 576 | ||
| 8243 | 577 | fun mk_eq thm = | 
| 8228 | 578 | if Logic.is_equals (Thm.concl_of thm) then [thm] | 
| 579 | else [thm RS reflect] handle THM _ => []; | |
| 580 | ||
| 8243 | 581 | fun mksimps thm = mk_eq (Drule.forall_elim_vars (#maxidx (Thm.rep_thm thm) + 1) thm); | 
| 582 | ||
| 8228 | 583 | fun init_ss thy = | 
| 584 | (simpset_ref_of thy := | |
| 585 | empty_ss setsubgoaler asm_simp_tac | |
| 586 | setSSolver safe_solver | |
| 587 | setSolver unsafe_solver | |
| 588 | setmksimps mksimps; thy); | |
| 8467 | 589 | in setup @ method_setup [] @ [init_ss] end; | 
| 8228 | 590 | |
| 4795 | 591 | |
| 8667 | 592 | |
| 593 | (** outer syntax **) | |
| 594 | ||
| 595 | val print_simpsetP = | |
| 596 | OuterSyntax.improper_command "print_simpset" "print context of Simplifier" | |
| 597 | OuterSyntax.Keyword.diag | |
| 9513 | 598 | (Scan.succeed (Toplevel.no_timing o Toplevel.unknown_context o (Toplevel.keep | 
| 9010 | 599 | (Toplevel.node_case print_simpset (print_local_simpset o Proof.context_of))))); | 
| 8667 | 600 | |
| 601 | val _ = OuterSyntax.add_parsers [print_simpsetP]; | |
| 602 | ||
| 1243 | 603 | end; | 
| 4795 | 604 | |
| 605 | ||
| 606 | structure BasicSimplifier: BASIC_SIMPLIFIER = Simplifier; | |
| 607 | open BasicSimplifier; |