Skip to content

Commit 065da59

Browse files
lzy0505Kaptch
andauthored
Port algebra/functions.v (#528)
--------- Co-authored-by: Sergei Stepanenko <sergei.stepanenko@cs.au.dk>
1 parent b72e489 commit 065da59

2 files changed

Lines changed: 281 additions & 0 deletions

File tree

Iris/Iris/Algebra.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ public import Iris.Algebra.COFESolver
66
public import Iris.Algebra.DFrac
77
public import Iris.Algebra.Excl
88
public import Iris.Algebra.Frac
9+
public import Iris.Algebra.Functions
910
public import Iris.Algebra.GenMap
1011
public import Iris.Algebra.LeibnizSet
1112
public import Iris.Algebra.LocalUpdates

Iris/Iris/Algebra/Functions.lean

Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
/-
2+
Copyright (c) 2026 Zongyuan Liu. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Zongyuan Liu
5+
-/
6+
module
7+
8+
public import Iris.Algebra.Updates
9+
meta import Iris.Std.RocqPorting
10+
11+
@[expose] public section
12+
13+
namespace Iris
14+
open OFE CMRA
15+
16+
/-!
17+
# Dependent Function Resources
18+
19+
Insertion and singleton operations for dependent functions whose codomains carry
20+
OFE or CMRA structure, together with their non-expansiveness, validity, core,
21+
composition, and update laws.
22+
-/
23+
24+
@[rocq_alias discrete_fun_insert]
25+
def discreteFunInsert {ι : Type _} [DecidableEq ι] {β : ι → Type _}
26+
(x : ι) (y : β x) (f : (a : ι) → β a) : (a : ι) → β a :=
27+
fun x' => if h : x = x' then h ▸ y else f x'
28+
29+
@[rocq_alias discrete_fun_singleton]
30+
def discreteFunSingleton {ι : Type _} [DecidableEq ι] {β : ι → Type _}
31+
[∀ i, UCMRA (β i)] (x : ι) (y : β x) : (a : ι) → β a :=
32+
discreteFunInsert x y fun _ => unit
33+
34+
section insert
35+
36+
variable {ι : Type _} [DecidableEq ι] {β : ι → Type _}
37+
38+
@[rocq_alias discrete_fun_lookup_insert, simp]
39+
theorem discreteFunInsert_self (f : (a : ι) → β a) (x : ι) (y : β x) :
40+
discreteFunInsert x y f x = y := by
41+
simp [discreteFunInsert]
42+
43+
@[rocq_alias discrete_fun_lookup_insert_ne, simp]
44+
theorem discreteFunInsert_of_ne (f : (a : ι) → β a) (x x' : ι)
45+
(y : β x) (h : x ≠ x') : discreteFunInsert x y f x' = f x' := by
46+
simp [discreteFunInsert, h]
47+
48+
end insert
49+
50+
section OFE
51+
52+
variable {ι : Type _} [DecidableEq ι] {β : ι → Type _} [∀ i, OFE (β i)]
53+
54+
@[rocq_alias discrete_funO_ofe_discrete]
55+
instance instDiscreteFunOfeDiscrete [∀ i, OFE.Discrete (β i)] :
56+
OFE.Discrete ((i : ι) → β i) where
57+
discrete_0 h := funext fun i => discrete_0 (h i)
58+
59+
omit [DecidableEq ι] in
60+
/-- Not an instance, cycle with `discreteE_apply`. -/
61+
theorem discreteE_pi {f : (a : ι) → β a} (hf : ∀ i, DiscreteE (f i)) : DiscreteE f where
62+
discrete h := funext fun i => (hf i).discrete (h i)
63+
64+
@[rocq_alias discrete_fun_insert_ne]
65+
instance instDiscreteFunInsertNonExpansive (x : ι) :
66+
NonExpansive₂ (discreteFunInsert (β := β) x) where
67+
ne {n y₁ y₂} hy {f₁ f₂} hf x' := by
68+
by_cases h : x = x'
69+
· subst h
70+
simpa using hy
71+
· rw [discreteFunInsert_of_ne (h := h) .., discreteFunInsert_of_ne (h := h) ..]
72+
exact hf x'
73+
74+
#rocq_ignore discrete_fun_insert_proper "Use the NonExpansive instance instead."
75+
76+
/-- Not an instance, cycle with `discreteE_pi`. -/
77+
theorem discreteE_apply {f : (a : ι) → β a} (hf : DiscreteE f) (x : ι) :
78+
DiscreteE (f x) where
79+
discrete {y} h := by
80+
have hfun : f ≡{0}≡ discreteFunInsert x y f := fun x' => by
81+
by_cases hxx' : x = x'
82+
· subst hxx'
83+
simpa using h
84+
· rw [discreteFunInsert_of_ne (h := hxx') ..]
85+
exact (congrFun (hf.discrete hfun) x).trans (discreteFunInsert_self ..)
86+
87+
@[rocq_alias discrete_fun_insert_discrete]
88+
instance instDiscreteFunInsertDiscrete (f : (a : ι) → β a) (x : ι) (y : β x)
89+
[DiscreteE f] [DiscreteE y] : DiscreteE (discreteFunInsert x y f) :=
90+
discreteE_pi fun x' => by
91+
by_cases h : x = x'
92+
· subst h
93+
rw [discreteFunInsert_self]
94+
infer_instance
95+
· rw [discreteFunInsert_of_ne (h := h) ..]
96+
exact discreteE_apply ‹DiscreteE f› x'
97+
98+
end OFE
99+
100+
section CMRA
101+
102+
variable {ι : Type _} [DecidableEq ι] {β : ι → Type _} [∀ i, UCMRA (β i)]
103+
104+
@[rocq_alias discrete_funR_cmra_discrete]
105+
instance instDiscreteFunCmraDiscrete [∀ i, CMRA.Discrete (β i)] :
106+
CMRA.Discrete ((i : ι) → β i) where
107+
discrete_valid h i := CMRA.Discrete.discrete_valid (h i)
108+
109+
@[rocq_alias discrete_fun_singleton_ne]
110+
instance instDiscreteFunSingletonNonExpansive (x : ι) :
111+
NonExpansive (discreteFunSingleton (β := β) x) where
112+
ne {_ _ _} h := instDiscreteFunInsertNonExpansive x |>.ne h .rfl
113+
114+
#rocq_ignore discrete_fun_singleton_proper "Use NonExpansive instance instead."
115+
116+
@[rocq_alias discrete_fun_lookup_singleton, simp]
117+
theorem discreteFunSingleton_self {x : ι} (y : β x) :
118+
discreteFunSingleton x y x = y := discreteFunInsert_self ..
119+
120+
@[rocq_alias discrete_fun_lookup_singleton_ne, simp]
121+
theorem discreteFunSingleton_of_ne {x x' : ι} (y : β x) (h : x ≠ x') :
122+
discreteFunSingleton x y x' = unit :=
123+
discreteFunInsert_of_ne (h := h) ..
124+
125+
@[rocq_alias discrete_fun_singleton_discrete]
126+
instance instDiscreteFunSingletonDiscrete {x : ι} (y : β x)
127+
[∀ i, DiscreteE (unit : β i)] [DiscreteE y] :
128+
DiscreteE (discreteFunSingleton x y) :=
129+
haveI : DiscreteE fun i : ι => (unit : β i) := discreteE_pi fun _ => inferInstance
130+
instDiscreteFunInsertDiscrete (fun _ => unit) x y
131+
132+
@[rocq_alias discrete_fun_singleton_validN]
133+
theorem discreteFunSingleton_validN_iff (n : Nat) {x : ι} (y : β x) :
134+
✓{n} discreteFunSingleton x y ↔ ✓{n} y := by
135+
constructor
136+
· exact fun h => discreteFunSingleton_self y ▸ h x
137+
· intro hy x'
138+
by_cases h : x = x'
139+
· subst h
140+
rw [discreteFunSingleton_self]
141+
exact hy
142+
· rw [discreteFunSingleton_of_ne y h]
143+
exact unit_validN
144+
145+
@[rocq_alias discrete_fun_singleton_valid]
146+
theorem discreteFunSingleton_valid_iff {x : ι} (y : β x) :
147+
✓ discreteFunSingleton x y ↔ ✓ y := by
148+
rw [valid_iff_validN, valid_iff_validN]
149+
exact forall_congr' fun n => discreteFunSingleton_validN_iff ..
150+
151+
@[rocq_alias discrete_fun_singleton_unit]
152+
theorem discreteFunSingleton_unit_eq (x : ι) :
153+
discreteFunSingleton x (unit : β x) = (unit : (a : ι) → β a) :=
154+
funext fun x' => by
155+
by_cases h : x = x'
156+
· subst h
157+
rw [discreteFunSingleton_self]
158+
rfl
159+
· rw [discreteFunSingleton_of_ne _ h]
160+
rfl
161+
162+
@[rocq_alias discrete_fun_singleton_core]
163+
theorem discreteFunSingleton_core_eq {x : ι} (y : β x) :
164+
core (discreteFunSingleton x y) = discreteFunSingleton x (core y) :=
165+
funext fun x' => by
166+
simp only [core, CMRA.pcore, Option.getD_some]
167+
by_cases h : x = x'
168+
· subst h
169+
rw [discreteFunSingleton_self, discreteFunSingleton_self]
170+
· rw [discreteFunSingleton_of_ne y h, discreteFunSingleton_of_ne _ h]
171+
exact core_eqv_self unit
172+
173+
@[rocq_alias discrete_fun_singleton_core_id]
174+
instance instDiscreteFunSingletonCoreId (x : ι) (y : β x) [CoreId y] :
175+
CoreId (discreteFunSingleton x y) :=
176+
coreId_iff_core_eqv_self.mpr <| (discreteFunSingleton_core_eq y).trans
177+
(congrArg (discreteFunSingleton x) (core_eqv_self y))
178+
179+
@[rocq_alias discrete_fun_singleton_op]
180+
theorem discreteFunSingleton_op_eq {x : ι} (y₁ y₂ : β x) :
181+
discreteFunSingleton x y₁ • discreteFunSingleton x y₂ =
182+
discreteFunSingleton x (y₁ • y₂) :=
183+
funext fun x' => by
184+
simp only [CMRA.op]
185+
by_cases h : x = x'
186+
· subst h
187+
rw [discreteFunSingleton_self, discreteFunSingleton_self, discreteFunSingleton_self]
188+
· rw [discreteFunSingleton_of_ne y₁ h, discreteFunSingleton_of_ne y₂ h,
189+
discreteFunSingleton_of_ne _ h]
190+
exact unit_left_id
191+
192+
@[rocq_alias discrete_fun_insert_updateP]
193+
theorem discreteFunInsert_updateP {x : ι} {P : β x → Prop} {Q : ((a : ι) → β a) → Prop}
194+
{g : (a : ι) → β a} {y₁ : β x} (hy : y₁ ~~>: P)
195+
(hQ : ∀ y₂, P y₂ → Q (discreteFunInsert x y₂ g)) :
196+
discreteFunInsert x y₁ g ~~>: Q := by
197+
refine UpdateP.total.mpr fun n gf hgf => ?_
198+
have hgf_at (a : ι) : ✓{n} discreteFunInsert x y₁ g a • gf a := hgf a
199+
obtain ⟨y₂, hy₂, hvalid⟩ := hy n (some (gf x))
200+
(by simpa only [CMRA.op?, discreteFunInsert_self] using hgf_at x)
201+
refine ⟨discreteFunInsert x y₂ g, hQ y₂ hy₂, fun x' => ?_⟩
202+
simp only [CMRA.op]
203+
by_cases hx'x : x' = x
204+
· subst x'
205+
simpa only [CMRA.op?, discreteFunInsert_self]
206+
· simpa only [discreteFunInsert_of_ne (h := Ne.symm hx'x) ..] using hgf_at x'
207+
208+
@[rocq_alias discrete_fun_insert_updateP']
209+
theorem discreteFunInsert_updateP' {x : ι} {P : β x → Prop} (g : (a : ι) → β a)
210+
{y₁ : β x} (hy : y₁ ~~>: P) :
211+
discreteFunInsert x y₁ g ~~>: fun g' => ∃ y₂, g' = discreteFunInsert x y₂ g ∧ P y₂ :=
212+
discreteFunInsert_updateP hy fun y₂ hy₂ => ⟨y₂, rfl, hy₂⟩
213+
214+
@[rocq_alias discrete_fun_insert_update]
215+
theorem discreteFunInsert_update (g : (a : ι) → β a) {x : ι} {y₁ y₂ : β x} (hy : y₁ ~~> y₂) :
216+
discreteFunInsert x y₁ g ~~> discreteFunInsert x y₂ g :=
217+
Update.of_updateP <| discreteFunInsert_updateP (UpdateP.of_update hy) fun _ hy₂ => hy₂ ▸ rfl
218+
219+
@[rocq_alias discrete_fun_singleton_updateP]
220+
theorem discreteFunSingleton_updateP {x : ι} {P : β x → Prop} (Q : ((a : ι) → β a) → Prop)
221+
{y₁ : β x} (hy : y₁ ~~>: P) (hQ : ∀ y₂, P y₂ → Q (discreteFunSingleton x y₂)) :
222+
discreteFunSingleton x y₁ ~~>: Q :=
223+
discreteFunInsert_updateP hy hQ
224+
225+
@[rocq_alias discrete_fun_singleton_updateP']
226+
theorem discreteFunSingleton_updateP' {x : ι} {P : β x → Prop}
227+
{y₁ : β x} (hy : y₁ ~~>: P) :
228+
discreteFunSingleton x y₁ ~~>: fun g => ∃ y₂, g = discreteFunSingleton x y₂ ∧ P y₂ :=
229+
discreteFunSingleton_updateP _ hy fun y₂ hy₂ => ⟨y₂, rfl, hy₂⟩
230+
231+
@[rocq_alias discrete_fun_singleton_update]
232+
theorem discreteFunSingleton_update {x : ι} {y₁ y₂ : β x} (hy : y₁ ~~> y₂) :
233+
discreteFunSingleton x y₁ ~~> discreteFunSingleton x y₂ :=
234+
discreteFunInsert_update _ hy
235+
236+
@[rocq_alias discrete_fun_singleton_updateP_empty]
237+
theorem discreteFunSingleton_updateP_unit {x : ι} {P : β x → Prop}
238+
{Q : ((a : ι) → β a) → Prop} (hy : unit ~~>: P)
239+
(hQ : ∀ y₂, P y₂ → Q (discreteFunSingleton x y₂)) : unit ~~>: Q :=
240+
discreteFunSingleton_unit_eq (β := β) x ▸ discreteFunSingleton_updateP Q hy hQ
241+
242+
@[rocq_alias discrete_fun_singleton_updateP_empty']
243+
theorem discreteFunSingleton_updateP_unit' {x : ι} {P : β x → Prop}
244+
(hy : (unit : β x) ~~>: P) :
245+
unit ~~>: fun g => ∃ y₂, g = discreteFunSingleton x y₂ ∧ P y₂ :=
246+
discreteFunSingleton_updateP_unit hy fun y₂ hy₂ => ⟨y₂, rfl, hy₂⟩
247+
248+
@[rocq_alias discrete_fun_singleton_update_empty]
249+
theorem discreteFunSingleton_update_unit {x : ι} {y : β x} (hy : unit ~~> y) :
250+
unit ~~> discreteFunSingleton x y :=
251+
Update.of_updateP <|
252+
discreteFunSingleton_updateP_unit (UpdateP.of_update hy) <| fun _ hz => hz ▸ rfl
253+
254+
end CMRA
255+
256+
section CMRA
257+
258+
variable {ι : Type _} {β : ι → Type _} [∀ i, UCMRA (β i)]
259+
260+
@[rocq_alias discrete_fun_updateP]
261+
theorem discreteFun_updateP {f : (a : ι) → β a} {P : (a : ι) → β a → Prop}
262+
{Q : ((a : ι) → β a) → Prop} (hf : ∀ a, f a ~~>: P a)
263+
(hQ : ∀ f', (∀ a, P a (f' a)) → Q f') : f ~~>: Q := by
264+
refine UpdateP.total.mpr fun n g hfg => ?_
265+
obtain ⟨f', hf'⟩ := Classical.axiomOfChoice fun a => hf a n (some (g a)) (hfg a)
266+
exact ⟨f', hQ f' fun a => (hf' a).1, fun a => (hf' a).2
267+
268+
@[rocq_alias discrete_fun_updateP']
269+
theorem discreteFun_updateP' {f : (a : ι) → β a} {P : (a : ι) → β a → Prop}
270+
(hf : ∀ a, f a ~~>: P a) : f ~~>: fun f' => ∀ a, P a (f' a) :=
271+
discreteFun_updateP hf fun _ h => h
272+
273+
@[rocq_alias discrete_fun_update]
274+
theorem discreteFun_update {f g : (a : ι) → β a} (hfg : ∀ a, f a ~~> g a) : f ~~> g :=
275+
Update.of_updateP <| discreteFun_updateP (fun a => UpdateP.of_update (hfg a))
276+
fun _ h => funext h
277+
278+
end CMRA
279+
280+
end Iris

0 commit comments

Comments
 (0)