Flooring, ceiling division #
This file defines division rounded up and down.
The setup is an ordered monoid α
acting on an ordered monoid β
. If a : α
, b : β
, we would
like to be able to "divide" b
by a
, namely find c : β
such that a • c = b
.
This is of course not always possible, but in some cases at least there is a least c
such that
b ≤ a • c
and a greatest c
such that a • c ≤ b
. We call the first one the "ceiling division
of b
by a
" and the second one the "flooring division of b
by a
"
If α
and β
are both ℕ
, then one can check that our flooring and ceiling divisions really are
the floor and ceil of the exact division.
If α
is ℕ
and β
is the functions ι → ℕ
, then the flooring and ceiling divisions are taken
pointwise.
In order theory terms, those operations are respectively the right and left adjoints to the map
b ↦ a • b
.
Main declarations #
FloorDiv
: Typeclass for the existence of a flooring division, denotedb ⌊/⌋ a
.CeilDiv
: Typeclass for the existence of a ceiling division, denotedb ⌈/⌉ a
.
Note in both cases we only allow dividing by positive inputs. We enforce the following junk values:
b ⌊/⌋ a = b ⌈/⌉ a = 0
ifa ≤ 0
0 ⌊/⌋ a = 0 ⌈/⌉ a = 0
Notation #
b ⌊/⌋ a
for the flooring division ofb
bya
b ⌈/⌉ a
for the ceiling division ofb
bya
TODO #
norm_num
extension- Prove
⌈a / b⌉ = a ⌈/⌉ b
whena, b : ℕ
Typeclass for division rounded down. For each a > 0
, this asserts the existence of a right
adjoint to the map b ↦ a • b : β → β
.
- floorDiv : β → α → β
Flooring division. If
a > 0
, thenb ⌊/⌋ a
is the greatestc
such thata • c ≤ b
. - floorDiv_gc : ∀ ⦃a : α⦄, 0 < a → GaloisConnection (fun (x : β) => a • x) fun (x : β) => x ⌊/⌋ a
Do not use this. Use
gc_floorDiv_smul
orgc_floorDiv_mul
instead. Do not use this. Use
floorDiv_nonpos
instead.Do not use this. Use
zero_floorDiv
instead.
Instances
Typeclass for division rounded up. For each a > 0
, this asserts the existence of a left
adjoint to the map b ↦ a • b : β → β
.
- ceilDiv : β → α → β
Ceiling division. If
a > 0
, thenb ⌈/⌉ a
is the leastc
such thatb ≤ a • c
. - ceilDiv_gc : ∀ ⦃a : α⦄, 0 < a → GaloisConnection (fun (x : β) => x ⌈/⌉ a) fun (x : β) => a • x
Do not use this. Use
gc_smul_ceilDiv
orgc_mul_ceilDiv
instead. Do not use this. Use
ceilDiv_nonpos
instead.Do not use this. Use
zero_ceilDiv
instead.
Instances
Flooring division. If a > 0
, then b ⌊/⌋ a
is the greatest c
such that a • c ≤ b
.
Equations
- «term_⌊/⌋_» = Lean.ParserDescr.trailingNode `«term_⌊/⌋_» 70 70 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " ⌊/⌋ ") (Lean.ParserDescr.cat `term 71))
Instances For
Ceiling division. If a > 0
, then b ⌈/⌉ a
is the least c
such that b ≤ a • c
.
Equations
- «term_⌈/⌉_» = Lean.ParserDescr.trailingNode `«term_⌈/⌉_» 70 70 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " ⌈/⌉ ") (Lean.ParserDescr.cat `term 71))
Instances For
Equations
- Nat.instFloorDiv = { floorDiv := HDiv.hDiv, floorDiv_gc := Nat.instFloorDiv.proof_1, floorDiv_nonpos := Nat.instFloorDiv.proof_2, zero_floorDiv := Nat.zero_div }
Equations
- Nat.instCeilDiv = { ceilDiv := fun (a b : ℕ) => (a + b - 1) / b, ceilDiv_gc := Nat.instCeilDiv.proof_1, ceilDiv_nonpos := Nat.instCeilDiv.proof_2, zero_ceilDiv := Nat.instCeilDiv.proof_3 }
Equations
- Finsupp.instFloorDiv = { floorDiv := fun (f : ι →₀ β) (a : α) => Finsupp.mapRange (fun (x : β) => x ⌊/⌋ a) ⋯ f, floorDiv_gc := ⋯, floorDiv_nonpos := ⋯, zero_floorDiv := ⋯ }
Equations
- Finsupp.instCeilDiv = { ceilDiv := fun (f : ι →₀ β) (a : α) => Finsupp.mapRange (fun (x : β) => x ⌈/⌉ a) ⋯ f, ceilDiv_gc := ⋯, ceilDiv_nonpos := ⋯, zero_ceilDiv := ⋯ }