Restructured lin.arith.package.
authornipkow
Thu, 23 Sep 1999 09:04:36 +0200
changeset 7582 2650c9c2ab7f
parent 7581 18070ae7a84c
child 7583 d1b40e0464b1
Restructured lin.arith.package.
src/HOL/Arith.ML
src/HOL/Integ/Bin.ML
src/Provers/Arith/fast_lin_arith.ML
--- a/src/HOL/Arith.ML	Wed Sep 22 21:49:37 1999 +0200
+++ b/src/HOL/Arith.ML	Thu Sep 23 09:04:36 1999 +0200
@@ -890,29 +890,18 @@
 
 end;
 
-structure Nat_LA_Data (* : LIN_ARITH_DATA *) =
-struct
-
-val lessD = [Suc_leI];
-
-(* reduce contradictory <= to False.
-   Most of the work is done by the cancel tactics.
-*)
-val add_rules = [add_0,add_0_right,Zero_not_Suc,Suc_not_Zero,le_0_eq];
+signature LIN_ARITH_DATA2 =
+sig
+  include LIN_ARITH_DATA
+  val discrete: (string * bool)list ref
+end;
 
-val cancel_sums_ss = HOL_basic_ss addsimps add_rules
-                                  addsimprocs nat_cancel_sums_add;
-
-val simp = simplify cancel_sums_ss;
-
-val add_mono_thms = map (fn s => prove_goal Arith.thy s
- (fn prems => [cut_facts_tac prems 1,
-               blast_tac (claset() addIs [add_le_mono]) 1]))
-["(i <= j) & (k <= l) ==> i + k <= j + (l::nat)",
- "(i  = j) & (k <= l) ==> i + k <= j + (l::nat)",
- "(i <= j) & (k  = l) ==> i + k <= j + (l::nat)",
- "(i  = j) & (k  = l) ==> i + k  = j + (l::nat)"
-];
+structure LA_Data_Ref: LIN_ARITH_DATA2 =
+struct
+  val add_mono_thms = ref ([]:thm list);
+  val lessD = ref ([]:thm list);
+  val ss_ref = ref HOL_basic_ss;
+  val discrete = ref ([]:(string*bool)list);
 
 (* Decomposition of terms *)
 
@@ -953,31 +942,44 @@
 fun negate(Some(x,i,rel,y,j,d)) = Some(x,i,"~"^rel,y,j,d)
   | negate None = None;
 
