l3lab/ntp-mathlib huggingface dataset:
theorem reduce_isSpecial : ∀ u : XgcdType, u.IsSpecial → u.reduce.IsSpecial
  | u =>
    dite (u.r = 0)
      (fun h hs => by
        rw [reduce_a h]
        exact u.finish_isSpecial hs)
      fun h hs => by
      have : SizeOf.sizeOf u.step < SizeOf.sizeOf u := u.step_wf h
      rw [reduce_b h]
      

Proof state:
u✝ x✝ : XgcdType
u : XgcdType := x✝
h : ¬r u = 0
hs : IsSpecial x✝
this : sizeOf (step u) < sizeOf u
⊢ IsSpecial (flip (reduce (step u)))

Next tactic:
exact (flip_isSpecial _).mpr (reduce_isSpecial _ (u.step_isSpecial hs))
theorem reduce_v : ∀ u : XgcdType, u.reduce.v = u.v
  | u =>
    dite (u.r = 0) (fun h => by 

Proof state:
u✝ x✝ : XgcdType
u : XgcdType := x✝
h : r u = 0
⊢ v (reduce x✝) = v x✝

Next tactic:
rw [reduce_a h, finish_v u h]
theorem reduce_v : ∀ u : XgcdType, u.reduce.v = u.v
  | u =>
    dite (u.r = 0) (fun h => by rw [reduce_a h, finish_v u h]) fun h => by
      

Proof state:
u✝ x✝ : XgcdType
u : XgcdType := x✝
h : ¬r u = 0
⊢ v (reduce x✝) = v x✝

Next tactic:
have : SizeOf.sizeOf u.step < SizeOf.sizeOf u := u.step_wf h
theorem reduce_v : ∀ u : XgcdType, u.reduce.v = u.v
  | u =>
    dite (u.r = 0) (fun h => by rw [reduce_a h, finish_v u h]) fun h => by
      have : SizeOf.sizeOf u.step < SizeOf.sizeOf u := u.step_wf h
      

Proof state:
u✝ x✝ : XgcdType
u : XgcdType := x✝
h : ¬r u = 0
this : sizeOf (step u) < sizeOf u
⊢ v (reduce x✝) = v x✝

Next tactic:
rw [reduce_b h, flip_v, reduce_v (step u), step_v u h, Prod.swap_swap]
theorem gcdA'_coe : (gcdA' a b : ℕ) = gcdW a b + gcdX a b := by
  

Proof state:
a b : ℕ+
⊢ ↑(gcdA' a b) = ↑(gcdW a b) + gcdX a b

Next tactic:
dsimp [gcdA', gcdX, gcdW, XgcdType.w]
theorem gcdA'_coe : (gcdA' a b : ℕ) = gcdW a b + gcdX a b := by
  dsimp [gcdA', gcdX, gcdW, XgcdType.w]
  

Proof state:
a b : ℕ+
⊢ succ ((xgcd a b).wp + (xgcd a b).x) = succ (xgcd a b).wp + (xgcd a b).x

Next tactic:
rw [Nat.succ_eq_add_one, Nat.succ_eq_add_one, add_right_comm]
theorem gcdB'_coe : (gcdB' a b : ℕ) = gcdY a b + gcdZ a b := by
  

Proof state:
a b : ℕ+
⊢ ↑(gcdB' a b) = gcdY a b + ↑(gcdZ a b)

Next tactic:
dsimp [gcdB', gcdY, gcdZ, XgcdType.z]
theorem gcdB'_coe : (gcdB' a b : ℕ) = gcdY a b + gcdZ a b := by
  dsimp [gcdB', gcdY, gcdZ, XgcdType.z]
  

Proof state:
a b : ℕ+
⊢ succ ((xgcd a b).y + (xgcd a b).zp) = (xgcd a b).y + succ (xgcd a b).zp

Next tactic:
rw [Nat.succ_eq_add_one, Nat.succ_eq_add_one, add_assoc]
theorem gcd_props :
    let d := gcdD a b
    let w := gcdW a b
    let x := gcdX a b
    let y := gcdY a b
    let z := gcdZ a b
    let a' := gcdA' a b
    let b' := gcdB' a b
    w * z = succPNat (x * y) ∧
      a = a' * d ∧
        b = b' * d ∧
          z * a' = succPNat (x * b') ∧
            w * b' = succPNat (y * a') ∧ (z * a : ℕ) = x * b + d ∧ (w * b : ℕ) = y * a + d := by
  

Proof state:
a b : ℕ+
⊢ let d := gcdD a b;
  let w := gcdW a b;
  let x := gcdX a b;
  let y := gcdY a b;
  let z := gcdZ a b;
  let a' := gcdA' a b;
  let b' := gcdB' a b;
  w * z = succPNat (x * y) ∧
    a = a' * d ∧
      b = b' * d ∧
        z * a' = succPNat (x * ↑b') ∧ w * b' = succPNat (y * ↑a') ∧ ↑z * ↑a = x * ↑b + ↑d ∧ ↑w * ↑b = y * ↑a + ↑d

