[Agda] Extensional equality, or how to avoid needing it?

Shin-Cheng Mu scm at iis.sinica.edu.tw
Thu Jan 8 15:41:31 CET 2009


Vector reversal can be defined in terms of a foldl:

   reverse : forall {a n} -> Vec a n -> Vec a n
   reverse {a} = foldl (Vec a) (\rev x -> x ∷ rev) []

where foldl has type

   foldl :  forall {a : Set} (b : ℕ -> Set) {m}
         -> (forall {n} -> b n -> a -> b (suc n))
         -> b zero
         -> Vec a m -> b m

In many situations when we want to prove properties
of reverse, we have to prove the property for a
generalisation of reverse, which I call "revcat",
which abstracts the third argument to foldl as well:

   revcat : forall {a m n}
          -> Vec a m -> Vec a n -> Vec a (m + n)
   revcat {a}{m}{n} xs ys =
      foldl (\i -> Vec a (i + n)) (\rev x -> x ∷ rev) ys xs

(They are related by the equation:
   revcat xs ys = reverse xs ++ ys)

For lists, it is a trivial matter proving that:

    reverse xs = revcat xs []

But how to do so for Vectors?

I started with:

   lemma : forall {a m} (xs : Vec a m)
         -> reverse xs ≅ revcat xs []
   lemma xs = { }0

and didn't get very far. The term reverse xs has type
Vec a m, while revcat xs [] has type Vec a (m + 0). Thus
we use heterogenous equality. The hole { }0 expects a
term having type:

?0 : foldl (Vec .a) (\{.n} rev x -> x ∷ rev) [] xs ≅
      foldl (\i -> Vec .a (i + 0)) (\{.n} rev x -> x ∷ rev) [] xs

The only part that does not match are the first arguments:
(\i -> Vec a i) and (\i -> Vec a (i + 0)). At the first
glance it appears that they are the same by congruence.
We can prove that

      forall i -> i ≅ (i + 0)

and by (a variation of) congruence we get

      forall i -> Vec a i ≅₁ Vec a (i + 0)

However, what we need now is

      (\i -> Vec a i) ≅₁ (\i -> Vec a (i + 0))  ... (1)

from which we may prove { }0 by congruence.
I could not figure out how to prove (1).

Is (1) provable at all? If not, is there a way to
avoid it?

Thanks!

sincerely,
Shin

    ---- Code attached below

module Rev where

open import Data.Product
open import Data.Nat
open import Data.Vec
open import Relation.Binary.HeterogeneousEquality
open import Algebra
open import Data.Nat.Properties

{- Defined in Data.Vec
reverse : forall {a n} -> Vec a n -> Vec a n
reverse {a} = foldl (Vec a) (\rev x -> x ∷ rev) []
-}

revcat : forall {a m n} -> Vec a m -> Vec a n -> Vec a (m + n)
revcat {a}{m}{n} xs ys = foldl (\i -> Vec a (i + n)) (\rev x -> x ∷  
rev) ys xs

lemma : forall {a m} (xs : Vec a m) -> reverse xs ≅ revcat xs []
lemma xs = {! !}
   where
      n+0=n = (proj₂ (CommutativeSemiring.+-identity  
commutativeSemiring))
         where open CommutativeSemiring commutativeSemiring


More information about the Agda mailing list