Skip to content

Commit 652a121

Browse files
hyperpolymathclaude
andcommitted
feat(formal): Wave 3 capstone — quantitative typing tracks usage soundly (QttTyping.v)
Fuses the three Wave-1/2 pieces — the term/typing structure of P2_Stlc, the multiplicity semiring of QttSemiring, and the occurrence-count usage of AffineUsage — into one judgment whose context tracks quantities: qtt Γ t A (Γ : uctx = var ↦ quantity) Q_Var consumes one variable once (usingle x); Q_App ADDS the two subcontexts (Γ₁ + Γ₂, context-splitting read backwards); Q_Lam binds a variable at the multiplicity it is used. Capstone theorem usage_soundness: the typing context records EXACTLY the QTT usage of every variable — qtt Γ t A → ∀ x, usage x t = Γ x — so the static quantity bookkeeping is sound w.r.t. actual occurrence counts. Corollary linear_uses_once: a term typed in a singleton context uses that one variable exactly once (linearity, read off the typing). Axiom-free, no Admitted. Scope: the static quantity discipline is now unified and proven sound against usage. The dynamic half — operational progress+preservation preserving the quantity accounting under reduction (a quantitative substitution lemma over P2_Stlc) — is the remaining step. Track now 13 files, 20 closure reports, no axioms. justfile/_CoqProject build QttTyping; .hypatia-ignore extends the Coq-not-V-lang carve-out; README gains the Wave-3 capstone; PROOF-NEEDS P-4 row updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPG9mEQXFyA3k7NWAzMNMr
1 parent 381ca17 commit 652a121

6 files changed

Lines changed: 119 additions & 10 deletions

File tree

.hypatia-ignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,5 @@ cicd_rules/vlang_detected:formal/QttSemiring.v
6767
cicd_rules/banned_language_file:formal/QttSemiring.v
6868
cicd_rules/vlang_detected:formal/AffineUsage.v
6969
cicd_rules/banned_language_file:formal/AffineUsage.v
70+
cicd_rules/vlang_detected:formal/QttTyping.v
71+
cicd_rules/banned_language_file:formal/QttTyping.v

docs/PROOF-NEEDS.adoc

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,13 @@ obligations. They are the "we might have missed" half of the brief.
143143
| **QTT affine usage.** Quantities `{0,1,ω}` are respected: `1`-vars used exactly
144144
once, `0`-vars erased, semiring laws hold.
145145
| L | `partial`
146-
| #513 must-have 3; **semiring + affine-usage mechanized** in
147-
`formal/QttSemiring.v` (`{0,1,ω}` laws + occurrence homomorphism) and
148-
`formal/AffineUsage.v` (`λx.x` affine, `λx. x x` not). The full *typed* QTT
149-
calculus (context splitting, progress+preservation tracking quantities)
150-
remains; prose `quantitative-types.md`
146+
| #513 must-have 3; **mechanized** across three files: `formal/QttSemiring.v`
147+
(`{0,1,ω}` laws + occurrence homomorphism), `formal/AffineUsage.v` (`λx.x`
148+
affine, `λx. x x` not), and `formal/QttTyping.v` — a quantitative type system
149+
whose usage context Γ is proven to track usage exactly
150+
(`usage x t = Γ x`). The *dynamic* half (operational progress+preservation
151+
preserving the quantity accounting under reduction) remains; prose
152+
`quantitative-types.md`
151153

152154
| P-5
153155
| **HM inference soundness + principality.** Inferred types are well-typed and