Next tactic:
intros d w x y z a' b'
theorem gcd_props :
    let d := gcdD a b
    let w := gcdW a b
    let x := gcdX a b
    let y := gcdY a b
    let z := gcdZ a b
    let a' := gcdA' a b
    let b' := gcdB' a b
    w * z = succPNat (x * y) ∧
      a = a' * d ∧
        b = b' * d ∧
          z * a' = succPNat (x * b') ∧
            w * b' = succPNat (y * a') ∧ (z * a : ℕ) = x * b + d ∧ (w * b : ℕ) = y * a + d := by
  intros d w x y z a' b'
  

Proof state:
a b : ℕ+
d : ℕ+ := gcdD a b
w : ℕ+ := gcdW a b
x : ℕ := gcdX a b
y : ℕ := gcdY a b
z : ℕ+ := gcdZ a b
a' : ℕ+ := gcdA' a b
b' : ℕ+ := gcdB' a b
⊢ w * z = succPNat (x * y) ∧
    a = a' * d ∧
      b = b' * d ∧
        z * a' = succPNat (x * ↑b') ∧ w * b' = succPNat (y * ↑a') ∧ ↑z * ↑a = x * ↑b + ↑d ∧ ↑w * ↑b = y * ↑a + ↑d

Next tactic:
let u := XgcdType.start a b
theorem gcd_props :
    let d := gcdD a b
    let w := gcdW a b
    let x := gcdX a b
    let y := gcdY a b
    let z := gcdZ a b
    let a' := gcdA' a b
    let b' := gcdB' a b
    w * z = succPNat (x * y) ∧
      a = a' * d ∧
        b = b' * d ∧
          z * a' = succPNat (x * b') ∧
            w * b' = succPNat (y * a') ∧ (z * a : ℕ) = x * b + d ∧ (w * b : ℕ) = y * a + d := by
  intros d w x y z a' b'
  let u := XgcdType.start a b
  

Proof state:
a b : ℕ+
d : ℕ+ := gcdD a b
w : ℕ+ := gcdW a b
x : ℕ := gcdX a b
y : ℕ := gcdY a b
z : ℕ+ := gcdZ a b
a' : ℕ+ := gcdA' a b
b' : ℕ+ := gcdB' a b
u : XgcdType := XgcdType.start a b
⊢ w * z = succPNat (x * y) ∧
    a = a' * d ∧
      b = b' * d ∧
        z * a' = succPNat (x * ↑b') ∧ w * b' = succPNat (y * ↑a') ∧ ↑z * ↑a = x * ↑b + ↑d ∧ ↑w * ↑b = y * ↑a + ↑d

Next tactic:
let ur := u.reduce
theorem gcd_props :
    let d := gcdD a b
    let w := gcdW a b
    let x := gcdX a b
    let y := gcdY a b
    let z := gcdZ a b
    let a' := gcdA' a b
    let b' := gcdB' a b
    w * z = succPNat (x * y) ∧
      a = a' * d ∧
        b = b' * d ∧
          z * a' = succPNat (x * b') ∧
            w * b' = succPNat (y * a') ∧ (z * a : ℕ) = x * b + d ∧ (w * b : ℕ) = y * a + d := by
  intros d w x y z a' b'
  let u := XgcdType.start a b
  let ur := u.reduce

  

Proof state:
a b : ℕ+
d : ℕ+ := gcdD a b
w : ℕ+ := gcdW a b
x : ℕ := gcdX a b
y : ℕ := gcdY a b
z : ℕ+ := gcdZ a b
a' : ℕ+ := gcdA' a b
b' : ℕ+ := gcdB' a b
u : XgcdType := XgcdType.start a b
ur : XgcdType := XgcdType.reduce u
⊢ w * z = succPNat (x * y) ∧
    a = a' * d ∧
      b = b' * d ∧
        z * a' = succPNat (x * ↑b') ∧ w * b' = succPNat (y * ↑a') ∧ ↑z * ↑a = x * ↑b + ↑d ∧ ↑w * ↑b = y * ↑a + ↑d

