feat(library/init/data/rbtree/lemmas): add mem_ins_of_mem lemma
This commit is contained in:
parent
d2b27035ae
commit
1b8f9d6550
2 changed files with 86 additions and 52 deletions
|
|
@ -111,7 +111,7 @@ def contains : rbnode α → α → bool
|
|||
| ordering.gt := contains b x
|
||||
end
|
||||
|
||||
protected def mem : α → rbnode α → Prop
|
||||
def mem : α → rbnode α → Prop
|
||||
| a leaf := false
|
||||
| a (red_node l v r) := mem a l ∨ cmp_using lt a v = ordering.eq ∨ mem a r
|
||||
| a (black_node l v r) := mem a l ∨ cmp_using lt a v = ordering.eq ∨ mem a r
|
||||
|
|
|
|||
|
|
@ -352,42 +352,42 @@ lemma is_searchable_of_is_searchable_of_incomp [is_strict_weak_order α lt] {t}
|
|||
begin
|
||||
induction t; intros; is_searchable_tactic,
|
||||
{ cases lo; simp [lift, *] at *, apply lt_of_lt_of_incomp, assumption, assumption },
|
||||
twice { apply ih_2 hc hs₂ }
|
||||
all_goals { apply ih_2 hc hs₂ }
|
||||
end
|
||||
|
||||
lemma is_searchable_of_incomp_of_is_searchable [is_strict_weak_order α lt] {t} : ∀ {lo lo' hi} (hc : ¬ lt lo' lo ∧ ¬ lt lo lo') (hs : is_searchable lt t (some lo) hi), is_searchable lt t (some lo') hi :=
|
||||
begin
|
||||
induction t; intros; is_searchable_tactic,
|
||||
{ cases hi; simp [lift, *] at *, cases hc, apply lt_of_incomp_of_lt, split, assumption, assumption, assumption },
|
||||
twice { apply ih_1 hc hs₁ }
|
||||
all_goals { apply ih_1 hc hs₁ }
|
||||
end
|
||||
|
||||
lemma is_searchable_some_low_of_is_searchable_of_lt {t} [is_trans α lt] : ∀ {lo hi lo'} (hlt : lt lo' lo) (hs : is_searchable lt t (some lo) hi), is_searchable lt t (some lo') hi :=
|
||||
begin
|
||||
induction t; intros; is_searchable_tactic,
|
||||
{ cases hi; simp [lift, *] at *, apply trans_of lt hlt, assumption },
|
||||
twice { apply ih_1 hlt hs₁ }
|
||||
all_goals { apply ih_1 hlt hs₁ }
|
||||
end
|
||||
|
||||
lemma is_searchable_none_low_of_is_searchable_some_low {t} : ∀ {y hi} (hlt : is_searchable lt t (some y) hi), is_searchable lt t none hi :=
|
||||
begin
|
||||
induction t; intros; is_searchable_tactic,
|
||||
{ simp [lift] },
|
||||
twice { apply ih_1 hs₁ }
|
||||
all_goals { apply ih_1 hs₁ }
|
||||
end
|
||||
|
||||
lemma is_searchable_some_high_of_is_searchable_of_lt {t} [is_trans α lt] : ∀ {lo hi hi'} (hlt : lt hi hi') (hs : is_searchable lt t lo (some hi)), is_searchable lt t lo (some hi') :=
|
||||
begin
|
||||
induction t; intros; is_searchable_tactic,
|
||||
{ cases lo; simp [lift, *] at *, apply trans_of lt, assumption, assumption},
|
||||
twice { apply ih_2 hlt hs₂ }
|
||||
all_goals { apply ih_2 hlt hs₂ }
|
||||
end
|
||||
|
||||
lemma is_searchable_none_high_of_is_searchable_some_high {t} : ∀ {lo y} (hlt : is_searchable lt t lo (some y)), is_searchable lt t lo none :=
|
||||
begin
|
||||
induction t; intros; is_searchable_tactic,
|
||||
{ cases lo; simp [lift] },
|
||||
twice { apply ih_2 hs₂ }
|
||||
all_goals { apply ih_2 hs₂ }
|
||||
end
|
||||
|
||||
lemma is_searchable_balance1 {l y r v t lo hi} (hl : is_searchable lt l lo (some y)) (hr : is_searchable lt r (some y) (some v)) (ht : is_searchable lt t (some v) hi) : is_searchable lt (balance1 l y r v t) lo hi :=
|
||||
|
|
@ -399,7 +399,7 @@ begin
|
|||
{ cases lo,
|
||||
{ apply is_searchable_none_low_of_is_searchable_some_low, assumption },
|
||||
{ simp [lift] at *, apply is_searchable_some_low_of_is_searchable_of_lt, assumption, assumption } },
|
||||
twice { apply is_searchable_balance1, repeat { assumption } }
|
||||
all_goals { apply is_searchable_balance1, repeat { assumption } }
|
||||
end
|
||||
|
||||
lemma is_searchable_balance2 {l y r v t lo hi} (ht : is_searchable lt t lo (some v)) (hl : is_searchable lt l (some v) (some y)) (hr : is_searchable lt r (some y) hi) : is_searchable lt (balance2 l y r v t) lo hi :=
|
||||
|
|
@ -411,7 +411,7 @@ begin
|
|||
{ cases hi,
|
||||
{ apply is_searchable_none_high_of_is_searchable_some_high, assumption },
|
||||
{ simp [lift] at *, apply is_searchable_some_high_of_is_searchable_of_lt, assumption, assumption } },
|
||||
twice { apply is_searchable_balance2, repeat { assumption } }
|
||||
all_goals { apply is_searchable_balance2, repeat { assumption } }
|
||||
end
|
||||
|
||||
lemma is_searchable_ins {t x} [is_strict_weak_order α lt] : ∀ {lo hi} (h : is_searchable lt t lo hi), lift lt lo (some x) → lift lt (some x) hi → is_searchable lt (ins lt t x) lo hi :=
|
||||
|
|
@ -457,44 +457,60 @@ namespace rbnode
|
|||
section membership_lemmas
|
||||
parameters {α : Type u} (lt : α → α → Prop) [decidable_rel lt]
|
||||
|
||||
local infix `∈` := rbnode.mem lt
|
||||
local infix `∈` := mem lt
|
||||
|
||||
lemma mem_balance1_node {x s} (v) (t : rbnode α) : x ∈ s → x ∈ balance1_node s v t :=
|
||||
lemma mem_balance1_node_of_mem_left {x s} (v) (t : rbnode α) : x ∈ s → x ∈ balance1_node s v t :=
|
||||
begin
|
||||
cases s,
|
||||
case leaf { simp [rbnode.mem] },
|
||||
case red_node l v r {
|
||||
{ simp [mem] },
|
||||
all_goals {
|
||||
intro h,
|
||||
simp [balance1_node], cases l; cases r,
|
||||
any_goals { simp [*, rbnode.mem, balance1] at * },
|
||||
all_goals { blast_disjs; simp [*] }
|
||||
},
|
||||
case black_node l v r {
|
||||
intro h,
|
||||
simp [balance1_node], cases l; cases r,
|
||||
any_goals { simp [*, rbnode.mem, balance1] at * },
|
||||
simp [balance1_node], cases lchild; cases rchild,
|
||||
any_goals { simp [*, mem, balance1] at * },
|
||||
all_goals { blast_disjs; simp [*] }
|
||||
}
|
||||
end
|
||||
|
||||
lemma mem_balance2_node {x s} (v) (t : rbnode α) : x ∈ s → x ∈ balance2_node s v t :=
|
||||
lemma mem_balance2_node_of_mem_left {x s} (v) (t : rbnode α) : x ∈ s → x ∈ balance2_node s v t :=
|
||||
begin
|
||||
cases s,
|
||||
case leaf { simp [rbnode.mem] },
|
||||
case red_node l v r {
|
||||
{ simp [mem] },
|
||||
all_goals {
|
||||
intro h,
|
||||
simp [balance2_node], cases l; cases r,
|
||||
any_goals { simp [*, rbnode.mem, balance2] at * },
|
||||
all_goals { blast_disjs; simp [*] }
|
||||
},
|
||||
case black_node l v r {
|
||||
intro h,
|
||||
simp [balance2_node], cases l; cases r,
|
||||
any_goals { simp [*, rbnode.mem, balance2] at * },
|
||||
simp [balance2_node], cases lchild; cases rchild,
|
||||
any_goals { simp [*, mem, balance2] at * },
|
||||
all_goals { blast_disjs; simp [*] }
|
||||
}
|
||||
end
|
||||
|
||||
lemma mem_balance1_node_of_mem_right {x t} (v) (s : rbnode α) : x ∈ t → x ∈ balance1_node s v t :=
|
||||
begin
|
||||
intros, cases s,
|
||||
{ simp [mem, balance1_node, *] },
|
||||
all_goals { simp [balance1_node], cases lchild; cases rchild; simp [*, mem, balance1] }
|
||||
end
|
||||
|
||||
lemma mem_balance2_node_of_mem_right {x t} (v) (s : rbnode α) : x ∈ t → x ∈ balance2_node s v t :=
|
||||
begin
|
||||
intros, cases s,
|
||||
{ simp [mem, balance2_node, *] },
|
||||
all_goals { simp [balance2_node], cases lchild; cases rchild; simp [*, mem, balance2] }
|
||||
end
|
||||
|
||||
lemma mem_balance1_node_of_incomp {x v} (s t) : (¬ lt x v ∧ ¬ lt v x) → s ≠ leaf → x ∈ balance1_node s v t :=
|
||||
begin
|
||||
intros, cases s,
|
||||
case leaf { contradiction },
|
||||
all_goals { simp [balance1_node], cases lchild; cases rchild; simp [*, mem, balance1] }
|
||||
end
|
||||
|
||||
lemma mem_balance2_node_of_incomp {x v} (s t) : (¬ lt v x ∧ ¬ lt x v) → s ≠ leaf → x ∈ balance2_node s v t :=
|
||||
begin
|
||||
intros, cases s,
|
||||
case leaf { contradiction },
|
||||
all_goals { simp [balance2_node], cases lchild; cases rchild; simp [*, mem, balance2] }
|
||||
end
|
||||
|
||||
lemma ins_ne_leaf (t : rbnode α) (x : α) : t.ins lt x ≠ leaf :=
|
||||
begin
|
||||
apply ins.induction lt t x,
|
||||
|
|
@ -506,30 +522,38 @@ end
|
|||
lemma mem_ins [is_irrefl α lt] (t : rbnode α) (x : α) : x ∈ t.ins lt x :=
|
||||
begin
|
||||
apply ins.induction lt t x,
|
||||
{ simp [ins, rbnode.mem], apply irrefl },
|
||||
any_goals { intros, simp [ins, rbnode.mem, *] },
|
||||
any_goals { right, left, apply irrefl },
|
||||
{ apply mem_balance1_node, assumption },
|
||||
{ apply mem_balance2_node, assumption }
|
||||
{ simp [ins, mem], apply irrefl },
|
||||
any_goals { intros, simp [ins, mem, *] },
|
||||
any_goals { simp [irrefl_of lt x] },
|
||||
{ apply mem_balance1_node_of_mem_left, assumption },
|
||||
{ apply mem_balance2_node_of_mem_left, assumption }
|
||||
end
|
||||
|
||||
lemma mem_black_node_of_mem_red_node {l r : rbnode α} {v a : α} : a ∈ red_node l v r → a ∈ black_node l v r :=
|
||||
λ h, h
|
||||
lemma mem_ins_of_mem [is_strict_weak_order α lt] {t : rbnode α} (z : α) : ∀ {x} (h : x ∈ t), x ∈ t.ins lt z :=
|
||||
begin
|
||||
apply ins.induction lt t z; intros,
|
||||
{ simp [mem, ins] at h, contradiction },
|
||||
all_goals { simp [ins, mem, *] at *, blast_disjs },
|
||||
any_goals { simp [h] },
|
||||
any_goals { simp [ih h] },
|
||||
{ have := incomp_trans_of lt hc h, simp [this] },
|
||||
{ apply mem_balance1_node_of_mem_left, apply ih h },
|
||||
{ have := ins_ne_leaf lt a z, apply mem_balance1_node_of_incomp, cases h, all_goals { simp [*] } },
|
||||
{ apply mem_balance1_node_of_mem_right, assumption },
|
||||
{ have := incomp_trans_of lt hc h, simp [this] },
|
||||
{ apply mem_balance2_node_of_mem_right, assumption },
|
||||
{ have := ins_ne_leaf lt a z, apply mem_balance2_node_of_incomp, cases h, simp [*], apply ins_ne_leaf },
|
||||
{ apply mem_balance2_node_of_mem_left, apply ih h }
|
||||
end
|
||||
|
||||
lemma mem_flip_red {a t} : mem lt a t → mem lt a (flip_red t) :=
|
||||
by intros; cases t; simp [flip_red, mem, *] at *
|
||||
|
||||
lemma mem_insert [is_irrefl α lt] : ∀ (a : α) (t : rbnode α), a ∈ t.insert lt a :=
|
||||
begin
|
||||
intros a t,
|
||||
simp [insert],
|
||||
have h : ins lt t a ≠ leaf, { apply ins_ne_leaf },
|
||||
generalize he : ins lt t a = r,
|
||||
cases r; simp [flip_red, insert],
|
||||
case leaf { contradiction },
|
||||
case black_node { rw [←he], apply mem_ins },
|
||||
case red_node {
|
||||
have : a ∈ red_node lchild val rchild, { rw [←he], apply mem_ins },
|
||||
apply mem_black_node_of_mem_red_node, assumption
|
||||
}
|
||||
end
|
||||
by intros; apply mem_flip_red; apply mem_ins
|
||||
|
||||
lemma mem_insert_of_mem [is_strict_weak_order α lt] {t x} (z) : x ∈ t → x ∈ t.insert lt z :=
|
||||
by intros; apply mem_flip_red; apply mem_ins_of_mem; assumption
|
||||
|
||||
end membership_lemmas
|
||||
|
||||
|
|
@ -538,9 +562,19 @@ end rbnode
|
|||
namespace rbtree
|
||||
variables {α : Type u} {lt : α → α → Prop} [decidable_rel lt]
|
||||
|
||||
lemma not_mem_mk_rbtree : ∀ (a : α), a ∉ mk_rbtree α lt :=
|
||||
by simp [has_mem.mem, rbtree.mem, rbnode.mem, mk_rbtree]
|
||||
|
||||
lemma mem_insert [is_irrefl α lt] : ∀ (a : α) (t : rbtree α lt), a ∈ t.insert a
|
||||
| a ⟨t, _⟩ := t.mem_insert lt a
|
||||
|
||||
lemma mem_insert_of_mem [is_strict_weak_order α lt] {a : α} {t : rbtree α lt} (b : α) : a ∈ t → a ∈ t.insert b :=
|
||||
begin
|
||||
cases t,
|
||||
simp [has_mem.mem, rbtree.mem, contains],
|
||||
apply rbnode.mem_insert_of_mem
|
||||
end
|
||||
|
||||
lemma contains_correct [is_strict_weak_order α lt] (a : α) (t : rbtree α lt) : a ∈ t ↔ (t.contains a = tt) :=
|
||||
begin
|
||||
cases t,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue