[Agda] Associativity for free!
Nicolas Pouillard
nicolas.pouillard at gmail.com
Wed Oct 26 23:28:56 CEST 2011
On Wed, Oct 26, 2011 at 4:48 PM, Alan Jeffrey <ajeffrey at bell-labs.com> wrote:
> Hi everyone,
>
> A quick note about a trick for representing lists (or any other monoid) up
> to associativity. Am I reinventing a wheel here?
Well done, nice trick!
I've just tried on natural numbers using difference nats, then vectors based
on these nats and finally associativity of ++ goes well.
module diffnat-assoc where
open import Data.Nat
open import Function
open import Relation.Binary.PropositionalEquality
record D : Set where
constructor mk
field
n : ℕ
f : ℕ → ℕ
.f✓ : f ≡ _+_ n
_ᴰ : ℕ → D
n ᴰ = mk n (_+_ n) refl
_+ᴰ_ : D → D → D
mk m f f✓ +ᴰ mk n g g✓ = mk (f n) (f ∘ g) (f∘g✓ f f✓ g g✓)
where
assoc : ∀ m {n} → (λ x → m + (n + x)) ≡ _+_ (m + n)
assoc zero = refl
assoc (suc m) = cong (_∘_ suc) (assoc m)
.f∘g✓ : ∀ f (f✓ : f ≡ _+_ m) g (g✓ : g ≡ _+_ n) → f ∘ g ≡ _+_ (f n)
f∘g✓ ._ refl ._ refl = assoc m
0ᴰ : D
0ᴰ = 0 ᴰ
1ᴰ : D
1ᴰ = 1 ᴰ
sucᴰ : D → D
sucᴰ = _+ᴰ_ 1ᴰ
free-assoc : ∀ {m n o} → m +ᴰ (n +ᴰ o) ≡ (m +ᴰ n) +ᴰ o
free-assoc = refl
data Vec (A : Set) : D → Set where
[] : Vec A 0ᴰ
_∷_ : ∀ {n} (x : A) (xs : Vec A n) → Vec A (sucᴰ n)
_++_ : ∀ {A m n} → Vec A m → Vec A n → Vec A (m +ᴰ n)
[] ++ ys = ys
(x ∷ xs) ++ ys = x ∷ (xs ++ ys)
free-Vec-assoc : ∀ {A m n o} → Vec A ((m +ᴰ n) +ᴰ o) ≡ Vec A (m +ᴰ (n +ᴰ o))
free-Vec-assoc = refl
-- With usual vectors one can't even state this
-- lemma using homogeneous equality.
++-assoc : ∀ {A m n o} (xs : Vec A m) (ys : Vec A n) (zs : Vec A o) →
(xs ++ ys) ++ zs ≡ xs ++ (ys ++ zs)
++-assoc [] ys zs = refl
++-assoc (x ∷ xs) ys zs = cong (_∷_ x) (++-assoc xs ys zs)
--
Nicolas Pouillard
http://nicolaspouillard.fr
More information about the Agda
mailing list