lean4-htt/library/data/hlist.lean
Leonardo de Moura 1e6b3614ab feat(frontends/lean): new pattern matching validation
@Kha, we now support variable/constant shadowing in patterns.
A constant may occur in a pattern if it is a constructor or tagged with
the new [pattern] attribute. In the standard library, I have tagged
'add', 'zero', 'one', 'bit0', 'bit1' and 'rfl' with this new attribute.
BTW, arbitrary constants and variables may occur nested in type ascriptions and
inaccessible terms.

Here is an example:

     meta_definition tactic_result_to_string {A : Type} : tactic_result A → string
     | (success a s)   := to_string a
     | (exception ⌞A⌟ e s) := "Exception: " ++ to_string (e ())

I had to use the inaccessible ⌞A⌟ in the example above, otherwise, we would be shadowing the parameter
{A : Type}, and we would get a type error.

The new validation is performed at to_pattern_fn (parser.cpp).
2016-08-07 11:31:11 -07:00

93 lines
2.9 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 :=
sorry -- 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 :=
sorry -- by intros; reflexivity
lemma eta_cons : ∀ {a l} (h : hlist B (a::l)), h = cons (head h) (tail h) :=
sorry -- begin intros, cases h, esimp end
lemma eta_nil : ∀ (h : hlist B []), h = nil :=
sorry -- 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 :=
sorry -- by intros; reflexivity
lemma eq_rec_on_cons : ∀ {a₁ a₂ l₁ l₂} (b : B a₁) (h : hlist B l₁) (e : a₁::l₁ = a₂::l₂),
eq.rec_on e (cons b h) = cons (eq.rec_on (head_eq_of_cons_eq e) b) (eq.rec_on (tail_eq_of_cons_eq e) h) :=
sorry
/-
begin
intros, injection e with e₁ e₂, revert e, subst a₂, subst l₂, intro e, esimp
end
-/
local attribute list.append [reducible]
lemma append_nil_right : ∀ {l} (h : hlist B l), append h nil = eq.rec_on (eq.symm (list.append_nil_right l)) h
:= sorry
/-
| [] nil := by esimp
| (a::l) (cons b h) :=
begin
change (cons b (append h nil)) = (eq.symm (list.append_nil_right (a :: l))) ▹ cons b h,
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 :=
sorry -- 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 a)
| (t::l) (cons b h) e :=
or.by_cases (eq_or_mem_of_mem_cons e)
(suppose a = t, eq.rec_on (eq.symm this) 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) :=
sorry -- by intros; reflexivity
end map
end hlist