refactor(library/data): rename fixed_list -> tuple
This commit is contained in:
parent
9bb778dc7c
commit
49eb7166f0
3 changed files with 66 additions and 66 deletions
|
@ -16,9 +16,9 @@ the expression =v = w= since it would not be able to establish that
|
||||||
_definitionally equal_.
|
_definitionally equal_.
|
||||||
|
|
||||||
#+BEGIN_SRC lean
|
#+BEGIN_SRC lean
|
||||||
import data.fixed_list data.nat
|
import data.tuple data.nat
|
||||||
open nat
|
open nat
|
||||||
check λ (v : fixed_list nat (2+3)) (w : fixed_list nat 5), v = w
|
check λ (v : tuple nat (2+3)) (w : tuple nat 5), v = w
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
Similarly, the following definition only type checks because =id= is transparent, and the type checker can establish that
|
Similarly, the following definition only type checks because =id= is transparent, and the type checker can establish that
|
||||||
|
|
|
@ -6,7 +6,7 @@ Author: Floris van Doorn, Leonardo de Moura
|
||||||
This file demonstrates how to encode vectors using indexed inductive families.
|
This file demonstrates how to encode vectors using indexed inductive families.
|
||||||
In standard library we do not use this approach.
|
In standard library we do not use this approach.
|
||||||
-/
|
-/
|
||||||
import data.nat data.list data.fin data.fixed_list
|
import data.nat data.list data.fin
|
||||||
open nat prod fin
|
open nat prod fin
|
||||||
|
|
||||||
inductive vector (A : Type) : nat → Type :=
|
inductive vector (A : Type) : nat → Type :=
|
||||||
|
|
|
@ -3,51 +3,51 @@ Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
||||||
Released under Apache 2.0 license as described in the file LICENSE.
|
Released under Apache 2.0 license as described in the file LICENSE.
|
||||||
Author: Leonardo de Moura
|
Author: Leonardo de Moura
|
||||||
|
|
||||||
The length of a list is encoded into its type.
|
Tuples are lists of a fixed size.
|
||||||
It is implemented as a subtype.
|
It is implemented as a subtype.
|
||||||
-/
|
-/
|
||||||
import logic data.list data.fin
|
import logic data.list data.fin
|
||||||
open nat list subtype function
|
open nat list subtype function
|
||||||
|
|
||||||
definition fixed_list [reducible] (A : Type) (n : nat) := {l : list A | length l = n}
|
definition tuple [reducible] (A : Type) (n : nat) := {l : list A | length l = n}
|
||||||
|
|
||||||
namespace fixed_list
|
namespace tuple
|
||||||
variables {A B C : Type}
|
variables {A B C : Type}
|
||||||
|
|
||||||
theorem induction_on [recursor 4] {P : ∀ {n}, fixed_list A n → Prop}
|
theorem induction_on [recursor 4] {P : ∀ {n}, tuple A n → Prop}
|
||||||
: ∀ {n} (v : fixed_list A n), (∀ (l : list A) {n : nat} (h : length l = n), P (tag l h)) → P v
|
: ∀ {n} (v : tuple A n), (∀ (l : list A) {n : nat} (h : length l = n), P (tag l h)) → P v
|
||||||
| n (tag l h) H := @H l n h
|
| n (tag l h) H := @H l n h
|
||||||
|
|
||||||
definition nil : fixed_list A 0 :=
|
definition nil : tuple A 0 :=
|
||||||
tag [] rfl
|
tag [] rfl
|
||||||
|
|
||||||
lemma length_succ {n : nat} {l : list A} (a : A) : length l = n → length (a::l) = succ n :=
|
lemma length_succ {n : nat} {l : list A} (a : A) : length l = n → length (a::l) = succ n :=
|
||||||
λ h, congr_arg succ h
|
λ h, congr_arg succ h
|
||||||
|
|
||||||
definition cons {n : nat} : A → fixed_list A n → fixed_list A (succ n)
|
definition cons {n : nat} : A → tuple A n → tuple A (succ n)
|
||||||
| a (tag v h) := tag (a::v) (length_succ a h)
|
| a (tag v h) := tag (a::v) (length_succ a h)
|
||||||
|
|
||||||
notation a :: b := cons a b
|
notation a :: b := cons a b
|
||||||
|
|
||||||
protected definition is_inhabited [instance] [h : inhabited A] : ∀ (n : nat), inhabited (fixed_list A n)
|
protected definition is_inhabited [instance] [h : inhabited A] : ∀ (n : nat), inhabited (tuple A n)
|
||||||
| 0 := inhabited.mk nil
|
| 0 := inhabited.mk nil
|
||||||
| (succ n) := inhabited.mk (inhabited.value h :: inhabited.value (is_inhabited n))
|
| (succ n) := inhabited.mk (inhabited.value h :: inhabited.value (is_inhabited n))
|
||||||
|
|
||||||
protected definition has_decidable_eq [instance] [h : decidable_eq A] : ∀ (n : nat), decidable_eq (fixed_list A n) :=
|
protected definition has_decidable_eq [instance] [h : decidable_eq A] : ∀ (n : nat), decidable_eq (tuple A n) :=
|
||||||
_
|
_
|
||||||
|
|
||||||
definition head {n : nat} : fixed_list A (succ n) → A
|
definition head {n : nat} : tuple A (succ n) → A
|
||||||
| (tag [] h) := by contradiction
|
| (tag [] h) := by contradiction
|
||||||
| (tag (a::v) h) := a
|
| (tag (a::v) h) := a
|
||||||
|
|
||||||
definition tail {n : nat} : fixed_list A (succ n) → fixed_list A n
|
definition tail {n : nat} : tuple A (succ n) → tuple A n
|
||||||
| (tag [] h) := by contradiction
|
| (tag [] h) := by contradiction
|
||||||
| (tag (a::v) h) := tag v (succ.inj h)
|
| (tag (a::v) h) := tag v (succ.inj h)
|
||||||
|
|
||||||
theorem head_cons {n : nat} (a : A) (v : fixed_list A n) : head (a :: v) = a :=
|
theorem head_cons {n : nat} (a : A) (v : tuple A n) : head (a :: v) = a :=
|
||||||
by induction v; reflexivity
|
by induction v; reflexivity
|
||||||
|
|
||||||
theorem tail_cons {n : nat} (a : A) (v : fixed_list A n) : tail (a :: v) = v :=
|
theorem tail_cons {n : nat} (a : A) (v : tuple A n) : tail (a :: v) = v :=
|
||||||
by induction v; reflexivity
|
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 :=
|
theorem head_lcons {n : nat} (a : A) (l : list A) (h : length (a::l) = succ n) : head (tag (a::l) h) = a :=
|
||||||
|
@ -56,19 +56,19 @@ namespace fixed_list
|
||||||
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) :=
|
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
|
rfl
|
||||||
|
|
||||||
definition last {n : nat} : fixed_list A (succ n) → A
|
definition last {n : nat} : tuple A (succ n) → A
|
||||||
| (tag l h) := list.last l (ne_nil_of_length_eq_succ h)
|
| (tag l h) := list.last l (ne_nil_of_length_eq_succ h)
|
||||||
|
|
||||||
theorem eta : ∀ {n : nat} (v : fixed_list A (succ n)), head v :: tail v = v
|
theorem eta : ∀ {n : nat} (v : tuple A (succ n)), head v :: tail v = v
|
||||||
| 0 (tag [] h) := by contradiction
|
| 0 (tag [] h) := by contradiction
|
||||||
| 0 (tag (a::l) h) := rfl
|
| 0 (tag (a::l) h) := rfl
|
||||||
| (n+1) (tag [] h) := by contradiction
|
| (n+1) (tag [] h) := by contradiction
|
||||||
| (n+1) (tag (a::l) h) := rfl
|
| (n+1) (tag (a::l) h) := rfl
|
||||||
|
|
||||||
definition of_list (l : list A) : fixed_list A (list.length l) :=
|
definition of_list (l : list A) : tuple A (list.length l) :=
|
||||||
tag l rfl
|
tag l rfl
|
||||||
|
|
||||||
definition to_list {n : nat} : fixed_list A n → list A
|
definition to_list {n : nat} : tuple A n → list A
|
||||||
| (tag l h) := l
|
| (tag l h) := l
|
||||||
|
|
||||||
theorem to_list_of_list (l : list A) : to_list (of_list l) = l :=
|
theorem to_list_of_list (l : list A) : to_list (of_list l) = l :=
|
||||||
|
@ -77,10 +77,10 @@ namespace fixed_list
|
||||||
theorem to_list_nil : to_list nil = ([] : list A) :=
|
theorem to_list_nil : to_list nil = ([] : list A) :=
|
||||||
rfl
|
rfl
|
||||||
|
|
||||||
theorem length_to_list {n : nat} : ∀ (v : fixed_list A n), list.length (to_list v) = n
|
theorem length_to_list {n : nat} : ∀ (v : tuple A n), list.length (to_list v) = n
|
||||||
| (tag l h) := h
|
| (tag l h) := h
|
||||||
|
|
||||||
theorem heq_of_list_eq {n m} : ∀ {v₁ : fixed_list A n} {v₂ : fixed_list A m}, to_list v₁ = to_list v₂ → n = m → v₁ == v₂
|
theorem heq_of_list_eq {n m} : ∀ {v₁ : tuple A n} {v₂ : tuple A m}, to_list v₁ = to_list v₂ → n = m → v₁ == v₂
|
||||||
| (tag l₁ h₁) (tag l₂ h₂) e₁ e₂ := begin
|
| (tag l₁ h₁) (tag l₂ h₂) e₁ e₂ := begin
|
||||||
clear heq_of_list_eq,
|
clear heq_of_list_eq,
|
||||||
subst e₂, subst h₁,
|
subst e₂, subst h₁,
|
||||||
|
@ -88,20 +88,20 @@ namespace fixed_list
|
||||||
subst l₁
|
subst l₁
|
||||||
end
|
end
|
||||||
|
|
||||||
theorem list_eq_of_heq {n m} {v₁ : fixed_list A n} {v₂ : fixed_list A m} : v₁ == v₂ → n = m → to_list v₁ = to_list v₂ :=
|
theorem list_eq_of_heq {n m} {v₁ : tuple A n} {v₂ : tuple A m} : v₁ == v₂ → n = m → to_list v₁ = to_list v₂ :=
|
||||||
begin
|
begin
|
||||||
intro h₁ h₂, revert v₁ v₂ h₁,
|
intro h₁ h₂, revert v₁ v₂ h₁,
|
||||||
subst n, intro v₁ v₂ h₁, rewrite [heq.to_eq h₁]
|
subst n, intro v₁ v₂ h₁, rewrite [heq.to_eq h₁]
|
||||||
end
|
end
|
||||||
|
|
||||||
theorem of_list_to_list {n : nat} (v : fixed_list A n) : of_list (to_list v) == v :=
|
theorem of_list_to_list {n : nat} (v : tuple A n) : of_list (to_list v) == v :=
|
||||||
begin
|
begin
|
||||||
apply heq_of_list_eq, rewrite to_list_of_list, rewrite length_to_list
|
apply heq_of_list_eq, rewrite to_list_of_list, rewrite length_to_list
|
||||||
end
|
end
|
||||||
|
|
||||||
/- append -/
|
/- append -/
|
||||||
|
|
||||||
definition append {n m : nat} : fixed_list A n → fixed_list A m → fixed_list A (n + m)
|
definition append {n m : nat} : tuple A n → tuple A m → tuple A (n + m)
|
||||||
| (tag l₁ h₁) (tag l₂ h₂) := tag (list.append l₁ l₂) (by rewrite [length_append, h₁, h₂])
|
| (tag l₁ h₁) (tag l₂ h₂) := tag (list.append l₁ l₂) (by rewrite [length_append, h₁, h₂])
|
||||||
|
|
||||||
infix ++ := append
|
infix ++ := append
|
||||||
|
@ -111,40 +111,40 @@ namespace fixed_list
|
||||||
lemma push_eq_rec : ∀ {n m : nat} {l : list A} (h₁ : n = m) (h₂ : length l = n), h₁ ▹ (tag l h₂) = tag l (h₁ ▹ h₂)
|
lemma push_eq_rec : ∀ {n m : nat} {l : list A} (h₁ : n = m) (h₂ : length l = n), h₁ ▹ (tag l h₂) = tag l (h₁ ▹ h₂)
|
||||||
| n n l (eq.refl n) h₂ := rfl
|
| n n l (eq.refl n) h₂ := rfl
|
||||||
|
|
||||||
theorem append_nil_right {n : nat} (v : fixed_list A n) : v ++ nil = v :=
|
theorem append_nil_right {n : nat} (v : tuple A n) : v ++ nil = v :=
|
||||||
induction_on v (λ l n h, by unfold [fixed_list.append, fixed_list.nil]; congruence; apply list.append_nil_right)
|
induction_on v (λ l n h, by unfold [tuple.append, tuple.nil]; congruence; apply list.append_nil_right)
|
||||||
|
|
||||||
theorem append_nil_left {n : nat} (v : fixed_list A n) : !zero_add ▹ (nil ++ v) = v :=
|
theorem append_nil_left {n : nat} (v : tuple A n) : !zero_add ▹ (nil ++ v) = v :=
|
||||||
induction_on v (λ l n h, begin unfold [fixed_list.append, fixed_list.nil], rewrite [push_eq_rec] end)
|
induction_on v (λ l n h, begin unfold [tuple.append, tuple.nil], rewrite [push_eq_rec] end)
|
||||||
|
|
||||||
theorem append_nil_left_heq {n : nat} (v : fixed_list A n) : nil ++ v == v :=
|
theorem append_nil_left_heq {n : nat} (v : tuple A n) : nil ++ v == v :=
|
||||||
heq_of_eq_rec_left !zero_add (append_nil_left v)
|
heq_of_eq_rec_left !zero_add (append_nil_left v)
|
||||||
|
|
||||||
theorem append.assoc {n₁ n₂ n₃} : ∀ (v₁ : fixed_list A n₁) (v₂ : fixed_list A n₂) (v₃ : fixed_list A n₃), !add.assoc ▹ ((v₁ ++ v₂) ++ v₃) = v₁ ++ (v₂ ++ v₃)
|
theorem append.assoc {n₁ n₂ n₃} : ∀ (v₁ : tuple A n₁) (v₂ : tuple A n₂) (v₃ : tuple A n₃), !add.assoc ▹ ((v₁ ++ v₂) ++ v₃) = v₁ ++ (v₂ ++ v₃)
|
||||||
| (tag l₁ h₁) (tag l₂ h₂) (tag l₃ h₃) := begin
|
| (tag l₁ h₁) (tag l₂ h₂) (tag l₃ h₃) := begin
|
||||||
unfold fixed_list.append, rewrite push_eq_rec,
|
unfold tuple.append, rewrite push_eq_rec,
|
||||||
congruence,
|
congruence,
|
||||||
apply list.append.assoc
|
apply list.append.assoc
|
||||||
end
|
end
|
||||||
|
|
||||||
theorem append.assoc_heq {n₁ n₂ n₃} (v₁ : fixed_list A n₁) (v₂ : fixed_list A n₂) (v₃ : fixed_list A n₃) : (v₁ ++ v₂) ++ v₃ == v₁ ++ (v₂ ++ v₃) :=
|
theorem append.assoc_heq {n₁ n₂ n₃} (v₁ : tuple A n₁) (v₂ : tuple A n₂) (v₃ : tuple A n₃) : (v₁ ++ v₂) ++ v₃ == v₁ ++ (v₂ ++ v₃) :=
|
||||||
heq_of_eq_rec_left !add.assoc (append.assoc v₁ v₂ v₃)
|
heq_of_eq_rec_left !add.assoc (append.assoc v₁ v₂ v₃)
|
||||||
|
|
||||||
/- reverse -/
|
/- reverse -/
|
||||||
|
|
||||||
definition reverse {n : nat} : fixed_list A n → fixed_list A n
|
definition reverse {n : nat} : tuple A n → tuple A n
|
||||||
| (tag l h) := tag (list.reverse l) (by rewrite [length_reverse, h])
|
| (tag l h) := tag (list.reverse l) (by rewrite [length_reverse, h])
|
||||||
|
|
||||||
theorem reverse_reverse {n : nat} (v : fixed_list A n) : reverse (reverse v) = v :=
|
theorem reverse_reverse {n : nat} (v : tuple A n) : reverse (reverse v) = v :=
|
||||||
induction_on v (λ l n h, begin unfold reverse, congruence, apply list.reverse_reverse end)
|
induction_on v (λ l n h, begin unfold reverse, congruence, apply list.reverse_reverse end)
|
||||||
|
|
||||||
theorem fixed_list0_eq_nil : ∀ (v : fixed_list A 0), v = nil
|
theorem tuple0_eq_nil : ∀ (v : tuple A 0), v = nil
|
||||||
| (tag [] h) := rfl
|
| (tag [] h) := rfl
|
||||||
| (tag (a::l) h) := by contradiction
|
| (tag (a::l) h) := by contradiction
|
||||||
|
|
||||||
/- mem -/
|
/- mem -/
|
||||||
|
|
||||||
definition mem {n : nat} (a : A) (v : fixed_list A n) : Prop :=
|
definition mem {n : nat} (a : A) (v : tuple A n) : Prop :=
|
||||||
a ∈ elt_of v
|
a ∈ elt_of v
|
||||||
|
|
||||||
notation e ∈ s := mem e s
|
notation e ∈ s := mem e s
|
||||||
|
@ -153,101 +153,101 @@ namespace fixed_list
|
||||||
theorem not_mem_nil (a : A) : a ∉ nil :=
|
theorem not_mem_nil (a : A) : a ∉ nil :=
|
||||||
list.not_mem_nil a
|
list.not_mem_nil a
|
||||||
|
|
||||||
theorem mem_cons [simp] {n : nat} (a : A) (v : fixed_list A n) : a ∈ a :: v :=
|
theorem mem_cons [simp] {n : nat} (a : A) (v : tuple A n) : a ∈ a :: v :=
|
||||||
induction_on v (λ l n h, !list.mem_cons)
|
induction_on v (λ l n h, !list.mem_cons)
|
||||||
|
|
||||||
theorem mem_cons_of_mem {n : nat} (y : A) {x : A} {v : fixed_list A n} : x ∈ v → x ∈ y :: v :=
|
theorem mem_cons_of_mem {n : nat} (y : A) {x : A} {v : tuple A n} : x ∈ v → x ∈ y :: v :=
|
||||||
induction_on v (λ l n h₁ h₂, list.mem_cons_of_mem y h₂)
|
induction_on v (λ l n h₁ h₂, list.mem_cons_of_mem y h₂)
|
||||||
|
|
||||||
theorem eq_or_mem_of_mem_cons {n : nat} {x y : A} {v : fixed_list A n} : x ∈ y::v → x = y ∨ x ∈ v :=
|
theorem eq_or_mem_of_mem_cons {n : nat} {x y : A} {v : tuple A n} : x ∈ y::v → x = y ∨ x ∈ v :=
|
||||||
induction_on v (λ l n h₁ h₂, eq_or_mem_of_mem_cons h₂)
|
induction_on v (λ l n h₁ h₂, eq_or_mem_of_mem_cons h₂)
|
||||||
|
|
||||||
theorem mem_singleton {n : nat} {x a : A} : x ∈ (a::nil : fixed_list A 1) → x = a :=
|
theorem mem_singleton {n : nat} {x a : A} : x ∈ (a::nil : tuple A 1) → x = a :=
|
||||||
assume h, list.mem_singleton h
|
assume h, list.mem_singleton h
|
||||||
|
|
||||||
/- map -/
|
/- map -/
|
||||||
|
|
||||||
definition map {n : nat} (f : A → B) : fixed_list A n → fixed_list B n
|
definition map {n : nat} (f : A → B) : tuple A n → tuple B n
|
||||||
| (tag l h) := tag (list.map f l) (by clear map; substvars; rewrite length_map)
|
| (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 :=
|
theorem map_nil (f : A → B) : map f nil = nil :=
|
||||||
rfl
|
rfl
|
||||||
|
|
||||||
theorem map_cons {n : nat} (f : A → B) (a : A) (v : fixed_list A n) : map f (a::v) = f a :: map f v :=
|
theorem map_cons {n : nat} (f : A → B) (a : A) (v : tuple A n) : map f (a::v) = f a :: map f v :=
|
||||||
by induction v; reflexivity
|
by induction v; reflexivity
|
||||||
|
|
||||||
theorem map_tag {n : nat} (f : A → B) (l : list A) (h : length l = n)
|
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) :=
|
: map f (tag l h) = tag (list.map f l) (by substvars; rewrite length_map) :=
|
||||||
by reflexivity
|
by reflexivity
|
||||||
|
|
||||||
theorem map_map {n : nat} (g : B → C) (f : A → B) (v : fixed_list A n) : map g (map f v) = map (g ∘ f) v :=
|
theorem map_map {n : nat} (g : B → C) (f : A → B) (v : tuple 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
|
begin cases v, rewrite *map_tag, apply subtype.eq, apply list.map_map end
|
||||||
|
|
||||||
theorem map_id {n : nat} (v : fixed_list A n) : map id v = v :=
|
theorem map_id {n : nat} (v : tuple A n) : map id v = v :=
|
||||||
begin induction v, unfold map, congruence, apply list.map_id end
|
begin induction v, unfold map, congruence, apply list.map_id end
|
||||||
|
|
||||||
theorem mem_map {n : nat} {a : A} {v : fixed_list A n} (f : A → B) : a ∈ v → f a ∈ map f v :=
|
theorem mem_map {n : nat} {a : A} {v : tuple A n} (f : A → B) : a ∈ v → f a ∈ map f v :=
|
||||||
begin induction v, unfold map, apply list.mem_map end
|
begin induction v, unfold map, apply list.mem_map end
|
||||||
|
|
||||||
theorem exists_of_mem_map {n : nat} {f : A → B} {b : B} {v : fixed_list A n} : b ∈ map f v → ∃a, a ∈ v ∧ f a = b :=
|
theorem exists_of_mem_map {n : nat} {f : A → B} {b : B} {v : tuple A n} : b ∈ map f v → ∃a, a ∈ v ∧ f a = b :=
|
||||||
begin induction v, unfold map, apply list.exists_of_mem_map end
|
begin induction v, unfold map, apply list.exists_of_mem_map end
|
||||||
|
|
||||||
theorem eq_of_map_const {n : nat} {b₁ b₂ : B} {v : fixed_list A n} : b₁ ∈ map (const A b₂) v → b₁ = b₂ :=
|
theorem eq_of_map_const {n : nat} {b₁ b₂ : B} {v : tuple A n} : b₁ ∈ map (const A b₂) v → b₁ = b₂ :=
|
||||||
begin induction v, unfold map, apply list.eq_of_map_const end
|
begin induction v, unfold map, apply list.eq_of_map_const end
|
||||||
|
|
||||||
/- product -/
|
/- product -/
|
||||||
|
|
||||||
definition product {n m : nat} : fixed_list A n → fixed_list B m → fixed_list (A × B) (n * m)
|
definition product {n m : nat} : tuple A n → tuple B m → tuple (A × B) (n * m)
|
||||||
| (tag l₁ h₁) (tag l₂ h₂) := tag (list.product l₁ l₂) (by rewrite [length_product, h₁, h₂])
|
| (tag l₁ h₁) (tag l₂ h₂) := tag (list.product l₁ l₂) (by rewrite [length_product, h₁, h₂])
|
||||||
|
|
||||||
theorem nil_product {m : nat} (v : fixed_list B m) : !zero_mul ▹ product (@nil A) v = nil :=
|
theorem nil_product {m : nat} (v : tuple B m) : !zero_mul ▹ product (@nil A) v = nil :=
|
||||||
begin induction v, unfold [nil, product], rewrite push_eq_rec end
|
begin induction v, unfold [nil, product], rewrite push_eq_rec end
|
||||||
|
|
||||||
theorem nil_product_heq {m : nat} (v : fixed_list B m) : product (@nil A) v == (@nil (A × B)) :=
|
theorem nil_product_heq {m : nat} (v : tuple B m) : product (@nil A) v == (@nil (A × B)) :=
|
||||||
heq_of_eq_rec_left _ (nil_product v)
|
heq_of_eq_rec_left _ (nil_product v)
|
||||||
|
|
||||||
theorem product_nil {n : nat} (v : fixed_list A n) : product v (@nil B) = nil :=
|
theorem product_nil {n : nat} (v : tuple A n) : product v (@nil B) = nil :=
|
||||||
begin induction v, unfold [nil, product], congruence, apply list.product_nil end
|
begin induction v, unfold [nil, product], congruence, apply list.product_nil end
|
||||||
|
|
||||||
theorem mem_product {n m : nat} {a : A} {b : B} {v₁ : fixed_list A n} {v₂ : fixed_list B m} : a ∈ v₁ → b ∈ v₂ → (a, b) ∈ product v₁ v₂ :=
|
theorem mem_product {n m : nat} {a : A} {b : B} {v₁ : tuple A n} {v₂ : tuple B m} : a ∈ v₁ → b ∈ v₂ → (a, b) ∈ product v₁ v₂ :=
|
||||||
begin cases v₁, cases v₂, unfold product, apply list.mem_product end
|
begin cases v₁, cases v₂, unfold product, apply list.mem_product end
|
||||||
|
|
||||||
theorem mem_of_mem_product_left {n m : nat} {a : A} {b : B} {v₁ : fixed_list A n} {v₂ : fixed_list B m} : (a, b) ∈ product v₁ v₂ → a ∈ v₁ :=
|
theorem mem_of_mem_product_left {n m : nat} {a : A} {b : B} {v₁ : tuple A n} {v₂ : tuple B m} : (a, b) ∈ product v₁ v₂ → a ∈ v₁ :=
|
||||||
begin cases v₁, cases v₂, unfold product, apply list.mem_of_mem_product_left end
|
begin cases v₁, cases v₂, unfold product, apply list.mem_of_mem_product_left end
|
||||||
|
|
||||||
theorem mem_of_mem_product_right {n m : nat} {a : A} {b : B} {v₁ : fixed_list A n} {v₂ : fixed_list B m} : (a, b) ∈ product v₁ v₂ → b ∈ v₂ :=
|
theorem mem_of_mem_product_right {n m : nat} {a : A} {b : B} {v₁ : tuple A n} {v₂ : tuple B m} : (a, b) ∈ product v₁ v₂ → b ∈ v₂ :=
|
||||||
begin cases v₁, cases v₂, unfold product, apply list.mem_of_mem_product_right end
|
begin cases v₁, cases v₂, unfold product, apply list.mem_of_mem_product_right end
|
||||||
|
|
||||||
/- ith -/
|
/- ith -/
|
||||||
open fin
|
open fin
|
||||||
|
|
||||||
definition ith {n : nat} : fixed_list A n → fin n → A
|
definition ith {n : nat} : tuple A n → fin n → A
|
||||||
| (tag l h₁) (mk i h₂) := list.ith l i (by rewrite h₁; exact h₂)
|
| (tag l h₁) (mk i h₂) := list.ith l i (by rewrite h₁; exact h₂)
|
||||||
|
|
||||||
lemma ith_zero {n : nat} (a : A) (v : fixed_list A n) (h : 0 < succ n) : ith (a::v) (mk 0 h) = a :=
|
lemma ith_zero {n : nat} (a : A) (v : tuple A n) (h : 0 < succ n) : ith (a::v) (mk 0 h) = a :=
|
||||||
by induction v; reflexivity
|
by induction v; reflexivity
|
||||||
|
|
||||||
lemma ith_fin_zero {n : nat} (a : A) (v : fixed_list A n) : ith (a::v) (zero n) = a :=
|
lemma ith_fin_zero {n : nat} (a : A) (v : tuple A n) : ith (a::v) (zero n) = a :=
|
||||||
by unfold zero; apply ith_zero
|
by unfold zero; apply ith_zero
|
||||||
|
|
||||||
lemma ith_succ {n : nat} (a : A) (v : fixed_list A n) (i : nat) (h : succ i < succ n)
|
lemma ith_succ {n : nat} (a : A) (v : tuple A n) (i : nat) (h : succ i < succ n)
|
||||||
: ith (a::v) (mk (succ i) h) = ith v (mk_pred i h) :=
|
: ith (a::v) (mk (succ i) h) = ith v (mk_pred i h) :=
|
||||||
by induction v; reflexivity
|
by induction v; reflexivity
|
||||||
|
|
||||||
lemma ith_fin_succ {n : nat} (a : A) (v : fixed_list A n) (i : fin n)
|
lemma ith_fin_succ {n : nat} (a : A) (v : tuple A n) (i : fin n)
|
||||||
: ith (a::v) (succ i) = ith v i :=
|
: ith (a::v) (succ i) = ith v i :=
|
||||||
begin cases i, unfold fin.succ, rewrite ith_succ end
|
begin cases i, unfold fin.succ, rewrite ith_succ end
|
||||||
|
|
||||||
lemma ith_zero_eq_head {n : nat} (v : fixed_list A (nat.succ n)) : ith v (zero n) = head v :=
|
lemma ith_zero_eq_head {n : nat} (v : tuple A (nat.succ n)) : ith v (zero n) = head v :=
|
||||||
by rewrite [-eta v, ith_fin_zero, head_cons]
|
by rewrite [-eta v, ith_fin_zero, head_cons]
|
||||||
|
|
||||||
lemma ith_succ_eq_ith_tail {n : nat} (v : fixed_list A (nat.succ n)) (i : fin n) : ith v (succ i) = ith (tail v) i :=
|
lemma ith_succ_eq_ith_tail {n : nat} (v : tuple A (nat.succ n)) (i : fin n) : ith v (succ i) = ith (tail v) i :=
|
||||||
by rewrite [-eta v, ith_fin_succ, tail_cons]
|
by rewrite [-eta v, ith_fin_succ, tail_cons]
|
||||||
|
|
||||||
protected lemma ext {n : nat} (v₁ v₂ : fixed_list A n) (h : ∀ i : fin n, ith v₁ i = ith v₂ i) : v₁ = v₂ :=
|
protected lemma ext {n : nat} (v₁ v₂ : tuple A n) (h : ∀ i : fin n, ith v₁ i = ith v₂ i) : v₁ = v₂ :=
|
||||||
begin
|
begin
|
||||||
induction n with n ih,
|
induction n with n ih,
|
||||||
rewrite [fixed_list0_eq_nil v₁, fixed_list0_eq_nil v₂],
|
rewrite [tuple0_eq_nil v₁, tuple0_eq_nil v₂],
|
||||||
rewrite [-eta v₁, -eta v₂], congruence,
|
rewrite [-eta v₁, -eta v₂], congruence,
|
||||||
show head v₁ = head v₂, by rewrite [-ith_zero_eq_head, -ith_zero_eq_head]; apply h,
|
show head v₁ = head v₂, by rewrite [-ith_zero_eq_head, -ith_zero_eq_head]; apply h,
|
||||||
have ∀ i : fin n, ith (tail v₁) i = ith (tail v₂) i, from
|
have ∀ i : fin n, ith (tail v₁) i = ith (tail v₂) i, from
|
||||||
|
@ -257,7 +257,7 @@ namespace fixed_list
|
||||||
|
|
||||||
/- tabulate -/
|
/- tabulate -/
|
||||||
|
|
||||||
definition tabulate : Π {n : nat}, (fin n → A) → fixed_list A n
|
definition tabulate : Π {n : nat}, (fin n → A) → tuple A n
|
||||||
| 0 f := nil
|
| 0 f := nil
|
||||||
| (n+1) f := f (@zero n) :: tabulate (λ i : fin n, f (succ i))
|
| (n+1) f := f (@zero n) :: tabulate (λ i : fin n, f (succ i))
|
||||||
|
|
||||||
|
@ -269,4 +269,4 @@ namespace fixed_list
|
||||||
{unfold tabulate, rewrite ith_zero},
|
{unfold tabulate, rewrite ith_zero},
|
||||||
{unfold tabulate, rewrite [ith_succ, ih]}
|
{unfold tabulate, rewrite [ith_succ, ih]}
|
||||||
end
|
end
|
||||||
end fixed_list
|
end tuple
|
Loading…
Reference in a new issue