mathlib documentation

tactic.norm_num

norm_num

Evaluating arithmetic expressions including *, +, -, ^, ≤

meta def tactic.refl_conv (e : expr) :

Reflexivity conversion: given e returns (e, ⊢ e = e)

meta def tactic.trans_conv (t₁ t₂ : exprtactic (expr × expr)) (e : expr) :

Transitivity conversion: given two conversions (which take an expression e and returns (e', ⊢ e = e')), produces another conversion that combines them with transitivity, treating failures as reflexivity conversions.

Faster version of mk_app ``bit0 [e].

Faster version of mk_app ``bit1 [e].

theorem norm_num.subst_into_add {α : Type u_1} [has_add α] (l r tl tr t : α) (prl : l = tl) (prr : r = tr) (prt : tl + tr = t) :
l + r = t

theorem norm_num.subst_into_mul {α : Type u_1} [has_mul α] (l r tl tr t : α) (prl : l = tl) (prr : r = tr) (prt : tl * tr = t) :
l * r = t

theorem norm_num.subst_into_neg {α : Type u_1} [has_neg α] (a ta t : α) (pra : a = ta) (prt : -ta = t) :
-a = t

meta inductive norm_num.match_numeral_result  :
Type

The result type of match_numeral, either 0, 1, or a top level decomposition of bit0 e or bit1 e. The other case means it is not a numeral.

Unfold the top level constructor of the numeral expression.

theorem norm_num.zero_succ {α : Type u_1} [semiring α] :
0 + 1 = 1

theorem norm_num.one_succ {α : Type u_1} [semiring α] :
1 + 1 = 2

theorem norm_num.bit0_succ {α : Type u_1} [semiring α] (a : α) :
bit0 a + 1 = bit1 a

theorem norm_num.bit1_succ {α : Type u_1} [semiring α] (a b : α) (h : a + 1 = b) :
bit1 a + 1 = bit0 b

Given a, b natural numerals, proves ⊢ a + 1 = b, assuming that this is provable. (It may prove garbage instead of failing if a + 1 = b is false.)

theorem norm_num.zero_adc {α : Type u_1} [semiring α] (a b : α) (h : a + 1 = b) :
0 + a + 1 = b

theorem norm_num.adc_zero {α : Type u_1} [semiring α] (a b : α) (h : a + 1 = b) :
a + 0 + 1 = b

theorem norm_num.one_add {α : Type u_1} [semiring α] (a b : α) (h : a + 1 = b) :
1 + a = b

theorem norm_num.add_bit0_bit0 {α : Type u_1} [semiring α] (a b c : α) (h : a + b = c) :
bit0 a + bit0 b = bit0 c

theorem norm_num.add_bit0_bit1 {α : Type u_1} [semiring α] (a b c : α) (h : a + b = c) :
bit0 a + bit1 b = bit1 c

theorem norm_num.add_bit1_bit0 {α : Type u_1} [semiring α] (a b c : α) (h : a + b = c) :
bit1 a + bit0 b = bit1 c

theorem norm_num.add_bit1_bit1 {α : Type u_1} [semiring α] (a b c : α) (h : a + b + 1 = c) :
bit1 a + bit1 b = bit0 c

theorem norm_num.adc_one_one {α : Type u_1} [semiring α] :
1 + 1 + 1 = 3

theorem norm_num.adc_bit0_one {α : Type u_1} [semiring α] (a b : α) (h : a + 1 = b) :
bit0 a + 1 + 1 = bit0 b

theorem norm_num.adc_one_bit0 {α : Type u_1} [semiring α] (a b : α) (h : a + 1 = b) :
1 + bit0 a + 1 = bit0 b

theorem norm_num.adc_bit1_one {α : Type u_1} [semiring α] (a b : α) (h : a + 1 = b) :
bit1 a + 1 + 1 = bit1 b

theorem norm_num.adc_one_bit1 {α : Type u_1} [semiring α] (a b : α) (h : a + 1 = b) :
1 + bit1 a + 1 = bit1 b

theorem norm_num.adc_bit0_bit0 {α : Type u_1} [semiring α] (a b c : α) (h : a + b = c) :
bit0 a + bit0 b + 1 = bit1 c

theorem norm_num.adc_bit1_bit0 {α : Type u_1} [semiring α] (a b c : α) (h : a + b + 1 = c) :
bit1 a + bit0 b + 1 = bit0 c

