src/Provers/clasimp.ML
author oheimb
Fri, 21 Jul 2000 17:46:43 +0200
changeset 9402 480a1b40fdd6
parent 8639 31bcb6b64d60
child 9440 a72fe5eafb5e
permissions -rw-r--r--
strengthened force_tac by using new first_best_tac
     1 (*  Title: 	Provers/clasimp.ML
     2     ID:         $Id$
     3     Author:     David von Oheimb, TU Muenchen
     4 
     5 Combination of classical reasoner and simplifier (depends on
     6 simplifier.ML, splitter.ML classical.ML, blast.ML).
     7 *)
     8 
     9 infix 4 addSIs2 addSEs2 addSDs2 addIs2 addEs2 addDs2 addsimps2 delsimps2;
    10 infix 4 addSss addss;
    11 
    12 signature CLASIMP_DATA =
    13 sig
    14   structure Simplifier: SIMPLIFIER
    15   structure Splitter: SPLITTER
    16   structure Classical: CLASSICAL
    17   structure Blast: BLAST
    18   sharing type Classical.claset = Blast.claset
    19 end
    20 
    21 signature CLASIMP =
    22 sig
    23   include CLASIMP_DATA
    24   type claset
    25   type simpset
    26   type clasimpset
    27   val addSIs2	: clasimpset * thm list -> clasimpset
    28   val addSEs2	: clasimpset * thm list -> clasimpset
    29   val addSDs2	: clasimpset * thm list -> clasimpset
    30   val addIs2	: clasimpset * thm list -> clasimpset
    31   val addEs2	: clasimpset * thm list -> clasimpset
    32   val addDs2	: clasimpset * thm list -> clasimpset
    33   val addsimps2	: clasimpset * thm list -> clasimpset
    34   val delsimps2	: clasimpset * thm list -> clasimpset
    35   val addSss	: claset * simpset -> claset
    36   val addss	: claset * simpset -> claset
    37   val CLASIMPSET  :(clasimpset -> tactic) -> tactic
    38   val CLASIMPSET' :(clasimpset -> 'a -> tactic) -> 'a -> tactic
    39   val clarsimp_tac: clasimpset -> int -> tactic
    40   val Clarsimp_tac:               int -> tactic
    41   val mk_auto_tac : clasimpset -> int -> int -> tactic
    42   val auto_tac	  : clasimpset -> tactic
    43   val Auto_tac	  : tactic
    44   val auto	  : unit -> unit
    45   val force_tac	  : clasimpset  -> int -> tactic
    46   val Force_tac	  : int -> tactic
    47   val force	  : int -> unit
    48   val change_global_css: (clasimpset * thm list -> clasimpset) -> theory attribute
    49   val change_local_css: (clasimpset * thm list -> clasimpset) -> Proof.context attribute
    50   val setup	  : (theory -> theory) list
    51 end;
    52 
    53 functor ClasimpFun(Data: CLASIMP_DATA): CLASIMP =
    54 struct
    55 
    56 open Data;
    57 
    58 type claset = Classical.claset;
    59 type simpset = Simplifier.simpset;
    60 type clasimpset = claset * simpset;
    61 
    62 
    63 (* clasimpset operations *)
    64 
    65 (*this interface for updating a clasimpset is rudimentary and just for
    66   convenience for the most common cases*)
    67 
    68 fun pair_upd1 f ((a,b),x) = (f(a,x), b);
    69 fun pair_upd2 f ((a,b),x) = (a, f(b,x));
    70 
    71 fun op addSIs2   arg = pair_upd1 Classical.addSIs arg;
    72 fun op addSEs2   arg = pair_upd1 Classical.addSEs arg;
    73 fun op addSDs2   arg = pair_upd1 Classical.addSDs arg;
    74 fun op addIs2    arg = pair_upd1 Classical.addIs arg;
    75 fun op addEs2    arg = pair_upd1 Classical.addEs arg;
    76 fun op addDs2    arg = pair_upd1 Classical.addDs arg;
    77 fun op addsimps2 arg = pair_upd2 Simplifier.addsimps arg;
    78 fun op delsimps2 arg = pair_upd2 Simplifier.delsimps arg;
    79 
    80 (*not totally safe: may instantiate unknowns that appear also in other subgoals*)
    81 val safe_asm_full_simp_tac = Simplifier.generic_simp_tac true (true,true,true);
    82 
    83 (*Add a simpset to a classical set!*)
    84 (*Caution: only one simpset added can be added by each of addSss and addss*)
    85 fun cs addSss ss = Classical.addSaltern (cs, ("safe_asm_full_simp_tac",
    86 			    CHANGED o safe_asm_full_simp_tac ss));
    87 fun cs addss  ss = Classical.addbefore  (cs, ("asm_full_simp_tac", 
    88 			    CHANGED o Simplifier.asm_full_simp_tac ss));
    89 
    90 (* tacticals *)
    91 
    92 fun CLASIMPSET tacf state =
    93   Classical.CLASET (fn cs => Simplifier.SIMPSET (fn ss => tacf (cs, ss))) state;
    94 
    95 fun CLASIMPSET' tacf i state =
    96   Classical.CLASET (fn cs => Simplifier.SIMPSET (fn ss => tacf (cs, ss) i)) state;
    97 
    98 
    99 fun clarsimp_tac (cs, ss) = safe_asm_full_simp_tac ss THEN_ALL_NEW
   100 			    Classical.clarify_tac (cs addSss ss);
   101 fun Clarsimp_tac i = clarsimp_tac (Classical.claset(), Simplifier.simpset()) i;
   102 
   103 
   104 (* auto_tac *)
   105 
   106 fun blast_depth_tac cs m i thm =
   107     Blast.depth_tac cs m i thm 
   108       handle Blast.TRANS s => (warning ("Blast_tac: " ^ s); Seq.empty);
   109  
   110 (* a variant of depth_tac that avoids interference of the simplifier 
   111    with dup_step_tac when they are combined by auto_tac *)
   112 local
   113 fun slow_step_tac' cs = Classical.appWrappers cs 
   114 	(Classical.instp_step_tac cs APPEND' Classical.haz_step_tac cs);
   115 in fun nodup_depth_tac cs m i state = SELECT_GOAL 
   116    (Classical.safe_steps_tac cs 1 THEN_ELSE 
   117 	(DEPTH_SOLVE (nodup_depth_tac cs m 1),
   118 	 Classical.inst0_step_tac cs 1 APPEND COND (K (m=0)) no_tac
   119 	     (slow_step_tac' cs 1 THEN DEPTH_SOLVE (nodup_depth_tac cs (m-1) 1))
   120         )) i state;
   121 end;
   122 
   123 (*Designed to be idempotent, except if blast_depth_tac instantiates variables
   124   in some of the subgoals*)
   125 fun mk_auto_tac (cs, ss) m n =
   126     let val cs' = cs addss ss
   127         val maintac = 
   128           blast_depth_tac cs m		     (* fast but can't use wrappers *)
   129           ORELSE'
   130           (CHANGED o nodup_depth_tac cs' n); (* slower but more general *)
   131     in  EVERY [ALLGOALS (Simplifier.asm_full_simp_tac ss),
   132 	       TRY (Classical.safe_tac cs),
   133 	       REPEAT (FIRSTGOAL maintac),
   134                TRY (Classical.safe_tac (cs addSss ss)),
   135 	       prune_params_tac] 
   136     end;
   137 
   138 fun auto_tac (cs,ss) = mk_auto_tac (cs,ss) 4 2;
   139 
   140 fun Auto_tac st = auto_tac (Classical.claset(), Simplifier.simpset()) st;
   141 
   142 fun auto () = by Auto_tac;
   143 
   144 (* force_tac *)
   145 
   146 (* aimed to solve the given subgoal totally, using whatever tools possible *)
   147 fun force_tac (cs,ss) = let val cs' = cs addss ss in SELECT_GOAL (EVERY [
   148 	Classical.clarify_tac cs' 1,
   149 	IF_UNSOLVED (Simplifier.asm_full_simp_tac ss 1),
   150 	ALLGOALS (Classical.first_best_tac cs')]) end;
   151 fun Force_tac i = force_tac (Classical.claset(), Simplifier.simpset()) i;
   152 fun force i = by (Force_tac i);
   153 
   154 
   155 (* attributes *)
   156 
   157 fun change_global_css f (thy, th) =
   158   let
   159     val cs_ref = Classical.claset_ref_of thy;
   160     val ss_ref = Simplifier.simpset_ref_of thy;
   161     val (cs', ss') = f ((! cs_ref, ! ss_ref), [th]);
   162   in cs_ref := cs'; ss_ref := ss'; (thy, th) end;
   163 
   164 fun change_local_css f (ctxt, th) =
   165   let
   166     val cs = Classical.get_local_claset ctxt;
   167     val ss = Simplifier.get_local_simpset ctxt;
   168     val (cs', ss') = f ((cs, ss), [th]);
   169     val ctxt' =
   170       ctxt
   171       |> Classical.put_local_claset cs'
   172       |> Simplifier.put_local_simpset ss';
   173   in (ctxt', th) end;
   174 
   175 
   176 (* methods *)
   177 
   178 fun get_local_clasimpset ctxt =
   179   (Classical.get_local_claset ctxt, Simplifier.get_local_simpset ctxt);
   180 
   181 val clasimp_modifiers =
   182   Simplifier.simp_modifiers @ Splitter.split_modifiers @ Classical.cla_modifiers;
   183 
   184 fun clasimp_meth tac prems ctxt = Method.METHOD (fn facts =>
   185   ALLGOALS (Method.insert_tac (prems @ facts)) THEN tac (get_local_clasimpset ctxt));
   186 
   187 fun clasimp_meth' tac prems ctxt = Method.METHOD (fn facts =>
   188   HEADGOAL (Method.insert_tac (prems @ facts) THEN' tac (get_local_clasimpset ctxt)));
   189 
   190 val clasimp_method = Method.bang_sectioned_args clasimp_modifiers o clasimp_meth;
   191 val clasimp_method' = Method.bang_sectioned_args clasimp_modifiers o clasimp_meth';
   192 
   193 
   194 val setup =
   195  [Method.add_methods
   196    [("clarsimp_tac", clasimp_method' clarsimp_tac, "clarsimp (improper!)"),
   197     ("auto", clasimp_method (CHANGED o auto_tac), "auto"),
   198     ("force", clasimp_method' force_tac, "force")]];
   199     
   200 
   201 
   202 end;