[Agda] Proof involving associativity of ++ of vectors

Shin-Cheng Mu scm at iis.sinica.edu.tw
Fri Oct 16 15:38:53 CEST 2009


Hi,

I have encountered this proof pattern a number of times, but
cannot figure out how to do the proof in Agda.

The property I want to prove is something like:

    thm : ∀ xs → P xs → Q xs

for vectors xs. Proving by induction, P (x ∷ xs) can be
reduced to P xs, but Q (x ∷ xs) and R (x ∷ xs) are just
themselves. So we try to prove a more general theorem:

    thm' : ∀ xs zs → P xs → Q (zs ++ xs)

The inductive case, if done by hand, would be something like:

        P (x : xs)
    =>  P xs
    =>    { induction (thm' xs (zs ++ [ x ])) }
        Q ((zs ++ [ x ]) ++ xs)
    ==  Q (zs ++ x ∷ xs)

Proving the theorem in Agda, I'd ideally like to do something
like:

    thm' : ∀ {m n} (xs : Vec A m) → (zs : Vec A n) →
             P xs → Q (zs ++ xs)
    thm' [] ... = ...
    thm' (x ∷ xs) zs pxs = thm' xs (zs ++ [ x ]) pxs

But apparently it does not type check, for the call to thm' has
type Q (zs ++ [ x ] ++ xs) while we need Q (zs ++ x ∷ xs),
and the result type is wrong for the same reason.

So it seems that I need to perform a type cast:

    thm (x ∷ xs) zs pxs qzsxs =
        subst (λ ws → Q ws) eq1 (thm xs (zs ++ [ x ]) pxs)   -- (*)

assuming that I can prove

   eq1 : ∀ {a m n} (xs : Vec a m) (x : a) (ys : Vec a n) →
                    (xs ++ [ x ]) ++ ys ≅ xs ++ (x ∷ ys)

But I am not even allowed to do this type cast -- Agda complains
about the type of ws in (*). Indeed, when we look at the type
of subst:

   subst : ∀ {a} (Q : a → Set) → ∀ {x y} → x ≅ y → Q x  
→ Q y

We notice that, in Q (zs ++ [ x ] ++ xs) and Q (zs ++ x ∷ xs),
Q is applied to arguments of different types, so we don't know
how to instantiate a in the type of subst.

I will probably have to resort to implement the type casting
Q ((xs ++ [ x ]) ++ ys) → Q (xs ++ (x ∷ ys)) for the special
case of Q (which I have not tried -- hope I won't run into the
same problem in a different level). But is there a better way
to do this kind of proof?

In one desperate attempt I tried to define

   rev : ∀ {a m n} → Vec₁ a m → Vec₁ a n → Vec₁ a (m + n)
   rev [] ys = ys
   rev (x ∷ xs) ys = rev xs (x ∷ ys)     -- (**)

(we also need a subst in (**)) and tried to prove

   thm'' : ∀ {m n} (xs : Vec A m) → (zs : Vec A n) →
             P xs → Q (rev zs xs)

hoping rev would make it easer to show that Q (rev (z ∷ zs) xs)
equals Q (rev zs (z ∷ xs)). However, rev (z ∷ zs) xs and
rev zs (z ∷ xs) still have different types and it seems that I
still need some complicated type casting so I gave up there.

Thanks!

sincerely,
Shin



More information about the Agda mailing list