src/HOL/Tools/lin_arith.ML
changeset 63205 97b721666890
parent 63201 f151704c08e4
child 63210 a0685d2b420b
equal deleted inserted replaced
63204:921a5be54132 63205:97b721666890
   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)