# Diophantine functions and Matiyasevic's theorem #

Hilbert's tenth problem asked whether there exists an algorithm which for a given integer polynomial determines whether this polynomial has integer solutions. It was answered in the negative in 1970, the final step being completed by Matiyasevic who showed that the power function is Diophantine.

Here a function is called Diophantine if its graph is Diophantine as a set. A subset S ⊆ ℕ ^ α in turn is called Diophantine if there exists an integer polynomial on α ⊕ β such that v ∈ S iff there exists t : ℕ^β with p (v, t) = 0.

## Main definitions #

• IsPoly: a predicate stating that a function is a multivariate integer polynomial.
• Poly: the type of multivariate integer polynomial functions.
• Dioph: a predicate stating that a set is Diophantine, i.e. a set S ⊆ ℕ^α is Diophantine if there exists a polynomial on α ⊕ β such that v ∈ S iff there exists t : ℕ^β with p (v, t) = 0.
• dioph_fn: a predicate on a function stating that it is Diophantine in the sense that its graph is Diophantine as a set.

## Main statements #

• pell_dioph states that solutions to Pell's equation form a Diophantine set.
• pow_dioph states that the power function is Diophantine, a version of Matiyasevic's theorem.

## Tags #

Matiyasevic's theorem, Hilbert's tenth problem

## TODO #

• Finish the solution of Hilbert's tenth problem.
• Connect Poly to MvPolynomial

### Multivariate integer polynomials #

Note that this duplicates MvPolynomial.

inductive IsPoly {α : Type u_1} :
((α))Prop

A predicate asserting that a function is a multivariate integer polynomial. (We are being a bit lazy here by allowing many representations for multiplication, rather than only allowing monomials and addition, but the definition is equivalent and this is easier to use.)

• proj: ∀ {α : Type u_1} (i : α), IsPoly fun (x : α) => (x i)
• const: ∀ {α : Type u_1} (n : ), IsPoly fun (x : α) => n
• sub: ∀ {α : Type u_1} {f g : (α)}, IsPoly fun (x : α) => f x - g x
• mul: ∀ {α : Type u_1} {f g : (α)}, IsPoly fun (x : α) => f x * g x
Instances For
theorem IsPoly.neg {α : Type u_1} {f : (α)} :
IsPoly (-f)
theorem IsPoly.add {α : Type u_1} {f : (α)} {g : (α)} (hf : ) (hg : ) :
IsPoly (f + g)
def Poly (α : Type u) :
Type (max 0 u)

The type of multivariate integer polynomials

