Skip to content

Commit fc3fffa

Browse files
hyperpolymathclaude
andcommitted
spec: add operational semantics for TypeQL-Experimental
Formal operational semantics covering: - Compile-time type rules for all 6 extensions (linear, session, effects, modal, proof-carrying, quantitative) - Runtime evaluation rules for connection management, session state machines, effect checking, modal scoping, proof verification - Extension composition semantics - 8 formal invariants including totality and zero-axiom guarantees Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent bdb2450 commit fc3fffa

File tree

1 file changed

+269
-0
lines changed

1 file changed

+269
-0
lines changed
Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
# SPDX-License-Identifier: PMPL-1.0-or-later
2+
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
3+
4+
# TypeQL-Experimental Operational Semantics
5+
6+
**Version:** 1.0.0
7+
**Date:** 2026-03-14
8+
9+
---
10+
11+
## 1. Notation
12+
13+
- `Γ` — Type context (variable typing assumptions)
14+
- `D` — Database state
15+
- `Γ, D ⊢ q : τ ⇓ v` — Query `q` has type `τ` and evaluates to `v`
16+
- `Γ ⊢ q : τ` — Query `q` type-checks to `τ` (compile-time)
17+
- Quantities: `0` (erased), `1` (linear), `ω` (unrestricted)
18+
19+
---
20+
21+
## 2. Values
22+
23+
```
24+
v ∈ Value ::=
25+
QueryResult(rows) query result set
26+
| LinConn(handle, remaining) linear connection (indexed by uses)
27+
| Session(state) session state machine
28+
| Box(world, v) modal box (scoped value)
29+
| ProvedResult(v, proof) result with attached theorem
30+
| BoundedResource(v, remaining) usage-limited resource
31+
| EffectSet(effects) declared effect set
32+
```
33+
34+
---
35+
36+
## 3. Type System (Compile-Time)
37+
38+
### 3.1 Linear Types (CONSUME AFTER N USE)
39+
40+
```
41+
Γ, (1 conn : LinConn (S n)) ⊢ query : τ
42+
───────────────────────────────────────────────────────── [Lin-Use]
43+
Γ ⊢ useConn(conn) : (QueryResult, LinConn n)
44+
45+
Γ, (1 conn : LinConn 0) ⊢ close : IO ()
46+
────────────────────────────────────────────────────── [Lin-Close]
47+
Γ ⊢ closeConn(conn) : IO ()
48+
49+
conn used twice (linear quantity violated)
50+
────────────────────────────────────────────────────── [Lin-Error]
51+
Γ ⊢ program ⇒ TYPE ERROR: linear variable used more than once
52+
```
53+
54+
### 3.2 Session Types (WITH SESSION)
55+
56+
```
57+
Γ, (1 s : Session Fresh) ⊢ auth(s) : Either AuthError (Session Authenticated)
58+
──────────────────────────────────────────────────────────────────────────── [Sess-Auth]
59+
60+
Γ, (1 s : Session InTransaction) ⊢ query(s, plan) : (QueryResult, Session InTransaction)
61+
───────────────────────────────────────────────────────────────────────────────────────── [Sess-Query]
62+
63+
Γ, (1 s : Session InTransaction) ⊢ commit(s) : Either TxError (Session Committed)
64+
────────────────────────────────────────────────────────────────────────────────────── [Sess-Commit]
65+
66+
Γ, (1 s : Session Fresh) ⊢ query(s, plan) ⇒ TYPE ERROR
67+
───────────────────────────────────────────────────────── [Sess-Error]
68+
(query requires Session InTransaction, not Session Fresh)
69+
```
70+
71+
### 3.3 Effect System (EFFECTS)
72+
73+
```
74+
actual_effects(q) = {Read} declared = {Read}
75+
actual ⊆ declared
76+
────────────────────────────────────────────────────── [Eff-Ok]
77+
Γ ⊢ q EFFECTS { Read } : τ
78+
79+
actual_effects(q) = {Read, Write} declared = {Read}
80+
Write ∉ declared
81+
────────────────────────────────────────────────────── [Eff-Error]
82+
Γ ⊢ q EFFECTS { Read } ⇒ TYPE ERROR: Write not in declared effects
83+
84+
Subsumes(declared, actual) = ∀e ∈ actual. e ∈ declared
85+
────────────────────────────────────────────────── [Eff-Subsumes]
86+
Γ ⊢ Subsumes(declared, actual) : Type
87+
```
88+
89+
### 3.4 Modal Types (IN TRANSACTION)
90+
91+
```
92+
Γ ⊢ v : a w : World
93+
─────────────────────────── [Modal-Box]
94+
Γ ⊢ MkBox(v) : Box w a
95+
96+
Γ ⊢ b : Box w a Γ ⊢ InScope w
97+
───────────────────────────────────── [Modal-Extract]
98+
Γ ⊢ extract(b) : a
99+
100+
Γ ⊢ b : Box w₁ a Γ ⊢ f : a → b
101+
───────────────────────────────────────── [Modal-Marshal]
102+
Γ ⊢ marshal(b, f) : Box w₂ b
103+
104+
Γ ⊢ b : Box w₁ a attempt extract without InScope w₁
105+
────────────────────────────────────────────────────────── [Modal-Error]
106+
TYPE ERROR: cannot extract from Box w₁ without InScope w₁ evidence
107+
```
108+
109+
### 3.5 Proof-Carrying Code (PROOF ATTACHED)
110+
111+
```
112+
Γ ⊢ q : QueryResult Γ ⊢ thm : Theorem
113+
Γ ⊢ verify(q, thm) succeeds
114+
───────────────────────────────────────────────── [Proof-Attach]
115+
Γ ⊢ q PROOF ATTACHED thm : ProvedResult QueryResult Theorem
116+
117+
ProvedResult(v, prf) = (result : τ ** ProofOf thm result)
118+
───────────────────────────────────────────────────────── [Proof-Type]
119+
(dependent pair: data bundled with its proof)
120+
```
121+
122+
### 3.6 Quantitative Types (USAGE LIMIT)
123+
124+
```
125+
Γ, (r : BoundedResource (S n) a) ⊢ consume(r) : (a, BoundedResource n a)
126+
───────────────────────────────────────────────────────────────────────── [Quant-Consume]
127+
128+
Γ, (r : BoundedResource 0 a) ⊢ consume(r) ⇒ TYPE ERROR
129+
────────────────────────────────────────────────────────── [Quant-Depleted]
130+
(no consume operation exists on BoundedResource 0)
131+
```
132+
133+
---
134+
135+
## 4. Runtime Semantics
136+
137+
### 4.1 Query Evaluation (standard VQL pipeline)
138+
139+
```
140+
D ⊢ SELECT modalities FROM hexad WHERE conditions ⇓ rows
141+
──────────────────────────────────────────────────────────── [Query-Base]
142+
Γ, D ⊢ query ⇓ QueryResult(rows)
143+
```
144+
145+
### 4.2 Linear Connection Runtime
146+
147+
```
148+
handle = open_connection(db_url) remaining = n
149+
──────────────────────────────────────────────────── [LinConn-Open]
150+
Γ, D ⊢ openConn(n) ⇓ LinConn(handle, n)
151+
152+
conn = LinConn(handle, S(k))
153+
result = execute(handle, plan)
154+
conn' = LinConn(handle, k)
155+
──────────────────────────────────────────── [LinConn-Use]
156+
Γ, D ⊢ useConn(conn, plan) ⇓ (result, conn')
157+
158+
conn = LinConn(handle, 0)
159+
close(handle)
160+
──────────────────────────────────────── [LinConn-Close]
161+
Γ, D ⊢ closeConn(conn) ⇓ ()
162+
```
163+
164+
### 4.3 Session State Machine Runtime
165+
166+
```
167+
s = Session Fresh
168+
auth_result = authenticate(credentials)
169+
──────────────────────────────────────────────────── [Session-Auth]
170+
Γ, D ⊢ auth(s, creds) ⇓ Right(Session Authenticated)
171+
| Left(AuthError)
172+
173+
s = Session Authenticated
174+
──────────────────────────────────────────────── [Session-Begin]
175+
Γ, D ⊢ beginTx(s) ⇓ Session InTransaction
176+
177+
s = Session InTransaction
178+
result = execute(plan)
179+
──────────────────────────────────────────────────── [Session-Query]
180+
Γ, D ⊢ query(s, plan) ⇓ (result, Session InTransaction)
181+
182+
s = Session InTransaction
183+
commit_result = commit_transaction()
184+
──────────────────────────────────────────────────── [Session-Commit]
185+
Γ, D ⊢ commit(s) ⇓ Right(Session Committed)
186+
| Left(TxError)
187+
```
188+
189+
### 4.4 Effect Checking Runtime
190+
191+
```
192+
query_plan = plan(q)
193+
actual = collect_effects(query_plan)
194+
actual ⊆ declared (verified at compile time by Idris2)
195+
──────────────────────────────────────────────────────────── [Effects-Run]
196+
Γ, D ⊢ q EFFECTS { declared } ⇓ execute(query_plan)
197+
```
198+
199+
### 4.5 Modal Scoping Runtime
200+
201+
```
202+
v computed in transaction scope w
203+
──────────────────────────────────── [Modal-Wrap]
204+
Γ, D ⊢ MkBox(v) ⇓ Box(w, v)
205+
206+
b = Box(w, v) current_scope = w (scope matches)
207+
──────────────────────────────────────────────────────── [Modal-Open]
208+
Γ, D ⊢ extract(b) ⇓ v
209+
```
210+
211+
### 4.6 Proof Verification Runtime
212+
213+
```
214+
result = execute(q)
215+
proof = verify_theorem(thm, result)
216+
proof succeeds
217+
───────────────────────────────────────────── [Proof-Verify]
218+
Γ, D ⊢ q PROOF ATTACHED thm ⇓ ProvedResult(result, proof)
219+
220+
proof fails
221+
───────────────────────────────────────────────── [Proof-Fail]
222+
Γ, D ⊢ q PROOF ATTACHED thm ⇓ ⊥("theorem verification failed")
223+
```
224+
225+
### 4.7 Resource Budget Runtime
226+
227+
```
228+
r = BoundedResource(v, S(k))
229+
──────────────────────────────────────────────────── [Resource-Use]
230+
Γ, D ⊢ consume(r) ⇓ (v, BoundedResource(v, k))
231+
232+
budget_remaining = 0 (enforced at compile time; never reached at runtime)
233+
```
234+
235+
---
236+
237+
## 5. Extension Composition
238+
239+
The six extensions compose independently because each operates on a different
240+
dimension of the type:
241+
242+
```
243+
Γ ⊢ q : QueryResult
244+
Γ ⊢ q CONSUME AFTER 1 USE (LinConn dimension)
245+
Γ ⊢ q WITH SESSION ReadOnly (Session dimension)
246+
Γ ⊢ q EFFECTS { Read, Cite } (Effect dimension)
247+
Γ ⊢ q IN TRANSACTION Committed (World dimension)
248+
Γ ⊢ q PROOF ATTACHED Integrity (Proof dimension)
249+
Γ ⊢ q USAGE LIMIT 100 (Budget dimension)
250+
────────────────────────────────────────────────────────────── [Compose]
251+
Γ ⊢ composed_query : ProvedResult (Box Committed QueryResult) IntegrityThm
252+
with linear connection, session protocol, effect bounds, and resource limit
253+
```
254+
255+
The `Checker.idr` module validates all six constraints simultaneously by
256+
composing individual check functions.
257+
258+
---
259+
260+
## 6. Invariants
261+
262+
1. **Linear safety:** A `LinConn n` is used exactly `n` times before closing. Enforced by QTT at compile time.
263+
2. **Protocol compliance:** Session operations only succeed in valid states. Enforced by indexed types.
264+
3. **Effect containment:** Actual effects ⊆ declared effects. Enforced by `Subsumes` proof.
265+
4. **Scope isolation:** Data in `Box w₁` cannot be extracted without `InScope w₁` evidence.
266+
5. **Proof integrity:** `ProvedResult` pairs are unforgeable — the proof must type-check.
267+
6. **Budget monotonicity:** `BoundedResource n` can only decrease to `BoundedResource (n-1)`.
268+
7. **Totality:** All Idris2 modules compile with `%default total` — no infinite loops, no partial functions.
269+
8. **Zero axioms:** No `believe_me`, `assert_total`, or `assert_smaller` in proof code.

0 commit comments

Comments
 (0)