theorem norm_num.adc_bit0_bit1 {α : Type u_1} [semiring α] (a b c : α) (h : a + b + 1 = c) :
bit0 a + bit1 b + 1 = bit0 c

theorem norm_num.adc_bit1_bit1 {α : Type u_1} [semiring α] (a b c : α) (h : a + b + 1 = c) :
bit1 a + bit1 b + 1 = bit1 c

Given a,b natural numerals, returns (r, ⊢ a + b = r).

theorem norm_num.bit0_mul {α : Type u_1} [semiring α] (a b c : α) (h : a * b = c) :
(bit0 a) * b = bit0 c

theorem norm_num.mul_bit0' {α : Type u_1} [semiring α] (a b c : α) (h : a * b = c) :
a * bit0 b = bit0 c

theorem norm_num.mul_bit0_bit0 {α : Type u_1} [semiring α] (a b c : α) (h : a * b = c) :
(bit0 a) * bit0 b = bit0 (bit0 c)

theorem norm_num.mul_bit1_bit1 {α : Type u_1} [semiring α] (a b c d e : α) (hc : a * b = c) (hd : a + b = d) (he : bit0 c + d = e) :
(bit1 a) * bit1 b = bit1 e

Given a,b natural numerals, returns (r, ⊢ a * b = r).

Given a a positive natural numeral, returns ⊢ 0 < a.

Given a a rational numeral, returns ⊢ 0 < a.

meta def norm_num.match_neg (a : expr) :

match_neg (- e) = some e, otherwise none

meta def norm_num.match_sign (a : expr) :

match_sign (- e) = inl e, match_sign 0 = inr ff, otherwise inr tt

theorem norm_num.ne_zero_of_pos {α : Type u_1} [ordered_add_comm_group α] (a : α) (a_1 : 0 < a) :
a 0

theorem norm_num.ne_zero_neg {α : Type u_1} [add_group α] (a : α) (a_1 : a 0) :
-a 0

Given a a rational numeral, returns ⊢ a ≠ 0.

