Skip to content

Commit 1a7d871

Browse files
feat: update operation for FinFun (#470)
This PR adds `FinFun.update` and proves some basic results about the functional interface and support of the resulting function. --------- Co-authored-by: Chris Henson <46805207+chenson2018@users.noreply.github.com> Co-authored-by: Chris Henson <chrishenson.net@gmail.com>
1 parent 74f5bf6 commit 1a7d871

4 files changed

Lines changed: 90 additions & 3 deletions

File tree

Cslib.lean

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ public import Cslib.Foundations.Control.Monad.Free
4848
public import Cslib.Foundations.Control.Monad.Free.Effects
4949
public import Cslib.Foundations.Control.Monad.Free.Fold
5050
public import Cslib.Foundations.Data.BiTape
51-
public import Cslib.Foundations.Data.FinFun
51+
public import Cslib.Foundations.Data.DecidableEqZero
52+
public import Cslib.Foundations.Data.FinFun.Basic
53+
public import Cslib.Foundations.Data.FinFun.Update
5254
public import Cslib.Foundations.Data.HasFresh
5355
public import Cslib.Foundations.Data.Nat.Segment
5456
public import Cslib.Foundations.Data.OmegaSequence.Defs
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/-
2+
Copyright (c) 2026 Fabrizio Montesi. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Fabrizio Montesi
5+
-/
6+
7+
module
8+
9+
public import Cslib.Init
10+
11+
@[expose] public section
12+
13+
namespace Cslib
14+
15+
/-- Equality to `Zero` is decidable for all elements of a type (`α`). -/
16+
abbrev DecidableEqZero (α : Type*) [Zero α] := ∀ a : α, Decidable (a = 0)
17+
18+
end Cslib
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,7 @@ theorem fn_eq_eq [Zero β] {f g : α →₀ β} (h : f.fn = g.fn) : f = g :=
8989
ext (congrFun h)
9090

9191
@[scoped grind =>]
92-
theorem congrFinFun [Zero β] {f g : α →₀ β} (h : f = g) (a : α) : f a = g a :=
93-
by grind
92+
theorem congrFinFun [Zero β] {f g : α →₀ β} (h : f = g) (a : α) : f a = g a := by grind
9493

9594
@[scoped grind =]
9695
theorem fromFun_eq [Zero β] [DecidableEq α] [∀ y : β, Decidable (y = 0)]
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/-
2+
Copyright (c) 2026 Fabrizio Montesi. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Fabrizio Montesi
5+
-/
6+
7+
module
8+
9+
public import Cslib.Foundations.Data.FinFun.Basic
10+
public import Cslib.Foundations.Data.DecidableEqZero
11+
public import Mathlib.Data.Finset.SDiff
12+
13+
@[expose] public section
14+
15+
/-! # Update for finite functions
16+
17+
This module defines the update operation for finite functions, that is, the equivalent of
18+
`Function.update` for `FinFun`.
19+
-/
20+
21+
namespace Cslib.FinFun
22+
23+
variable [Zero β] [DecidableEq α] [DecidableEqZero β]
24+
25+
set_option linter.tacticAnalysis.verifyGrindOnly false in
26+
/-- `FinFun` equivalent of `Function.update`. -/
27+
def update (f : α →₀ β) (a : α) (b : β) : α →₀ β where
28+
fn := Function.update f.fn a b
29+
support := if b = 0 then f.support \ {a} else f.support ∪ {a}
30+
mem_support_fn := by
31+
by_cases b = 0
32+
· grind only [= Finset.mem_sdiff, = Finset.mem_singleton, = Function.update, = mem_support_fn]
33+
· grind
34+
35+
/-- `FinFun.update` is consistent with `Function.update`. -/
36+
@[scoped grind =, simp]
37+
theorem update_coe (f : α →₀ β) : (f.update a b : α → β) = Function.update f a b := by
38+
grind [update]
39+
40+
/-- Conditional characterisation of the functional interface of `FinFun.update`. -/
41+
@[scoped grind =]
42+
theorem update_apply (f : α →₀ β) : ((f.update a' b) a) = if a = a' then b else f a := by
43+
simp [Function.update_apply]
44+
45+
/-- Conditional characterisation of the support of an updated `FinFun`. -/
46+
@[scoped grind =]
47+
theorem update_support (f : α →₀ β) :
48+
(f.update a b).support = if b = 0 then f.support \ {a} else f.support ∪ {a} := by simp [update]
49+
50+
/-- Updating a finite function on the same key is the same as doing the last update. -/
51+
@[scoped grind =, simp]
52+
theorem update_idem (f : α →₀ β) : (f.update a b).update a b' = f.update a b' := by grind
53+
54+
/-- Updates on different keys commute. -/
55+
@[scoped grind =]
56+
theorem update_comm (f : α →₀ β) (h : a ≠ a') :
57+
(f.update a b).update a' b' = (f.update a' b').update a b := by
58+
grind only [←= ext, = update_apply]
59+
60+
/-- Updates that do not change mappings are redundant. -/
61+
@[scoped grind =]
62+
theorem update_self (f : α →₀ β) : (f.update a (f a)) = f := by grind
63+
64+
/-- Updating a function never grows its support more than adding the key. -/
65+
@[scoped grind .]
66+
theorem update_support_subseteq (f : α →₀ β) : (f.update a b).support ⊆ f.support ∪ {a} := by grind
67+
68+
end Cslib.FinFun

0 commit comments

Comments
 (0)