Next tactic:
have _ : d = ur.a := rfl
theorem gcd_props :
    let d := gcdD a b
    let w := gcdW a b
    let x := gcdX a b
    let y := gcdY a b
    let z := gcdZ a b
    let a' := gcdA' a b
    let b' := gcdB' a b
    w * z = succPNat (x * y) ∧
      a = a' * d ∧
        b = b' * d ∧
          z * a' = succPNat (x * b') ∧
            w * b' = succPNat (y * a') ∧ (z * a : ℕ) = x * b + d ∧ (w * b : ℕ) = y * a + d := by
  intros d w x y z a' b'
  let u := XgcdType.start a b
  let ur := u.reduce

  have _ : d = ur.a := rfl
  

Proof state:
a b : ℕ+
d : ℕ+ := gcdD a b
w : ℕ+ := gcdW a b
x : ℕ := gcdX a b
y : ℕ := gcdY a b
z : ℕ+ := gcdZ a b
a' : ℕ+ := gcdA' a b
b' : ℕ+ := gcdB' a b
u : XgcdType := XgcdType.start a b
ur : XgcdType := XgcdType.reduce u
x✝ : d = XgcdType.a ur
⊢ w * z = succPNat (x * y) ∧
    a = a' * d ∧
      b = b' * d ∧
        z * a' = succPNat (x * ↑b') ∧ w * b' = succPNat (y * ↑a') ∧ ↑z * ↑a = x * ↑b + ↑d ∧ ↑w * ↑b = y * ↑a + ↑d

Next tactic:
have hb : d = ur.b := u.reduce_isReduced'
theorem gcd_props :
    let d := gcdD a b
    let w := gcdW a b
    let x := gcdX a b
    let y := gcdY a b
    let z := gcdZ a b
    let a' := gcdA' a b
    let b' := gcdB' a b
    w * z = succPNat (x * y) ∧
      a = a' * d ∧
        b = b' * d ∧
          z * a' = succPNat (x * b') ∧
            w * b' = succPNat (y * a') ∧ (z * a : ℕ) = x * b + d ∧ (w * b : ℕ) = y * a + d := by
  intros d w x y z a' b'
  let u := XgcdType.start a b
  let ur := u.reduce

  have _ : d = ur.a := rfl
  have hb : d = ur.b := u.reduce_isReduced'
  

Proof state:
a b : ℕ+
d : ℕ+ := gcdD a b
w : ℕ+ := gcdW a b
x : ℕ := gcdX a b
y : ℕ := gcdY a b
z : ℕ+ := gcdZ a b
a' : ℕ+ := gcdA' a b
b' : ℕ+ := gcdB' a b
u : XgcdType := XgcdType.start a b
ur : XgcdType := XgcdType.reduce u
x✝ : d = XgcdType.a ur
hb : d = XgcdType.b ur
⊢ w * z = succPNat (x * y) ∧
    a = a' * d ∧
      b = b' * d ∧
        z * a' = succPNat (x * ↑b') ∧ w * b' = succPNat (y * ↑a') ∧ ↑z * ↑a = x * ↑b + ↑d ∧ ↑w * ↑b = y * ↑a + ↑d

Next tactic:
have ha' : (a' : ℕ) = w + x := gcdA'_coe a b
theorem gcd_props :
    let d := gcdD a b
    let w := gcdW a b
    let x := gcdX a b
    let y := gcdY a b
    let z := gcdZ a b
    let a' := gcdA' a b
    let b' := gcdB' a b
    w * z = succPNat (x * y) ∧
      a = a' * d ∧
        b = b' * d ∧
          z * a' = succPNat (x * b') ∧
            w * b' = succPNat (y * a') ∧ (z * a : ℕ) = x * b + d ∧ (w * b : ℕ) = y * a + d := by
  intros d w x y z a' b'
  let u := XgcdType.start a b
  let ur := u.reduce

  have _ : d = ur.a := rfl
  have hb : d = ur.b := u.reduce_isReduced'
  have ha' : (a' : ℕ) = w + x := gcdA'_coe a b
  

Proof state:
a b : ℕ+
d : ℕ+ := gcdD a b
w : ℕ+ := gcdW a b
x : ℕ := gcdX a b
y : ℕ := gcdY a b
z : ℕ+ := gcdZ a b
a' : ℕ+ := gcdA' a b
b' : ℕ+ := gcdB' a b
u : XgcdType := XgcdType.start a b
ur : XgcdType := XgcdType.reduce u
x✝ : d = XgcdType.a ur
hb : d = XgcdType.b ur
ha' : ↑a' = ↑w + x
⊢ w * z = succPNat (x * y) ∧
    a = a' * d ∧
      b = b' * d ∧
        z * a' = succPNat (x * ↑b') ∧ w * b' = succPNat (y * ↑a') ∧ ↑z * ↑a = x * ↑b + ↑d ∧ ↑w * ↑b = y * ↑a + ↑d

