module Doubling where
open import Preliminaries
open import IntegerAlgebra
twist-alg : IntAlg (ℤ + ℤ)
twist-alg .IntAlg.S = +-symm ∘ₑ +-congr id-iso ℤ.S
twist-alg .IntAlg.Z = inl ℤ.Z
double-alg : {X : Set} → IntAlg X → IntAlg X
double-alg X-alg .IntAlg.S = X-alg .IntAlg.S ∘ₑ X-alg .IntAlg.S
double-alg X-alg .IntAlg.Z = X-alg .IntAlg.Z
abstract
halve : ℤ → ℤ + ℤ
halve = ℤ-rec twist-alg
double : ℤ + ℤ → ℤ
double = +-ind (ℤ-rec (double-alg ℤ-alg)) (ℤ.S .fun ∘ ℤ-rec (double-alg ℤ-alg))
double-S : (x : ℤ + ℤ) → ℤ.S .fun (double x) ≡ double (twist-alg .IntAlg.S .fun x)
double-S = +-ind (λ x → refl) λ x → symm (ℤ-rec-S (double-alg ℤ-alg) x)
double-halve : (x : ℤ) → double (halve x) ≡ x
double-halve = ℤ-rec-uniq ℤ-alg
(λ x → ap double (ℤ-rec-S twist-alg x) • symm (double-S (halve x)))
(ap double (ℤ-rec-Z _) • ℤ-rec-Z _)
(λ _ → refl) refl
halve-double : (x : ℤ) → halve (double (inl x)) ≡ inl x
halve-double = ℤ-rec-uniq (double-alg twist-alg)
(λ x → ap halve (ℤ-rec-S _ _) • ℤ-rec-S _ _ • ap (twist-alg .IntAlg.S .fun) (ℤ-rec-S twist-alg _))
(ap halve (ℤ-rec-Z _) • ℤ-rec-Z _) (λ x → refl) refl
halve-iso : ℤ ≅ ℤ + ℤ
halve-iso .fun = halve
halve-iso .inv = double
halve-iso .inv-fun = double-halve
halve-iso .fun-inv = +-ind halve-double λ x → ℤ-rec-S _ _ • ap (twist-alg .IntAlg.S .fun) (halve-double x)