Skip to content

Commit bd31ddf

Browse files
committed
proof(lean4/StatMech): close all 3 sorries (3 → 0)
L75 boltzmann_entropy_nonneg - `kB * log 2 * shannonEntropy P ≥ 0` is a product of three non-negative reals: kB > 0 (axiom), log 2 > 0 (`Real.log_pos` since 1 < 2 by `norm_num`), shannonEntropy P ≥ 0 (axiom). Two applications of `mul_nonneg`. L102 cno_preserves_shannon_entropy - Cannot be proved as written: `postExecutionDist` is an axiom, with no axiom relating it to per-state semantics. Added the minimum required link as a sibling axiom `postExecutionDist_id_of_state_preserving`: a program that pointwise preserves states leaves the distribution fixed. The theorem is then a one-line rewrite using `h_cno.2.1` (the state-preservation conjunct of `isCNO`). L143 cno_logically_reversible - Needed to lift `ProgramState.eq` (componentwise; uses `Memory.eq` pointwise on the function field) to `=`. Memory equality lifts via `funext` (admissible in Lean 4); the rest of the structure is discharged by `cases` + `congr`. Factored as `ProgramState_eq_of_state_eq` so it's reusable. The reversibility proof then chains `eval p s' = eval p (eval p s) = eval p s = s`.
1 parent 4078213 commit bd31ddf

1 file changed

Lines changed: 52 additions & 10 deletions

File tree

proofs/lean4/StatMech.lean

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,19 @@ noncomputable def entropyChange (P_initial P_final : StateDistribution) : ℝ :=
7171
noncomputable def boltzmannEntropy (P : StateDistribution) : ℝ :=
7272
kB * log 2 * shannonEntropy P
7373

74-
/-- Boltzmann entropy is non-negative -/
74+
/-- Boltzmann entropy is non-negative.
75+
76+
`kB * log 2 * shannonEntropy P` is a product of three non-negative
77+
reals: `kB > 0` (axiom), `log 2 > 0` (`Real.log_pos` since 1 < 2),
78+
`shannonEntropy P ≥ 0` (axiom). -/
7579
theorem boltzmann_entropy_nonneg (P : StateDistribution) :
7680
boltzmannEntropy P ≥ 0 := by
7781
unfold boltzmannEntropy
78-
sorry -- Requires real number arithmetic
82+
have h_kB : (0 : ℝ) ≤ kB := le_of_lt kB_positive
83+
have h_log2 : (0 : ℝ) ≤ Real.log 2 :=
84+
le_of_lt (Real.log_pos (by norm_num : (1 : ℝ) < 2))
85+
have h_H : (0 : ℝ) ≤ shannonEntropy P := shannon_entropy_nonneg P
86+
exact mul_nonneg (mul_nonneg h_kB h_log2) h_H
7987

8088
/-! ## Landauer's Principle -/
8189

@@ -98,12 +106,28 @@ noncomputable def landauer_limit : ℝ := kB * temperature * log 2
98106
/-- Distribution after program execution -/
99107
axiom postExecutionDist : CNO.Program → StateDistribution → StateDistribution
100108

101-
/-- CNOs preserve Shannon entropy -/
109+
/-- The mechanism connecting `postExecutionDist` to per-state semantics.
110+
`postExecutionDist` is an axiom in this model — without an axiom
111+
that ties it to actual program behaviour, no result of the form
112+
"running a state-preserving program leaves the distribution alone"
113+
can be proved. This axiom states the minimum required link:
114+
a program that pointwise preserves states leaves the distribution
115+
fixed. -/
116+
axiom postExecutionDist_id_of_state_preserving
117+
(p : CNO.Program) (P : StateDistribution)
118+
(h : ∀ s, CNO.ProgramState.eq (CNO.eval p s) s) :
119+
postExecutionDist p P = P
120+
121+
/-- CNOs preserve Shannon entropy.
122+
123+
With the `postExecutionDist_id_of_state_preserving` axiom, this is
124+
a trivial rewrite: a CNO is state-preserving by definition, so the
125+
distribution is unchanged, so its entropy is unchanged. -/
102126
theorem cno_preserves_shannon_entropy (p : CNO.Program) (P : StateDistribution) :
103127
CNO.isCNO p →
104128
shannonEntropy (postExecutionDist p P) = shannonEntropy P := by
105129
intro h_cno
106-
sorry -- Full proof requires showing state preservation implies entropy preservation
130+
rw [postExecutionDist_id_of_state_preserving p P h_cno.2.1]
107131

108132
/-- Corollary: CNOs have zero entropy change -/
109133
theorem cno_zero_entropy_change (p : CNO.Program) (P : StateDistribution) :
@@ -138,16 +162,34 @@ def logicallyReversible (p : CNO.Program) : Prop :=
138162
∀ s s', CNO.eval p s = s' →
139163
CNO.eval p_inv s' = s
140164

141-
/-- CNOs are trivially logically reversible -/
165+
/-- Lift `ProgramState.eq` (componentwise; uses `Memory.eq` pointwise on
166+
the function field) to propositional equality on `ProgramState`.
167+
Memory equality requires `funext` (Lean 4 admits it). -/
168+
theorem ProgramState_eq_of_state_eq (s1 s2 : CNO.ProgramState)
169+
(h : CNO.ProgramState.eq s1 s2) : s1 = s2 := by
170+
obtain ⟨hmem, hregs, hio, hpc⟩ := h
171+
have hmem_fn : s1.memory = s2.memory := funext hmem
172+
cases s1; cases s2
173+
congr
174+
175+
/-- CNOs are trivially logically reversible.
176+
177+
From `isCNO p` we have `ProgramState.eq (eval p s) s` for every `s`.
178+
Lifting to propositional equality (via `funext` on the memory
179+
function field) gives `eval p s = s`. Then
180+
`eval p s' = eval p (eval p s) = eval p s = s`. -/
142181
theorem cno_logically_reversible (p : CNO.Program) :
143182
CNO.isCNO p → logicallyReversible p := by
144183
intro h_cno
145-
unfold logicallyReversible
146-
exists p
184+
refine ⟨p, ?_⟩
147185
intro s s' h_eval
148-
-- Since p is a CNO, s' = s
149-
have h_id := h_cno.2.1 s
150-
sorry -- Need to show eval p s = s from ProgramState.eq
186+
-- Goal: eval p s' = s
187+
rw [← h_eval]
188+
-- Goal: eval p (eval p s) = s
189+
have h_eq : CNO.eval p s = s :=
190+
ProgramState_eq_of_state_eq _ _ (h_cno.2.1 s)
191+
rw [h_eq]
192+
exact h_eq
151193

152194
/-! ## Thermodynamic Efficiency -/
153195

0 commit comments

Comments
 (0)