Next tactic:
have hb' : (b' : ℕ) = y + z := gcdB'_coe a b
theorem gcd_props :
    let d := gcdD a b
    let w := gcdW a b
    let x := gcdX a b
    let y := gcdY a b
    let z := gcdZ a b
    let a' := gcdA' a b
    let b' := gcdB' a b
    w * z = succPNat (x * y) ∧
      a = a' * d ∧
        b = b' * d ∧
          z * a' = succPNat (x * b') ∧
            w * b' = succPNat (y * a') ∧ (z * a : ℕ) = x * b + d ∧ (w * b : ℕ) = y * a + d := by
  intros d w x y z a' b'
  let u := XgcdType.start a b
  let ur := u.reduce

  have _ : d = ur.a := rfl
  have hb : d = ur.b := u.reduce_isReduced'
  have ha' : (a' : ℕ) = w + x := gcdA'_coe a b
  have hb' : (b' : ℕ) = y + z := gcdB'_coe a b
  

Proof state:
a b : ℕ+
d : ℕ+ := gcdD a b
w : ℕ+ := gcdW a b
x : ℕ := gcdX a b
y : ℕ := gcdY a b
z : ℕ+ := gcdZ a b
a' : ℕ+ := gcdA' a b
b' : ℕ+ := gcdB' a b
u : XgcdType := XgcdType.start a b
ur : XgcdType := XgcdType.reduce u
x✝ : d = XgcdType.a ur
hb : d = XgcdType.b ur
ha' : ↑a' = ↑w + x
hb' : ↑b' = y + ↑z
⊢ w * z = succPNat (x * y) ∧
    a = a' * d ∧
      b = b' * d ∧
        z * a' = succPNat (x * ↑b') ∧ w * b' = succPNat (y * ↑a') ∧ ↑z * ↑a = x * ↑b + ↑d ∧ ↑w * ↑b = y * ↑a + ↑d

Next tactic:
have hdet : w * z = succPNat (x * y) := u.reduce_isSpecial' rfl
theorem gcd_props :
    let d := gcdD a b
    let w := gcdW a b
    let x := gcdX a b
    let y := gcdY a b
    let z := gcdZ a b
    let a' := gcdA' a b
    let b' := gcdB' a b
    w * z = succPNat (x * y) ∧
      a = a' * d ∧
        b = b' * d ∧
          z * a' = succPNat (x * b') ∧
            w * b' = succPNat (y * a') ∧ (z * a : ℕ) = x * b + d ∧ (w * b : ℕ) = y * a + d := by
  intros d w x y z a' b'
  let u := XgcdType.start a b
  let ur := u.reduce

  have _ : d = ur.a := rfl
  have hb : d = ur.b := u.reduce_isReduced'
  have ha' : (a' : ℕ) = w + x := gcdA'_coe a b
  have hb' : (b' : ℕ) = y + z := gcdB'_coe a b
  have hdet : w * z = succPNat (x * y) := u.reduce_isSpecial' rfl
  

Proof state:
a b : ℕ+
d : ℕ+ := gcdD a b
w : ℕ+ := gcdW a b
x : ℕ := gcdX a b
y : ℕ := gcdY a b
z : ℕ+ := gcdZ a b
a' : ℕ+ := gcdA' a b
b' : ℕ+ := gcdB' a b
u : XgcdType := XgcdType.start a b
ur : XgcdType := XgcdType.reduce u
x✝ : d = XgcdType.a ur
hb : d = XgcdType.b ur
ha' : ↑a' = ↑w + x
hb' : ↑b' = y + ↑z
hdet : w * z = succPNat (x * y)
⊢ w * z = succPNat (x * y) ∧
    a = a' * d ∧
      b = b' * d ∧
        z * a' = succPNat (x * ↑b') ∧ w * b' = succPNat (y * ↑a') ∧ ↑z * ↑a = x * ↑b + ↑d ∧ ↑w * ↑b = y * ↑a + ↑d

Next tactic:
constructor
theorem gcd_props :
    let d := gcdD a b
    let w := gcdW a b
    let x := gcdX a b
    let y := gcdY a b
    let z := gcdZ a b
    let a' := gcdA' a b
    let b' := gcdB' a b
    w * z = succPNat (x * y) ∧
      a = a' * d ∧
        b = b' * d ∧
          z * a' = succPNat (x * b') ∧
            w * b' = succPNat (y * a') ∧ (z * a : ℕ) = x * b + d ∧ (w * b : ℕ) = y * a + d := by
  intros d w x y z a' b'
  let u := XgcdType.start a b
  let ur := u.reduce

  have _ : d = ur.a := rfl
  have hb : d = ur.b := u.reduce_isReduced'
  have ha' : (a' : ℕ) = w + x := gcdA'_coe a b
  have hb' : (b' : ℕ) = y + z := gcdB'_coe a b
  have hdet : w * z = succPNat (x * y) := u.reduce_isSpecial' rfl
  constructor
  

