Large Signal Model · Lean source

PacketTree.lean

Declared contract recorded Coverage and evidence

The cited release explicitly reports completion of its registered formal contract, under its exact hypotheses.

This viewer reads the retained source; it does not run Lean or assign new claim mappings.

KomorebiLSM/PacketTree.lean186 lines

Original source pathLean/KomorebiLSM/PacketTree.lean
Skip declarations and read code

Skip source text

1 import Mathlib.Algebra.BigOperators.Group.Finset.Basic
2 import Mathlib.Data.Fintype.Sum
3 import Mathlib.Data.Fintype.Sigma
4 import Mathlib.Data.Fintype.BigOperators
5 
6 /-! Finite rooted trees and path-complete cuts. A selection is arbitrary
7 on nodes. Completeness means exactly one selected node on each full
8 root-to-leaf path. Reconstruction is derived from local conservation,
9 not included in the definition of a cut. -/
10 set_option autoImplicit false
11 open scoped BigOperators
12 namespace Komorebi.LSM
13 
14 /-- Every internal node has a finite nonempty child family. -/
15 inductive PacketTree where
16   | leaf : PacketTree
17   | branch (n : ℕ) (child : Fin (n + 1) → PacketTree) : PacketTree
18 
19 namespace PacketTree
20 
21 /-- Nodes have structural addresses, even when labels coincide. -/
22 @[reducible] def Node : PacketTree → Type
23   | .leaf => Unit
24   | .branch n child => Unit ⊕ (Σ i : Fin (n + 1), Node (child i))
25 
26 /-- Full root-to-leaf paths are indexed by the leaf they reach. -/
27 @[reducible] def Leaf : PacketTree → Type
28   | .leaf => Unit
29   | .branch n child => Σ i : Fin (n + 1), Leaf (child i)
30 
31 def root : (t : PacketTree) → Node t
32   | .leaf => ()
33   | .branch _ _ => Sum.inl ()
34 
35 /-- A canonical leaf proves that no descendant branch is empty. -/
36 def firstLeaf : (t : PacketTree) → Leaf t
37   | .leaf => ()
38   | .branch _ child => ⟨0, firstLeaf (child 0)⟩
39 
40 /-- Counts every selected node along a full path, including the root. -/
41 def pathCount : (t : PacketTree) → (Node t → Bool) → Leaf t → ℕ
42   | .leaf, s, _ => (s ()).toNat
43   | .branch _ child, s, p => (s (Sum.inl ())).toNat +
44       pathCount (child p.1) (fun v => s (Sum.inr ⟨p.1, v⟩)) p.2
45 
46 def IsCompleteCut (t : PacketTree) (s : Node t → Bool) : Prop :=
47   ∀ p : Leaf t, pathCount t s p = 1
48 
49 /-- Canonical recursive finite sum over every node. -/
50 def nodeSum {A : Type*} [AddCommMonoid A] : (t : PacketTree) → (Node t → A) → A
51   | .leaf, f => f ()
52   | .branch _ child, f => f (Sum.inl ()) +
53       ∑ i, nodeSum (child i) (fun v => f (Sum.inr ⟨i, v⟩))
54 
55 def selectedSum {A : Type*} [AddCommMonoid A]
56     (t : PacketTree) (s : Node t → Bool) (f : Node t → A) : A :=
57   nodeSum t (fun v => if s v then f v else 0)
58 
59 /-- Local conservation imposes no condition on terminal node labels. -/
60 def Conservative {A : Type*} [AddCommMonoid A] :
61     (t : PacketTree) → (Node t → A) → Prop
62   | .leaf, _ => True
63   | .branch _ child, f =>
64       f (Sum.inl ()) = ∑ i, f (Sum.inr ⟨i, root (child i)⟩) ∧
65       ∀ i, Conservative (child i) (fun v => f (Sum.inr ⟨i, v⟩))
66 
67 theorem nodeSum_zero {A : Type*} [AddCommMonoid A] (t : PacketTree) :
68     nodeSum t (fun _ => (0 : A)) = 0 := by
69   induction t with
70   | leaf => rfl
71   | branch n child ih => simp [nodeSum, ih]
72 
73 theorem pathCount_zero_iff (t : PacketTree) (s : Node t → Bool) :
74     (∀ p, pathCount t s p = 0) ↔ (∀ v, s v = false) := by
75   induction t with
76   | leaf =>
77       constructor
78       · intro h v
79         cases v
80         simpa [pathCount] using h ()
81       · intro h p
82         cases p
83         simp [pathCount, h ()]
84   | branch n child ih =>
85       constructor
86       · intro h
87         have hroot : s (Sum.inl ()) = false := by
88           have h0 := h ⟨0, firstLeaf (child 0)⟩
89           cases hs : s (Sum.inl ()) <;> simp [pathCount, hs] at h0 ⊢
90         intro v
91         cases v with
92         | inl u => cases u; exact hroot
93         | inr p =>
94             apply (ih p.1 (fun v => s (Sum.inr ⟨p.1, v⟩))).mp
95             · intro q
96               simpa [pathCount, hroot] using h ⟨p.1, q⟩
97       · intro h p
98         have hi := (ih p.1 (fun v => s (Sum.inr ⟨p.1, v⟩))).mpr
99           (fun v => h (Sum.inr ⟨p.1, v⟩))
100         simp [pathCount, h (Sum.inl ()), hi]
101 
102 theorem completeCut_leaf (s : Node .leaf → Bool) :
103     IsCompleteCut .leaf s ↔ s () = true := by
104   simp [IsCompleteCut, pathCount, Leaf]
105 
106 /-- The path criterion forces either a root-only cut or full child cuts. -/
107 theorem completeCut_branch {n : ℕ} {child : Fin (n+1) → PacketTree}
108     (s : Node (.branch n child) → Bool) :
109     IsCompleteCut (.branch n child) s ↔
110       (s (Sum.inl ()) = true ∧ ∀ i v, s (Sum.inr ⟨i, v⟩) = false) ∨
111       (s (Sum.inl ()) = false ∧ ∀ i,
112         IsCompleteCut (child i) (fun v => s (Sum.inr ⟨i, v⟩))) := by
113   constructor
114   · intro h
115     cases hs : s (Sum.inl ()) with
116     | false =>
117         right
118         refine ⟨rfl, ?_⟩
119         intro i p
120         simpa [pathCount, hs] using h ⟨i, p⟩
121     | true =>
122         left
123         refine ⟨rfl, ?_⟩
124         intro i
125         apply (pathCount_zero_iff (child i) _).mp
126         intro p
127         have hp := h ⟨i, p⟩
128         simpa [pathCount, hs] using hp
129   · rintro (⟨hr, hz⟩ | ⟨hr, hc⟩) p
130     · have hp := (pathCount_zero_iff (child p.1) _).mpr (hz p.1) p.2
131       simp [pathCount, hr, hp]
132     · simpa [pathCount, hr] using hc p.1 p.2
133 
134 /-- Complete cuts conserve any additive label with conservative splits. -/
135 theorem selectedSum_eq_root {A : Type*} [AddCommMonoid A]
136     (t : PacketTree) (s : Node t → Bool) (f : Node t → A)
137     (cut : IsCompleteCut t s) (hf : Conservative t f) :
138     selectedSum t s f = f (root t) := by
139   induction t with
140   | leaf =>
141       have hs := (completeCut_leaf s).mp cut
142       simp [selectedSum, nodeSum, root, hs]
143   | branch n child ih =>
144       rcases (completeCut_branch s).mp cut with ⟨hr, hz⟩ | ⟨hr, hc⟩
145       · simp [selectedSum, nodeSum, hr, hz, nodeSum_zero, root]
146       · have hh (i : Fin (n+1)) := ih i
147           (fun v => s (Sum.inr ⟨i, v⟩)) (fun v => f (Sum.inr ⟨i, v⟩))
148           (hc i) (hf.2 i)
149         simp only [selectedSum] at hh
150         simp only [selectedSum, nodeSum, hr, Bool.false_eq_true, ↓reduceIte,
151           zero_add, hh]
152         exact hf.1.symm
153 
154 /-- An explicit enumeration of all structural node addresses. -/
155 @[instance_reducible] def nodeFintype : (t : PacketTree) → Fintype (Node t)
156   | .leaf => inferInstanceAs (Fintype Unit)
157   | .branch n child => by
158       letI (i : Fin (n+1)) : Fintype (Node (child i)) := nodeFintype (child i)
159       exact inferInstanceAs (Fintype (Unit ⊕ (Σ i : Fin (n+1), Node (child i))))
160 
161 instance instFintypeNode (t : PacketTree) : Fintype (Node t) := nodeFintype t
162 
163 theorem nodeSum_eq_sum {A : Type*} [AddCommMonoid A]
164     (t : PacketTree) (f : Node t → A) :
165     nodeSum t f = ∑ v, f v := by
166   induction t with
167   | leaf =>
168       change f () = ∑ v : Unit, f v
169       simp
170   | branch n child ih =>
171       change f (Sum.inl ()) + ∑ i, nodeSum (child i) (fun v => f (Sum.inr ⟨i,v⟩)) = _
172       rw [Fintype.sum_sum_type, Fintype.sum_sigma]
173       simp only [Finset.univ_unique, PUnit.default_eq_unit, Finset.sum_singleton]
174       congr 1
175       exact Finset.sum_congr rfl (fun i _ => ih i _)
176 
177 /-- Standard finite-sum form of the complete-antichain conservation law. -/
178 theorem complete_cut_sum {A : Type*} [AddCommMonoid A]
179     (t : PacketTree) (s : Node t → Bool) (f : Node t → A)
180     (cut : IsCompleteCut t s) (hf : Conservative t f) :
181     (∑ v, if s v then f v else 0) = f (root t) := by
182   rw [← nodeSum_eq_sum]
183   exact selectedSum_eq_root t s f cut hf
184 
185 end PacketTree
186 end Komorebi.LSM

Back to source controls

Original file and source record

This copy matches the recorded source file. Its publication here does not change the work’s review status.

SHA-256: e92979213f3c4d7244c1c4eb4796b2c910c3d8306b298bca54cbecce90a7f0ff

Original source on GitHub

Back to Large Signal Model