|
| 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