Proof state:
case left
a b : ℕ+
d : ℕ+ := gcdD a b
w : ℕ+ := gcdW a b
x : ℕ := gcdX a b
y : ℕ := gcdY a b
z : ℕ+ := gcdZ a b
a' : ℕ+ := gcdA' a b
b' : ℕ+ := gcdB' a b
u : XgcdType := XgcdType.start a b
ur : XgcdType := XgcdType.reduce u
x✝ : d = XgcdType.a ur
hb : d = XgcdType.b ur
ha' : ↑a' = ↑w + x
hb' : ↑b' = y + ↑z
hdet : w * z = succPNat (x * y)
⊢ w * z = succPNat (x * y)
case right
a b : ℕ+
d : ℕ+ := gcdD a b
w : ℕ+ := gcdW a b
x : ℕ := gcdX a b
y : ℕ := gcdY a b
z : ℕ+ := gcdZ a b
a' : ℕ+ := gcdA' a b
b' : ℕ+ := gcdB' a b
u : XgcdType := XgcdType.start a b
ur : XgcdType := XgcdType.reduce u
x✝ : d = XgcdType.a ur
hb : d = XgcdType.b ur
ha' : ↑a' = ↑w + x
hb' : ↑b' = y + ↑z
hdet : w * z = succPNat (x * y)
⊢ a = a' * d ∧
    b = b' * d ∧
      z * a' = succPNat (x * ↑b') ∧ w * b' = succPNat (y * ↑a') ∧ ↑z * ↑a = x * ↑b + ↑d ∧ ↑w * ↑b = y * ↑a + ↑d

Next tactic:
exact hdet
theorem gcd_props :
    let d := gcdD a b
    let w := gcdW a b
    let x := gcdX a b
    let y := gcdY a b
    let z := gcdZ a b
    let a' := gcdA' a b
    let b' := gcdB' a b
    w * z = succPNat (x * y) ∧
      a = a' * d ∧
        b = b' * d ∧
          z * a' = succPNat (x * b') ∧
            w * b' = succPNat (y * a') ∧ (z * a : ℕ) = x * b + d ∧ (w * b : ℕ) = y * a + d := by
  intros d w x y z a' b'
  let u := XgcdType.start a b
  let ur := u.reduce

  have _ : d = ur.a := rfl
  have hb : d = ur.b := u.reduce_isReduced'
  have ha' : (a' : ℕ) = w + x := gcdA'_coe a b
  have hb' : (b' : ℕ) = y + z := gcdB'_coe a b
  have hdet : w * z = succPNat (x * y) := u.reduce_isSpecial' rfl
  constructor
  exact hdet
  

Proof state:
case right
a b : ℕ+
d : ℕ+ := gcdD a b
w : ℕ+ := gcdW a b
x : ℕ := gcdX a b
y : ℕ := gcdY a b
z : ℕ+ := gcdZ a b
a' : ℕ+ := gcdA' a b
b' : ℕ+ := gcdB' a b
u : XgcdType := XgcdType.start a b
ur : XgcdType := XgcdType.reduce u
x✝ : d = XgcdType.a ur
hb : d = XgcdType.b ur
ha' : ↑a' = ↑w + x
hb' : ↑b' = y + ↑z
hdet : w * z = succPNat (x * y)
⊢ a = a' * d ∧
    b = b' * d ∧
      z * a' = succPNat (x * ↑b') ∧ w * b' = succPNat (y * ↑a') ∧ ↑z * ↑a = x * ↑b + ↑d ∧ ↑w * ↑b = y * ↑a + ↑d

Next tactic:
have hdet' : (w * z : ℕ) = x * y + 1 := by rw [← mul_coe, hdet, succPNat_coe]
theorem gcd_props :
    let d := gcdD a b
    let w := gcdW a b
    let x := gcdX a b
    let y := gcdY a b
    let z := gcdZ a b
    let a' := gcdA' a b
    let b' := gcdB' a b
    w * z = succPNat (x * y) ∧
      a = a' * d ∧
        b = b' * d ∧
          z * a' = succPNat (x * b') ∧
            w * b' = succPNat (y * a') ∧ (z * a : ℕ) = x * b + d ∧ (w * b : ℕ) = y * a + d := by
  intros d w x y z a' b'
  let u := XgcdType.start a b
  let ur := u.reduce

  have _ : d = ur.a := rfl
  have hb : d = ur.b := u.reduce_isReduced'
  have ha' : (a' : ℕ) = w + x := gcdA'_coe a b
  have hb' : (b' : ℕ) = y + z := gcdB'_coe a b
  have hdet : w * z = succPNat (x * y) := u.reduce_isSpecial' rfl
  constructor
  exact hdet
  have hdet' : (w * z : ℕ) = x * y + 1 := by 

