Search code examples
coqdependent-typetheorem-proving

Coq vector: shiftin, shiftout, and last


I am working on a verification problem in Coq that requires extensive use of the standard vector library Coq.Vectors. There are many useful definitions, but I don't see some desired properties being proved.

I need to operate on the last element in a vector. I think shiftin and last-shiftout form an inverse on the non-empty vector. But I failed to prove the following.

From Coq Require Import Vector.

Lemma shiftin_last_shiftout:
  forall A (n:nat) (x: t A (S n)),
  x = shiftin (last x) (shiftout x).

Solution

  • This lemma can be proven rather straightforwardly by first proving a helper lemma. Specifically, if we know that shiftin (last t0) (shiftout t0) = t0, then the rest quickly follows. Proving that helper lemma requires a trick:

    From Coq Require Import Vector.
    
    Lemma vec_shiftin_eq' A n (t0 : t A n) :
      match n as n' return t A n' -> Prop with 0 => fun _ => True | S nn =>
          fun t0 => shiftin (last t0) (shiftout t0) = t0 end t0.
    Proof.
      induction t0 as [|el1 n t0' IH]; [easy|].
      destruct t0' as [|el2 n t0']; [easy|].
      simpl in IH|-*. rewrite IH. easy.
    Qed.
    
    Lemma vec_shiftin_eq A n (t0 t1 : t A (S n)) :
        t0 = t1 <-> shiftin (last t0) (shiftout t0) = shiftin (last t1) (shiftout t1).
    Proof. now rewrite !(vec_shiftin_eq' A (S n)). Qed.
    
    Print Assumptions vec_shiftin_eq.
    (* Closed under the global context *)
    

    We want to prove our helper lemma by induction on the vector. But induction on the vector always requires that the n indicating its length is unconstrained, i.e. that it is a free variable. Doing induction where it is S n does not work. To work around this, we are forced to generalize the induction statement to something that works for all n, which requires saying what should hold at n=0. We say that nothing interesting is happening at n=0, i.e. True. With this, the induction goes through without a hinch.