author  wenzelm 
Mon, 16 Nov 1998 13:54:35 +0100  
changeset 5897  b3548f939dd2 
parent 5728  1d1175ef2d56 
child 6391  0da748358eff 
permissions  rwrr 
5589  1 
(* Title: Provers/Arith/abel_cancel.ML 
2 
ID: $Id$ 

3 
Author: Lawrence C Paulson, Cambridge University Computer Laboratory 

4 
Copyright 1998 University of Cambridge 

5 

6 
Simplification procedures for abelian groups (e.g. integers, reals) 

7 

8 
 Cancel complementary terms in sums 

9 
 Cancel like terms on opposite sides of relations 

10 
*) 

11 

12 

13 
signature ABEL_CANCEL = 

14 
sig 

5610  15 
val ss : simpset (*basic simpset of objectlogtic*) 
16 
val eq_reflection : thm (*objectequality to metaequality*) 

5589  17 

5610  18 
val thy : theory (*the theory of the group*) 
19 
val T : typ (*the type of group elements*) 

5589  20 

5610  21 
val zero : term 
5589  22 
val add_cancel_21 : thm 
23 
val add_cancel_end : thm 

24 
val add_left_cancel : thm 

5610  25 
val add_assoc : thm 
26 
val add_commute : thm 

27 
val add_left_commute : thm 

28 
val add_0 : thm 

29 
val add_0_right : thm 

5589  30 

31 
val eq_diff_eq : thm 

32 
val eqI_rules : thm list 

33 
val dest_eqI : thm > term 

34 

35 
val diff_def : thm 

36 
val minus_add_distrib : thm 

37 
val minus_minus : thm 

38 
val minus_0 : thm 

39 

40 
val add_inverses : thm list 

41 
val cancel_simps : thm list 

42 
end; 

43 

44 

45 
functor Abel_Cancel (Data: ABEL_CANCEL) = 

46 
struct 

47 

5728
1d1175ef2d56
eliminated 'let ... in structure ...' to make SML/NJ 0.93 happy;
wenzelm
parents:
5610
diff
changeset

48 
open Data; 
1d1175ef2d56
eliminated 'let ... in structure ...' to make SML/NJ 0.93 happy;
wenzelm
parents:
5610
diff
changeset

49 

5589  50 
val prepare_ss = Data.ss addsimps [add_assoc, diff_def, 
51 
minus_add_distrib, minus_minus, 

52 
minus_0, add_0, add_0_right]; 

53 

54 
(*prove while suppressing timing information*) 

55 
fun prove ct = setmp Goals.proof_timing false (prove_goalw_cterm [] ct); 

56 

57 
val plus = Const ("op +", [Data.T,Data.T] > Data.T); 

58 
val minus = Const ("uminus", Data.T > Data.T); 

59 

60 
(*Cancel corresponding terms on the two sides of the equation, NOT on 

61 
the same side!*) 

62 
val cancel_ss = 

63 
Data.ss addsimps [add_cancel_21, add_cancel_end, minus_minus] @ 

64 
Data.cancel_simps; 

65 

66 
val inverse_ss = Data.ss addsimps Data.add_inverses; 

67 

68 
fun mk_sum [] = Data.zero 

69 
 mk_sum tms = foldr1 (fn (x,y) => plus $ x $ y) tms; 

70 

71 
(*We map t to t and (in other cases) t to t. No need to check the type of 

72 
uminus, since the simproc is only called on sums of type T.*) 

73 
fun negate (Const("uminus",_) $ t) = t 

74 
 negate t = minus $ t; 

75 

76 
(*Flatten a formula built from +, binary  and unary . 

77 
No need to check types PROVIDED they are checked upon entry!*) 

78 
fun add_terms neg (Const ("op +", _) $ x $ y, ts) = 

79 
add_terms neg (x, add_terms neg (y, ts)) 

80 
 add_terms neg (Const ("op ", _) $ x $ y, ts) = 

81 
add_terms neg (x, add_terms (not neg) (y, ts)) 

82 
 add_terms neg (Const ("uminus", _) $ x, ts) = 

83 
add_terms (not neg) (x, ts) 

84 
 add_terms neg (x, ts) = 

85 
(if neg then negate x else x) :: ts; 

86 

87 
fun terms fml = add_terms false (fml, []); 

88 

89 
exception Cancel; 

90 

91 
(*Cancels just the first occurrence of u, leaving the rest unchanged*) 

92 
fun cancelled (u, t::ts) = if u aconv t then ts else t :: cancelled(u,ts) 

93 
 cancelled _ = raise Cancel; 

94 

95 

96 
val trace = ref false; 

97 