Proof state:
a b : ℕ+
d : ℕ+ := gcdD a b
w : ℕ+ := gcdW a b
x : ℕ := gcdX a b
y : ℕ := gcdY a b
z : ℕ+ := gcdZ a b
a' : ℕ+ := gcdA' a b
b' : ℕ+ := gcdB' a b
u : XgcdType := XgcdType.start a b
ur : XgcdType := XgcdType.reduce u
x✝ : d = XgcdType.a ur
hb : d = XgcdType.b ur
ha' : ↑a' = ↑w + x
hb' : ↑b' = y + ↑z
hdet : w * z = succPNat (x * y)
⊢ ↑w * ↑z = x * y + 1

Next tactic:
rw [← mul_coe, hdet, succPNat_coe]
theorem gcd_props :
    let d := gcdD a b
    let w := gcdW a b
    let x := gcdX a b
    let y := gcdY a b
    let z := gcdZ a b
    let a' := gcdA' a b
    let b' := gcdB' a b
    w * z = succPNat (x * y) ∧
      a = a' * d ∧
        b = b' * d ∧
          z * a' = succPNat (x * b') ∧
            w * b' = succPNat (y * a') ∧ (z * a : ℕ) = x * b + d ∧ (w * b : ℕ) = y * a + d := by
  intros d w x y z a' b'
  let u := XgcdType.start a b
  let ur := u.reduce

  have _ : d = ur.a := rfl
  have hb : d = ur.b := u.reduce_isReduced'
  have ha' : (a' : ℕ) = w + x := gcdA'_coe a b
  have hb' : (b' : ℕ) = y + z := gcdB'_coe a b
  have hdet : w * z = succPNat (x * y) := u.reduce_isSpecial' rfl
  constructor
  exact hdet
  have hdet' : (w * z : ℕ) = x * y + 1 := by rw [← mul_coe, hdet, succPNat_coe]
  

Proof state:
case right
a b : ℕ+
d : ℕ+ := gcdD a b
w : ℕ+ := gcdW a b
x : ℕ := gcdX a b
y : ℕ := gcdY a b
z : ℕ+ := gcdZ a b
a' : ℕ+ := gcdA' a b
b' : ℕ+ := gcdB' a b
u : XgcdType := XgcdType.start a b
ur : XgcdType := XgcdType.reduce u
x✝ : d = XgcdType.a ur
hb : d = XgcdType.b ur
ha' : ↑a' = ↑w + x
hb' : ↑b' = y + ↑z
hdet : w * z = succPNat (x * y)
hdet' : ↑w * ↑z = x * y + 1
⊢ a = a' * d ∧
    b = b' * d ∧
      z * a' = succPNat (x * ↑b') ∧ w * b' = succPNat (y * ↑a') ∧ ↑z * ↑a = x * ↑b + ↑d ∧ ↑w * ↑b = y * ↑a + ↑d

Next tactic:
have _ : u.v = ⟨a, b⟩ := XgcdType.start_v a b
theorem gcd_props :
    let d := gcdD a b
    let w := gcdW a b
    let x := gcdX a b
    let y := gcdY a b
    let z := gcdZ a b
    let a' := gcdA' a b
    let b' := gcdB' a b
    w * z = succPNat (x * y) ∧
      a = a' * d ∧
        b = b' * d ∧
          z * a' = succPNat (x * b') ∧
            w * b' = succPNat (y * a') ∧ (z * a : ℕ) = x * b + d ∧ (w * b : ℕ) = y * a + d := by
  intros d w x y z a' b'
  let u := XgcdType.start a b
  let ur := u.reduce

  have _ : d = ur.a := rfl
  have hb : d = ur.b := u.reduce_isReduced'
  have ha' : (a' : ℕ) = w + x := gcdA'_coe a b
  have hb' : (b' : ℕ) = y + z := gcdB'_coe a b
  have hdet : w * z = succPNat (x * y) := u.reduce_isSpecial' rfl
  constructor
  exact hdet
  have hdet' : (w * z : ℕ) = x * y + 1 := by rw [← mul_coe, hdet, succPNat_coe]
  have _ : u.v = ⟨a, b⟩ := XgcdType.start_v a b
  

