/- 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) -- ── Composition over schema-defined inductive types (REL1) ────────────────── -- Composition over `.ind S params` flows through `eval_comp_stuck` -- (`.ind ≠ .pi`). Derived theorems below make the case explicit. -- REL1.1 / REL2: pointwise distribution through ctor args. /-- Composition over a non-trivial `.ind` line reduces to a stuck `ncomp` neutral. Derived from `eval_comp_stuck`. -/ theorem eval_comp_ind (env : CEnv) (i : DimVar) (S : CTypeSchema) (params : List CType) (φ : FaceFormula) (u t : CTerm) (hφ₁ : φ ≠ .top) (hφ₂ : φ ≠ .bot) (hA : CType.dimAbsent i (.ind S params) = false) : eval env (.comp i (.ind S params) φ u t) = .vneu (.ncomp i (.ind S params) φ (eval env u) (eval env t)) := eval_comp_stuck env i (.ind S params) φ u t hφ₁ hφ₂ hA (by intro _ _ h; nomatch h) /-- Composition over a constant `.ind` line reduces to homogeneous composition. Derived from `eval_comp_const`. -/ theorem eval_comp_ind_const (env : CEnv) (i : DimVar) (S : CTypeSchema) (params : List CType) (φ : FaceFormula) (u t : CTerm) (hφ₁ : φ ≠ .top) (hφ₂ : φ ≠ .bot) (hA : CType.dimAbsent i (.ind S params) = true) : eval env (.comp i (.ind S params) φ u t) = vHCompValue (.ind S params) φ (eval env (.plam i u)) (eval env t) := eval_comp_const env i (.ind S params) φ u t hφ₁ hφ₂ hA /-- Composition over `.ind` at `φ = .top`: the system covers everything, so the result is the tube body at `i := 1`. Direct corollary of C1. -/ theorem eval_comp_ind_top (env : CEnv) (i : DimVar) (S : CTypeSchema) (params : List CType) (u t : CTerm) : eval env (.comp i (.ind S params) .top u t) = eval env (u.substDim i .one) := eval_comp_top env i (.ind S params) u t /-- Composition over `.ind` at `φ = .bot`: the system contributes nothing, so the result is transport of the base. Direct corollary of C2. -/ theorem eval_comp_ind_bot (env : CEnv) (i : DimVar) (S : CTypeSchema) (params : List CType) (u t : CTerm) : eval env (.comp i (.ind S params) .bot u t) = eval env (.transp i (.ind S params) .bot t) := eval_comp_bot env i (.ind S params) u t