154 (* FIXME: Shouldn't we simplify nested quotients, e.g. '(s/t)/u' could |
154 (* FIXME: Shouldn't we simplify nested quotients, e.g. '(s/t)/u' could |
155 become 's/(t*u)', and '(s*t)/u' could become 's*(t/u)' ? Note that |
155 become 's/(t*u)', and '(s*t)/u' could become 's*(t/u)' ? Note that |
156 if we choose to do so here, the simpset used by arith must be able to |
156 if we choose to do so here, the simpset used by arith must be able to |
157 perform the same simplifications. *) |
157 perform the same simplifications. *) |
158 (* quotient 's / t', where the denominator t can be NONE *) |
158 (* quotient 's / t', where the denominator t can be NONE *) |
159 (* Note: will raise Rat.DIVZERO iff m' is Rat.zero *) |
159 (* Note: will raise Rat.DIVZERO iff m' is @0 *) |
160 if of_field_sort thy (domain_type T) then |
160 if of_field_sort thy (domain_type T) then |
161 let |
161 let |
162 val (os',m') = demult (s, m); |
162 val (os',m') = demult (s, m); |
163 val (ot',p) = demult (t, Rat.one) |
163 val (ot',p) = demult (t, @1) |
164 in (case (os',ot') of |
164 in (case (os',ot') of |
165 (SOME s', SOME t') => SOME (mC $ s' $ t') |
165 (SOME s', SOME t') => SOME (mC $ s' $ t') |
166 | (SOME s', NONE) => SOME s' |
166 | (SOME s', NONE) => SOME s' |
167 | (NONE, SOME t') => |
167 | (NONE, SOME t') => |
168 SOME (mC $ Const (@{const_name Groups.one}, domain_type (snd (dest_Const mC))) $ t') |
168 SOME (mC $ Const (@{const_name Groups.one}, domain_type (snd (dest_Const mC))) $ t') |
170 Rat.mult m' (Rat.inv p)) |
170 Rat.mult m' (Rat.inv p)) |
171 end |
171 end |
172 else (SOME atom, m) |
172 else (SOME atom, m) |
173 (* terms that evaluate to numeric constants *) |
173 (* terms that evaluate to numeric constants *) |
174 | demult (Const (@{const_name Groups.uminus}, _) $ t, m) = demult (t, Rat.neg m) |
174 | demult (Const (@{const_name Groups.uminus}, _) $ t, m) = demult (t, Rat.neg m) |
175 | demult (Const (@{const_name Groups.zero}, _), _) = (NONE, Rat.zero) |
175 | demult (Const (@{const_name Groups.zero}, _), _) = (NONE, @0) |
176 | demult (Const (@{const_name Groups.one}, _), m) = (NONE, m) |
176 | demult (Const (@{const_name Groups.one}, _), m) = (NONE, m) |
177 (*Warning: in rare cases (neg_)numeral encloses a non-numeral, |
177 (*Warning: in rare cases (neg_)numeral encloses a non-numeral, |
178 in which case dest_numeral raises TERM; hence all the handles below. |
178 in which case dest_numeral raises TERM; hence all the handles below. |
179 Same for Suc-terms that turn out not to be numerals - |
179 Same for Suc-terms that turn out not to be numerals - |
180 although the simplifier should eliminate those anyway ...*) |
180 although the simplifier should eliminate those anyway ...*) |
225 else add_atom all m pi |
225 else add_atom all m pi |
226 | poly (all as Const f $ x, m, pi) = |
226 | poly (all as Const f $ x, m, pi) = |
227 if member (op =) inj_consts f then poly (x, m, pi) else add_atom all m pi |
227 if member (op =) inj_consts f then poly (x, m, pi) else add_atom all m pi |
228 | poly (all, m, pi) = |
228 | poly (all, m, pi) = |
229 add_atom all m pi |
229 add_atom all m pi |
230 val (p, i) = poly (lhs, Rat.one, ([], Rat.zero)) |
230 val (p, i) = poly (lhs, @1, ([], @0)) |
231 val (q, j) = poly (rhs, Rat.one, ([], Rat.zero)) |
231 val (q, j) = poly (rhs, @1, ([], @0)) |
232 in |
232 in |
233 case rel of |
233 case rel of |
234 @{const_name Orderings.less} => SOME (p, i, "<", q, j) |
234 @{const_name Orderings.less} => SOME (p, i, "<", q, j) |
235 | @{const_name Orderings.less_eq} => SOME (p, i, "<=", q, j) |
235 | @{const_name Orderings.less_eq} => SOME (p, i, "<=", q, j) |
236 | @{const_name HOL.eq} => SOME (p, i, "=", q, j) |
236 | @{const_name HOL.eq} => SOME (p, i, "=", q, j) |