Proof state:
case right
a b : ℕ+
d : ℕ+ := gcdD a b
w : ℕ+ := gcdW a b
x : ℕ := gcdX a b
y : ℕ := gcdY a b
z : ℕ+ := gcdZ a b
a' : ℕ+ := gcdA' a b
b' : ℕ+ := gcdB' a b
u : XgcdType := XgcdType.start a b
ur : XgcdType := XgcdType.reduce u
x✝¹ : d = XgcdType.a ur
hb : d = XgcdType.b ur
ha' : ↑a' = ↑w + x
hb' : ↑b' = y + ↑z
hdet : w * z = succPNat (x * y)
hdet' : ↑w * ↑z = x * y + 1
x✝ : XgcdType.v u = (↑a, ↑b)
⊢ a = a' * d ∧
    b = b' * d ∧
      z * a' = succPNat (x * ↑b') ∧ w * b' = succPNat (y * ↑a') ∧ ↑z * ↑a = x * ↑b + ↑d ∧ ↑w * ↑b = y * ↑a + ↑d

Next tactic:
let hv : Prod.mk (w * d + x * ur.b : ℕ) (y * d + z * ur.b : ℕ) = ⟨a, b⟩ :=
    u.reduce_v.trans (XgcdType.start_v a b)
theorem gcd_props :
    let d := gcdD a b
    let w := gcdW a b
    let x := gcdX a b
    let y := gcdY a b
    let z := gcdZ a b
    let a' := gcdA' a b
    let b' := gcdB' a b
    w * z = succPNat (x * y) ∧
      a = a' * d ∧
        b = b' * d ∧
          z * a' = succPNat (x * b') ∧
            w * b' = succPNat (y * a') ∧ (z * a : ℕ) = x * b + d ∧ (w * b : ℕ) = y * a + d := by
  intros d w x y z a' b'
  let u := XgcdType.start a b
  let ur := u.reduce

  have _ : d = ur.a := rfl
  have hb : d = ur.b := u.reduce_isReduced'
  have ha' : (a' : ℕ) = w + x := gcdA'_coe a b
  have hb' : (b' : ℕ) = y + z := gcdB'_coe a b
  have hdet : w * z = succPNat (x * y) := u.reduce_isSpecial' rfl
  constructor
  exact hdet
  have hdet' : (w * z : ℕ) = x * y + 1 := by rw [← mul_coe, hdet, succPNat_coe]
  have _ : u.v = ⟨a, b⟩ := XgcdType.start_v a b
  let hv : Prod.mk (w * d + x * ur.b : ℕ) (y * d + z * ur.b : ℕ) = ⟨a, b⟩ :=
    u.reduce_v.trans (XgcdType.start_v a b)
  

Proof state:
case right
a b : ℕ+
d : ℕ+ := gcdD a b
w : ℕ+ := gcdW a b
x : ℕ := gcdX a b
y : ℕ := gcdY a b
z : ℕ+ := gcdZ a b
a' : ℕ+ := gcdA' a b
b' : ℕ+ := gcdB' a b
u : XgcdType := XgcdType.start a b
ur : XgcdType := XgcdType.reduce u
x✝¹ : d = XgcdType.a ur
hb : d = XgcdType.b ur
ha' : ↑a' = ↑w + x
hb' : ↑b' = y + ↑z
hdet : w * z = succPNat (x * y)
hdet' : ↑w * ↑z = x * y + 1
x✝ : XgcdType.v u = (↑a, ↑b)
hv : (↑w * ↑d + x * ↑(XgcdType.b ur), y * ↑d + ↑z * ↑(XgcdType.b ur)) = (↑a, ↑b) :=
  (XgcdType.reduce_v u).trans (XgcdType.start_v a b)
⊢ a = a' * d ∧
    b = b' * d ∧
      z * a' = succPNat (x * ↑b') ∧ w * b' = succPNat (y * ↑a') ∧ ↑z * ↑a = x * ↑b + ↑d ∧ ↑w * ↑b = y * ↑a + ↑d

Next tactic:
rw [← hb, ← add_mul, ← add_mul, ← ha', ← hb'] at hv
theorem gcd_props :
    let d := gcdD a b
    let w := gcdW a b
    let x := gcdX a b
    let y := gcdY a b
    let z := gcdZ a b
    let a' := gcdA' a b
    let b' := gcdB' a b
    w * z = succPNat (x * y) ∧
      a = a' * d ∧
        b = b' * d ∧
          z * a' = succPNat (x * b') ∧
            w * b' = succPNat (y * a') ∧ (z * a : ℕ) = x * b + d ∧ (w * b : ℕ) = y * a + d := by
  intros d w x y z a' b'
  let u := XgcdType.start a b
  let ur := u.reduce

  have _ : d = ur.a := rfl
  have hb : d = ur.b := u.reduce_isReduced'
  have ha' : (a' : ℕ) = w + x := gcdA'_coe a b
  have hb' : (b' : ℕ) = y + z := gcdB'_coe a b
  have hdet : w * z = succPNat (x * y) := u.reduce_isSpecial' rfl
  constructor
  exact hdet
  have hdet' : (w * z : ℕ) = x * y + 1 := by rw [← mul_coe, hdet, succPNat_coe]
  have _ : u.v = ⟨a, b⟩ := XgcdType.start_v a b
  let hv : Prod.mk (w * d + x * ur.b : ℕ) (y * d + z * ur.b : ℕ) = ⟨a, b⟩ :=
    u.reduce_v.trans (XgcdType.start_v a b)
  rw [← hb, ← add_mul, ← add_mul, ← ha', ← hb'] at hv
  

