Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit ae5357f

Browse files
committed
refactor(data/finsupp/basic): split out alist results (#18250)
This file is getting quite long, and nothing else builds upon these results. These lemmas and definitions are copied without modification. They were originally from #15443.
1 parent 800d3d4 commit ae5357f

File tree

2 files changed

+107
-94
lines changed

2 files changed

+107
-94
lines changed

src/data/finsupp/alist.lean

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/-
2+
Copyright (c) 2022 Violeta Hernández. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Violeta Hernández
5+
-/
6+
import data.finsupp.basic
7+
import data.list.alist
8+
9+
/-!
10+
# Connections between `finsupp` and `alist`
11+
12+
## Main definitions
13+
14+
* `finsupp.to_alist`
15+
* `alist.lookup_finsupp`: converts an association list into a finitely supported function
16+
via `alist.lookup`, sending absent keys to zero.
17+
18+
-/
19+
20+
namespace finsupp
21+
variables {α M : Type*} [has_zero M]
22+
23+
/-- Produce an association list for the finsupp over its support using choice. -/
24+
@[simps] noncomputable def to_alist (f : α →₀ M) : alist (λ x : α, M) :=
25+
⟨f.graph.to_list.map prod.to_sigma, begin
26+
rw [list.nodupkeys, list.keys, list.map_map, prod.fst_comp_to_sigma, list.nodup_map_iff_inj_on],
27+
{ rintros ⟨b, m⟩ hb ⟨c, n⟩ hc (rfl : b = c),
28+
rw [finset.mem_to_list, finsupp.mem_graph_iff] at hb hc,
29+
dsimp at hb hc,
30+
rw [←hc.1, hb.1] },
31+
{ apply finset.nodup_to_list }
32+
end
33+
34+
@[simp] lemma to_alist_keys_to_finset [decidable_eq α] (f : α →₀ M) :
35+
f.to_alist.keys.to_finset = f.support :=
36+
by { ext, simp [to_alist, alist.mem_keys, alist.keys, list.keys] }
37+
38+
@[simp] lemma mem_to_alist {f : α →₀ M} {x : α} : x ∈ f.to_alist ↔ f x ≠ 0 :=
39+
begin
40+
classical,
41+
rw [alist.mem_keys, ←list.mem_to_finset, to_alist_keys_to_finset, mem_support_iff]
42+
end
43+
44+
end finsupp
45+
46+
namespace alist
47+
variables {α M : Type*} [has_zero M]
48+
open list
49+
50+
/-- Converts an association list into a finitely supported function via `alist.lookup`, sending
51+
absent keys to zero. -/
52+
noncomputable def lookup_finsupp (l : alist (λ x : α, M)) : α →₀ M :=
53+
{ support := by haveI := classical.dec_eq α; haveI := classical.dec_eq M; exact
54+
(l.1.filter $ λ x, sigma.snd x ≠ 0).keys.to_finset,
55+
to_fun := λ a, by haveI := classical.dec_eq α; exact (l.lookup a).get_or_else 0,
56+
mem_support_to_fun := λ a, begin
57+
classical,
58+
simp_rw [mem_to_finset, list.mem_keys, list.mem_filter, ←mem_lookup_iff],
59+
cases lookup a l;
60+
simp
61+
end }
62+
63+
@[simp] lemma lookup_finsupp_apply [decidable_eq α] (l : alist (λ x : α, M)) (a : α) :
64+
l.lookup_finsupp a = (l.lookup a).get_or_else 0 :=
65+
by convert rfl
66+
67+
@[simp] lemma lookup_finsupp_support [decidable_eq α] [decidable_eq M] (l : alist (λ x : α, M)) :
68+
l.lookup_finsupp.support = (l.1.filter $ λ x, sigma.snd x ≠ 0).keys.to_finset :=
69+
by convert rfl
70+
71+
lemma lookup_finsupp_eq_iff_of_ne_zero [decidable_eq α]
72+
{l : alist (λ x : α, M)} {a : α} {x : M} (hx : x ≠ 0) :
73+
l.lookup_finsupp a = x ↔ x ∈ l.lookup a :=
74+
by { rw lookup_finsupp_apply, cases lookup a l with m; simp [hx.symm] }
75+
76+
lemma lookup_finsupp_eq_zero_iff [decidable_eq α] {l : alist (λ x : α, M)} {a : α} :
77+
l.lookup_finsupp a = 0 ↔ a ∉ l ∨ (0 : M) ∈ l.lookup a :=
78+
by { rw [lookup_finsupp_apply, ←lookup_eq_none], cases lookup a l with m; simp }
79+
80+
@[simp] lemma empty_lookup_finsupp : lookup_finsupp (∅ : alist (λ x : α, M)) = 0 :=
81+
by { classical, ext, simp }
82+
83+
@[simp] lemma insert_lookup_finsupp [decidable_eq α] (l : alist (λ x : α, M)) (a : α) (m : M) :
84+
(l.insert a m).lookup_finsupp = l.lookup_finsupp.update a m :=
85+
by { ext b, by_cases h : b = a; simp [h] }
86+
87+
@[simp] lemma singleton_lookup_finsupp (a : α) (m : M) :
88+
(singleton a m).lookup_finsupp = finsupp.single a m :=
89+
by { classical, simp [←alist.insert_empty] }
90+
91+
@[simp] lemma _root_.finsupp.to_alist_lookup_finsupp (f : α →₀ M) : f.to_alist.lookup_finsupp = f :=
92+
begin
93+
ext,
94+
by_cases h : f a = 0,
95+
{ suffices : f.to_alist.lookup a = none,
96+
{ simp [h, this] },
97+
{ simp [lookup_eq_none, h] } },
98+
{ suffices : f.to_alist.lookup a = some (f a),
99+
{ simp [h, this] },
100+
{ apply mem_lookup_iff.2,
101+
simpa using h } }
102+
end
103+
104+
lemma lookup_finsupp_surjective : function.surjective (@lookup_finsupp α M _) :=
105+
λ f, ⟨_, finsupp.to_alist_lookup_finsupp f⟩
106+
107+
end alist

src/data/finsupp/basic.lean

Lines changed: 0 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import algebra.big_operators.finsupp
77
import algebra.hom.group_action
88
import algebra.regular.smul
99
import data.finset.preimage
10-
import data.list.alist
1110
import data.rat.big_operators
1211

1312
/-!
@@ -16,8 +15,6 @@ import data.rat.big_operators
1615
## Main declarations
1716
1817
* `finsupp.graph`: the finset of input and output pairs with non-zero outputs.
19-
* `alist.lookup_finsupp`: converts an association list into a finitely supported function
20-
via `alist.lookup`, sending absent keys to zero.
2118
* `finsupp.map_range.equiv`: `finsupp.map_range` as an equiv.
2219
* `finsupp.map_domain`: maps the domain of a `finsupp` by a function and by summing.
2320
* `finsupp.comap_domain`: postcomposition of a `finsupp` with a function injective on the preimage
@@ -107,101 +104,10 @@ end
107104
@[simp] lemma graph_eq_empty {f : α →₀ M} : f.graph = ∅ ↔ f = 0 :=
108105
(graph_injective α M).eq_iff' graph_zero
109106

110-
/-- Produce an association list for the finsupp over its support using choice. -/
111-
@[simps] def to_alist (f : α →₀ M) : alist (λ x : α, M) :=
112-
⟨f.graph.to_list.map prod.to_sigma, begin
113-
rw [list.nodupkeys, list.keys, list.map_map, prod.fst_comp_to_sigma, list.nodup_map_iff_inj_on],
114-
{ rintros ⟨b, m⟩ hb ⟨c, n⟩ hc (rfl : b = c),
115-
rw [mem_to_list, finsupp.mem_graph_iff] at hb hc,
116-
dsimp at hb hc,
117-
rw [←hc.1, hb.1] },
118-
{ apply nodup_to_list }
119-
end
120-
121-
@[simp] lemma to_alist_keys_to_finset [decidable_eq α] (f : α →₀ M) :
122-
f.to_alist.keys.to_finset = f.support :=
123-
by { ext, simp [to_alist, alist.mem_keys, alist.keys, list.keys] }
124-
125-
@[simp] lemma mem_to_alist {f : α →₀ M} {x : α} : x ∈ f.to_alist ↔ f x ≠ 0 :=
126-
begin
127-
classical,
128-
rw [alist.mem_keys, ←list.mem_to_finset, to_alist_keys_to_finset, mem_support_iff]
129-
end
130-
131107
end graph
132108

133109
end finsupp
134110

135-
/-! ### Declarations about `alist.lookup_finsupp` -/
136-
137-
section lookup_finsupp
138-
139-
variable [has_zero M]
140-
141-
namespace alist
142-
open list
143-
144-
/-- Converts an association list into a finitely supported function via `alist.lookup`, sending
145-
absent keys to zero. -/
146-
def lookup_finsupp (l : alist (λ x : α, M)) : α →₀ M :=
147-
{ support := by haveI := classical.dec_eq α; haveI := classical.dec_eq M; exact
148-
(l.1.filter $ λ x, sigma.snd x ≠ 0).keys.to_finset,
149-
to_fun := λ a, by haveI := classical.dec_eq α; exact (l.lookup a).get_or_else 0,
150-
mem_support_to_fun := λ a, begin
151-
classical,
152-
simp_rw [mem_to_finset, list.mem_keys, list.mem_filter, ←mem_lookup_iff],
153-
cases lookup a l;
154-
simp
155-
end }
156-
157-
@[simp] lemma lookup_finsupp_apply [decidable_eq α] (l : alist (λ x : α, M)) (a : α) :
158-
l.lookup_finsupp a = (l.lookup a).get_or_else 0 :=
159-
by convert rfl
160-
161-
@[simp] lemma lookup_finsupp_support [decidable_eq α] [decidable_eq M] (l : alist (λ x : α, M)) :
162-
l.lookup_finsupp.support = (l.1.filter $ λ x, sigma.snd x ≠ 0).keys.to_finset :=
163-
by convert rfl
164-
165-
lemma lookup_finsupp_eq_iff_of_ne_zero [decidable_eq α]
166-
{l : alist (λ x : α, M)} {a : α} {x : M} (hx : x ≠ 0) :
167-
l.lookup_finsupp a = x ↔ x ∈ l.lookup a :=
168-
by { rw lookup_finsupp_apply, cases lookup a l with m; simp [hx.symm] }
169-
170-
lemma lookup_finsupp_eq_zero_iff [decidable_eq α] {l : alist (λ x : α, M)} {a : α} :
171-
l.lookup_finsupp a = 0 ↔ a ∉ l ∨ (0 : M) ∈ l.lookup a :=
172-
by { rw [lookup_finsupp_apply, ←lookup_eq_none], cases lookup a l with m; simp }
173-
174-
@[simp] lemma empty_lookup_finsupp : lookup_finsupp (∅ : alist (λ x : α, M)) = 0 :=
175-
by { classical, ext, simp }
176-
177-
@[simp] lemma insert_lookup_finsupp [decidable_eq α] (l : alist (λ x : α, M)) (a : α) (m : M) :
178-
(l.insert a m).lookup_finsupp = l.lookup_finsupp.update a m :=
179-
by { ext b, by_cases h : b = a; simp [h] }
180-
181-
@[simp] lemma singleton_lookup_finsupp (a : α) (m : M) :
182-
(singleton a m).lookup_finsupp = finsupp.single a m :=
183-
by { classical, simp [←alist.insert_empty] }
184-
185-
@[simp] lemma _root_.finsupp.to_alist_lookup_finsupp (f : α →₀ M) : f.to_alist.lookup_finsupp = f :=
186-
begin
187-
ext,
188-
by_cases h : f a = 0,
189-
{ suffices : f.to_alist.lookup a = none,
190-
{ simp [h, this] },
191-
{ simp [lookup_eq_none, h] } },
192-
{ suffices : f.to_alist.lookup a = some (f a),
193-
{ simp [h, this] },
194-
{ apply mem_lookup_iff.2,
195-
simpa using h } }
196-
end
197-
198-
lemma lookup_finsupp_surjective : surjective (@lookup_finsupp α M _) :=
199-
λ f, ⟨_, finsupp.to_alist_lookup_finsupp f⟩
200-
201-
end alist
202-
203-
end lookup_finsupp
204-
205111
/-! ### Declarations about `map_range` -/
206112

207113
section map_range

0 commit comments

Comments
 (0)