/- Copyright (c) 2015 Microsoft Corporation. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Author: Leonardo de Moura vectors as list subtype -/ import logic data.list data.subtype algebra.function open nat list subtype function definition vec [reducible] (A : Type) (n : nat) := {l : list A | length l = n} namespace vec variables {A B C : Type} definition nil : vec A 0 := tag [] rfl lemma length_succ {n : nat} {l : list A} (a : A) : length l = n → length (a::l) = succ n := λ h, congr_arg succ h definition cons {n : nat} : A → vec A n → vec A (succ n) | a (tag v h) := tag (a::v) (length_succ a h) notation a :: b := cons a b protected definition is_inhabited [instance] [h : inhabited A] : ∀ (n : nat), inhabited (vec A n) | 0 := inhabited.mk nil | (succ n) := inhabited.mk (inhabited.value h :: inhabited.value (is_inhabited n)) theorem vec0_eq_nil : ∀ (v : vec A 0), v = nil | (tag [] h) := rfl | (tag (a::l) h) := by contradiction definition head {n : nat} : vec A (succ n) → A | (tag [] h) := by contradiction | (tag (a::v) h) := a definition tail {n : nat} : vec A (succ n) → vec A n | (tag [] h) := by contradiction | (tag (a::v) h) := tag v (succ_inj h) theorem head_cons {n : nat} (a : A) (v : vec A n) : head (a :: v) = a := by induction v; reflexivity theorem tail_cons {n : nat} (a : A) (v : vec A n) : tail (a :: v) = v := by induction v; reflexivity theorem head_lcons {n : nat} (a : A) (l : list A) (h : length (a::l) = succ n) : head (tag (a::l) h) = a := rfl theorem tail_lcons {n : nat} (a : A) (l : list A) (h : length (a::l) = succ n) : tail (tag (a::l) h) = tag l (succ_inj h) := rfl theorem eta : ∀ {n : nat} (v : vec A (succ n)), head v :: tail v = v | 0 (tag [] h) := by contradiction | 0 (tag (a::l) h) := rfl | (n+1) (tag [] h) := by contradiction | (n+1) (tag (a::l) h) := rfl definition mem {n : nat} (a : A) (v : vec A n) : Prop := a ∈ elt_of v definition last {n : nat} : vec A (succ n) → A | (tag l h) := list.last l (ne_nil_of_length_eq_succ h) definition map {n : nat} (f : A → B) : vec A n → vec B n | (tag l h) := tag (list.map f l) (by clear map; substvars; rewrite length_map) theorem map_nil (f : A → B) : map f nil = nil := rfl theorem map_cons {n : nat} (f : A → B) (a : A) (v : vec A n) : map f (a::v) = f a :: map f v := by induction v; reflexivity theorem map_tag {n : nat} (f : A → B) (l : list A) (h : length l = n) : map f (tag l h) = tag (list.map f l) (by substvars; rewrite length_map) := by reflexivity theorem map_map {n : nat} (g : B → C) (f : A → B) (v : vec A n) : map g (map f v) = map (g ∘ f) v := begin cases v, rewrite *map_tag, apply subtype.eq, apply list.map_map end end vec