Proof state:
case right
a b : ℕ+
d : ℕ+ := gcdD a b
w : ℕ+ := gcdW a b
x : ℕ := gcdX a b
y : ℕ := gcdY a b
z : ℕ+ := gcdZ a b
a' : ℕ+ := gcdA' a b
b' : ℕ+ := gcdB' a b
u : XgcdType := XgcdType.start a b
ur : XgcdType := XgcdType.reduce u
x✝¹ : d = XgcdType.a ur
hb : d = XgcdType.b ur
ha' : ↑a' = ↑w + x
hb' : ↑b' = y + ↑z
hdet : w * z = succPNat (x * y)
hdet' : ↑w * ↑z = x * y + 1
x✝ : XgcdType.v u = (↑a, ↑b)
hv : (↑a' * ↑d, ↑b' * ↑d) = (↑a, ↑b)
⊢ a = a' * d ∧
    b = b' * d ∧
      z * a' = succPNat (x * ↑b') ∧ w * b' = succPNat (y * ↑a') ∧ ↑z * ↑a = x * ↑b + ↑d ∧ ↑w * ↑b = y * ↑a + ↑d

Next tactic:
have ha'' : (a : ℕ) = a' * d := (congr_arg Prod.fst hv).symm
theorem gcd_props :
    let d := gcdD a b
    let w := gcdW a b
    let x := gcdX a b
    let y := gcdY a b
    let z := gcdZ a b
    let a' := gcdA' a b
    let b' := gcdB' a b
    w * z = succPNat (x * y) ∧
      a = a' * d ∧
        b = b' * d ∧
          z * a' = succPNat (x * b') ∧
            w * b' = succPNat (y * a') ∧ (z * a : ℕ) = x * b + d ∧ (w * b : ℕ) = y * a + d := by
  intros d w x y z a' b'
  let u := XgcdType.start a b
  let ur := u.reduce

  have _ : d = ur.a := rfl
  have hb : d = ur.b := u.reduce_isReduced'
  have ha' : (a' : ℕ) = w + x := gcdA'_coe a b
  have hb' : (b' : ℕ) = y + z := gcdB'_coe a b
  have hdet : w * z = succPNat (x * y) := u.reduce_isSpecial' rfl
  constructor
  exact hdet
  have hdet' : (w * z : ℕ) = x * y + 1 := by rw [← mul_coe, hdet, succPNat_coe]
  have _ : u.v = ⟨a, b⟩ := XgcdType.start_v a b
  let hv : Prod.mk (w * d + x * ur.b : ℕ) (y * d + z * ur.b : ℕ) = ⟨a, b⟩ :=
    u.reduce_v.trans (XgcdType.start_v a b)
  rw [← hb, ← add_mul, ← add_mul, ← ha', ← hb'] at hv
  have ha'' : (a : ℕ) = a' * d := (congr_arg Prod.fst hv).symm
  

Proof state:
case right
a b : ℕ+
d : ℕ+ := gcdD a b
w : ℕ+ := gcdW a b
x : ℕ := gcdX a b
y : ℕ := gcdY a b
z : ℕ+ := gcdZ a b
a' : ℕ+ := gcdA' a b
b' : ℕ+ := gcdB' a b
u : XgcdType := XgcdType.start a b
ur : XgcdType := XgcdType.reduce u
x✝¹ : d = XgcdType.a ur
hb : d = XgcdType.b ur
ha' : ↑a' = ↑w + x
hb' : ↑b' = y + ↑z
hdet : w * z = succPNat (x * y)
hdet' : ↑w * ↑z = x * y + 1
x✝ : XgcdType.v u = (↑a, ↑b)
hv : (↑a' * ↑d, ↑b' * ↑d) = (↑a, ↑b)
ha'' : ↑a = ↑a' * ↑d
⊢ a = a' * d ∧
    b = b' * d ∧
      z * a' = succPNat (x * ↑b') ∧ w * b' = succPNat (y * ↑a') ∧ ↑z * ↑a = x * ↑b + ↑d ∧ ↑w * ↑b = y * ↑a + ↑d

Next tactic:
have hb'' : (b : ℕ) = b' * d := (congr_arg Prod.snd hv).symm