{-# OPTIONS --without-K --safe #-}
module Data.Product.Nary.NonDependent.Properties where
open import Data.Nat.Base using (zero; suc; 2+; _+_)
open import Data.Product.Base as Prod
open import Data.Product.Relation.Binary.Pointwise.NonDependent using (≡×≡⇒≡; ≡⇒≡×≡)
open import Data.Product.Nary.NonDependent
open import Function.Bundles using (Inverse; _↔_; mk↔ₛ′)
open import Function.Definitions
open import Function.Nary.NonDependent.Base
open import Relation.Binary.PropositionalEquality.Core
using (_≡_; refl; cong; cong₂; trans)
open import Relation.Binary.PropositionalEquality.Properties
using (module ≡-Reasoning)
open import Tactic.Cong using (cong!)
open ≡-Reasoning
Product⊤↔Product : ∀ n {ls} {as : Sets n ls} → Product⊤ n as ↔ Product n as
Product⊤↔Product n = mk↔ₛ′ (toProduct n) (toProduct⊤ n) (invˡ n) (invʳ n)
where
invˡ : ∀ n {ls} {as : Sets n ls} → StrictlyInverseˡ _≡_ (toProduct n {as = as}) (toProduct⊤ n)
invˡ 0 _ = refl
invˡ 1 _ = refl
invˡ (2+ n) (a , as) = ≡×≡⇒≡ (refl , invˡ (suc n) as)
invʳ : ∀ n {ls} {as : Sets n ls} → StrictlyInverseʳ _≡_ (toProduct n {as = as}) (toProduct⊤ n)
invʳ 0 _ = refl
invʳ 1 _ = refl
invʳ (2+ n) (a , as) = ≡×≡⇒≡ (refl , invʳ (suc n) as)
splitAt⊤-append⊤-identity :
∀ m n {lsa lsb} {as : Sets m lsa} {bs : Sets n lsb} →
(pa : Product⊤ m as) → (pb : Product⊤ n bs) →
splitAt⊤ m n (append⊤ m n pa pb) ≡ (pa , pb)
splitAt⊤-append⊤-identity zero _ _ _ = ≡×≡⇒≡ (refl , refl)
splitAt⊤-append⊤-identity (suc m) n (a , as) bs =
let eq , eqs = ≡⇒≡×≡ (splitAt⊤-append⊤-identity m n as bs)
in ≡×≡⇒≡ (≡×≡⇒≡ (refl , eq) , eqs)
append⊤-splitAt⊤-identity :
∀ m n {lsa lsb} {as : Sets m lsa} {bs : Sets n lsb} →
(p : Product⊤ (m + n) (sappend m n as bs)) →
uncurry (append⊤ m n) (splitAt⊤ m n p) ≡ p
append⊤-splitAt⊤-identity zero n p = refl
append⊤-splitAt⊤-identity (suc m) n (a , as) = ≡×≡⇒≡ (refl , append⊤-splitAt⊤-identity m n as)
splitAt-append-identity :
∀ m n {lsa lsb} {as : Sets m lsa} {bs : Sets n lsb} →
(pa : Product m as) → (pb : Product n bs) →
splitAt m n (append m n pa pb) ≡ (pa , pb)
splitAt-append-identity m n {as = as} {bs} pa pb = begin
splitAt m n (append m n pa pb)
≡⟨⟩
map (toProduct m) (toProduct n)
(splitAt⊤ m n (toProduct⊤ (m + n) (toProduct (m + n)
(append⊤ m n (toProduct⊤ m pa) (toProduct⊤ n pb)))))
≡⟨ cong! (strictlyInverseʳ (Product⊤↔Product (m + n)) _) ⟩
map (toProduct m) (toProduct n)
(splitAt⊤ m n
(append⊤ m n (toProduct⊤ m pa) (toProduct⊤ n pb)))
≡⟨ cong (map (toProduct m) (toProduct n)) eq ⟩
map (toProduct m) (toProduct n) (toProduct⊤ m pa , toProduct⊤ n pb)
≡⟨ ≡×≡⇒≡ (strictlyInverseˡ (Product⊤↔Product m) pa , strictlyInverseˡ (Product⊤↔Product n) pb) ⟩
pa , pb
∎
where
eq = splitAt⊤-append⊤-identity m n (toProduct⊤ m pa) (toProduct⊤ n pb)
open Inverse