src/Provers/Arith/combine_coeff.ML
author paulson
Fri, 23 Jul 1999 17:24:48 +0200
changeset 7072 c3f3fd86e11c
permissions -rw-r--r--
new simprocs assoc_fold and combine_coeff
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7072
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
     1
(*  Title:      Provers/Arith/combine_coeff.ML
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
     2
    ID:         $Id$
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
     3
    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
     4
    Copyright   1999  University of Cambridge
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
     5
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
     6
Simplification procedure to combine literal coefficients in sums of products
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
     7
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
     8
Example, #3*x + y - (x*#2) goes to x + y
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
     9
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    10
For the relations <, <= and =, the difference is simplified
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    11
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    12
[COULD BE GENERALIZED to products of exponentials?]
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    13
*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    14
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    15
signature COMBINE_COEFF_DATA =
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    16
sig
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    17
  val ss		: simpset	(*basic simpset of object-logtic*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    18
  val eq_reflection	: thm		(*object-equality to meta-equality*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    19
  val thy		: theory	(*the theory of the group*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    20
  val T			: typ		(*the type of group elements*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    21
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    22
  val trans             : thm           (*transitivity of equals*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    23
  val add_ac		: thm list      (*AC-rules for the addition operator*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    24
  val diff_def		: thm		(*Defines x-y as x + -y *)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    25
  val minus_add_distrib	: thm           (* -(x+y) = -x + -y *)        
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    26
  val minus_minus	: thm           (* - -x = x *)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    27
  val mult_commute 	: thm		(*commutative law for the product*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    28
  val mult_1_right 	: thm           (*the law x*1=x *)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    29
  val add_mult_distrib  : thm           (*law w*(x+y) = w*x + w*y *)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    30
  val diff_mult_distrib : thm           (*law w*(x-y) = w*x - w*y *)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    31
  val mult_minus_right  : thm           (*law x * -y = -(x*y) *)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    32
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    33
  val rel_iff_rel_0_rls : thm list      (*e.g. (x < y) = (x-y < 0) *)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    34
  val dest_eqI		: thm -> term   (*to get patterns from the rel rules*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    35
end;
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    36
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    37
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    38
functor Combine_Coeff (Data: COMBINE_COEFF_DATA) =
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    39
struct
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    40
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    41
 local open Data 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    42
 in
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    43
 val rhs_ss = ss addsimps
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    44
                    [add_mult_distrib, diff_mult_distrib,
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    45
		     mult_minus_right, mult_1_right];
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    46
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    47
 val lhs_ss = ss addsimps
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    48
		 add_ac @
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    49
		 [diff_def, minus_add_distrib, minus_minus, mult_commute];
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    50
 end;
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    51
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    52
 (*prove while suppressing timing information*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    53
 fun prove name ct tacf = 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    54
     setmp Goals.proof_timing false (prove_goalw_cterm [] ct) tacf
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    55
     handle ERROR =>
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    56
	 error(name ^ " simproc:\nfailed to prove " ^ string_of_cterm ct);
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    57
                
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    58
 val plus = Const ("op +", [Data.T,Data.T] ---> Data.T);
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    59
 val minus = Const ("op -", [Data.T,Data.T] ---> Data.T);
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    60
 val uminus = Const ("uminus", Data.T --> Data.T);
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    61
 val times = Const ("op *", [Data.T,Data.T] ---> Data.T);
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    62
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    63
 val number_of = Const ("Numeral.number_of", 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    64
			Type ("Numeral.bin", []) --> Data.T);
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    65
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    66
 val zero = number_of $ HOLogic.pls_const;
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    67
 val one =  number_of $ (HOLogic.bit_const $ 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    68
			 HOLogic.pls_const $ 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    69
			 HOLogic.true_const);
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    70
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    71
 (*We map -t to t and (in other cases) t to -t.  No need to check the type of
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    72
   uminus, since the simproc is only called on sums of type T.*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    73
 fun negate (Const("uminus",_) $ t) = t
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    74
   | negate t                       = uminus $ t;
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    75
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    76
 fun mk_sum []  = zero
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    77
   | mk_sum tms = foldr1 (fn (x,y) => plus $ x $ y) tms;
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    78
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    79
 fun attach_coeff (Bound ~1,ns) = mk_sum ns  (*just a literal*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    80
   | attach_coeff (x,ns) = times $ x $ (mk_sum ns);
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    81
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    82
 fun add_atom (x, (neg,m)) pairs = 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    83
   let val m' = if neg then negate m else m
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    84
   in 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    85
       case gen_assoc (op aconv) (pairs, x) of
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    86
	   Some n => gen_overwrite (op aconv) (pairs, (x, m'::n))
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    87
	 | None => (x,[m']) :: pairs
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    88
   end;
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    89
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    90
 (**STILL MISSING: a treatment of nested coeffs, e.g. a*(b*3) **)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    91
 (*Convert a formula built from +, * and - (binary and unary) to a
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    92
   (atom, coeff) association list.  Handles t+t, t-t, -t, a*n, n*a, n, a
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    93
   where n denotes a numeric literal and a is any other term.
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    94
   No need to check types PROVIDED they are checked upon entry!*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    95
 fun add_terms neg (Const("op +", _) $ x $ y, pairs) =
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    96
	 add_terms neg (x, add_terms neg (y, pairs))
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    97
   | add_terms neg (Const("op -", _) $ x $ y, pairs) =
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    98
	 add_terms neg (x, add_terms (not neg) (y, pairs))
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
    99
   | add_terms neg (Const("uminus", _) $ x, pairs) = 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   100
	 add_terms (not neg) (x, pairs)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   101
   | add_terms neg (lit as Const("Numeral.number_of", _) $ _, pairs) =
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   102
	 (*literal: make it the coefficient of a dummy term*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   103
	 add_atom (Bound ~1, (neg, lit)) pairs
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   104
   | add_terms neg (Const("op *", _) $ x 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   105
		             $ (lit as Const("Numeral.number_of", _) $ _),
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   106
		    pairs) =
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   107
	 (*coefficient on the right*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   108
	 add_atom (x, (neg, lit)) pairs
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   109
   | add_terms neg (Const("op *", _) 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   110
		             $ (lit as Const("Numeral.number_of", _) $ _)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   111
                             $ x, pairs) =
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   112
	 (*coefficient on the left*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   113
	 add_atom (x, (neg, lit)) pairs
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   114
   | add_terms neg (x, pairs) = add_atom (x, (neg, one)) pairs;
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   115
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   116
 fun terms fml = add_terms false (fml, []);
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   117
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   118
 exception CC_fail;
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   119
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   120
 (*The number of terms in t, assuming no collapsing takes place*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   121
 fun term_count (Const("op +", _) $ x $ y) = term_count x + term_count y
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   122
   | term_count (Const("op -", _) $ x $ y) = term_count x + term_count y
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   123
   | term_count (Const("uminus", _) $ x) = term_count x
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   124
   | term_count x = 1;
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   125
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   126
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   127
 val trace = ref false;
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   128
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   129
 (*The simproc for sums*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   130
 fun sum_proc sg _ lhs =
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   131
   let fun show t = string_of_cterm (Thm.cterm_of sg t)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   132
       val _ = if !trace then writeln 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   133
	                   ("combine_coeff sum simproc: LHS = " ^ show lhs)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   134
	       else ()
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   135
       val ts = terms lhs
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   136
       val _ = if term_count lhs = length ts 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   137
               then raise CC_fail (*we can't reduce the number of terms*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   138
               else ()  
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   139
       val rhs = mk_sum (map attach_coeff ts)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   140
       val _ = if !trace then writeln ("RHS = " ^ show rhs) else ()
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   141
       val th = prove "combine_coeff" 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   142
	           (Thm.cterm_of sg (Logic.mk_equals (lhs, rhs)))
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   143
		   (fn _ => [rtac Data.eq_reflection 1,
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   144
			     simp_tac rhs_ss 1,
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   145
			     IF_UNSOLVED (simp_tac lhs_ss 1)])
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   146
   in Some th end
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   147
   handle CC_fail => None;
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   148
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   149
 val sum_conv = 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   150
     Simplifier.mk_simproc "combine_coeff_sums"
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   151
       (map (Thm.read_cterm (Theory.sign_of Data.thy)) 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   152
	[("x + y", Data.T), ("x - y", Data.T)])
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   153
       sum_proc;
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   154
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   155
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   156
 (*The simproc for relations, which just replaces x<y by x-y<0 and simplifies*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   157
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   158
 val trans_eq_reflection = Data.trans RS Data.eq_reflection |> standard;
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   159
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   160
 fun rel_proc sg asms (lhs as (rel$lt$rt)) =
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   161
   let val _ = if !trace then writeln
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   162
                               ("cc_rel simproc: LHS = " ^ 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   163
				string_of_cterm (cterm_of sg lhs))
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   164
	       else ()
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   165
       val _ = if lt=zero orelse rt=zero then raise CC_fail 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   166
               else ()   (*this simproc can do nothing if either side is zero*)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   167
       val cc_th = the (sum_proc sg asms (minus $ lt $ rt))
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   168
                   handle OPTION => raise CC_fail
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   169
       val _ = if !trace then 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   170
		 writeln ("cc_th = " ^ string_of_thm cc_th)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   171
	       else ()
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   172
       val cc_lr = #2 (Logic.dest_equals (concl_of cc_th))
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   173
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   174
       val rhs = rel $ cc_lr $ zero
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   175
       val _ = if !trace then 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   176
		 writeln ("RHS = " ^ string_of_cterm (Thm.cterm_of sg rhs))
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   177
	       else ()
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   178
       val ct = Thm.cterm_of sg (Logic.mk_equals (lhs,rhs))
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   179
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   180
       val th = prove "cc_rel" ct 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   181
                  (fn _ => [rtac trans_eq_reflection 1,
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   182
			    resolve_tac Data.rel_iff_rel_0_rls 1,
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   183
			    simp_tac (Data.ss addsimps [cc_th]) 1])
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   184
   in Some th end
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   185
   handle CC_fail => None;
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   186
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   187
 val rel_conv = 
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   188
     Simplifier.mk_simproc "cc_relations"
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   189
       (map (Thm.cterm_of (Theory.sign_of Data.thy) o Data.dest_eqI)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   190
            Data.rel_iff_rel_0_rls)
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   191
       rel_proc;
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   192
c3f3fd86e11c new simprocs assoc_fold and combine_coeff
paulson
parents:
diff changeset
   193
end;