98 
(*Make a simproc to cancel complementary terms in sums. Examples: 

99 
xx = 0 x+(yx) = y x+(y+(x+z)) = y+z 

100 
It will unfold the definition of diff and associate to the right if 

101 
necessary. Rewriting is faster if the formula is already 

102 
in that form. 

103 
*) 

104 

105 
fun sum_proc sg _ lhs = 

106 
let val _ = if !trace then writeln ("cancel_sums: LHS = " ^ 

107 
string_of_cterm (cterm_of sg lhs)) 

108 
else () 

109 
val (head::tail) = terms lhs 

110 
val head' = negate head 

111 
val rhs = mk_sum (cancelled (head',tail)) 

112 
and chead' = Thm.cterm_of sg head' 

113 
val _ = if !trace then 

114 
writeln ("RHS = " ^ string_of_cterm (Thm.cterm_of sg rhs)) 

115 
else () 

5610  116 
val ct = Thm.cterm_of sg (Logic.mk_equals (lhs, rhs)) 
5589  117 
val thm = prove ct 
5610  118 
(fn _ => [rtac eq_reflection 1, 
119 
simp_tac prepare_ss 1, 

5589  120 
IF_UNSOLVED (simp_tac cancel_ss 1), 
121 
IF_UNSOLVED (simp_tac inverse_ss 1)]) 

122 
handle ERROR => 

123 
error("cancel_sums simproc:\nfailed to prove " ^ 

124 
string_of_cterm ct) 

5610  125 
in Some thm end 
5589  126 
handle Cancel => None; 
127 

128 

129 
val sum_conv = 

130 
Simplifier.mk_simproc "cancel_sums" 

131 
(map (Thm.read_cterm (sign_of Data.thy)) 

132 
[("x + y", Data.T), ("x  y", Data.T)]) 

133 
sum_proc; 

134 

135 

136 
(*A simproc to cancel like terms on the opposite sides of relations: 

137 
(x + y  z < z + x) = (y < 0) 

138 
Works for (=) and (<=) as well as (<), if the necessary rules are supplied. 

139 
Reduces the problem to subtraction and calls the previous simproc. 

140 
*) 

141 

142 
(*Cancel the FIRST occurrence of a term. If it's repeated, then repeated 

143 
calls to the simproc will be needed.*) 

144 
fun cancel1 ([], u) = raise Match (*impossible: it's a common term*) 

145 
 cancel1 (t::ts, u) = if t aconv u then ts 

146 
else t :: cancel1 (ts,u); 

147 

148 

149 
val sum_cancel_ss = Data.ss addsimprocs [sum_conv] 

150 
addsimps [add_0, add_0_right]; 

151 

152 
val add_ac_ss = Data.ss addsimps [add_assoc,add_commute,add_left_commute]; 

153 

154 
fun rel_proc sg _ (lhs as (rel$lt$rt)) = 

155 
let val _ = if !trace then writeln ("cancel_relations: LHS = " ^ 

156 
string_of_cterm (cterm_of sg lhs)) 

157 
else () 

158 
val ltms = terms lt 

159 
and rtms = terms rt 

160 
val common = (*inter_term miscounts repetitions, so squash them*) 

161 
gen_distinct (op aconv) (inter_term (ltms, rtms)) 

162 
val _ = if null common then raise Cancel (*nothing to do*) 

163 
else () 

164 

165 
fun cancelled tms = mk_sum (foldl cancel1 (tms, common)) 

166 

167 
val lt' = cancelled ltms 

168 
and rt' = cancelled rtms 

169 

170 
val rhs = rel$lt'$rt' 

171 
val _ = if !trace then 

172 
writeln ("RHS = " ^ string_of_cterm (Thm.cterm_of sg rhs)) 

173 
else () 

5610  174 
val ct = Thm.cterm_of sg (Logic.mk_equals (lhs,rhs)) 
5589  175 

176 
val thm = prove ct 

5610  177 
(fn _ => [rtac eq_reflection 1, 
178 
resolve_tac eqI_rules 1, 

5589  179 
simp_tac prepare_ss 1, 
180 
simp_tac sum_cancel_ss 1, 

181 
IF_UNSOLVED (simp_tac add_ac_ss 1)]) 

182 
handle ERROR => 

183 
error("cancel_relations simproc:\nfailed to prove " ^ 

184 
string_of_cterm ct) 

5610  185 
in Some thm end 
5589  186 
handle Cancel => None; 
187 

188 
val rel_conv = 

189 
Simplifier.mk_simproc "cancel_relations" 

190 
(map (Thm.cterm_of (sign_of Data.thy) o Data.dest_eqI) eqI_rules) 

191 
rel_proc; 

192 

193 
end; 