Built with doc-gen4, running Lean4. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓to navigate, Ctrl+πŸ–±οΈto focus. On Mac, use Cmdinstead of Ctrl.
import Mathlib
/-!
## Linear Diaphontine Equations

We solve linear diaphontine equations of the form `a * x + b * y = c` where `a`, `b`, `c` are integers if they have a solution with proof. Otherwise, we return a proof that there is no solution.
-/

/--
Solution of the linear diaphontine equation `a * x + b * y = c` where `a`, `b`, `c` are integers or a proof that there is no solution.
-/
inductive 
DiaphontineSolution: β„€ β†’ β„€ β†’ β„€ β†’ Sort ?u.7
DiaphontineSolution
(a b c :
β„€: Type
β„€
) where |
solution: {a b c : β„€} β†’ (x y : β„€) β†’ a * x + b * y = c β†’ DiaphontineSolution a b c
solution
: (x y :
β„€: Type
β„€
) β†’ a * x + b * y = c β†’
DiaphontineSolution: β„€ β†’ β„€ β†’ β„€ β†’ Sort ?u.7
DiaphontineSolution
a b c |
unsolvable: {a b c : β„€} β†’ (βˆ€ (x y : β„€), Β¬a * x + b * y = c) β†’ DiaphontineSolution a b c
unsolvable
: (βˆ€ x y :
β„€: Type
β„€
, Β¬ (a * x + b * y = c)) β†’
DiaphontineSolution: β„€ β†’ β„€ β†’ β„€ β†’ Sort ?u.7
DiaphontineSolution
a b c /-! This has a solution if and only if the gcd of `a` and `b` divides `c`. * If the gcd of `a` and `b` divides `c`, by Bezout's Lemma there are integers `x` and `y` such that `a * x + b * y = gcd a b`. Further, as `gcd a b` divides `c`, we have an integer `d` such that `(gcd a b) * d = c`. Then `x * d` and `y * d` are integers such that `a * (x * d) + b * (y * d) = c`. * The converse follows as `gcd a b` divides `a` and `b`, hence `c = a * x + b * y`. The main results we need are in the library. Here are most of them: ```lean #check Int.gcd_dvd_left -- βˆ€ (i j : β„€), ↑(Int.gcd i j) ∣ i #check Int.emod_add_ediv -- βˆ€ (a b : β„€), a % b + b * (a / b) = a #check Int.emod_eq_zero_of_dvd -- βˆ€ {a b : β„€}, a ∣ b β†’ b % a = 0 #check Int.dvd_mul_right -- βˆ€ (a b : β„€), a ∣ a * b #check Int.gcd_eq_gcd_ab -- βˆ€ (x y : β„€), ↑(Int.gcd x y) = x * Int.gcdA x y + y * Int.gcdB x y #check dvd_add /-βˆ€ {Ξ± : Type u_1} [inst : Add Ξ±] [inst_1 : Semigroup Ξ±] [inst_2 : LeftDistribClass Ξ±] {a b c : Ξ±}, a ∣ b β†’ a ∣ c β†’ a ∣ b + c-/ ``` -/
Int.gcd_dvd_left (i j : β„€) : ↑(Int.gcd i j) ∣ i
Int.gcd_dvd_left: βˆ€ (i j : β„€), ↑(Int.gcd i j) ∣ i
Int.gcd_dvd_left
-- βˆ€ (i j : β„€), ↑(Int.gcd i j) ∣ i
Int.emod_add_ediv (a b : β„€) : a % b + b * (a / b) = a
Int.emod_add_ediv: βˆ€ (a b : β„€), a % b + b * (a / b) = a
Int.emod_add_ediv
-- βˆ€ (a b : β„€), a % b + b * (a / b) = a
Int.emod_eq_zero_of_dvd {a b : β„€} (a✝ : a ∣ b) : b % a = 0
Int.emod_eq_zero_of_dvd: βˆ€ {a b : β„€}, a ∣ b β†’ b % a = 0
Int.emod_eq_zero_of_dvd
-- βˆ€ {a b : β„€}, a ∣ b β†’ b % a = 0
Int.dvd_mul_right (a b : β„€) : a ∣ a * b
Int.dvd_mul_right: βˆ€ (a b : β„€), a ∣ a * b
Int.dvd_mul_right
-- βˆ€ (a b : β„€), a ∣ a * b
Int.gcd_eq_gcd_ab (x y : β„€) : ↑(Int.gcd x y) = x * Int.gcdA x y + y * Int.gcdB x y
Int.gcd_eq_gcd_ab: βˆ€ (x y : β„€), ↑(Int.gcd x y) = x * Int.gcdA x y + y * Int.gcdB x y
Int.gcd_eq_gcd_ab
-- βˆ€ (x y : β„€), ↑(Int.gcd x y) = x * Int.gcdA x y + y * Int.gcdB x y
dvd_add.{u_1} {Ξ± : Type u_1} [inst✝ : Add Ξ±] [inst✝¹ : Semigroup Ξ±] [inst✝² : LeftDistribClass Ξ±] {a b c : Ξ±} (h₁ : a ∣ b) (hβ‚‚ : a ∣ c) : a ∣ b + c
dvd_add: βˆ€ {Ξ± : Type u_1} [inst : Add Ξ±] [inst_1 : Semigroup Ξ±] [inst_2 : LeftDistribClass Ξ±] {a b c : Ξ±}, a ∣ b β†’ a ∣ c β†’ a ∣ b + c
dvd_add
/-βˆ€ {Ξ± : Type u_1} [inst : Add Ξ±] [inst_1 : Semigroup Ξ±] [inst_2 : LeftDistribClass Ξ±] {a b c : Ξ±}, a ∣ b β†’ a ∣ c β†’ a ∣ b + c-/ /-- Given `a b : β„€` such that `b ∣ a`, we return an integer `q` such that `a = b * q`. -/ def
dvdQuotient: (a b : β„€) β†’ b ∣ a β†’ { q // a = b * q }
dvdQuotient
(a b:
Int: Type
Int
)(
h: b ∣ a
h
: b ∣ a) : {q :
Int: Type
Int
// a = b * q} := let
q: ?m.1032
q
:= a / b ⟨
q: ?m.1032
q
,

Goals accomplished! πŸ™
a, b: β„€

h: b ∣ a

q:= a / b: β„€


a = b * q
a, b: β„€

h: b ∣ a

q:= a / b: β„€


a = b * q
a, b: β„€

h: b ∣ a

q:= a / b: β„€


a % b + b * (a / b) = b * q
a, b: β„€

h: b ∣ a

q:= a / b: β„€


a = b * q
a, b: β„€

h: b ∣ a

q:= a / b: β„€


0 + b * (a / b) = b * q
a, b: β„€

h: b ∣ a

q:= a / b: β„€


a = b * q
a, b: β„€

h: b ∣ a

q:= a / b: β„€


b * (a / b) = b * q

Goals accomplished! πŸ™
⟩ /-- If `a * x + b * y = c` has a solution, then `gcd a b` divides `c`. -/ lemma
eqn_solvable_divides: βˆ€ (a b c : β„€), (βˆƒ x y, a * x + b * y = c) β†’ ↑(Int.gcd a b) ∣ c
eqn_solvable_divides
(a b c :
β„€: Type
β„€
) : (βˆƒ x :
β„€: Type
β„€
, βˆƒ y :
β„€: Type
β„€
, a * x + b * y = c) β†’ ↑(
Int.gcd: β„€ β†’ β„€ β†’ β„•
Int.gcd
a b) ∣ c :=

Goals accomplished! πŸ™
a, b, c: β„€


(βˆƒ x y, a * x + b * y = c) β†’ ↑(Int.gcd a b) ∣ c
a, b, c, x, y: β„€

h: a * x + b * y = c


↑(Int.gcd a b) ∣ c
a, b, c: β„€


(βˆƒ x y, a * x + b * y = c) β†’ ↑(Int.gcd a b) ∣ c
a, b, c, x, y: β„€

h: a * x + b * y = c


↑(Int.gcd a b) ∣ c
a, b, c, x, y: β„€

h: a * x + b * y = c


↑(Int.gcd a b) ∣ a * x + b * y
a, b, c, x, y: β„€

h: a * x + b * y = c


↑(Int.gcd a b) ∣ a * x + b * y
a, b, c: β„€


(βˆƒ x y, a * x + b * y = c) β†’ ↑(Int.gcd a b) ∣ c
a, b, c, x, y: β„€

h: a * x + b * y = c


h₁
↑(Int.gcd a b) ∣ a * x
a, b, c, x, y: β„€

h: a * x + b * y = c


hβ‚‚
↑(Int.gcd a b) ∣ b * y
a, b, c: β„€


(βˆƒ x y, a * x + b * y = c) β†’ ↑(Int.gcd a b) ∣ c
a, b, c, x, y: β„€

h: a * x + b * y = c


h₁
↑(Int.gcd a b) ∣ a * x
a, b, c, x, y: β„€

h: a * x + b * y = c


hβ‚‚
↑(Int.gcd a b) ∣ b * y
a, b, c, x, y: β„€

h: a * x + b * y = c


↑(Int.gcd a b) ∣ a
a, b, c, x, y: β„€

h: a * x + b * y = c


a ∣ a * x
a, b, c, x, y: β„€

h: a * x + b * y = c


h₁
↑(Int.gcd a b) ∣ a * x
a, b, c, x, y: β„€

h: a * x + b * y = c


hβ‚‚
↑(Int.gcd a b) ∣ b * y
a, b, c, x, y: β„€

h: a * x + b * y = c


↑(Int.gcd a b) ∣ a
a, b, c, x, y: β„€

h: a * x + b * y = c


a ∣ a * x

Goals accomplished! πŸ™
a, b, c, x, y: β„€

h: a * x + b * y = c


h₁
↑(Int.gcd a b) ∣ a * x
a, b, c, x, y: β„€

h: a * x + b * y = c


hβ‚‚
↑(Int.gcd a b) ∣ b * y
a, b, c, x, y: β„€

h: a * x + b * y = c


a ∣ a * x

Goals accomplished! πŸ™
a, b, c: β„€


(βˆƒ x y, a * x + b * y = c) β†’ ↑(Int.gcd a b) ∣ c
a, b, c, x, y: β„€

h: a * x + b * y = c


hβ‚‚
↑(Int.gcd a b) ∣ b * y
a, b, c, x, y: β„€

h: a * x + b * y = c


↑(Int.gcd a b) ∣ b
a, b, c, x, y: β„€

h: a * x + b * y = c


b ∣ b * y
a, b, c, x, y: β„€

h: a * x + b * y = c


hβ‚‚
↑(Int.gcd a b) ∣ b * y
a, b, c, x, y: β„€

h: a * x + b * y = c


↑(Int.gcd a b) ∣ b
a, b, c, x, y: β„€

h: a * x + b * y = c


b ∣ b * y

Goals accomplished! πŸ™
a, b, c, x, y: β„€

h: a * x + b * y = c


hβ‚‚
↑(Int.gcd a b) ∣ b * y
a, b, c, x, y: β„€

h: a * x + b * y = c


b ∣ b * y

Goals accomplished! πŸ™
/-- Solution or proof there is no solution for `a * x + b * y = c` -/ def
DiaphontineSolution.solve: (a b c : β„€) β†’ DiaphontineSolution a b c
DiaphontineSolution.solve
(a b c :
β„€: Type
β„€
) :
DiaphontineSolution: β„€ β†’ β„€ β†’ β„€ β†’ Type
DiaphontineSolution
a b c := if
h: ?m.1982
h
: ↑(
Int.gcd: β„€ β†’ β„€ β†’ β„•
Int.gcd
a b) ∣ c then

Goals accomplished! πŸ™
a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c


a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c

d: β„€

h': c = ↑(Int.gcd a b) * d


a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c


a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c

d: β„€

h': c = ↑(Int.gcd a b) * d


a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c

d: β„€

h': c = (a * Int.gcdA a b + b * Int.gcdB a b) * d


a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c

d: β„€

h': c = (a * Int.gcdA a b + b * Int.gcdB a b) * d


a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c

d: β„€

h': c = (a * Int.gcdA a b + b * Int.gcdB a b) * d


a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c


a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c

d: β„€

h': c = (a * Int.gcdA a b + b * Int.gcdB a b) * d


a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c

d: β„€

h': c = a * Int.gcdA a b * d + b * Int.gcdB a b * d


a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c

d: β„€

h': c = (a * Int.gcdA a b + b * Int.gcdB a b) * d


a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c

d: β„€

h': c = a * (Int.gcdA a b * d) + b * Int.gcdB a b * d


a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c

d: β„€

h': c = (a * Int.gcdA a b + b * Int.gcdB a b) * d


a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c

d: β„€

h': c = a * (Int.gcdA a b * d) + b * (Int.gcdB a b * d)


a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c

d: β„€

h': c = a * (Int.gcdA a b * d) + b * (Int.gcdB a b * d)


a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c

d: β„€

h': c = a * (Int.gcdA a b * d) + b * (Int.gcdB a b * d)


a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c


a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c

d: β„€

h': c = a * (Int.gcdA a b * d) + b * (Int.gcdB a b * d)

x:= Int.gcdA a b * d: β„€


a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c


a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c

d: β„€

h': c = a * (Int.gcdA a b * d) + b * (Int.gcdB a b * d)

x:= Int.gcdA a b * d: β„€

y:= Int.gcdB a b * d: β„€


a, b, c: β„€

h: ↑(Int.gcd a b) ∣ c



Goals accomplished! πŸ™
else

Goals accomplished! πŸ™
a, b, c: β„€

h: ¬↑(Int.gcd a b) ∣ c


a, b, c: β„€

h: ¬↑(Int.gcd a b) ∣ c


a
βˆ€ (x y : β„€), Β¬a * x + b * y = c
a, b, c: β„€

h: ¬↑(Int.gcd a b) ∣ c


a, b, c: β„€

h: ¬↑(Int.gcd a b) ∣ c

x, y: β„€

contra: a * x + b * y = c


a
a, b, c: β„€

h: ¬↑(Int.gcd a b) ∣ c


a, b, c: β„€

h: ¬↑(Int.gcd a b) ∣ c

x, y: β„€

contra: a * x + b * y = c


a
↑(Int.gcd a b) ∣ c
a, b, c: β„€

h: ¬↑(Int.gcd a b) ∣ c


a, b, c: β„€

h: ¬↑(Int.gcd a b) ∣ c

x, y: β„€

contra: a * x + b * y = c


a
βˆƒ x y, a * x + b * y = c
a, b, c: β„€

h: ¬↑(Int.gcd a b) ∣ c


a, b, c: β„€

h: ¬↑(Int.gcd a b) ∣ c

x, y: β„€

contra: a * x + b * y = c


a
a * x + b * y = c
a, b, c: β„€

h: ¬↑(Int.gcd a b) ∣ c



Goals accomplished! πŸ™