@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
44Authors: Sean Leather, Mario Carneiro
55-/
66import data.list.alist
7- import data.finset.basic
7+ import data.finset.sigma
88import data.part
99/-!
1010# Finite maps over `multiset`
@@ -35,6 +35,14 @@ quot.lift_on s list.nodupkeys (λ s t p, propext $ perm_nodupkeys p)
3535
3636@[simp] theorem coe_nodupkeys {l : list (sigma β)} : @nodupkeys α β l ↔ l.nodupkeys := iff.rfl
3737
38+ lemma nodup_keys {m : multiset (Σ a, β a)} : m.keys.nodup ↔ m.nodupkeys :=
39+ by { rcases m with ⟨l⟩, refl }
40+
41+ alias nodup_keys ↔ _ nodupkeys.nodup_keys
42+
43+ lemma nodupkeys.nodup {m : multiset (Σ a, β a)} (h : m.nodupkeys) : m.nodup :=
44+ h.nodup_keys.of_map _
45+
3846end multiset
3947
4048/-! ### finmap -/
@@ -63,6 +71,8 @@ def list.to_finmap [decidable_eq α] (s : list (sigma β)) : finmap β := s.to_a
6371namespace finmap
6472open alist
6573
74+ lemma nodup_entries (f : finmap β) : f.entries.nodup := f.nodupkeys.nodup
75+
6676/-! ### lifting from alist -/
6777
6878/-- Lift a permutation-respecting function on `alist` to `finmap`. -/
@@ -129,7 +139,7 @@ theorem mem_def {a : α} {s : finmap β} :
129139
130140/-- The set of keys of a finite map. -/
131141def keys (s : finmap β) : finset α :=
132- ⟨s.entries.keys, induction_on s keys_nodup ⟩
142+ ⟨s.entries.keys, s.nodupkeys.nodup_keys ⟩
133143
134144@[simp] theorem keys_val (s : alist β) : (keys ⟦s⟧).val = s.keys := rfl
135145
@@ -197,6 +207,23 @@ induction_on s $ λ s, alist.lookup_is_some
197207theorem lookup_eq_none {a} {s : finmap β} : lookup a s = none ↔ a ∉ s :=
198208induction_on s $ λ s, alist.lookup_eq_none
199209
210+ lemma mem_lookup_iff {f : finmap β} {a : α} {b : β a} :
211+ b ∈ f.lookup a ↔ sigma.mk a b ∈ f.entries :=
212+ by { rcases f with ⟨⟨l⟩, hl⟩, exact list.mem_lookup_iff hl }
213+
214+ /-- A version of `finmap.mem_lookup_iff` with LHS in the simp-normal form. -/
215+ lemma lookup_eq_some_iff {f : finmap β} {a : α} {b : β a} :
216+ f.lookup a = some b ↔ sigma.mk a b ∈ f.entries :=
217+ mem_lookup_iff
218+
219+ @[simp] lemma sigma_keys_lookup (f : finmap β) :
220+ f.keys.sigma (λ i, (f.lookup i).to_finset) = ⟨f.entries, f.nodup_entries⟩ :=
221+ begin
222+ ext x,
223+ have : x ∈ f.entries → x.fst ∈ f.keys, from multiset.mem_map_of_mem _,
224+ simpa [lookup_eq_some_iff]
225+ end
226+
200227@[simp] lemma lookup_singleton_eq {a : α} {b : β a} : (singleton a b).lookup a = some b :=
201228by rw [singleton, lookup_to_finmap, alist.singleton, alist.lookup, lookup_cons_eq]
202229
@@ -206,7 +233,7 @@ decidable_of_iff _ lookup_is_some
206233lemma mem_iff {a : α} {s : finmap β} : a ∈ s ↔ ∃ b, s.lookup a = some b :=
207234induction_on s $ λ s,
208235iff.trans list.mem_keys $ exists_congr $ λ b,
209- (mem_lookup_iff s.nodupkeys).symm
236+ (list. mem_lookup_iff s.nodupkeys).symm
210237
211238lemma mem_of_lookup_eq_some {a : α} {b : β a} {s : finmap β} (h : s.lookup a = some b) : a ∈ s :=
212239mem_iff.mpr ⟨_, h⟩
@@ -221,6 +248,46 @@ begin
221248 rw h,
222249end
223250
251+ /-- An equivalence between `finmap β` and pairs `(keys : finset α, lookup : Π a, option (β a))` such
252+ that `(lookup a).is_some ↔ a ∈ keys`. -/
253+ @[simps apply_coe_fst apply_coe_snd]
254+ def keys_lookup_equiv :
255+ finmap β ≃ {f : finset α × (Π a, option (β a)) // ∀ i, (f.2 i).is_some ↔ i ∈ f.1 } :=
256+ { to_fun := λ f, ⟨(f.keys, λ i, f.lookup i), λ i, lookup_is_some⟩,
257+ inv_fun := λ f, ⟨(f.1 .1 .sigma $ λ i, (f.1 .2 i).to_finset).val,
258+ begin
259+ refine multiset.nodup_keys.1 ((finset.nodup _).map_on _),
260+ simp only [finset.mem_val, finset.mem_sigma, option.mem_to_finset, option.mem_def],
261+ rintro ⟨i, x⟩ ⟨hi, hx⟩ ⟨j, y⟩ ⟨hj, hy⟩ (rfl : i = j),
262+ obtain rfl : x = y, from option.some.inj (hx.symm.trans hy),
263+ refl
264+ end ⟩,
265+ left_inv := λ f, ext $ by simp,
266+ right_inv := λ ⟨⟨s, f⟩, hf⟩,
267+ begin
268+ ext : 2 ; dsimp [keys],
269+ { ext1 i,
270+ have : i ∈ s → (∃ x, f i = some x),
271+ from λ hi, ⟨option.get _, option.get_mem $ (hf i).2 hi⟩,
272+ simpa [multiset.keys] },
273+ { ext i x : 2 ,
274+ simp only [option.mem_def, lookup_eq_some_iff, finset.mem_val, finset.mem_sigma,
275+ option.mem_to_finset, and_iff_right_iff_imp, ← hf],
276+ exact λ h, option.is_some_iff_exists.2 ⟨_, h⟩ }
277+ end }
278+
279+ @[simp] lemma keys_lookup_equiv_symm_apply_keys :
280+ ∀ f : {f : finset α × (Π a, option (β a)) // ∀ i, (f.2 i).is_some ↔ i ∈ f.1 },
281+ (keys_lookup_equiv.symm f).keys = (f : finset α × Π a, option (β a)).1 :=
282+ keys_lookup_equiv.surjective.forall.2 $ λ f,
283+ by simp only [equiv.symm_apply_apply, keys_lookup_equiv_apply_coe_fst]
284+
285+ @[simp] lemma keys_lookup_equiv_symm_apply_lookup :
286+ ∀ (f : {f : finset α × (Π a, option (β a)) // ∀ i, (f.2 i).is_some ↔ i ∈ f.1 }) a,
287+ (keys_lookup_equiv.symm f).lookup a = (f : finset α × Π a, option (β a)).2 a :=
288+ keys_lookup_equiv.surjective.forall.2 $ λ f a,
289+ by simp only [equiv.symm_apply_apply, keys_lookup_equiv_apply_coe_snd]
290+
224291/-! ### replace -/
225292
226293/-- Replace a key with a given value in a finite map.
0 commit comments