theorem norm_num.clear_denom_div {α : Type u_1} [division_ring α] (a b b' c d : α) (h₀ : b 0) (h₁ : b * b' = d) (h₂ : a * b' = c) :
(a / b) * d = c

Given a nonnegative rational and d a natural number, returns (b, ⊢ a * d = b). (d should be a multiple of the denominator of a, so that b is a natural number.)

theorem norm_num.clear_denom_add {α : Type u_1} [division_ring α] (a a' b b' c c' d : α) (h₀ : d 0) (ha : a * d = a') (hb : b * d = b') (hc : c * d = c') (h : a' + b' = c') :
a + b = c

Given a,b,c nonnegative rational numerals, returns ⊢ a + b = c.

theorem norm_num.add_pos_neg_pos {α : Type u_1} [add_group α] (a b c : α) (h : c + b = a) :
a + -b = c

theorem norm_num.add_pos_neg_neg {α : Type u_1} [add_group α] (a b c : α) (h : c + a = b) :
a + -b = -c

theorem norm_num.add_neg_pos_pos {α : Type u_1} [add_group α] (a b c : α) (h : a + c = b) :
-a + b = c

theorem norm_num.add_neg_pos_neg {α : Type u_1} [add_group α] (a b c : α) (h : b + c = a) :
-a + b = -c

theorem norm_num.add_neg_neg {α : Type u_1} [add_group α] (a b c : α) (h : b + a = c) :
-a + -b = -c

Given a,b,c rational numerals, returns ⊢ a + b = c.

Given a,b rational numerals, returns (c, ⊢ a + b = c).

theorem norm_num.clear_denom_simple_nat {α : Type u_1} [division_ring α] (a : α) :
1 0 a * 1 = a

theorem norm_num.clear_denom_simple_div {α : Type u_1} [division_ring α] (a b : α) (h : b 0) :
b 0 (a / b) * b = a

Given a a nonnegative rational numeral, returns (b, c, ⊢ a * b = c) where b and c are natural numerals. (b will be the denominator of a.)

theorem norm_num.clear_denom_mul {α : Type u_1} [field α] (a a' b b' c c' d₁ d₂ d : α) (ha : d₁ 0 a * d₁ = a') (hb : d₂ 0 b * d₂ = b') (hc : c * d = c') (hd : d₁ * d₂ = d) (h : a' * b' = c') :
a * b = c

Given a,b nonnegative rational numerals, returns (c, ⊢ a * b = c).

theorem norm_num.mul_neg_pos {α : Type u_1} [ring α] (a b c : α) (h : a * b = c) :
(-a) * b = -c

theorem norm_num.mul_pos_neg {α : Type u_1} [ring α] (a b c : α) (h : a * b = c) :
a * -b = -c

theorem norm_num.mul_neg_neg {α : Type u_1} [ring α] (a b c : α) (h : a * b = c) :
(-a) * -b = c

Given a,b rational numerals, returns (c, ⊢ a * b = c).

theorem norm_num.inv_neg {α : Type u_1} [division_ring α] (a b : α) (h : a⁻¹ = b) :
(-a)⁻¹ = -b

theorem norm_num.inv_one {α : Type u_1} [division_ring α] :
1⁻¹ = 1

theorem norm_num.inv_one_div {α : Type u_1} [division_ring α] (a : α) :
(1 / a)⁻¹ = a

theorem norm_num.inv_div_one {α : Type u_1} [division_ring α] (a : α) :
a⁻¹ = 1 / a

theorem norm_num.inv_div {α : Type u_1} [division_ring α] (a b : α) :
(a / b)⁻¹ = b / a

Given a a rational numeral, returns (b, ⊢ a⁻¹ = b).

theorem norm_num.div_eq {α : Type u_1} [division_ring α] (a b b' c : α) (hb : b⁻¹ = b') (h : a * b' = c) :
a / b = c

Given a,b rational numerals, returns (c, ⊢ a / b = c).

Given a a rational numeral, returns (b, ⊢ -a = b).

theorem norm_num.sub_pos {α : Type u_1} [add_group α] (a b b' c : α) (hb : -b = b') (h : a + b' = c) :
a - b = c

theorem norm_num.sub_neg {α : Type u_1} [add_group α] (a b c : α) (h : a + b = c) :
a - -b = c

Given a,b rational numerals, returns (c, ⊢ a - b = c).

theorem norm_num.sub_nat_pos (a b c : ) (h : b + c = a) :
a - b = c

theorem norm_num.sub_nat_neg (a b c : ) (h : a + c = b) :
a - b = 0

Given a : nat,b : nat natural numerals, returns (c, ⊢ a - b = c).

theorem norm_num.int_sub_hack (a b c : ) (h : a - b = c) :
a - b = c

This is needed because when a and b are numerals lean is more likely to unfold them than unfold the instances in order to prove that add_group_has_sub = int.has_sub.

Given a : ℤ, b : ℤ integral numerals, returns (c, ⊢ a - b = c).

meta def norm_num.eval_field (a : expr) :

Evaluates the basic field operations +,neg,-,*,inv,/ on numerals. Also handles nat subtraction. Does not do recursive simplification; that is, 1 + 1 + 1 will not simplify but 2 + 1 will. This is handled by the top level simp call in norm_num.derive.

theorem norm_num.pow_bit0 {α : Type u} [monoid α] (a c' c : α) (b : ) (h : a ^ b = c') (h₂ : c' * c' = c) :
a ^ bit0 b = c

theorem norm_num.pow_bit1 {α : Type u} [monoid α] (a c₁ c₂ c : α) (b : ) (h : a ^ b = c₁) (h₂ : c₁ * c₁ = c₂) (h₃ : c₂ * a = c) :
a ^ bit1 b = c

Given a a rational numeral and b : nat, returns (c, ⊢ a ^ b = c).

meta def norm_num.eval_pow (a : expr) :

Evaluates expressions of the form a ^ b, monoid.pow a b or nat.pow a b.

theorem norm_num.nonneg_pos {α : Type u_1} [ordered_cancel_add_comm_monoid α] (a : α) (a_1 : 0 < a) :
0 a

theorem norm_num.lt_one_bit0 {α : Type u_1} [linear_ordered_semiring α] (a : α) (h : 1 a) :
1 < bit0 a

theorem norm_num.lt_one_bit1 {α : Type u_1} [linear_ordered_semiring α] (a : α) (h : 0 < a) :
1 < bit1 a

theorem norm_num.lt_bit0_bit0 {α : Type u_1} [linear_ordered_semiring α] (a b : α) (a_1 : a < b) :
bit0 a < bit0 b

theorem norm_num.lt_bit0_bit1 {α : Type u_1} [linear_ordered_semiring α] (a b : α) (h : a b) :
bit0 a < bit1 b

theorem norm_num.lt_bit1_bit0 {α : Type u_1} [linear_ordered_semiring α] (a b : α) (h : a + 1 b) :
bit1 a < bit0 b

theorem norm_num.lt_bit1_bit1 {α : Type u_1} [linear_ordered_semiring α] (a b : α) (a_1 : a < b) :
bit1 a < bit1 b

theorem norm_num.le_one_bit0 {α : Type u_1} [linear_ordered_semiring α] (a : α) (h : 1 a) :
1 bit0 a

theorem norm_num.le_one_bit1 {α : Type u_1} [linear_ordered_semiring α] (a : α) (h : 0 < a) :
1 bit1 a

theorem norm_num.le_bit0_bit0 {α : Type u_1} [linear_ordered_semiring α] (a b : α) (a_1 : a b) :

theorem norm_num.le_bit0_bit1 {α : Type u_1} [linear_ordered_semiring α] (a b : α) (h : a b) :

theorem norm_num.le_bit1_bit0 {α : Type u_1} [linear_ordered_semiring α] (a b : α) (h : a + 1 b) :

theorem norm_num.le_bit1_bit1 {α : Type u_1} [linear_ordered_semiring α] (a b : α) (a_1 : a b) :

theorem norm_num.sle_one_bit0 {α : Type u_1} [linear_ordered_semiring α] (a : α) (a_1 : 1 a) :
1 + 1 bit0 a

theorem norm_num.sle_one_bit1 {α : Type u_1} [linear_ordered_semiring α] (a : α) (a_1 : 1 a) :
1 + 1 bit1 a

theorem norm_num.sle_bit0_bit0 {α : Type u_1} [linear_ordered_semiring α] (a b : α) (a_1 : a + 1 b) :
bit0 a + 1 bit0 b

theorem norm_num.sle_bit0_bit1 {α : Type u_1} [linear_ordered_semiring α] (a b : α) (h : a b) :
bit0 a + 1 bit1 b

theorem norm_num.sle_bit1_bit0 {α : Type u_1} [linear_ordered_semiring α] (a b : α) (h : a + 1 b) :
bit1 a + 1 bit0 b

theorem norm_num.sle_bit1_bit1 {α : Type u_1} [linear_ordered_semiring α] (a b : α) (h : a + 1 b) :
bit1 a + 1 bit1 b

Given a a rational numeral, returns ⊢ 0 ≤ a.

Given a a rational numeral, returns ⊢ 1 ≤ a.

Given a,b natural numerals, proves ⊢ a < b.

theorem norm_num.clear_denom_lt {α : Type u_1} [linear_ordered_semiring α] (a a' b b' d : α) (h₀ : 0 < d) (ha : a * d = a') (hb : b * d = b') (h : a' < b') :
a < b

Given a,b nonnegative rational numerals, proves ⊢ a < b.

theorem norm_num.lt_neg_pos {α : Type u_1} [ordered_add_comm_group α] (a b : α) (ha : 0 < a) (hb : 0 < b) :
-a < b

Given a,b rational numerals, proves ⊢ a < b.

theorem norm_num.clear_denom_le {α : Type u_1} [linear_ordered_semiring α] (a a' b b' d : α) (h₀ : 0 < d) (ha : a * d = a') (hb : b * d = b') (h : a' b') :
a b

Given a,b nonnegative rational numerals, proves ⊢ a ≤ b.

theorem norm_num.le_neg_pos {α : Type u_1} [ordered_add_comm_group α] (a b : α) (ha : 0 a) (hb : 0 b) :
-a b

Given a,b rational numerals, proves ⊢ a ≤ b.

Given a,b rational numerals, proves ⊢ a ≠ b. This version tries to prove ⊢ a < b or ⊢ b < a, and so is not appropriate for types without an order relation.

theorem norm_num.nat_cast_zero {α : Type u_1} [semiring α] :
0 = 0

theorem norm_num.nat_cast_one {α : Type u_1} [semiring α] :
1 = 1

theorem norm_num.nat_cast_bit0 {α : Type u_1} [semiring α] (a : ) (a' : α) (h : a = a') :
(bit0 a) = bit0 a'

theorem norm_num.nat_cast_bit1 {α : Type u_1} [semiring α] (a : ) (a' : α) (h : a = a') :
(bit1 a) = bit1 a'

theorem norm_num.int_cast_zero {α : Type u_1} [ring α] :
0 = 0

theorem norm_num.int_cast_one {α : Type u_1} [ring α] :
1 = 1

theorem norm_num.int_cast_bit0 {α : Type u_1} [ring α] (a : ) (a' : α) (h : a = a') :
(bit0 a) = bit0 a'

theorem norm_num.int_cast_bit1 {α : Type u_1} [ring α] (a : ) (a' : α) (h : a = a') :
(bit1 a) = bit1 a'

theorem norm_num.rat_cast_bit0 {α : Type u_1} [division_ring α] [char_zero α] (a : ) (a' : α) (h : a = a') :
(bit0 a) = bit0 a'

theorem norm_num.rat_cast_bit1 {α : Type u_1} [division_ring α] [char_zero α] (a : ) (a' : α) (h : a = a') :
(bit1 a) = bit1 a'

Given a' : α a natural numeral, returns (a : ℕ, ⊢ ↑a = a'). (Note that the returned value is on the left of the equality.)

Given a' : α a natural numeral, returns (a : ℤ, ⊢ ↑a = a'). (Note that the returned value is on the left of the equality.)

Given a' : α a natural numeral, returns (a : ℚ, ⊢ ↑a = a'). (Note that the returned value is on the left of the equality.)

theorem norm_num.rat_cast_div {α : Type u_1} [division_ring α] [char_zero α] (a b : ) (a' b' : α) (ha : a = a') (hb : b = b') :
(a / b) = a' / b'

Given a' : α a nonnegative rational numeral, returns (a : ℚ, ⊢ ↑a = a'). (Note that the returned value is on the left of the equality.)

theorem norm_num.int_cast_neg {α : Type u_1} [ring α] (a : ) (a' : α) (h : a = a') :
-a = -a'

theorem norm_num.rat_cast_neg {α : Type u_1} [division_ring α] (a : ) (a' : α) (h : a = a') :
-a = -a'

Given a' : α an integer numeral, returns (a : ℤ, ⊢ ↑a = a'). (Note that the returned value is on the left of the equality.)