-fun decomp1 tab (T,xxx) =
+fun decomp1 (T,xxx) =
   (case T of
      Type("fun",[Type(D,[]),_]) =>
-       (case assoc(!tab,D) of
+       (case assoc(!discrete,D) of
           None => None
         | Some d => (case decomp2 xxx of
                        None => None
                      | Some(p,i,rel,q,j) => Some(p,i,rel,q,j,d)))
    | _ => None);
 
-(* tab: (string * bool)list ref  contains the discreteneness flag *)
-fun decomp tab (_$(Const(rel,T)$lhs$rhs)) = decomp1 tab (T,(rel,lhs,rhs))
-  | decomp tab (_$(Const("Not",_)$(Const(rel,T)$lhs$rhs))) =
-      negate(decomp1 tab (T,(rel,lhs,rhs)))
-  | decomp _ _ = None
-
+fun decomp (_$(Const(rel,T)$lhs$rhs)) = decomp1 (T,(rel,lhs,rhs))
+  | decomp (_$(Const("Not",_)$(Const(rel,T)$lhs$rhs))) =
+      negate(decomp1 (T,(rel,lhs,rhs)))
+  | decomp _ = None
 end;
 
-structure LA_Data_Ref =
-struct
-  val add_mono_thms = ref Nat_LA_Data.add_mono_thms
-  val lessD = ref Nat_LA_Data.lessD
-  val simp = ref Nat_LA_Data.simp
-  val discrete = ref [("nat",true)]
-  val decomp = Nat_LA_Data.decomp discrete
+let
+
+(* reduce contradictory <= to False.
+   Most of the work is done by the cancel tactics.
+*)
+val add_rules = [add_0,add_0_right,Zero_not_Suc,Suc_not_Zero,le_0_eq];
+
+val add_mono_thms = map (fn s => prove_goal Arith.thy s
+ (fn prems => [cut_facts_tac prems 1,
+               blast_tac (claset() addIs [add_le_mono]) 1]))
+["(i <= j) & (k <= l) ==> i + k <= j + (l::nat)",
+ "(i  = j) & (k <= l) ==> i + k <= j + (l::nat)",
+ "(i <= j) & (k  = l) ==> i + k <= j + (l::nat)",
+ "(i  = j) & (k  = l) ==> i + k  = j + (l::nat)"
+];
+
+in
+LA_Data_Ref.add_mono_thms := !LA_Data_Ref.add_mono_thms @ add_mono_thms;
+LA_Data_Ref.lessD := !LA_Data_Ref.lessD @ [Suc_leI];
+LA_Data_Ref.ss_ref := !LA_Data_Ref.ss_ref addsimps add_rules
+                      addsimprocs nat_cancel_sums_add;
+LA_Data_Ref.discrete := !LA_Data_Ref.discrete @ [("nat",true)]
 end;
 
 structure Fast_Arith =
@@ -985,14 +987,16 @@
 
 val fast_arith_tac = Fast_Arith.lin_arith_tac;
 
+let
 val nat_arith_simproc_pats =
   map (fn s => Thm.read_cterm (Theory.sign_of Arith.thy) (s, HOLogic.boolT))
       ["(m::nat) < n","(m::nat) <= n", "(m::nat) = n"];
 
-val fast_nat_arith_simproc = mk_simproc "fast_nat_arith" nat_arith_simproc_pats
-                                        Fast_Arith.lin_arith_prover;
-
-Addsimprocs [fast_nat_arith_simproc];
+val fast_nat_arith_simproc = mk_simproc
+  "fast_nat_arith" nat_arith_simproc_pats Fast_Arith.lin_arith_prover;
+in
+Addsimprocs [fast_nat_arith_simproc]
+end;
 
 (* Because of fast_nat_arith_simproc, the arithmetic solver is really only
 useful to detect inconsistencies among the premises for subgoals which are
@@ -1017,9 +1021,10 @@
    (max m n + k <= r) = (m+k <= r & n+k <= r)
    (l <= min m n + k) = (l <= m+k & l <= n+k)
 *)
-val arith_tac =
-  refute_tac (K true) (REPEAT o split_tac[nat_diff_split,split_min,split_max])
-             ((REPEAT_DETERM o etac linorder_neqE) THEN' fast_arith_tac);
+val arith_tac_split_thms = ref [nat_diff_split,split_min,split_max];
+fun arith_tac i =
+  refute_tac (K true) (REPEAT o split_tac (!arith_tac_split_thms))
+             ((REPEAT_DETERM o etac linorder_neqE) THEN' fast_arith_tac) i;
 
 
 (* proof method setup *)
--- a/src/HOL/Integ/Bin.ML	Wed Sep 22 21:49:37 1999 +0200
+++ b/src/HOL/Integ/Bin.ML	Thu Sep 23 09:04:36 1999 +0200
@@ -480,22 +480,17 @@
 (The latter option is very inefficient!)
 *)
 
-structure Int_LA_Data(*: LIN_ARITH_DATA*) =
-struct
-
-val lessD = Nat_LA_Data.lessD @ [add1_zle_eq RS iffD2];
+(* Update parameters of arithmetic prover *)
+let
 
 (* reduce contradictory <= to False *)
 val add_rules = simp_thms @ bin_arith_simps @ bin_rel_simps @
                 [int_0,zmult_0,zmult_0_right];
 
-val cancel_sums_ss = Nat_LA_Data.cancel_sums_ss addsimps add_rules
-          addsimprocs [Int_Cancel.sum_conv, Int_Cancel.rel_conv,
-                       Int_CC.sum_conv, Int_CC.rel_conv];
+val simprocs = [Int_Cancel.sum_conv, Int_Cancel.rel_conv,
+                Int_CC.sum_conv, Int_CC.rel_conv];
 
-val simp = simplify cancel_sums_ss;
-
-val add_mono_thms = Nat_LA_Data.add_mono_thms @
+val add_mono_thms =
   map (fn s => prove_goal Int.thy s
                  (fn prems => [cut_facts_tac prems 1,
                       asm_simp_tac (simpset() addsimps [zadd_zle_mono]) 1]))
@@ -505,31 +500,24 @@
      "(i  = j) & (k  = l) ==> i + k  = j + (l::int)"
     ];
 
+in
+LA_Data_Ref.add_mono_thms := !LA_Data_Ref.add_mono_thms @ add_mono_thms;
+LA_Data_Ref.lessD := !LA_Data_Ref.lessD @ [add1_zle_eq RS iffD2];
+LA_Data_Ref.ss_ref := !LA_Data_Ref.ss_ref addsimps add_rules
+                      addsimprocs simprocs;
+LA_Data_Ref.discrete := !LA_Data_Ref.discrete @ [("IntDef.int",true)]
 end;
 
-(* Update parameters of arithmetic prover *)
-LA_Data_Ref.add_mono_thms := Int_LA_Data.add_mono_thms;
-LA_Data_Ref.lessD :=         Int_LA_Data.lessD;
-LA_Data_Ref.simp :=          Int_LA_Data.simp;
-LA_Data_Ref.discrete := !LA_Data_Ref.discrete @ [("IntDef.int",true)];
-
-
+let
 val int_arith_simproc_pats =
   map (fn s => Thm.read_cterm (Theory.sign_of Int.thy) (s, HOLogic.boolT))
       ["(m::int) < n","(m::int) <= n", "(m::int) = n"];
 
-val fast_int_arith_simproc = mk_simproc "fast_int_arith" int_arith_simproc_pats
-                                        Fast_Arith.lin_arith_prover;
-
-Addsimprocs [fast_int_arith_simproc];
-
-(* FIXME: K true should be replaced by a sensible test to speed things up
-   in case there are lots of irrelevant terms involved.
-
-val arith_tac =
-  refute_tac (K true) (REPEAT o split_tac[nat_diff_split])
-             ((REPEAT_DETERM o etac linorder_neqE) THEN' fast_arith_tac);
-*)
+val fast_int_arith_simproc = mk_simproc
+  "fast_int_arith" int_arith_simproc_pats Fast_Arith.lin_arith_prover;
+in
+Addsimprocs [fast_int_arith_simproc]
+end;
 
 (* Some test data
 Goal "!!a::int. [| a <= b; c <= d; x+y<z |] ==> a+c <= b+d";
--- a/src/Provers/Arith/fast_lin_arith.ML	Wed Sep 22 21:49:37 1999 +0200
+++ b/src/Provers/Arith/fast_lin_arith.ML	Thu Sep 23 09:04:36 1999 +0200
@@ -17,6 +17,8 @@
 (in)equations. lin_arith_prover tries to prove or disprove the term.
 *)
 
+(* Debugging: (*? -> (*?*), !*) -> (*!*) *)
+
 (*** Data needed for setting up the linear arithmetic package ***)
 
 signature LIN_ARITH_LOGIC =
@@ -54,9 +56,8 @@
                             (* [| i rel1 j; m rel2 n |] ==> i + m rel3 j + n *)
   val lessD:            thm list ref (* m < n ==> m+1 <= n *)
   val decomp:
-    term ->
-      ((term * int)list * int * string * (term * int)list * int * bool)option
-  val simp: (thm -> thm) ref
+    term -> ((term*int)list * int * string * (term*int)list * int * bool)option
+  val ss_ref: simpset ref
 end;
 (*
 decomp(`x Rel y') should yield (p,i,Rel,q,j,d)
@@ -65,7 +66,7 @@
          of summand * multiplicity pairs and a constant summand and
          d indicates if the domain is discrete.
 
-simp must reduce contradictory <= to False.
+ss_ref must reduce contradictory <= to False.
    It should also cancel common summands to keep <= reduced;
    otherwise <= can grow to massive proportions.
 *)
@@ -202,7 +203,7 @@
 
 
 fun elim ineqs =
-  let (*val dummy = print_ineqs ineqs;*)
+  let (*?val dummy = print_ineqs ineqs;!*)
       val (triv,nontriv) = partition is_trivial ineqs in
   if not(null triv)
   then case find_first is_answer triv of
@@ -268,19 +269,20 @@
         in if n < 0 then mul(~n,thm) RS LA_Logic.sym else mul(n,thm) end;
 
       fun simp thm =
-        let val thm' = !LA_Data.simp thm
+        let val thm' = simplify (!LA_Data.ss_ref) thm
         in if LA_Logic.is_False thm' then raise FalseE thm' else thm' end
 
-      fun mk(Asm i) = ((*writeln"Asm";prth*)(nth_elem(i,asms)))
-        | mk(Nat(i)) = ((*writeln"N";*)LA_Logic.mk_nat_thm sg (nth_elem(i,atoms)))
-        | mk(LessD(j)) = ((*writeln"L";prth*)(hd([mk j] RL !LA_Data.lessD)))
-        | mk(NotLeD(j)) = ((*writeln"NLe";prth*)(mk j RS LA_Logic.not_leD))
-        | mk(NotLeDD(j)) = ((*writeln"NLeD";prth*)(hd([mk j RS LA_Logic.not_leD] RL !LA_Data.lessD)))
-        | mk(NotLessD(j)) = ((*writeln"NL";prth*)(mk j RS LA_Logic.not_lessD))
-        | mk(Added(j1,j2)) = ((*writeln"+";prth*)(simp((*prth*)(addthms (mk j1) (mk j2)))))
-        | mk(Multiplied(n,j)) = ((*writeln"*";*)multn(n,mk j))
+      fun mk(Asm i) = ((*?writeln"Asm";prth!*)(nth_elem(i,asms)))
+        | mk(Nat(i)) = ((*?writeln"Nat";!*)LA_Logic.mk_nat_thm sg (nth_elem(i,atoms)))
+        | mk(LessD(j)) = ((*?writeln"L";prth!*)(hd([mk j] RL !LA_Data.lessD)))
+        | mk(NotLeD(j)) = ((*?writeln"NLe";prth!*)(mk j RS LA_Logic.not_leD))
+        | mk(NotLeDD(j)) = ((*?writeln"NLeD";prth!*)(hd([mk j RS LA_Logic.not_leD] RL !LA_Data.lessD)))
+        | mk(NotLessD(j)) = ((*?writeln"NL";prth!*)(mk j RS LA_Logic.not_lessD))
+        | mk(Added(j1,j2)) = ((*?writeln"+";prth!*)(simp((*?prth!*)(addthms (mk j1) (mk j2)))))
+        | mk(Multiplied(n,j)) = ((*?writeln"*";!*)multn(n,mk j))
 
-  in (*writeln"mkthm";*)!LA_Data.simp(mk just) handle FalseE thm => thm end
+  in (*?writeln"mkthm";!*)
+     simplify (!LA_Data.ss_ref) (mk just) handle FalseE thm => thm end
 end;
 
 fun coeff poly atom = case assoc(poly,atom) of None => 0 | Some i => i;