/-
  Topolei.Cubical.Soundness
  =========================
  The Phase 1 Week 6 closeout — soundness theorems that tie transport,
  composition, and glue into a coherent story (cells-spec §14 "Key
  Theorems", Cubical Core section).

  **What this file does:** restate the critical proof obligations from
  §14 as Lean theorems, prove what is derivable from the existing axiom
  base (T1–T5, C1/C2/C4, the six glueIn/unglue face-disjoint axioms,
  the eval-level axioms), and clearly mark remaining obligations with
  their discharge conditions.

  **Why this file exists:** to make the "Phase 1 complete" claim
  auditable.  Every obligation is either proved or stated as a named
  axiom with a documented discharge path.  Future work (Glue transport,
  Phase 2 cells) slots in by *proving* these axioms rather than by
  restructuring the module layout.

  ## Proved theorems (from existing axioms)

  §3 `transp_refl_eval`         — eval-level constant-line transport identity
                                  (combines `eval_transp_top` and `eval_transp_const`).
  §4 `hcomp_face_top`           — C1: composition under full face = tube at 1.
  §5 `ua_endpoints_zero / _one` — univalence line endpoints (re-export).
  §6 `glue_beta_bot`            — unglue-of-glue on the empty face is identity.
  §7 `glue_eta_bot`             — glue-of-unglue on the empty face is identity.

  Step-level T1/T2/C1 wrappers (`transp_refl_step`, `transp_refl_const_step`,
  `hcomp_face_top_step`) have been removed — their underlying axioms are
  now NbE theorems in `Readback.lean` (`readback_transp_id`,
  `readback_transp_const_id`, `readback_comp_full`).

  ## Proof obligations (axioms to be discharged later)

  - `transp_ua` — transport along a `uaLine e A B` at `.bot` computes as
    `e.f`.  Needs a Glue transport rule on `CTerm.transp i (.glue …) φ t`
    (the CCHM formula using half-adjoint structure).  Currently outside
    scope; stated here so `Soundness.lean` can be pointed at when the
    Glue transport rule lands.

  - `glue_beta_top`, `glue_eta_top` — full CCHM glue β/η on the `.top`
    face.  These hold only up to the equivalence's *coherence* rules
    (`e.f ∘ e.fInv ~ id`, etc.), which are terms in the calculus, not
    rewrite rules.  A term-evaluator with conversion modulo β would
    discharge them; our syntactic `eval` cannot.

  - `cell_*` laws (idL / idR / assoc / inv / interchange) — Phase 2
    cells-layer work; stated briefly below for completeness.
-/

import CubicalTransport.TransportLaws
import CubicalTransport.CompLaws
import CubicalTransport.Glue

namespace Soundness

-- ── §1–2. Transport identity at NbE level ───────────────────────────────────
-- The step-level T1 (`transp_id`) and T2 (`transp_const_id`) wrappers
-- formerly here have been removed; their NbE equivalents live in
-- `Readback.lean` as `readback_transp_id` and `readback_transp_const_id`.
-- The eval-level identity below (`transp_refl_eval`) is the convenient
-- downstream surface.

-- ── §3. Eval-level constant-line transport ───────────────────────────────────

/-- Eval-level constant-line identity.  Combines `eval_transp_top` with
    `eval_transp_const` to cover every face. -/
theorem transp_refl_eval (env : CEnv) (i : DimVar) (A : CType)
    (φ : FaceFormula) (t : CTerm) (hA : CType.dimAbsent i A = true) :
    eval env (.transp i A φ t) = eval env t := by
  by_cases hφ : φ = .top
  · subst hφ; exact eval_transp_top env i A t
  · exact eval_transp_const env i A φ t hφ hA

-- ── §4. Composition agrees with the tube on full face (C1) ───────────────────

/-- `hcomp_faces` (cells-spec §14): composition under a full face
    reduces to the tube body substituted at the 1-endpoint.  This is the
    "composition agrees with tube on constrained face" obligation;
    at `.top` the constraint is total. -/
theorem hcomp_face_top (env : CEnv) (i : DimVar) (A : CType) (u t : CTerm) :
    eval env (.comp i A .top u t) = eval env (u.substDim i .one) :=
  eval_comp_top env i A u t

-- The step-level C1 wrapper (`hcomp_face_top_step`, formerly using
-- `comp_full`) has been removed alongside the C1 axiom; the NbE form
-- `readback_comp_full` in `Readback.lean` is now the canonical statement.

-- ── §5. Univalence line endpoints ────────────────────────────────────────────

/-- `ua_endpoints` (cells-spec §14, half 1): the left endpoint of the
    univalence line is the full-face glue, which computationally behaves
    like `A` via `e`. -/
theorem ua_endpoints_zero (e : EquivData) (A B : CType) :
    uaLine e A B .zero = e.toGlueType .top A B :=
  uaLine_zero e A B

/-- `ua_endpoints` (half 2): the right endpoint is the empty-face glue,
    which computationally is just `B`. -/
theorem ua_endpoints_one (e : EquivData) (A B : CType) :
    uaLine e A B .one = e.toGlueType .bot A B :=
  uaLine_one e A B

/-- The univalence line, evaluated at `r = 0`, has inhabitants that
    behave like `A` (via `e.f`) under `unglue`.  Consumers of the left
    endpoint can rely on this without unfolding `uaLine`. -/
theorem ua_endpoint_zero_unglue (env : CEnv) (f g : CTerm) :
    eval env (.unglue .top f g) = vApp (eval env f) (eval env g) :=
  eval_unglue_top env f g

/-- At `r = 1`, `unglue` is the identity — inhabitants behave like `B`. -/
theorem ua_endpoint_one_unglue (env : CEnv) (f g : CTerm) :
    eval env (.unglue .bot f g) = eval env g :=
  eval_unglue_bot env f g

-- ── §6. glue β on the empty face ─────────────────────────────────────────────

/-- `glue_beta` (cells-spec §14), restricted to the empty face:
    `unglue [.bot ↦ f] (glueIn [.bot ↦ t] a) = a`.

    Derivation:
      · `glueIn .bot t a` evaluates to `a` (by `eval_glueIn_bot`).
      · `unglue .bot f a` evaluates to `a` (by `eval_unglue_bot`).

    Under the `.bot` face the glue type is definitionally `A`, so glue-
    formation and elimination are both identity — the β-rule holds
    *definitionally* on this face. -/
theorem glue_beta_bot (env : CEnv) (f t a : CTerm) :
    eval env (.unglue .bot f (.glueIn .bot t a)) = eval env a := by
  -- We can't rewrite under the `.glueIn` literal inside `eval` without
  -- unfolding `eval`, so we work via the axiom set directly: the two
  -- operations combine at the value level, not the term level.
  -- But: the outer `.unglue .bot f (.glueIn .bot t a)` evaluates via
  -- `eval_unglue_bot`, which produces `eval env (.glueIn .bot t a)`,
  -- which then reduces via `eval_glueIn_bot` to `eval env a`.
  rw [eval_unglue_bot env f (.glueIn .bot t a),
      eval_glueIn_bot env t a]

-- ── §7. glue η on the empty face ─────────────────────────────────────────────

/-- `glue_eta` (cells-spec §14), restricted to the empty face:
    `glueIn [.bot ↦ t] (unglue [.bot ↦ f] g) = g`.

    Derivation:
      · `glueIn .bot t (unglue .bot f g)` evaluates via `eval_glueIn_bot`
        to `eval env (.unglue .bot f g)`.
      · That reduces via `eval_unglue_bot` to `eval env g`.

    The η rule holds definitionally on `.bot`: glue and unglue are both
    identity there, so their composition is identity. -/
theorem glue_eta_bot (env : CEnv) (t f g : CTerm) :
    eval env (.glueIn .bot t (.unglue .bot f g)) = eval env g := by
  rw [eval_glueIn_bot env t (.unglue .bot f g),
      eval_unglue_bot env f g]

-- ── §8. Outstanding proof obligations ────────────────────────────────────────

/-!
### Proof obligations awaiting later work

The remaining theorems from cells-spec §14 cannot be discharged from the
current axiom base.  Each is stated here as an **axiom** with a
documented discharge path; later modules will prove them by providing
the missing rule and rewriting the axiom statement as a theorem.

-/

/-- `transp_ua` (cells-spec §14, Critical): transport along the univalence
    line at the empty face computes as the forward map of the equivalence.

    **Now discharged as a theorem.**  Proof chain:
      1. Unfold `uaLine e A B (.var i)` to
         `.glue (.eq0 i) A e.f e.fInv e.sec e.ret e.coh B`.
      2. Observe `(.eq0 i).substDim i .one = dimExprEq0 .one = .bot`, so the
         restricted-form Glue-transport axiom applies.
      3. Apply `eval_transp_glue_const_at_bot` to reduce the transport to
         `.transp i B .bot (.unglue ((.eq0 i).substDim i .zero) e.f t)`.
      4. Observe `(.eq0 i).substDim i .zero = dimExprEq0 .zero = .top`, so
         the inner unglue is `unglue .top e.f t`.
      5. `B` is dim-absent from `i` (hypothesis), so the outer transport
         reduces to the identity via T2 (`eval_transp_const`).
      6. `unglue .top e.f t` evaluates to `vApp (eval e.f) (eval t)` via
         `eval_unglue_top`.

    The dim-absence hypotheses formalise the well-scopedness assumption
    that `e`, `A`, `B` are supplied from outside the transport binder. -/
theorem transp_ua (env : CEnv) (i : DimVar) (e : EquivData) (A B : CType)
    (t : CTerm)
    (hA : A.dimAbsent i = true)
    (hB : B.dimAbsent i = true)
    (hf : e.f.dimAbsent i = true)
    (hfInv : e.fInv.dimAbsent i = true)
    (hsec : e.sec.dimAbsent i = true)
    (hret : e.ret.dimAbsent i = true)
    (hcoh : e.coh.dimAbsent i = true) :
    eval env (.transp i (uaLine e A B (.var i)) .bot t) =
    vApp (eval env e.f) (eval env t) := by
  -- Step 1: unfold `uaLine` / `toGlueType` / `dimExprEq0 (.var i)` — all rfl.
  show eval env (.transp i
      (.glue (FaceFormula.eq0 i) A e.f e.fInv e.sec e.ret e.coh B) .bot t) = _
  -- Step 2: compute the substDim facts about the inner face.
  have hφ1 : (FaceFormula.eq0 i).substDim i .one = .bot := by
    show (if i = i then FaceFormula.dimExprEq0 DimExpr.one else FaceFormula.eq0 i) = .bot
    simp [FaceFormula.dimExprEq0]
  have hφ0 : (FaceFormula.eq0 i).substDim i .zero = .top := by
    show (if i = i then FaceFormula.dimExprEq0 DimExpr.zero else FaceFormula.eq0 i) = .top
    simp [FaceFormula.dimExprEq0]
  -- Step 3: apply the restricted-form Glue-transport axiom.
  rw [eval_transp_glue_const_at_bot env i (FaceFormula.eq0 i) A
        e.f e.fInv e.sec e.ret e.coh B .bot t
        (by intro h; nomatch h)
        hA hB hf hfInv hsec hret hcoh hφ1]
  -- Step 4: simplify the inner face at `i = 0` to `.top`.
  rw [hφ0]
  -- Step 5: T2 on the constant `B` line, at `.bot ≠ .top`.
  rw [eval_transp_const env i B .bot _ (by intro h; nomatch h) hB]
  -- Step 6: `unglue .top` is forward-map application.
  exact eval_unglue_top env e.f t

/-- `transp_ua_inverse` (companion to `transp_ua`): transport along the
    "reversed" univalence line at the empty face computes as the inverse
    map of the equivalence.

    Construction: `uaLine e A B (.inv (.var i))` carries the inner glue
    face `dimExprEq0 (.inv (.var i)) = dimExprEq1 (.var i) = .eq1 i`
    (rather than `.eq0 i` for the forward `(.var i)` direction).  At
    `i := 1` this collapses to `.top`, triggering
    `eval_transp_glue_const_at_top` and producing the T-side witness via
    `e.fInv`.  At `i := 0` the inner face is `.bot`, so the inner
    `unglue` is identity; `B` is constant in `i`, so the outer transport
    is identity (T2); the result is `e.fInv` applied to the input.

    Together with `transp_ua`, this exhibits the two principal directions
    of the equivalence as the computational content of Glue transport at
    the constant-component sub-cases. -/
theorem transp_ua_inverse (env : CEnv) (i : DimVar) (e : EquivData) (A B : CType)
    (t : CTerm)
    (hA : A.dimAbsent i = true)
    (hB : B.dimAbsent i = true)
    (hf : e.f.dimAbsent i = true)
    (hfInv : e.fInv.dimAbsent i = true)
    (hsec : e.sec.dimAbsent i = true)
    (hret : e.ret.dimAbsent i = true)
    (hcoh : e.coh.dimAbsent i = true) :
    eval env (.transp i (uaLine e A B (.inv (.var i))) .bot t) =
    vApp (eval env e.fInv) (eval env t) := by
  -- Step 1: unfold `uaLine` / `toGlueType` / `dimExprEq0 (.inv (.var i))`.
  -- `dimExprEq0 (.inv r) = dimExprEq1 r` and `dimExprEq1 (.var i) = .eq1 i`,
  -- both by rfl on the case-splits in `Face.lean`.
  show eval env (.transp i
      (.glue (FaceFormula.eq1 i) A e.f e.fInv e.sec e.ret e.coh B) .bot t) = _
  -- Step 2: compute the substDim facts about the inner face.
  have hφ1 : (FaceFormula.eq1 i).substDim i .one = .top := by
    show (if i = i then FaceFormula.dimExprEq1 DimExpr.one else FaceFormula.eq1 i) = .top
    simp [FaceFormula.dimExprEq1]
  have hφ0 : (FaceFormula.eq1 i).substDim i .zero = .bot := by
    show (if i = i then FaceFormula.dimExprEq1 DimExpr.zero else FaceFormula.eq1 i) = .bot
    simp [FaceFormula.dimExprEq1]
  -- Step 3: apply the `_at_top` axiom.
  rw [eval_transp_glue_const_at_top env i (FaceFormula.eq1 i) A
        e.f e.fInv e.sec e.ret e.coh B .bot t
        (by intro h; nomatch h)
        hA hB hf hfInv hsec hret hcoh hφ1]
  -- Step 4: simplify the inner face at `i = 0` to `.bot`.
  rw [hφ0]
  -- Step 5: peel the outer `.app` so we can rewrite under it.
  rw [eval_app env e.fInv
        (.transp i B .bot (.unglue .bot e.f t))]
  -- Step 6: T2 on the constant `B` line.
  rw [eval_transp_const env i B .bot _ (by intro h; nomatch h) hB]
  -- Step 7: `unglue .bot` is identity.
  rw [eval_unglue_bot env e.f t]

/-- `glue_beta` (cells-spec §14, full statement): on any face, `unglue` of
    `glueIn` returns the A-side, provided the equivalence's overlap
    condition `e.f t = a` holds (implicit in glueIn's well-typedness).

    **Discharged via `eval_unglue_of_glueIn`** (Eval.lean, Stage 1.3,
    2026-04-23).  The eval-level β-rule recognises the redex shape
    and short-circuits under the `h_overlap` hypothesis.  This is no
    longer an axiom at the Soundness layer — the axiom provenance is
    now a single eval-level Rust-discharge rule. -/
theorem glue_beta (env : CEnv) (φ : FaceFormula) (f t a : CTerm)
    (h_overlap :
        eval env (.app f t) = eval env a) :
    eval env (.unglue φ f (.glueIn φ t a)) = eval env a :=
  eval_unglue_of_glueIn env φ f t a h_overlap

/-- `glue_eta` (cells-spec §14, full statement): on any face, `glueIn`
    of `unglue` returns the original term, under the overlap condition
    `t = e.f g`.

    **Discharged via `eval_glueIn_of_unglue`** (Eval.lean, Stage 1.3,
    2026-04-23).  Dual to `glue_beta`; same discipline. -/
theorem glue_eta (env : CEnv) (φ : FaceFormula) (f t g : CTerm)
    (h_overlap :
        eval env t = eval env (.app f g)) :
    eval env (.glueIn φ t (.unglue φ f g)) = eval env g :=
  eval_glueIn_of_unglue env φ f t g h_overlap

/-!
### Phase 2 cells-layer laws (deferred)

The cell-layer laws (`cell_left_unit`, `cell_right_unit`, `cell_assoc`,
`cell_inv_left`, `par_seq_interchange`) are Phase 2 material — they
require a `Cell` structure with composition operations, which we haven't
built.  The cells-spec §14 Cell Layer rows are therefore neither proved
nor stated as axioms in this module; they will arise as theorems (not
axioms) in `Cell/Basic.lean` and `Cell/Compose.lean` once those exist,
with the cell structure itself being defined in terms of the cubical
primitives proved here.
-/

end Soundness