Given a' : α a rational numeral, returns (a : ℚ, ⊢ ↑a = a'). (Note that the returned value is on the left of the equality.)

theorem norm_num.nat_cast_ne {α : Type u_1} [semiring α] [char_zero α] (a b : ) (a' b' : α) (ha : a = a') (hb : b = b') (h : a b) :
a' b'

theorem norm_num.int_cast_ne {α : Type u_1} [ring α] [char_zero α] (a b : ) (a' b' : α) (ha : a = a') (hb : b = b') (h : a b) :
a' b'

theorem norm_num.rat_cast_ne {α : Type u_1} [division_ring α] [char_zero α] (a b : ) (a' b' : α) (ha : a = a') (hb : b = b') (h : a b) :
a' b'

meta def norm_num.prove_ne (a : tactic.instance_cache) (a_1 a_2 : expr) (a_3 a_4 : ) :

Given a,b rational numerals, proves ⊢ a ≠ b. Currently it tries two methods:

  • Prove ⊢ a < b or ⊢ b < a, if the base type has an order
  • Embed ↑(a':ℚ) = a and ↑(b':ℚ) = b, and then prove a' ≠ b'. This requires that the base type be char_zero, and also that it be a division_ring so that the coercion from is well defined.

We may also add coercions to and as well in order to support char_zero rings and semirings.