formal/QttTyping.v

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
(* SPDX-License-Identifier: MPL-2.0 *)
2+
(* SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath) *)
3+
4+
(*
5+
QttTyping.v
6+
═══════════
7+
Wave 3 (capstone): a **quantitative type system** that fuses the three Wave-1/2
8+
pieces — the term structure + typing discipline of P2_Stlc, the multiplicity
9+
semiring of QttSemiring, and the occurrence-count usage of AffineUsage — into
10+
one judgment whose context *tracks quantities*.
11+
12+
`qtt Γ t A` : Γ : uctx (a usage context, var ↦ quantity) records how much each
13+
variable is used in t. Q_Var consumes one variable once; Q_App ADDS the two
14+
subcontexts (`Γ₁ + Γ₂`, the QTT context-splitting read backwards); Q_Lam binds
15+
a variable at the multiplicity it is used.
16+
17+
The capstone theorem **usage_soundness**: the typing context records EXACTLY
18+
the QTT usage of every variable —
19+
20+
qtt Γ t A → ∀ x, usage x t = Γ x
21+
22+
— so the type system's quantity bookkeeping is sound w.r.t. actual occurrence
23+
counts. Corollary **linear_uses_once**: a term typed in a singleton context
24+
uses exactly that one variable, exactly once. Axiom-free, no Admitted.
25+
26+
Scope: the *static* quantity discipline is now unified and proven sound
27+
against usage. Operational progress+preservation that PRESERVES the quantity
28+
accounting under reduction (the dynamic half) is the remaining step.
29+
30+
`.v` is Coq, not V-lang — see formal/README.adoc and .hypatia-ignore.
31+
*)
32+
33+
Require Import PeanoNat.
34+
Require Import ASFormal.QttSemiring.
35+
Require Import ASFormal.AffineUsage.
36+
37+
(* Multiplicity-annotated types: a function records how often it uses its arg. *)
38+
Inductive qty := QBase | QArr (q : quant) (A B : qty).
39+
40+
(* Usage contexts. *)
41+
Definition uctx := id -> quant.
42+
Definition uadd (G1 G2 : uctx) : uctx := fun x => qplus (G1 x) (G2 x).
43+
Definition usingle (x : id) : uctx := fun y => if Nat.eqb x y then One else Zero.
44+
Definition uext (G : uctx) (x : id) (q : quant) : uctx :=
45+
fun y => if Nat.eqb x y then q else G y.
46+
47+
(* Quantitative typing: the context records each variable's usage. *)
48+
Inductive qtt : uctx -> tm -> qty -> Prop :=
49+
| Q_Var : forall x A, qtt (usingle x) (var x) A
50+
| Q_App : forall G1 G2 f a q A B,
51+
qtt G1 f (QArr q A B) -> qtt G2 a A -> qtt (uadd G1 G2) (app f a) B
52+
| Q_Lam : forall G x q A B b,
53+
G x = Zero -> qtt (uext G x q) b B -> qtt G (lam x b) (QArr q A B).
54+
55+
(* ── capstone: the typing context records exactly the usage ─────────────── *)
56+
57+
Theorem usage_soundness : forall G t A,
58+
qtt G t A -> forall x, usage x t = G x.
59+
Proof.
60+
intros G t A H.
61+
induction H as [ x A
62+
| G1 G2 f a q A B Hf IHf Ha IHa
63+
| G x q A B b Hz Hb IHb ]; intro z.
64+
- (* Q_Var *)
65+
unfold usage, usingle; simpl. rewrite (Nat.eqb_sym x z).
66+
destruct (Nat.eqb z x); reflexivity.
67+
- (* Q_App *)
68+
rewrite usage_app, (IHf z), (IHa z); unfold uadd; reflexivity.
69+
- (* Q_Lam *)
70+
destruct (Nat.eqb z x) eqn:E.
71+
+ apply Nat.eqb_eq in E; subst z.
72+
rewrite usage_lam_bound; symmetry; exact Hz.
73+
+ assert (usage z (lam x b) = usage z b) as Hlz
74+
by (unfold usage; simpl; rewrite E; reflexivity).
75+
rewrite Hlz, (IHb z); unfold uext; rewrite (Nat.eqb_sym x z), E; reflexivity.
76+
Qed.
77+
78+
(* A term typed in a singleton context uses exactly that one variable, once —
79+
the essence of linearity, now read off the typing. *)
80+
Corollary linear_uses_once : forall x t A,
81+
qtt (usingle x) t A ->
82+
usage x t = One /\ (forall y, y <> x -> usage y t = Zero).
83+
Proof.
84+
intros x t A H; split.
85+
- rewrite (usage_soundness _ _ _ H x); unfold usingle; rewrite Nat.eqb_refl; reflexivity.
86+
- intros y Hy. rewrite (usage_soundness _ _ _ H y); unfold usingle.
87+
assert (x <> y) as Hxy by (intro Hc; apply Hy; symmetry; exact Hc).
88+
apply Nat.eqb_neq in Hxy; rewrite Hxy; reflexivity.
89+
Qed.
90+
91+
Print Assumptions usage_soundness.
92+
Print Assumptions linear_uses_once.

formal/README.adoc

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ cannot mistake it. Coq has no `v.mod` manifest, so `vmod_detected` never fires.
7979
| **P-4** (Wave 2) — affine usage over the semiring: `λx.x` affine, `λx. x x`
8080
not (variable totals `ω`)
8181
| **mechanized**, axiom-free
82+
83+
| `QttTyping.v`
84+
| **P-4** (Wave 3) — quantitative typing fusing all three: the typing context
85+
tracks usage, proven sound (`usage x t = Γ x`)
86+
| **mechanized**, axiom-free
8287
|===
8388

8489
All mechanized theorems report *Closed under the global context* under `Print
@@ -139,10 +144,17 @@ The quantities `{0,1,ω}` and their algebra are what make AffineScript *affine*:
139144
well-formedness. Payoff: `λx.x` is affine; `λx. x x` is **not** — its variable
140145
totals `ω`, exceeding the affine bound. The mechanized statement of "a linear
141146
value may not be duplicated".
142-
143-
The full *typed* QTT calculus — context splitting `Γ = Γ₁ + Γ₂`, progress +
144-
preservation tracking quantities, on top of `P2_Stlc.v` — is the next
145-
increment.
147+
* **`QttTyping.v`** (Wave 3 capstone) — a **quantitative type system** fusing all
148+
three: `qtt Γ t A` where the usage context Γ tracks quantities (`Q_App` adds
149+
`Γ₁ + Γ₂`, `Q_Lam` binds at the used multiplicity). The capstone theorem
150+
`usage_soundness : qtt Γ t A → ∀x, usage x t = Γ x` proves the typing context
151+
records *exactly* the QTT usage — the static quantity discipline is sound
152+
against occurrence counts. Corollary: a term typed in a singleton context uses
153+
that variable exactly once.
154+
155+
The remaining step is the *dynamic* half: operational progress + preservation
156+
that PRESERVES the quantity accounting under reduction (a quantitative
157+
substitution lemma over `P2_Stlc.v`).
146158

147159
== K-1 and its growth
148160

formal/_CoqProject

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ P2_Progress.v
1111
P2_Stlc.v
1212
QttSemiring.v
1313
AffineUsage.v
14+
QttTyping.v

formal/justfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ check:
1212
for f in K1_CodegenPreservation K1Let_CodegenPreservation Siblings_Stated \
1313
F1_TransformerPreservation F3_PragmaDecidable F4_ErrorFaithful \
1414
P3_BorrowSound P3_BorrowGraph P2_Progress P2_Stlc \
15-
QttSemiring AffineUsage; do
15+
QttSemiring AffineUsage QttTyping; do
1616
echo "== coqc $f.v =="
1717
o="$(coqc -Q . ASFormal "$f.v")"
1818
printf '%s\n' "$o"

0 commit comments

Comments
 (0)