86 lines
2.6 KiB
Text
86 lines
2.6 KiB
Text
/-
|
|
Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
Author: Leonardo de Moura
|
|
|
|
Heterogeneous lists
|
|
-/
|
|
import data.list logic.cast
|
|
open list
|
|
|
|
inductive hlist {A : Type} (B : A → Type) : list A → Type :=
|
|
| nil {} : hlist B []
|
|
| cons : ∀ {a : A}, B a → ∀ {l : list A}, hlist B l → hlist B (a::l)
|
|
|
|
namespace hlist
|
|
variables {A : Type} {B : A → Type}
|
|
|
|
definition head : Π {a l}, hlist B (a :: l) → B a
|
|
| a l (cons b h) := b
|
|
|
|
lemma head_cons : ∀ {a l} (b : B a) (h : hlist B l), head (cons b h) = b :=
|
|
by intros; reflexivity
|
|
|
|
definition tail : Π {a l}, hlist B (a :: l) → hlist B l
|
|
| a l (cons b h) := h
|
|
|
|
lemma tail_cons : ∀ {a l} (b : B a) (h : hlist B l), tail (cons b h) = h :=
|
|
by intros; reflexivity
|
|
|
|
lemma eta_cons : ∀ {a l} (h : hlist B (a::l)), h = cons (head h) (tail h) :=
|
|
begin intros, cases h, esimp end
|
|
|
|
lemma eta_nil : ∀ (h : hlist B []), h = nil :=
|
|
begin intros, cases h, esimp end
|
|
|
|
definition append : Π {l₁ l₂}, hlist B l₁ → hlist B l₂ → hlist B (l₁++l₂)
|
|
| ⌞[]⌟ l₂ nil h₂ := h₂
|
|
| ⌞a::l₁⌟ l₂ (cons b h₁) h₂ := cons b (append h₁ h₂)
|
|
|
|
lemma append_nil_left : ∀ {l} (h : hlist B l), append nil h = h :=
|
|
by intros; reflexivity
|
|
|
|
open eq.ops
|
|
lemma eq_rec_on_cons : ∀ {a₁ a₂ l₁ l₂} (b : B a₁) (h : hlist B l₁) (e : a₁::l₁ = a₂::l₂),
|
|
e ▹ cons b h = cons (head_eq_of_cons_eq e ▹ b) (tail_eq_of_cons_eq e ▹ h) :=
|
|
begin
|
|
intros, injection e with e₁ e₂, revert e, subst a₂, subst l₂, intro e, esimp
|
|
end
|
|
|
|
lemma append_nil_right : ∀ {l} (h : hlist B l), append h nil = (list.append_nil_right l)⁻¹ ▹ h
|
|
| [] nil := by esimp
|
|
| (a::l) (cons b h) :=
|
|
begin
|
|
unfold append, rewrite [append_nil_right h], xrewrite eq_rec_on_cons
|
|
end
|
|
|
|
lemma append_nil_right_heq {l} (h : hlist B l) : append h nil == h :=
|
|
by rewrite append_nil_right; apply eq_rec_heq
|
|
|
|
section get
|
|
variables [decA : decidable_eq A]
|
|
include decA
|
|
|
|
definition get {a : A} : ∀ {l : list A}, hlist B l → a ∈ l → B a
|
|
| [] nil e := absurd e !not_mem_nil
|
|
| (t::l) (cons b h) e :=
|
|
or.by_cases (eq_or_mem_of_mem_cons e)
|
|
(suppose a = t, by subst t; exact b)
|
|
(suppose a ∈ l, get h this)
|
|
end get
|
|
|
|
section map
|
|
variable {C : A → Type}
|
|
variable (f : Π ⦃a⦄, B a → C a)
|
|
|
|
definition map : ∀ {l}, hlist B l → hlist C l
|
|
| ⌞[]⌟ nil := nil
|
|
| ⌞a::l⌟ (cons b h) := cons (f b) (map h)
|
|
|
|
lemma map_nil : map f nil = nil :=
|
|
rfl
|
|
|
|
lemma map_cons : ∀ {a l} (b : B a) (h : hlist B l), map f (cons b h) = cons (f b) (map f h) :=
|
|
by intros; reflexivity
|
|
end map
|
|
end hlist
|