src/Pure/simplifier.ML
author wenzelm
Tue, 24 Nov 2009 17:54:33 +0100
changeset 33890 a87ad4be59a4
parent 33673 4b0f2599ed48
child 35232 f588e1169c8b
permissions -rw-r--r--
Added tag isa2009-1-test for changeset 4328de748fb2
     1 (*  Title:      Pure/simplifier.ML
     2     Author:     Tobias Nipkow and Markus Wenzel, TU Muenchen
     3 
     4 Generic simplifier, suitable for most logics (see also
     5 meta_simplifier.ML for the actual meta-level rewriting engine).
     6 *)
     7 
     8 signature BASIC_SIMPLIFIER =
     9 sig
    10   include BASIC_META_SIMPLIFIER
    11   val change_simpset: (simpset -> simpset) -> unit
    12   val global_simpset_of: theory -> simpset
    13   val Addsimprocs: simproc list -> unit
    14   val Delsimprocs: simproc list -> unit
    15   val simpset_of: Proof.context -> simpset
    16   val generic_simp_tac: bool -> bool * bool * bool -> simpset -> int -> tactic
    17   val safe_asm_full_simp_tac: simpset -> int -> tactic
    18   val               simp_tac: simpset -> int -> tactic
    19   val           asm_simp_tac: simpset -> int -> tactic
    20   val          full_simp_tac: simpset -> int -> tactic
    21   val        asm_lr_simp_tac: simpset -> int -> tactic
    22   val      asm_full_simp_tac: simpset -> int -> tactic
    23   val          simplify: simpset -> thm -> thm
    24   val      asm_simplify: simpset -> thm -> thm
    25   val     full_simplify: simpset -> thm -> thm
    26   val   asm_lr_simplify: simpset -> thm -> thm
    27   val asm_full_simplify: simpset -> thm -> thm
    28 end;
    29 
    30 signature SIMPLIFIER =
    31 sig
    32   include BASIC_SIMPLIFIER
    33   val pretty_ss: Proof.context -> simpset -> Pretty.T
    34   val clear_ss: simpset -> simpset
    35   val debug_bounds: bool Unsynchronized.ref
    36   val inherit_context: simpset -> simpset -> simpset
    37   val the_context: simpset -> Proof.context
    38   val context: Proof.context -> simpset -> simpset
    39   val theory_context: theory  -> simpset -> simpset
    40   val simproc_i: theory -> string -> term list
    41     -> (theory -> simpset -> term -> thm option) -> simproc
    42   val simproc: theory -> string -> string list
    43     -> (theory -> simpset -> term -> thm option) -> simproc
    44   val          rewrite: simpset -> conv
    45   val      asm_rewrite: simpset -> conv
    46   val     full_rewrite: simpset -> conv
    47   val   asm_lr_rewrite: simpset -> conv
    48   val asm_full_rewrite: simpset -> conv
    49   val get_ss: Context.generic -> simpset
    50   val map_ss: (simpset -> simpset) -> Context.generic -> Context.generic
    51   val attrib: (simpset * thm list -> simpset) -> attribute
    52   val simp_add: attribute
    53   val simp_del: attribute
    54   val cong_add: attribute
    55   val cong_del: attribute
    56   val map_simpset: (simpset -> simpset) -> theory -> theory
    57   val get_simproc: Context.generic -> xstring -> simproc
    58   val def_simproc: {name: string, lhss: string list,
    59     proc: morphism -> simpset -> cterm -> thm option, identifier: thm list} ->
    60     local_theory -> local_theory
    61   val def_simproc_i: {name: string, lhss: term list,
    62     proc: morphism -> simpset -> cterm -> thm option, identifier: thm list} ->
    63     local_theory -> local_theory
    64   val cong_modifiers: Method.modifier parser list
    65   val simp_modifiers': Method.modifier parser list
    66   val simp_modifiers: Method.modifier parser list
    67   val method_setup: Method.modifier parser list -> theory -> theory
    68   val easy_setup: thm -> thm list -> theory -> theory
    69 end;
    70 
    71 structure Simplifier: SIMPLIFIER =
    72 struct
    73 
    74 open MetaSimplifier;
    75 
    76 
    77 (** pretty printing **)
    78 
    79 fun pretty_ss ctxt ss =
    80   let
    81     val pretty_cterm = Syntax.pretty_term ctxt o Thm.term_of;
    82     val pretty_thm = Display.pretty_thm ctxt;
    83     fun pretty_proc (name, lhss) = Pretty.big_list (name ^ ":") (map pretty_cterm lhss);
    84     fun pretty_cong (name, thm) =
    85       Pretty.block [Pretty.str (name ^ ":"), Pretty.brk 1, pretty_thm thm];
    86 
    87     val {simps, procs, congs, loopers, unsafe_solvers, safe_solvers, ...} = dest_ss ss;
    88   in
    89     [Pretty.big_list "simplification rules:" (map (pretty_thm o #2) simps),
    90       Pretty.big_list "simplification procedures:" (map pretty_proc (sort_wrt #1 procs)),
    91       Pretty.big_list "congruences:" (map pretty_cong congs),
    92       Pretty.strs ("loopers:" :: map quote loopers),
    93       Pretty.strs ("unsafe solvers:" :: map quote unsafe_solvers),
    94       Pretty.strs ("safe solvers:" :: map quote safe_solvers)]
    95     |> Pretty.chunks
    96   end;
    97 
    98 
    99 
   100 (** simpset data **)
   101 
   102 structure SimpsetData = Generic_Data
   103 (
   104   type T = simpset;
   105   val empty = empty_ss;
   106   fun extend ss = MetaSimplifier.inherit_context empty_ss ss;
   107   val merge = merge_ss;
   108 );
   109 
   110 val get_ss = SimpsetData.get;
   111 val map_ss = SimpsetData.map;
   112 
   113 
   114 (* attributes *)
   115 
   116 fun attrib f = Thm.declaration_attribute (fn th => map_ss (fn ss => f (ss, [th])));
   117 
   118 val simp_add = attrib (op addsimps);
   119 val simp_del = attrib (op delsimps);
   120 val cong_add = attrib (op addcongs);
   121 val cong_del = attrib (op delcongs);
   122 
   123 
   124 (* global simpset *)
   125 
   126 fun map_simpset f = Context.theory_map (map_ss f);
   127 fun change_simpset f = Context.>> (Context.map_theory (map_simpset f));
   128 fun global_simpset_of thy =
   129   MetaSimplifier.context (ProofContext.init thy) (get_ss (Context.Theory thy));
   130 
   131 fun Addsimprocs args = change_simpset (fn ss => ss addsimprocs args);
   132 fun Delsimprocs args = change_simpset (fn ss => ss delsimprocs args);
   133 
   134 
   135 (* local simpset *)
   136 
   137 fun simpset_of ctxt = MetaSimplifier.context ctxt (get_ss (Context.Proof ctxt));
   138 
   139 val _ = ML_Antiquote.value "simpset"
   140   (Scan.succeed "Simplifier.simpset_of (ML_Context.the_local_context ())");
   141 
   142 
   143 
   144 (** named simprocs **)
   145 
   146 (* data *)
   147 
   148 structure Simprocs = Generic_Data
   149 (
   150   type T = simproc Name_Space.table;
   151   val empty : T = Name_Space.empty_table "simproc";
   152   val extend = I;
   153   fun merge simprocs = Name_Space.merge_tables simprocs;
   154 );
   155 
   156 
   157 (* get simprocs *)
   158 
   159 fun get_simproc context xname =
   160   let
   161     val (space, tab) = Simprocs.get context;
   162     val name = Name_Space.intern space xname;
   163   in
   164     (case Symtab.lookup tab name of
   165       SOME proc => proc
   166     | NONE => error ("Undefined simplification procedure: " ^ quote name))
   167   end;
   168 
   169 val _ = ML_Antiquote.value "simproc" (Scan.lift Args.name >> (fn name =>
   170   "Simplifier.get_simproc (ML_Context.the_generic_context ()) " ^ ML_Syntax.print_string name));
   171 
   172 
   173 (* define simprocs *)
   174 
   175 local
   176 
   177 fun gen_simproc prep {name, lhss, proc, identifier} lthy =
   178   let
   179     val b = Binding.name name;
   180     val naming = Local_Theory.naming_of lthy;
   181     val simproc = make_simproc
   182       {name = Name_Space.full_name naming b,
   183        lhss =
   184         let
   185           val lhss' = prep lthy lhss;
   186           val ctxt' = lthy
   187             |> fold Variable.declare_term lhss'
   188             |> fold Variable.auto_fixes lhss';
   189         in Variable.export_terms ctxt' lthy lhss' end
   190         |> map (Thm.cterm_of (ProofContext.theory_of lthy)),
   191        proc = proc,
   192        identifier = identifier};
   193   in
   194     lthy |> Local_Theory.declaration false (fn phi =>
   195       let
   196         val b' = Morphism.binding phi b;
   197         val simproc' = morph_simproc phi simproc;
   198       in
   199         Simprocs.map (#2 o Name_Space.define true naming (b', simproc'))
   200         #> map_ss (fn ss => ss addsimprocs [simproc'])
   201       end)
   202   end;
   203 
   204 in
   205 
   206 val def_simproc = gen_simproc Syntax.read_terms;
   207 val def_simproc_i = gen_simproc Syntax.check_terms;
   208 
   209 end;
   210 
   211 
   212 
   213 (** simplification tactics and rules **)
   214 
   215 fun solve_all_tac solvers ss =
   216   let
   217     val (_, {subgoal_tac, ...}) = MetaSimplifier.internal_ss ss;
   218     val solve_tac = subgoal_tac (MetaSimplifier.set_solvers solvers ss) THEN_ALL_NEW (K no_tac);
   219   in DEPTH_SOLVE (solve_tac 1) end;
   220 
   221 (*NOTE: may instantiate unknowns that appear also in other subgoals*)
   222 fun generic_simp_tac safe mode ss =
   223   let
   224     val (_, {loop_tacs, solvers = (unsafe_solvers, solvers), ...}) = MetaSimplifier.internal_ss ss;
   225     val loop_tac = FIRST' (map (fn (_, tac) => tac ss) (rev loop_tacs));
   226     val solve_tac = FIRST' (map (MetaSimplifier.solver ss)
   227       (rev (if safe then solvers else unsafe_solvers)));
   228 
   229     fun simp_loop_tac i =
   230       asm_rewrite_goal_tac mode (solve_all_tac unsafe_solvers) ss i THEN
   231       (solve_tac i ORELSE TRY ((loop_tac THEN_ALL_NEW simp_loop_tac) i));
   232   in simp_loop_tac end;
   233 
   234 local
   235 
   236 fun simp rew mode ss thm =
   237   let
   238     val (_, {solvers = (unsafe_solvers, _), ...}) = MetaSimplifier.internal_ss ss;
   239     val tacf = solve_all_tac (rev unsafe_solvers);
   240     fun prover s th = Option.map #1 (Seq.pull (tacf s th));
   241   in rew mode prover ss thm end;
   242 
   243 in
   244 
   245 val simp_thm = simp MetaSimplifier.rewrite_thm;
   246 val simp_cterm = simp MetaSimplifier.rewrite_cterm;
   247 
   248 end;
   249 
   250 
   251 (* tactics *)
   252 
   253 val simp_tac = generic_simp_tac false (false, false, false);
   254 val asm_simp_tac = generic_simp_tac false (false, true, false);
   255 val full_simp_tac = generic_simp_tac false (true, false, false);
   256 val asm_lr_simp_tac = generic_simp_tac false (true, true, false);
   257 val asm_full_simp_tac = generic_simp_tac false (true, true, true);
   258 val safe_asm_full_simp_tac = generic_simp_tac true (true, true, true);
   259 
   260 
   261 (* conversions *)
   262 
   263 val          simplify = simp_thm (false, false, false);
   264 val      asm_simplify = simp_thm (false, true, false);
   265 val     full_simplify = simp_thm (true, false, false);
   266 val   asm_lr_simplify = simp_thm (true, true, false);
   267 val asm_full_simplify = simp_thm (true, true, true);
   268 
   269 val          rewrite = simp_cterm (false, false, false);
   270 val      asm_rewrite = simp_cterm (false, true, false);
   271 val     full_rewrite = simp_cterm (true, false, false);
   272 val   asm_lr_rewrite = simp_cterm (true, true, false);
   273 val asm_full_rewrite = simp_cterm (true, true, true);
   274 
   275 
   276 
   277 (** concrete syntax of attributes **)
   278 
   279 (* add / del *)
   280 
   281 val simpN = "simp";
   282 val congN = "cong";
   283 val onlyN = "only";
   284 val no_asmN = "no_asm";
   285 val no_asm_useN = "no_asm_use";
   286 val no_asm_simpN = "no_asm_simp";
   287 val asm_lrN = "asm_lr";
   288 
   289 
   290 (* simprocs *)
   291 
   292 local
   293 
   294 val add_del =
   295   (Args.del -- Args.colon >> K (op delsimprocs) ||
   296     Scan.option (Args.add -- Args.colon) >> K (op addsimprocs))
   297   >> (fn f => fn simproc => fn phi => Thm.declaration_attribute
   298       (K (map_ss (fn ss => f (ss, [morph_simproc phi simproc])))));
   299 
   300 in
   301 
   302 val simproc_att =
   303   Scan.peek (fn context =>
   304     add_del :|-- (fn decl =>
   305       Scan.repeat1 (Args.named_attribute (decl o get_simproc context))
   306       >> (Library.apply o map Morphism.form)));
   307 
   308 end;
   309 
   310 
   311 (* conversions *)
   312 
   313 local
   314 
   315 fun conv_mode x =
   316   ((Args.parens (Args.$$$ no_asmN) >> K simplify ||
   317     Args.parens (Args.$$$ no_asm_simpN) >> K asm_simplify ||
   318     Args.parens (Args.$$$ no_asm_useN) >> K full_simplify ||
   319     Scan.succeed asm_full_simplify) |> Scan.lift) x;
   320 
   321 in
   322 
   323 val simplified = conv_mode -- Attrib.thms >>
   324   (fn (f, ths) => Thm.rule_attribute (fn context =>
   325     f ((if null ths then I else MetaSimplifier.clear_ss)
   326         (simpset_of (Context.proof_of context)) addsimps ths)));
   327 
   328 end;
   329 
   330 
   331 (* setup attributes *)
   332 
   333 val _ = Context.>> (Context.map_theory
   334  (Attrib.setup (Binding.name simpN) (Attrib.add_del simp_add simp_del)
   335     "declaration of Simplifier rewrite rule" #>
   336   Attrib.setup (Binding.name congN) (Attrib.add_del cong_add cong_del)
   337     "declaration of Simplifier congruence rule" #>
   338   Attrib.setup (Binding.name "simproc") simproc_att
   339     "declaration of simplification procedures" #>
   340   Attrib.setup (Binding.name "simplified") simplified "simplified rule"));
   341 
   342 
   343 
   344 (** method syntax **)
   345 
   346 val cong_modifiers =
   347  [Args.$$$ congN -- Args.colon >> K ((I, cong_add): Method.modifier),
   348   Args.$$$ congN -- Args.add -- Args.colon >> K (I, cong_add),
   349   Args.$$$ congN -- Args.del -- Args.colon >> K (I, cong_del)];
   350 
   351 val simp_modifiers =
   352  [Args.$$$ simpN -- Args.colon >> K (I, simp_add),
   353   Args.$$$ simpN -- Args.add -- Args.colon >> K (I, simp_add),
   354   Args.$$$ simpN -- Args.del -- Args.colon >> K (I, simp_del),
   355   Args.$$$ simpN -- Args.$$$ onlyN -- Args.colon
   356     >> K (Context.proof_map (map_ss MetaSimplifier.clear_ss), simp_add)]
   357    @ cong_modifiers;
   358 
   359 val simp_modifiers' =
   360  [Args.add -- Args.colon >> K (I, simp_add),
   361   Args.del -- Args.colon >> K (I, simp_del),
   362   Args.$$$ onlyN -- Args.colon
   363     >> K (Context.proof_map (map_ss MetaSimplifier.clear_ss), simp_add)]
   364    @ cong_modifiers;
   365 
   366 val simp_options =
   367  (Args.parens (Args.$$$ no_asmN) >> K simp_tac ||
   368   Args.parens (Args.$$$ no_asm_simpN) >> K asm_simp_tac ||
   369   Args.parens (Args.$$$ no_asm_useN) >> K full_simp_tac ||
   370   Args.parens (Args.$$$ asm_lrN) >> K asm_lr_simp_tac ||
   371   Scan.succeed asm_full_simp_tac);
   372 
   373 fun simp_method more_mods meth =
   374   Args.bang_facts -- Scan.lift simp_options --|
   375     Method.sections (more_mods @ simp_modifiers') >>
   376     (fn (prems, tac) => fn ctxt => METHOD (fn facts => meth ctxt tac (prems @ facts)));
   377 
   378 
   379 
   380 (** setup **)
   381 
   382 fun method_setup more_mods =
   383   Method.setup (Binding.name simpN)
   384     (simp_method more_mods (fn ctxt => fn tac => fn facts =>
   385       HEADGOAL (Method.insert_tac facts THEN'
   386         (CHANGED_PROP oo tac) (simpset_of ctxt))))
   387     "simplification" #>
   388   Method.setup (Binding.name "simp_all")
   389     (simp_method more_mods (fn ctxt => fn tac => fn facts =>
   390       ALLGOALS (Method.insert_tac facts) THEN
   391         (CHANGED_PROP o ALLGOALS o tac) (simpset_of ctxt)))
   392     "simplification (all goals)";
   393 
   394 fun easy_setup reflect trivs = method_setup [] #> Context.theory_map (map_ss (fn _ =>
   395   let
   396     val trivialities = Drule.reflexive_thm :: trivs;
   397 
   398     fun unsafe_solver_tac prems = FIRST' [resolve_tac (trivialities @ prems), assume_tac];
   399     val unsafe_solver = mk_solver "easy unsafe" unsafe_solver_tac;
   400 
   401     (*no premature instantiation of variables during simplification*)
   402     fun safe_solver_tac prems = FIRST' [match_tac (trivialities @ prems), eq_assume_tac];
   403     val safe_solver = mk_solver "easy safe" safe_solver_tac;
   404 
   405     fun mk_eq thm =
   406       if can Logic.dest_equals (Thm.concl_of thm) then [thm]
   407       else [thm RS reflect] handle THM _ => [];
   408 
   409     fun mksimps thm = mk_eq (Thm.forall_elim_vars (#maxidx (Thm.rep_thm thm) + 1) thm);
   410   in
   411     empty_ss setsubgoaler asm_simp_tac
   412     setSSolver safe_solver
   413     setSolver unsafe_solver
   414     setmksimps mksimps
   415   end));
   416 
   417 end;
   418 
   419 structure Basic_Simplifier: BASIC_SIMPLIFIER = Simplifier;
   420 open Basic_Simplifier;