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