Equations
Instances For
instance Poly.instFunLike {α : Type u_1} :
FunLike (Poly α) (α)
Equations
• Poly.instFunLike = { coe := Subtype.val, coe_injective' := }
theorem Poly.isPoly {α : Type u_1} (f : Poly α) :
IsPoly f

The underlying function of a Poly is a polynomial

theorem Poly.ext_iff {α : Type u_1} {f : Poly α} {g : Poly α} :
f = g ∀ (x : α), f x = g x
theorem Poly.ext {α : Type u_1} {f : Poly α} {g : Poly α} :
(∀ (x : α), f x = g x)f = g

Extensionality for Poly α

def Poly.proj {α : Type u_1} (i : α) :
Poly α

The ith projection function, x_i.

Equations
• = fun (x : α) => (x i),
Instances For
@[simp]
theorem Poly.proj_apply {α : Type u_1} (i : α) (x : α) :
(Poly.proj i) x = (x i)
def Poly.const {α : Type u_1} (n : ) :
Poly α

The constant function with value n : ℤ.

Equations
• = fun (x : α) => n,
Instances For
@[simp]
theorem Poly.const_apply {α : Type u_1} (n : ) (x : α) :
(Poly.const n) x = n
instance Poly.instZero {α : Type u_1} :
Zero (Poly α)
Equations
• Poly.instZero = { zero := }
instance Poly.instOne {α : Type u_1} :
One (Poly α)
Equations
• Poly.instOne = { one := }
instance Poly.instNeg {α : Type u_1} :
Neg (Poly α)
Equations
• Poly.instNeg = { neg := fun (f : Poly α) => -f, }
instance Poly.instAdd {α : Type u_1} :
Equations
• Poly.instAdd = { add := fun (f g : Poly α) => f + g, }
instance Poly.instSub {α : Type u_1} :
Sub (Poly α)
Equations
• Poly.instSub = { sub := fun (f g : Poly α) => f - g, }
instance Poly.instMul {α : Type u_1} :
Mul (Poly α)
Equations
• Poly.instMul = { mul := fun (f g : Poly α) => f * g, }
@[simp]
theorem Poly.coe_zero {α : Type u_1} :
0 = (Poly.const 0)
@[simp]
theorem Poly.coe_one {α : Type u_1} :
1 = (Poly.const 1)
@[simp]
theorem Poly.coe_neg {α : Type u_1} (f : Poly α) :
(-f) = -f
@[simp]
theorem Poly.coe_add {α : Type u_1} (f : Poly α) (g : Poly α) :
(f + g) = f + g
@[simp]
theorem Poly.coe_sub {α : Type u_1} (f : Poly α) (g : Poly α) :
(f - g) = f - g
@[simp]
theorem Poly.coe_mul {α : Type u_1} (f : Poly α) (g : Poly α) :
(f * g) = f * g
@[simp]
theorem Poly.zero_apply {α : Type u_1} (x : α) :
0 x = 0
@[simp]
theorem Poly.one_apply {α : Type u_1} (x : α) :
1 x = 1
@[simp]
theorem Poly.neg_apply {α : Type u_1} (f : Poly α) (x : α) :
(-f) x = -f x
@[simp]
theorem Poly.add_apply {α : Type u_1} (f : Poly α) (g : Poly α) (x : α) :
(f + g) x = f x + g x
@[simp]
theorem Poly.sub_apply {α : Type u_1} (f : Poly α) (g : Poly α) (x : α) :
(f - g) x = f x - g x
@[simp]
theorem Poly.mul_apply {α : Type u_1} (f : Poly α) (g : Poly α) (x : α) :
(f * g) x = f x * g x
instance Poly.instInhabited (α : Type u_4) :
Equations
• = { default := 0 }
instance Poly.instAddCommGroup {α : Type u_1} :
Equations
instance Poly.instAddGroupWithOne {α : Type u_1} :
Equations
instance Poly.instCommRing {α : Type u_1} :
Equations
• Poly.instCommRing =
theorem Poly.induction {α : Type u_1} {C : Poly αProp} (H1 : ∀ (i : α), C (Poly.proj i)) (H2 : ∀ (n : ), C (Poly.const n)) (H3 : ∀ (f g : Poly α), C fC gC (f - g)) (H4 : ∀ (f g : Poly α), C fC gC (f * g)) (f : Poly α) :
C f
def Poly.sumsq {α : Type u_1} :
List (Poly α)Poly α

The sum of squares of a list of polynomials. This is relevant for Diophantine equations, because it means that a list of equations can be encoded as a single equation: x = 0 ∧ y = 0 ∧ z = 0 is equivalent to x^2 + y^2 + z^2 = 0.

Equations
Instances For
theorem Poly.sumsq_nonneg {α : Type u_1} (x : α) (l : List (Poly α)) :
0 (Poly.sumsq l) x
theorem Poly.sumsq_eq_zero {α : Type u_1} (x : α) (l : List (Poly α)) :
(Poly.sumsq l) x = 0 List.Forall (fun (a : Poly α) => a x = 0) l
def Poly.map {α : Type u_4} {β : Type u_5} (f : αβ) (g : Poly α) :
Poly β

Map the index set of variables, replacing x_i with x_(f i).

Equations
Instances For
@[simp]
theorem Poly.map_apply {α : Type u_4} {β : Type u_5} (f : αβ) (g : Poly α) (v : β) :
(Poly.map f g) v = g (v f)

### Diophantine sets #

def Dioph {α : Type u} (S : Set (α)) :

A set S ⊆ ℕ^α is Diophantine if there exists a polynomial on α ⊕ β such that v ∈ S iff there exists t : ℕ^β with p (v, t) = 0.

Equations
Instances For
theorem Dioph.ext {α : Type u} {S : Set (α)} {S' : Set (α)} (d : ) (H : ∀ (v : α), v S v S') :
theorem Dioph.of_no_dummies {α : Type u} (S : Set (α)) (p : Poly α) (h : ∀ (v : α), S v p v = 0) :
theorem Dioph.inject_dummies_lem {α : Type u} {β : Type u} {γ : Type u} (f : βγ) (g : γ) (inv : ∀ (x : β), g (f x) = some x) (p : Poly (α β)) (v : α) :
(∃ (t : β), p (Sum.elim v t) = 0) ∃ (t : γ), (Poly.map (Sum.elim Sum.inl (Sum.inr f)) p) (Sum.elim v t) = 0
theorem Dioph.inject_dummies {α : Type u} {β : Type u} {γ : Type u} {S : Set (α)} (f : βγ) (g : γ) (inv : ∀ (x : β), g (f x) = some x) (p : Poly (α β)) (h : ∀ (v : α), S v ∃ (t : β), p (Sum.elim v t) = 0) :
∃ (q : Poly (α γ)), ∀ (v : α), S v ∃ (t : γ), q (Sum.elim v t) = 0
theorem Dioph.reindex_dioph {α : Type u} (β : Type u) {S : Set (α)} (f : αβ) :
Dioph {v : β | v f S}
theorem Dioph.DiophList.forall {α : Type u} (l : List (Set (α))) (d : List.Forall Dioph l) :
Dioph {v : α | List.Forall (fun (S : Set (α)) => v S) l}
theorem Dioph.inter {α : Type u} {S : Set (α)} {S' : Set (α)} (d : ) (d' : Dioph S') :
Dioph (S S')
theorem Dioph.union {α : Type u} {S : Set (α)} {S' : Set (α)} :
Dioph S'Dioph (S S')
def Dioph.DiophPFun {α : Type u} (f : (α) →. ) :

A partial function is Diophantine if its graph is Diophantine.

Equations
Instances For
def Dioph.DiophFn {α : Type u} (f : (α)) :

A function is Diophantine if its graph is Diophantine.

Equations
Instances For
theorem Dioph.reindex_diophFn {α : Type u} {β : Type u} {f : (α)} (g : αβ) (d : ) :
Dioph.DiophFn fun (v : β) => f (v g)
theorem Dioph.ex_dioph {α : Type u} {β : Type u} {S : Set (α β)} :
Dioph {v : α | ∃ (x : β), Sum.elim v x S}
theorem Dioph.ex1_dioph {α : Type u} {S : Set ()} :
Dioph {v : α | ∃ (x : ), S}
theorem Dioph.dom_dioph {α : Type u} {f : (α) →. } (d : ) :
Dioph f.Dom
theorem Dioph.diophFn_iff_pFun {α : Type u} (f : (α)) :
theorem Dioph.abs_poly_dioph {α : Type u} (p : Poly α) :
Dioph.DiophFn fun (v : α) => (p v).natAbs
theorem Dioph.proj_dioph {α : Type u} (i : α) :
Dioph.DiophFn fun (v : α) => v i
theorem Dioph.diophPFun_comp1 {α : Type u} {S : Set ()} (d : ) {f : (α) →. } (df : ) :
Dioph {v : α | ∃ (h : f.Dom v), Option.elim' (f.fn v h) v S}
theorem Dioph.diophFn_comp1 {α : Type u} {S : Set ()} (d : ) {f : (α)} (df : ) :
Dioph {v : α | Option.elim' (f v) v S}
theorem Dioph.diophFn_vec_comp1 {n : } {S : Set (Vector3 n.succ)} (d : ) {f : } (df : ) :
Dioph {v : | Vector3.cons (f v) v S}
theorem Dioph.vec_ex1_dioph (n : ) {S : Set (Vector3 n.succ)} (d : ) :
Dioph {v : Fin2 n | ∃ (x : ), S}
theorem Dioph.diophFn_vec {n : } (f : ) :
Dioph {v : Fin2 (n + 1) | f (v Fin2.fs) = v Fin2.fz}
theorem Dioph.diophPFun_vec {n : } (f : →. ) :
Dioph {v : Fin2 (n + 1) | f.graph (v Fin2.fs, v Fin2.fz)}
theorem Dioph.diophFn_compn {α : Type} {n : } {S : Set (α Fin2 n)} :
∀ {f : Vector3 ((α)) n}, VectorAllP Dioph.DiophFn fDioph {v : α | (Sum.elim v fun (i : Fin2 n) => f i v) S}
theorem Dioph.dioph_comp {α : Type} {n : } {S : Set (Vector3 n)} (d : ) (f : Vector3 ((α)) n) (df : VectorAllP Dioph.DiophFn f) :
Dioph {v : α | (fun (i : Fin2 n) => f i v) S}
theorem Dioph.diophFn_comp {α : Type} {n : } {f : } (df : ) (g : Vector3 ((α)) n) (dg : VectorAllP Dioph.DiophFn g) :
Dioph.DiophFn fun (v : α) => f fun (i : Fin2 n) => g i v
Equations
Instances For
Equations
Instances For
Equations
Instances For
Equations
Instances For
theorem Dioph.proj_dioph_of_nat {n : } (m : ) [] :
Dioph.DiophFn fun (v : ) => v (Fin2.ofNat' m)
Equations
Instances For
theorem Dioph.const_dioph {α : Type} (n : ) :
Equations
Instances For
theorem Dioph.dioph_comp2 {α : Type} {f : (α)} {g : (α)} (df : ) (dg : ) {S : Prop} (d : Dioph fun (v : ) => S (v (Fin2.ofNat' 0)) (v (Fin2.ofNat' 1))) :
Dioph fun (v : α) => S (f v) (g v)
theorem Dioph.diophFn_comp2 {α : Type} {f : (α)} {g : (α)} (df : ) (dg : ) {h : } (d : Dioph.DiophFn fun (v : ) => h (v (Fin2.ofNat' 0)) (v (Fin2.ofNat' 1))) :
Dioph.DiophFn fun (v : α) => h (f v) (g v)
theorem Dioph.eq_dioph {α : Type} {f : (α)} {g : (α)} (df : ) (dg : ) :
Dioph fun (v : α) => f v = g v
Equations
Instances For
theorem Dioph.add_dioph {α : Type} {f : (α)} {g : (α)} (df : ) (dg : ) :
Dioph.DiophFn fun (v : α) => f v + g v
Equations
Instances For
theorem Dioph.mul_dioph {α : Type} {f : (α)} {g : (α)} (df : ) (dg : ) :
Dioph.DiophFn fun (v : α) => f v * g v
Equations
Instances For
theorem Dioph.le_dioph {α : Type} {f : (α)} {g : (α)} (df : ) (dg : ) :
Dioph {v : α | f v g v}
Equations
Instances For
theorem Dioph.lt_dioph {α : Type} {f : (α)} {g : (α)} (df : ) (dg : ) :
Dioph {v : α | f v < g v}
Equations
Instances For
theorem Dioph.ne_dioph {α : Type} {f : (α)} {g : (α)} (df : ) (dg : ) :
Dioph {v : α | f v g v}
Equations
Instances For
theorem Dioph.sub_dioph {α : Type} {f : (α)} {g : (α)} (df : ) (dg : ) :
Dioph.DiophFn fun (v : α) => f v - g v
Equations
Instances For
theorem Dioph.dvd_dioph {α : Type} {f : (α)} {g : (α)} (df : ) (dg : ) :
Dioph fun (v : α) => f v g v
Equations
Instances For
theorem Dioph.mod_dioph {α : Type} {f : (α)} {g : (α)} (df : ) (dg : ) :
Dioph.DiophFn fun (v : α) => f v % g v
Equations
Instances For
theorem Dioph.modEq_dioph {α : Type} {f : (α)} {g : (α)} (df : ) (dg : ) {h : (α)} (dh : ) :
Dioph fun (v : α) => f v g v [MOD h v]
Equations
Instances For
theorem Dioph.div_dioph {α : Type} {f : (α)} {g : (α)} (df : ) (dg : ) :
Dioph.DiophFn fun (v : α) => f v / g v
Equations
Instances For
theorem Dioph.pell_dioph :
Dioph fun (v : ) => ∃ (h : 1 < v (Fin2.ofNat' 0)), Pell.xn h (v (Fin2.ofNat' 1)) = v (Fin2.ofNat' 2) Pell.yn h (v (Fin2.ofNat' 1)) = v (Fin2.ofNat' 3)
theorem Dioph.xn_dioph :
Dioph.DiophPFun fun (v : ) => { Dom := 1 < v (Fin2.ofNat' 0), get := fun (h : 1 < v (Fin2.ofNat' 0)) => Pell.xn h (v (Fin2.ofNat' 1)) }
theorem Dioph.pow_dioph {α : Type} {f : (α)} {g : (α)} (df : ) (dg : ) :
Dioph.DiophFn fun (v : α) => f v ^ g v

A version of Matiyasevic's theorem