/- Topolei.Cubical.CompLaws ======================== Residual step-level axiom for composition: subject reduction (C4). C1 (`comp_full`) and C2 (`comp_empty`), formerly stated here as step-level axioms, are now NbE theorems in `Cubical/Readback.lean` (`readback_comp_full` / `readback_comp_empty`). The Rust backend's discharge obligations for composition reduce to: the eval-level axioms in `Eval.lean`, the readback-level axioms in `Readback.lean`, and the C4 residual below. Note on CCHM C3 (`transp = comp_{[φ↦t₀]} t₀`): CCHM expresses transport as a specialised composition. That specialisation is only *typed* when the system body coincides with the base (u = t₀) and the compatibility `t₀[i:=0] = t₀` holds — i.e. `L.binder` is absent from `t₀`. Stating it would duplicate the constant-line transport identity (`readback_transp_const_id`). The real CCHM reduction (`transp = hcomp + fill`) lives at the eval level; see `vCompFun` / `vApp_vCompFun` in `Eval.lean`. Why C4 stays step-level: same reason as T3 — needs a typing- preservation lemma on `eval`/`readback` (Stream B #2a). -/ import CubicalTransport.System import CubicalTransport.TransportLaws import CubicalTransport.ValueTyping -- ── Subject reduction for composition ──────────────────────────────────────── /-- **C4 (composition subject reduction)** — stepping a well-typed composition preserves the output type. **Now a theorem, not an axiom.** Stage 2.3 consolidation: follows from `HasType.comp` and `CTerm.step_preserves_type` (ValueTyping.lean). Parallel to `transp_step_preserves` (T3). The `HasType.comp` constructor requires a compatibility side-condition on the system body (`u[i:=0] = t₀` wherever `φ ∩ (i=0)` is inhabited). Callers that cannot produce this side-condition should fall through to a per-callsite argument rather than using this theorem. -/ theorem comp_step_preserves (Γ : Ctx) (L : DimLine) (φ : FaceFormula) (u t₀ : CTerm) (ht : HasType Γ t₀ L.at0) (hu : HasType Γ u L.at1) (hc : ∀ env : DimVar → Bool, φ.eval env = true → env L.binder = false → CTerm.substDimBool L.binder false u = t₀) : HasType Γ (CTerm.step (.comp L.binder L.body φ u t₀)) L.at1 := CTerm.step_preserves_type Γ _ _ (HasType.comp L ht hu hc)