@@ -127,11 +127,14 @@ theorem lambda_id_is_cno_on_values : isLambdaCNO lambda_id := by
127127 · apply BetaReduceStar.beta_step
128128 · apply BetaReduce.beta_app
129129 · unfold subst; simp; apply BetaReduceStar.beta_refl
130- · -- arg is in normal form: this is NOT provable for arbitrary arg.
131- -- E.g., if arg = (λx.x)(λx.x), it's not in normal form.
132- -- The identity function preserves whatever arg is, so if arg
133- -- doesn't normalize, (λx.x) arg doesn't either. This is expected.
134- sorry -- GENUINE: unprovable without restricting arg to normal forms
130+ · -- DESIGN_FLAW: isNormalForm is unprovable for arbitrary arg.
131+ -- isLambdaCNO quantifies over ALL lambda terms, including divergent
132+ -- ones like Ω = (λx.xx)(λx.xx). The identity function faithfully
133+ -- returns arg unchanged, so if arg is not in normal form, neither
134+ -- is the result. The fix would be to restrict isLambdaCNO to args
135+ -- that are already values (in normal form), or to split termination
136+ -- from identity behavior. See isLambdaCNOWeak for the correct approach.
137+ sorry -- DESIGN_FLAW: isNormalForm demanded for arbitrary args
135138
136139 · -- Identity
137140 apply BetaReduceStar.beta_step
@@ -140,6 +143,36 @@ theorem lambda_id_is_cno_on_values : isLambdaCNO lambda_id := by
140143 simp
141144 apply BetaReduceStar.beta_refl
142145
146+ /-! ## Congruence Lemma for Multi-Step Reduction -/
147+
148+ /-- If `a →* b` then `f a →* f b`.
149+ Proved by induction on the BetaReduceStar derivation,
150+ lifting each single step via `BetaReduce.beta_app_right`. -/
151+ theorem BetaReduceStar_app_right (f a b : LambdaTerm)
152+ (h : BetaReduceStar a b) : BetaReduceStar (LApp f a) (LApp f b) := by
153+ induction h with
154+ | beta_refl t =>
155+ exact BetaReduceStar.beta_refl _
156+ | beta_step t1 t2 t3 h_step _ ih =>
157+ exact BetaReduceStar.beta_step _ _ _ (BetaReduce.beta_app_right f t1 t2 h_step) ih
158+
159+ /-- If `a →* b` then `a c →* b c`.
160+ Dual congruence lemma lifting under the left side of application. -/
161+ theorem BetaReduceStar_app_left (a b c : LambdaTerm)
162+ (h : BetaReduceStar a b) : BetaReduceStar (LApp a c) (LApp b c) := by
163+ induction h with
164+ | beta_refl t =>
165+ exact BetaReduceStar.beta_refl _
166+ | beta_step t1 t2 t3 h_step _ ih =>
167+ exact BetaReduceStar.beta_step _ _ _ (BetaReduce.beta_app_left t1 t2 c h_step) ih
168+
169+ /-- Transitivity of multi-step reduction. -/
170+ theorem BetaReduceStar_trans (a b c : LambdaTerm)
171+ (h1 : BetaReduceStar a b) (h2 : BetaReduceStar b c) : BetaReduceStar a c := by
172+ induction h1 with
173+ | beta_refl _ => exact h2
174+ | beta_step t1 t2 _ h_step _ ih => exact BetaReduceStar.beta_step _ _ _ h_step (ih h2)
175+
143176/-! ## Composition Theorem -/
144177
145178/-- Composing two lambda CNOs yields a CNO -/
@@ -161,9 +194,12 @@ theorem lambda_cno_composition_weak (f g : LambdaTerm) :
161194 simp
162195 -- After beta: f (g arg)
163196 -- g arg →* arg (by hg), so f (g arg) →* f arg →* arg
164- -- This requires congruence lemmas for BetaReduceStar under LApp
165- -- which are not available without additional infrastructure
166- sorry -- GENUINE: requires multi-step congruence lemma for BetaReduceStar
197+ -- Use BetaReduceStar_app_right to lift (g arg →* arg) under f,
198+ -- then transitivity with (f arg →* arg).
199+ have hg_arg := hg arg
200+ have h_congr := BetaReduceStar_app_right f (LApp g arg) arg hg_arg
201+ have hf_arg := hf arg
202+ exact BetaReduceStar_trans _ _ _ h_congr hf_arg
167203
168204theorem lambda_cno_composition (f g : LambdaTerm) :
169205 isLambdaCNO f →
@@ -173,10 +209,25 @@ theorem lambda_cno_composition (f g : LambdaTerm) :
173209 unfold isLambdaCNO at *
174210 intro arg
175211 constructor
176- · -- Terminates: requires congruence + composition of multi-step reductions
177- sorry -- GENUINE: requires BetaReduceStar congruence infrastructure
212+ · -- Terminates: isLambdaCNO demands (∃ nf, evaluatesTo ... nf) which requires
213+ -- isNormalForm on the result. Since isLambdaCNO quantifies over ALL args
214+ -- (including non-normalizing ones like Ω), the identity function faithfully
215+ -- returns the non-normalizing arg, making isNormalForm unprovable.
216+ -- DESIGN_FLAW: isNormalForm demanded for arbitrary args; would need to
217+ -- restrict isLambdaCNO to args already in normal form (values).
218+ sorry -- DESIGN_FLAW: isNormalForm unprovable for arbitrary args
178219 · -- Identity: ((λx. f (g x)) arg) →* arg
179- sorry -- GENUINE: requires BetaReduceStar congruence infrastructure
220+ -- Beta-reduce the outer lambda: (λx. f (g x)) arg →β f (g arg)
221+ -- Then: g arg →* arg (by hg), f (g arg) →* f arg (by congruence),
222+ -- and f arg →* arg (by hf). Chain by transitivity.
223+ have ⟨_, hf_id⟩ := hf arg
224+ have ⟨_, hg_id⟩ := hg arg
225+ apply BetaReduceStar.beta_step
226+ · apply BetaReduce.beta_app
227+ · unfold subst lambda_compose
228+ simp
229+ have h_congr := BetaReduceStar_app_right f (LApp g arg) arg hg_id
230+ exact BetaReduceStar_trans _ _ _ h_congr hf_id
180231
181232/-! ## Non-CNO Examples -/
182233
@@ -250,7 +301,10 @@ theorem eta_expanded_id_is_cno :
250301 · apply BetaReduce.beta_app
251302 · unfold subst lambda_id; simp
252303 apply BetaReduceStar.beta_refl
253- · sorry -- GENUINE: same issue as lambda_id_is_cno - arg may not be in normal form
304+ · -- DESIGN_FLAW: same issue as lambda_id_is_cno_on_values — isNormalForm
305+ -- demanded for arbitrary args. The eta-expanded identity reduces arg
306+ -- faithfully, but if arg is not in normal form, neither is the result.
307+ sorry -- DESIGN_FLAW: isNormalForm demanded for arbitrary args
254308 · -- (λx. (λy.y) x) arg →* arg
255309 apply BetaReduceStar.beta_step
256310 · apply BetaReduce.beta_app
0 commit comments