12.2.4.3.Β Arithmetic
Typically, arithmetic operations on integers are accessed using Lean's overloaded arithmetic notation.
In particular, the instances of Add Int
, Neg Int
, Sub Int
, and Mul Int
allow ordinary infix operators to be used.
Division is somewhat more intricate, because there are multiple sensible notions of division on integers.
πdefInt.add (m n : Int) : Int
Addition of two integers.
13
#eval (7 : Int) + (6 : Int) -- 13
0
#eval (6 : Int) + (-6 : Int) -- 0
Implemented by efficient native code.
πdefInt.sub (m n : Int) : Int
Subtraction of two integers.
57
#eval (63 : Int) - (6 : Int) -- 57
7
#eval (7 : Int) - (0 : Int) -- 7
-7
#eval (0 : Int) - (7 : Int) -- -7
Implemented by efficient native code.
πdefInt.subNatNat (m n : Nat) : Int
Subtraction of two natural numbers.
πdefInt.neg (n : Int) : Int
Negation of an integer.
Implemented by efficient native code.
πdefInt.negOfNat : Nat β Int
Negation of a natural number.
πdefInt.mul (m n : Int) : Int
Multiplication of two integers.
378
#eval (63 : Int) * (6 : Int) -- 378
-36
#eval (6 : Int) * (-6 : Int) -- -36
0
#eval (7 : Int) * (0 : Int) -- 0
Implemented by efficient native code.
πdefInt.pow (m : Int) : Nat β Int
Power of an integer to some natural number.
16
#eval (2 : Int) ^ 4 -- 16
1
#eval (10 : Int) ^ 0 -- 1
0
#eval (0 : Int) ^ 10 -- 0
-343
#eval (-7 : Int) ^ 3 -- -343
πdefInt.gcd (m n : Int) : Nat
Computes the greatest common divisor of two integers, as a Nat
.
πdefInt.lcm (m n : Int) : Nat
Computes the least common multiple of two integers, as a Nat
.
12.2.4.3.1.Β Divisionπ
The Div Int
and Mod Int
instances implement Euclidean division, described in the reference for Int.ediv
.
This is not, however, the only sensible convention for rounding and remainders in division.
Four pairs of division and modulus functions are available, implementing various conventions.
Division by 0
In all integer division conventions, division by 0
is defined to be 0
:
0
#eval Int.ediv 5 0
0
#eval Int.ediv 0 0
0
#eval Int.ediv (-5) 0
0
#eval Int.bdiv 5 0
0
#eval Int.bdiv 0 0
0
#eval Int.bdiv (-5) 0
0
#eval Int.fdiv 5 0
0
#eval Int.fdiv 0 0
0
#eval Int.fdiv (-5) 0
0
#eval Int.tdiv 5 0
0
#eval Int.tdiv 0 0
0
#eval Int.tdiv (-5) 0
All evaluate to 0.
πdefInt.ediv : Int β Int β Int
Integer division. This version of Int.div
uses the E-rounding convention
(euclidean division), in which Int.emod x y
satisfies 0 β€ mod x y < natAbs y
for y β 0
and Int.ediv
is the unique function satisfying emod x y + (ediv x y) * y = x
.
This is the function powering the /
notation on integers.
Examples:
0
#eval (7 : Int) / (0 : Int) -- 0
0
#eval (0 : Int) / (7 : Int) -- 0
2
#eval (12 : Int) / (6 : Int) -- 2
-2
#eval (12 : Int) / (-6 : Int) -- -2
-2
#eval (-12 : Int) / (6 : Int) -- -2
2
#eval (-12 : Int) / (-6 : Int) -- 2
1
#eval (12 : Int) / (7 : Int) -- 1
-1
#eval (12 : Int) / (-7 : Int) -- -1
-2
#eval (-12 : Int) / (7 : Int) -- -2
2
#eval (-12 : Int) / (-7 : Int) -- 2
Implemented by efficient native code.
πdefInt.emod : Int β Int β Int
Integer modulus. This version of Int.mod
uses the E-rounding convention
(euclidean division), in which Int.emod x y
satisfies 0 β€ emod x y < natAbs y
for y β 0
and Int.ediv
is the unique function satisfying emod x y + (ediv x y) * y = x
.
This is the function powering the %
notation on integers.
Examples:
7
#eval (7 : Int) % (0 : Int) -- 7
0
#eval (0 : Int) % (7 : Int) -- 0
0
#eval (12 : Int) % (6 : Int) -- 0
0
#eval (12 : Int) % (-6 : Int) -- 0
0
#eval (-12 : Int) % (6 : Int) -- 0
0
#eval (-12 : Int) % (-6 : Int) -- 0
5
#eval (12 : Int) % (7 : Int) -- 5
5
#eval (12 : Int) % (-7 : Int) -- 5
2
#eval (-12 : Int) % (7 : Int) -- 2
2
#eval (-12 : Int) % (-7 : Int) -- 2
Implemented by efficient native code.
πdefInt.bmod (x : Int) (m : Nat) : Int
Balanced modulus. This version of Integer modulus uses the
balanced rounding convention, which guarantees that
m/2 β€ bmod x m < m/2
for m β 0
and bmod x m
is congruent
to x
modulo m
.
If m = 0
, then bmod x m = x
.
πdefInt.fdiv : Int β Int β Int
Integer division. This version of division uses the F-rounding convention
(flooring division), in which Int.fdiv x y
satisfies fdiv x y = floor (x / y)
and Int.fmod
is the unique function satisfying fmod x y + (fdiv x y) * y = x
.
Examples:
0
#eval (7 : Int).fdiv (0 : Int) -- 0
0
#eval (0 : Int).fdiv (7 : Int) -- 0
2
#eval (12 : Int).fdiv (6 : Int) -- 2
-2
#eval (12 : Int).fdiv (-6 : Int) -- -2
-2
#eval (-12 : Int).fdiv (6 : Int) -- -2
2
#eval (-12 : Int).fdiv (-6 : Int) -- 2
1
#eval (12 : Int).fdiv (7 : Int) -- 1
-2
#eval (12 : Int).fdiv (-7 : Int) -- -2
-2
#eval (-12 : Int).fdiv (7 : Int) -- -2
1
#eval (-12 : Int).fdiv (-7 : Int) -- 1
πdefInt.fmod : Int β Int β Int
Integer modulus. This version of Int.mod
uses the F-rounding convention
(flooring division), in which Int.fdiv x y
satisfies fdiv x y = floor (x / y)
and Int.fmod
is the unique function satisfying fmod x y + (fdiv x y) * y = x
.
Examples:
7
#eval (7 : Int).fmod (0 : Int) -- 7
0
#eval (0 : Int).fmod (7 : Int) -- 0
0
#eval (12 : Int).fmod (6 : Int) -- 0
0
#eval (12 : Int).fmod (-6 : Int) -- 0
0
#eval (-12 : Int).fmod (6 : Int) -- 0
0
#eval (-12 : Int).fmod (-6 : Int) -- 0
5
#eval (12 : Int).fmod (7 : Int) -- 5
-2
#eval (12 : Int).fmod (-7 : Int) -- -2
2
#eval (-12 : Int).fmod (7 : Int) -- 2
-5
#eval (-12 : Int).fmod (-7 : Int) -- -5
πdefInt.tdiv : Int β Int β Int
tdiv
uses the "T-rounding"
(Truncation-rounding) convention, meaning that it rounds toward
zero. Also note that division by zero is defined to equal zero.
The relation between integer division and modulo is found in
Int.tmod_add_tdiv
which states that
tmod a b + b * (tdiv a b) = a
, unconditionally.
Examples:
0
#eval (7 : Int).tdiv (0 : Int) -- 0
0
#eval (0 : Int).tdiv (7 : Int) -- 0
2
#eval (12 : Int).tdiv (6 : Int) -- 2
-2
#eval (12 : Int).tdiv (-6 : Int) -- -2
-2
#eval (-12 : Int).tdiv (6 : Int) -- -2
2
#eval (-12 : Int).tdiv (-6 : Int) -- 2
1
#eval (12 : Int).tdiv (7 : Int) -- 1
-1
#eval (12 : Int).tdiv (-7 : Int) -- -1
-1
#eval (-12 : Int).tdiv (7 : Int) -- -1
1
#eval (-12 : Int).tdiv (-7 : Int) -- 1
Implemented by efficient native code.
12.2.4.6.Β Proof Automation
The functions in this section are primarily parts of the implementation of simplification rules employed by simp
.
They are probably only of interest to users who are implementing custom proof automation that involves integers.
πdefInt.fromExpr? (e : Lean.Expr)
: Lean.Meta.SimpM (Option Int)
πdefInt.isPosValue : Lean.Meta.Simp.DSimproc
Return .done
for positive Int values. We don't want to unfold in the symbolic evaluator.
πdefInt.reduceAbs : Lean.Meta.Simp.DSimproc
πdefInt.reduceAdd : Lean.Meta.Simp.DSimproc
πdefInt.reduceBEq : Lean.Meta.Simp.DSimproc
πdefInt.reduceBNe : Lean.Meta.Simp.DSimproc
πdefInt.reduceBdiv : Lean.Meta.Simp.DSimproc
πdefInt.reduceBin (declName : Lean.Name)
(arity : Nat) (op : Int β Int β Int)
(e : Lean.Expr)
: Lean.Meta.SimpM Lean.Meta.Simp.DStep
πdefInt.reduceBinIntNatOp (name : Lean.Name)
(op : Int β Nat β Int) (e : Lean.Expr)
: Lean.Meta.SimpM Lean.Meta.Simp.DStep
πdefInt.reduceBinPred (declName : Lean.Name)
(arity : Nat) (op : Int β Int β Bool)
(e : Lean.Expr)
: Lean.Meta.SimpM Lean.Meta.Simp.Step
πdefInt.reduceBmod : Lean.Meta.Simp.DSimproc
πdefInt.reduceBoolPred (declName : Lean.Name)
(arity : Nat) (op : Int β Int β Bool)
(e : Lean.Expr)
: Lean.Meta.SimpM Lean.Meta.Simp.DStep
πdefInt.reduceDiv : Lean.Meta.Simp.DSimproc
πdefInt.reduceEq : Lean.Meta.Simp.Simproc
πdefInt.reduceFDiv : Lean.Meta.Simp.DSimproc
πdefInt.reduceFMod : Lean.Meta.Simp.DSimproc
πdefInt.reduceGE : Lean.Meta.Simp.Simproc
πdefInt.reduceGT : Lean.Meta.Simp.Simproc
πdefInt.reduceLE : Lean.Meta.Simp.Simproc
πdefInt.reduceLT : Lean.Meta.Simp.Simproc
πdefInt.reduceMod : Lean.Meta.Simp.DSimproc
πdefInt.reduceMul : Lean.Meta.Simp.DSimproc
πdefInt.reduceNatCore (declName : Lean.Name)
(op : Int β Nat) (e : Lean.Expr)
: Lean.Meta.SimpM Lean.Meta.Simp.DStep
πdefInt.reduceNe : Lean.Meta.Simp.Simproc
πdefInt.reduceNeg : Lean.Meta.Simp.DSimproc
πdefInt.reduceNegSucc : Lean.Meta.Simp.DSimproc
πdefInt.reduceOfNat : Lean.Meta.Simp.DSimproc
πdefInt.reducePow : Lean.Meta.Simp.DSimproc
πdefInt.reduceSub : Lean.Meta.Simp.DSimproc
πdefInt.reduceTDiv : Lean.Meta.Simp.DSimproc
πdefInt.reduceTMod : Lean.Meta.Simp.DSimproc
πdefInt.reduceToNat : Lean.Meta.Simp.DSimproc
πdefInt.reduceUnary (declName : Lean.Name)
(arity : Nat) (op : Int β Int)
(e : Lean.Expr)
: Lean.Meta.SimpM Lean.Meta.Simp.DStep