meta def norm_num.true_intro (p : expr) :

Given ∣- p, returns (true, ⊢ p = true).

meta def norm_num.false_intro (p : expr) :

Given ∣- ¬ p, returns (false, ⊢ p = false).

theorem norm_num.not_refl_false_intro {α : Sort u_1} (a : α) :
a a = false

meta def norm_num.eval_ineq (a : expr) :

Evaluates the inequality operations =,<,>,,, on numerals.

theorem norm_num.nat_succ_eq (a b c : ) (h₁ : a = b) (h₂ : b + 1 = c) :
a.succ = c

Evaluates the expression nat.succ ... (nat.succ n) where n is a natural numeral. (We could also just handle nat.succ n here and rely on simp to work bottom up, but we figure that towers of successors coming from e.g. induction are a common case.)

theorem norm_num.nat_div (a b q r m : ) (hm : q * b = m) (h : r + m = a) (h₂ : r < b) :
a / b = q

theorem norm_num.int_div (a b q r m : ) (hm : q * b = m) (h : r + m = a) (h₁ : 0 r) (h₂ : r < b) :
a / b = q

theorem norm_num.nat_mod (a b q r m : ) (hm : q * b = m) (h : r + m = a) (h₂ : r < b) :
a % b = r

theorem norm_num.int_mod (a b q r m : ) (hm : q * b = m) (h : r + m = a) (h₁ : 0 r) (h₂ : r < b) :
a % b = r

