{-# OPTIONS --exact-split #-}
{-# OPTIONS --no-sized-types #-}
{-# OPTIONS --no-universe-polymorphism #-}
{-# OPTIONS --without-K #-}
module FOTC.Program.GCD.Total.CommonDivisorI where
open import FOTC.Base
open import FOTC.Data.Nat
open import FOTC.Data.Nat.Divisibility.By0
open import FOTC.Data.Nat.Divisibility.By0.PropertiesI
open import FOTC.Data.Nat.Induction.NonAcc.LexicographicI
open import FOTC.Data.Nat.Inequalities
open import FOTC.Data.Nat.Inequalities.EliminationPropertiesI
open import FOTC.Data.Nat.Inequalities.PropertiesI
open import FOTC.Data.Nat.PropertiesI
open import FOTC.Program.GCD.Total.ConversionRulesI
open import FOTC.Program.GCD.Total.Definitions
open import FOTC.Program.GCD.Total.GCD
open import FOTC.Program.GCD.Total.TotalityI
gcd-00∣0 : gcd zero zero ∣ zero
gcd-00∣0 = subst (λ x → x ∣ zero) (sym gcd-00) 0∣0
gcd-0S-∣₁ : ∀ {n} → N n → gcd zero (succ₁ n) ∣ zero
gcd-0S-∣₁ {n} Nn = subst (λ x → x ∣ zero)
(sym (gcd-0S n))
(S∣0 n)
gcd-S0-∣₁ : ∀ {m} → N m → gcd (succ₁ m) zero ∣ succ₁ m
gcd-S0-∣₁ {m} Nm = subst (λ x → x ∣ succ₁ m)
(sym (gcd-S0 m))
(∣-refl (nsucc Nm))
gcd-S≯S-∣₁ :
∀ {m n} → N m → N n →
(gcd (succ₁ m) (succ₁ n ∸ succ₁ m) ∣ succ₁ m) →
succ₁ m ≯ succ₁ n →
gcd (succ₁ m) (succ₁ n) ∣ succ₁ m
gcd-S≯S-∣₁ {m} {n} Nm Nn ih Sm≯Sn =
subst (λ x → x ∣ succ₁ m)
(sym (gcd-S≯S m n Sm≯Sn))
ih
gcd-S>S-∣₁ :
∀ {m n} → N m → N n →
(gcd (succ₁ m ∸ succ₁ n) (succ₁ n) ∣ (succ₁ m ∸ succ₁ n)) →
(gcd (succ₁ m ∸ succ₁ n) (succ₁ n) ∣ succ₁ n) →
succ₁ m > succ₁ n →
gcd (succ₁ m) (succ₁ n) ∣ succ₁ m
gcd-S>S-∣₁ {m} {n} Nm Nn ih gcd-∣₂ Sm>Sn =
subst (λ x → x ∣ succ₁ m)
(sym (gcd-S>S m n Sm>Sn))
(subst (λ y → gcd (succ₁ m ∸ succ₁ n) (succ₁ n) ∣ y)
(x>y→x∸y+y≡x (nsucc Nm) (nsucc Nn) Sm>Sn)
(x∣y→x∣z→x∣y+z
{gcd (succ₁ m ∸ succ₁ n) (succ₁ n)}
{succ₁ m ∸ succ₁ n}
{succ₁ n}
(gcd-N Sm-Sn-N (nsucc Nn))
Sm-Sn-N
(nsucc Nn)
ih
gcd-∣₂
)
)
where
Sm-Sn-N : N (succ₁ m ∸ succ₁ n)
Sm-Sn-N = ∸-N (nsucc Nm) (nsucc Nn)
gcd-0S-∣₂ : ∀ {n} → N n → gcd zero (succ₁ n) ∣ succ₁ n
gcd-0S-∣₂ {n} Nn = subst (λ x → x ∣ succ₁ n)
(sym (gcd-0S n))
(∣-refl (nsucc Nn))
gcd-S0-∣₂ : ∀ {m} → N m → gcd (succ₁ m) zero ∣ zero
gcd-S0-∣₂ {m} Nm = subst (λ x → x ∣ zero)
(sym (gcd-S0 m))
(S∣0 m)
gcd-S>S-∣₂ :
∀ {m n} → N m → N n →
(gcd (succ₁ m ∸ succ₁ n) (succ₁ n) ∣ succ₁ n) →
succ₁ m > succ₁ n →
gcd (succ₁ m) (succ₁ n) ∣ succ₁ n
gcd-S>S-∣₂ {m} {n} Nm Nn ih Sm>Sn =
subst (λ x → x ∣ succ₁ n)
(sym (gcd-S>S m n Sm>Sn))
ih
gcd-S≯S-∣₂ :
∀ {m n} → N m → N n →
(gcd (succ₁ m) (succ₁ n ∸ succ₁ m) ∣ (succ₁ n ∸ succ₁ m)) →
(gcd (succ₁ m) (succ₁ n ∸ succ₁ m) ∣ succ₁ m) →
succ₁ m ≯ succ₁ n →
gcd (succ₁ m) (succ₁ n) ∣ succ₁ n
gcd-S≯S-∣₂ {m} {n} Nm Nn ih gcd-∣₁ Sm≯Sn =
subst (λ x → x ∣ succ₁ n)
(sym (gcd-S≯S m n Sm≯Sn))
(subst (λ y → gcd (succ₁ m) (succ₁ n ∸ succ₁ m) ∣ y)
(x≤y→y∸x+x≡y (nsucc Nm) (nsucc Nn) (x≯y→x≤y (nsucc Nm) (nsucc Nn) Sm≯Sn))
(x∣y→x∣z→x∣y+z
{gcd (succ₁ m) (succ₁ n ∸ succ₁ m)}
{succ₁ n ∸ succ₁ m}
{succ₁ m}
(gcd-N (nsucc Nm) Sn-Sm-N)
Sn-Sm-N
(nsucc Nm)
ih
gcd-∣₁
)
)
where
Sn-Sm-N : N (succ₁ n ∸ succ₁ m)
Sn-Sm-N = ∸-N (nsucc Nn) (nsucc Nm)
gcd-00-CD : CD zero zero (gcd zero zero)
gcd-00-CD = gcd-00∣0 , gcd-00∣0
gcd-0S-CD : ∀ {n} → N n → CD zero (succ₁ n) (gcd zero (succ₁ n))
gcd-0S-CD Nn = (gcd-0S-∣₁ Nn , gcd-0S-∣₂ Nn)
gcd-S0-CD : ∀ {m} → N m → CD (succ₁ m) zero (gcd (succ₁ m) zero)
gcd-S0-CD Nm = (gcd-S0-∣₁ Nm , gcd-S0-∣₂ Nm)
gcd-S>S-CD :
∀ {m n} → N m → N n →
(CD (succ₁ m ∸ succ₁ n) (succ₁ n) (gcd (succ₁ m ∸ succ₁ n) (succ₁ n))) →
succ₁ m > succ₁ n →
CD (succ₁ m) (succ₁ n) (gcd (succ₁ m) (succ₁ n))
gcd-S>S-CD {m} {n} Nm Nn acc Sm>Sn =
(gcd-S>S-∣₁ Nm Nn acc-∣₁ acc-∣₂ Sm>Sn , gcd-S>S-∣₂ Nm Nn acc-∣₂ Sm>Sn)
where
acc-∣₁ : gcd (succ₁ m ∸ succ₁ n) (succ₁ n) ∣ (succ₁ m ∸ succ₁ n)
acc-∣₁ = ∧-proj₁ acc
acc-∣₂ : gcd (succ₁ m ∸ succ₁ n) (succ₁ n) ∣ succ₁ n
acc-∣₂ = ∧-proj₂ acc
gcd-S≯S-CD :
∀ {m n} → N m → N n →
(CD (succ₁ m) (succ₁ n ∸ succ₁ m) (gcd (succ₁ m) (succ₁ n ∸ succ₁ m))) →
succ₁ m ≯ succ₁ n →
CD (succ₁ m) (succ₁ n) (gcd (succ₁ m) (succ₁ n))
gcd-S≯S-CD {m} {n} Nm Nn acc Sm≯Sn =
(gcd-S≯S-∣₁ Nm Nn acc-∣₁ Sm≯Sn , gcd-S≯S-∣₂ Nm Nn acc-∣₂ acc-∣₁ Sm≯Sn)
where
acc-∣₁ : gcd (succ₁ m) (succ₁ n ∸ succ₁ m) ∣ succ₁ m
acc-∣₁ = ∧-proj₁ acc
acc-∣₂ : gcd (succ₁ m) (succ₁ n ∸ succ₁ m) ∣ (succ₁ n ∸ succ₁ m)
acc-∣₂ = ∧-proj₂ acc
gcd-x>y-CD :
∀ {m n} → N m → N n →
(∀ {o p} → N o → N p → Lexi o p m n → CD o p (gcd o p)) →
m > n →
CD m n (gcd m n)
gcd-x>y-CD nzero Nn _ 0>n = ⊥-elim (0>x→⊥ Nn 0>n)
gcd-x>y-CD (nsucc Nm) nzero _ _ = gcd-S0-CD Nm
gcd-x>y-CD (nsucc {m} Nm) (nsucc {n} Nn) ah Sm>Sn = gcd-S>S-CD Nm Nn ih Sm>Sn
where
ih : CD (succ₁ m ∸ succ₁ n) (succ₁ n) (gcd (succ₁ m ∸ succ₁ n) (succ₁ n))
ih = ah {succ₁ m ∸ succ₁ n}
{succ₁ n}
(∸-N (nsucc Nm) (nsucc Nn))
(nsucc Nn)
([Sx∸Sy,Sy]<[Sx,Sy] Nm Nn)
gcd-x≯y-CD :
∀ {m n} → N m → N n →
(∀ {o p} → N o → N p → Lexi o p m n → CD o p (gcd o p)) →
m ≯ n →
CD m n (gcd m n)
gcd-x≯y-CD nzero nzero _ _ = gcd-00-CD
gcd-x≯y-CD nzero (nsucc Nn) _ _ = gcd-0S-CD Nn
gcd-x≯y-CD (nsucc _) nzero _ Sm≯0 = ⊥-elim (S≯0→⊥ Sm≯0)
gcd-x≯y-CD (nsucc {m} Nm) (nsucc {n} Nn) ah Sm≯Sn = gcd-S≯S-CD Nm Nn ih Sm≯Sn
where
ih : CD (succ₁ m) (succ₁ n ∸ succ₁ m) (gcd (succ₁ m) (succ₁ n ∸ succ₁ m))
ih = ah {succ₁ m}
{succ₁ n ∸ succ₁ m}
(nsucc Nm)
(∸-N (nsucc Nn) (nsucc Nm))
([Sx,Sy∸Sx]<[Sx,Sy] Nm Nn)
gcdCD : ∀ {m n} → N m → N n → CD m n (gcd m n)
gcdCD = Lexi-wfind A h
where
A : D → D → Set
A i j = CD i j (gcd i j)
h : ∀ {i j} → N i → N j → (∀ {k l} → N k → N l → Lexi k l i j → A k l) →
A i j
h Ni Nj ah = case (gcd-x>y-CD Ni Nj ah) (gcd-x≯y-CD Ni Nj ah) (x>y∨x≯y Ni Nj)