theorem norm_num.int_div_neg (a b c' c : ) (h : a / b = c') (h₂ : -c' = c) :
a / -b = c

theorem norm_num.int_mod_neg (a b c : ) (h : a % b = c) :
a % -b = c

Given a,b numerals in nat or int,

  • prove_div_mod ic a b ff returns (c, ⊢ a / b = c)
  • prove_div_mod ic a b tt returns (c, ⊢ a % b = c)
theorem norm_num.dvd_eq_nat (a b c : ) (p : Prop) (h₁ : b % a = c) (h₂ : c = 0 = p) :
a b = p

theorem norm_num.dvd_eq_int (a b c : ) (p : Prop) (h₁ : b % a = c) (h₂ : c = 0 = p) :
a b = p

Evaluates some extra numeric operations on nat and int, specifically nat.succ, / and %, and (divisibility).

theorem norm_num.not_prime_helper (a b n : ) (h : a * b = n) (h₁ : 1 < a) (h₂ : 1 < b) :

theorem norm_num.is_prime_helper (n : ) (h₁ : 1 < n) (h₂ : n.min_fac = n) :

theorem norm_num.min_fac_bit0 (n : ) :
(bit0 n).min_fac = 2

def norm_num.min_fac_helper (n k : ) :
Prop

A predicate representing partial progress in a proof of min_fac.

Equations
theorem norm_num.min_fac_helper_1 {n k k' : } (e : k + 1 = k') (np : (bit1 n).min_fac bit1 k) (h : norm_num.min_fac_helper n k) :

theorem norm_num.min_fac_helper_2 (n k k' : ) (e : k + 1 = k') (np : ¬nat.prime (bit1 k)) (h : norm_num.min_fac_helper n k) :

theorem norm_num.min_fac_helper_3 (n k k' c : ) (e : k + 1 = k') (nc : bit1 n % bit1 k = c) (c0 : 0 < c) (h : norm_num.min_fac_helper n k) :

theorem norm_num.min_fac_helper_4 (n k : ) (hd : bit1 n % bit1 k = 0) (h : norm_num.min_fac_helper n k) :

theorem norm_num.min_fac_helper_5 (n k k' : ) (e : (bit1 k) * bit1 k = k') (hd : bit1 n < k') (h : norm_num.min_fac_helper n k) :

meta def norm_num.prove_non_prime (e : expr) (n d₁ : ) :

Given e a natural numeral and d : nat a factor of it, return ⊢ ¬ prime e.

Given a,a1 := bit1 a, n1 the value of a1, b and p : min_fac_helper a b, returns (c, ⊢ min_fac a1 = c).

Given a a natural numeral, returns (b, ⊢ min_fac a = b).

meta def norm_num.eval_prime (a : expr) :

Evaluates the prime and min_fac functions.

meta def norm_num.derive' (e : expr) :

This version of derive does not fail when the input is already a numeral

meta def norm_num.derive (a : expr) :

Basic version of norm_num that does not call simp.

Normalize numerical expressions. Supports the operations + - * / ^ and % over numerical types such as , , , , and some general algebraic types, and can prove goals of the form A = B, A ≠ B, A < B and A ≤ B, where A and B are numerical expressions. It also has a relatively simple primality prover.

Normalizes a numerical expression and tries to close the goal with the result.

Basic version of norm_num that does not call simp.

Normalize numerical expressions. Supports the operations + - * / ^ and % over numerical types such as , , , , and some general algebraic types, and can prove goals of the form A = B, A ≠ B, A < B and A ≤ B, where A and B are numerical expressions. It also has a relatively simple primality prover.