Prime Language
Technical Specification
Prime is a general-purpose, statically typed programming language designed to compete with Go and Rust as the language of choice for the AI era. It combines a familiar object-oriented structure with probabilistic types, first-class tensor operations, and quantum-ready linear types — all built into the core language, not bolted on as libraries. Prime compiles to efficient bytecode executed by PrimeVM, making it well-suited for systems programming, cloud-native services, AI inference pipelines, and future quantum-hybrid workloads.
Language Architecture Overview
1.1 Design Philosophy
Prime is built on the conviction that the next generation of general-purpose languages must treat AI inference and quantum computation as first-class language concerns — not as external library calls made over opaque APIs. In the same way that Go made concurrency a core language primitive (goroutines, channels) and Rust made memory safety a compile-time guarantee (ownership, lifetimes), Prime makes probabilistic reasoning and linear resource management structural properties of the type system itself.
Three structural pillars define Prime:
-
Object-Oriented Familiarity. Prime adopts a Java-inspired class and
module system. Classes, interfaces, modules, and a strict access-modifier hierarchy
(
pub,priv,prot) provide scaffolding that engineers from Java, C#, or TypeScript backgrounds can adopt immediately. -
Probabilistic Type Integration. The
prob<T>wrapper elevates uncertainty into the type system. The compiler tracks confidence at every inference boundary and enforces explicit handling of low-confidence branches — making probabilistic programs as rigorous as deterministic ones. -
Quantum Readiness via Linear Types. The
qstatemodifier subjects a variable to the compiler's linear-type borrow checker, enforcing the No-Cloning Theorem at compile time. When Prime targets quantum hardware or a simulator, these invariants are already guaranteed — no runtime assertion required.
Prime is general-purpose: it is equally suited to writing a web server, a CLI tool, a machine-learning pipeline, or a quantum optimisation routine. The AI and quantum features impose zero overhead on programs that do not use them.
1.2 Compilation Pipeline
| Stage | Artifact | Responsibility |
|---|---|---|
primec — Lexer / Parser |
AST | Tokenises source; validates against CFG; emits parse errors in machine-readable JSON. |
primec — Type Checker |
Typed AST | Resolves prob<T> propagation; enforces linear-type move semantics for qstate variables; validates tensor shape at compile time. |
primec — Bytecode Emitter |
.primevm file |
Emits stack-based bytecode with opcode extensions for INFER, QGATE, and TMUL. |
| PrimeVM Runtime | Execution result | Interprets .primevm; routes INFER opcodes to the local 0.3B model; routes QGATE opcodes to the quantum simulation layer or hardware adapter. |
1.3 Module System
Each .prime file declares exactly one module at its head. Modules are
the unit of compilation, linking, and access control. Module paths are hierarchical
and reverse-DNS scoped, following Go and Java conventions.
module com.example.risk.scoring; import com.example.quantum.Gates; import com.example.ai.ClassificationModel; import std.io; import std.time;
1.4 Comparison with Go and Rust
| Feature | Go | Rust | Prime |
|---|---|---|---|
| Memory safety | GC | Ownership / borrow checker | GC + linear types for qstate |
| Concurrency model | Goroutines + channels | async/await + Send/Sync | Coroutines + channels (planned) |
| Probabilistic types | None (library only) | None (library only) | Native prob<T> |
| Tensor math | None (library only) | None (library only) | Native tensor<T, Dims> with shape checking |
| AI inference | External call | External call | Native infer() keyword |
| Quantum safety | None | None | Compile-time No-Cloning enforcement |
| Compilation target | Native binary | Native binary / WASM | PrimeVM bytecode (.primevm) |
Type System & Primitives
2.1 Classical Primitives
| Type | Width | Default | Notes |
|---|---|---|---|
int | 64-bit signed | 0 | Two's complement; detectable overflow is a compile-time error. |
float | 64-bit IEEE 754 | 0.0 | NaN propagation follows IEEE 754; comparing with NaN emits a compiler warning. |
string | Immutable UTF-8 heap | "" | Interned by the VM; == performs value equality, not reference equality. |
boolean | 1-bit logical | false | Only the literals true and false are legal values. |
byte | 8-bit unsigned | 0 | Used for binary I/O and buffer operations. |
void | — | — | Method return type only; not a first-class value. |
int customerId = 481923; float riskScore = 0.74; string policyRef = "POL-2024-EU-00391"; boolean isEligible = true;
2.2 Probabilistic Types — prob<T>
prob<T> wraps any type T together with a
compiler-managed confidence scalar in the range [0.0, 1.0].
Confidence is a type-level annotation — not a runtime field — that primec
propagates through the dataflow graph and exposes as a read-only property.
Declaration Syntax
prob<T> identifier = value confidence float_literal ;
Compiler Rules
- The
confidenceclause is mandatory on any direct literal assignment to aprob<T>variable. - When a
prob<T>is produced by aninfer()expression, confidence is populated from the model's softmax output — no explicit clause is written. - Confidence propagates through arithmetic: for binary operations
a op b, the result confidence ismin(a.confidence, b.confidence)(conservative model). - Assigning a
prob<T>to a bareTvariable is a compile-time error unless guarded by aconfidence >= thresholdgate.
Example
// Direct construction prob<string> tradingIntent = "BUY" confidence 0.94; // Accessing properties float c = tradingIntent.confidence; // 0.94 string v = tradingIntent.value; // "BUY" // Confidence-gated unwrap — required before assigning to classical type if (tradingIntent.confidence >= 0.90) { string confirmed = tradingIntent.value; executeOrder(confirmed); } else { flagForReview(tradingIntent); }
2.3 Tensor Types — tensor<T, Dims...>
Tensor types are native to Prime's type system. Shape is encoded in the type signature and checked at compile time — mismatched shapes cause a type error, not a runtime panic. No external library is required.
Syntax
tensor<float, 2, 3> // 2×3 matrix of float64 tensor<int, 4> // 1-D vector of 4 int64 tensor<float, 3, 3, 3> // 3-D tensor
Native Operators
| Operator | Operation | Shape Constraint |
|---|---|---|
+ | Element-wise addition | Identical shape required. |
- | Element-wise subtraction | Identical shape required. |
* | Matrix multiplication | tensor<T,M,N> * tensor<T,N,P> → tensor<T,M,P> |
@ | Hadamard (element-wise) product | Identical shape required. |
.T | Transpose | tensor<T,M,N>.T → tensor<T,N,M> |
tensor<float, 2, 3> featureMatrix = [ [1.0, 2.0, 3.0], [4.0, 5.0, 6.0] ]; tensor<float, 3, 2> projection = [ [1.0, 0.0], [0.0, 1.0], [0.5, 0.5] ]; // (2×3) * (3×2) → (2×2) — shape verified at compile time tensor<float, 2, 2> reduced = featureMatrix * projection; tensor<float, 3, 2> transposed = featureMatrix.T;
featureMatrix * featureMatrix (both 2×3) emits:
"E0051: matrix multiplication requires inner dimensions to match: got 3 ≠ 2."
No shape mismatch can reach runtime.
Native AI Keywords & Dispatch
3.1 The infer() Operator
infer() is a first-class language keyword — not a library call — that
suspends the executing coroutine, serialises input into PrimeVM's inference protocol,
dispatches to the local 0.3B model, and deserialises the result into a
prob<T> value. The confidence scalar comes from the model's
post-softmax probability for the top-1 token class.
Syntax Forms
// Form 1 — open-ended generation prob<string> result = infer(inputExpr); // Form 2 — constrained classification prob<string> label = infer(inputExpr) classifying ["LabelA", "LabelB", "LabelC"]; // Form 3 — typed generation with schema hint prob<float> score = infer(inputExpr) as float;
VM Bytecode Lowering
PUSH_STR <serialised input> PUSH_LABELS <label array> ; Form 2 only INFER_CLS ; blocks until model responds STORE_PROB <target register> ; writes (value, confidence) pair
3.2 Enterprise Classification Example
Document triage pipeline for a regulatory compliance platform. Incoming case narratives are classified into three disposition categories; low-confidence results are routed to human review.
module com.example.compliance.triage; pub class CaseTriage { pub static string triageCase(string narrative, int caseId) { prob<string> classification = infer(narrative) classifying ["APPROVE", "ESCALATE", "REJECT"]; if (classification.confidence >= 0.92) { auditLog(caseId, classification.value, classification.confidence); return classification.value; } if (classification.confidence >= 0.70) { string enriched = "[REVIEW CONTEXT] " + narrative; prob<string> refined = infer(enriched) classifying ["APPROVE", "ESCALATE", "REJECT"]; if (refined.confidence >= 0.85) { auditLog(caseId, refined.value, refined.confidence); return refined.value; } } ReviewQueue.enqueue(caseId, classification.confidence); return "PENDING_REVIEW"; } priv static void auditLog(int id, string disposition, float conf) { AuditStore.write(id, disposition, conf, Timestamp.now()); } }
classifying clause enables logit masking (see §5.1). PrimeVM passes
the label set to the inference subsystem, so the model can only emit tokens that
prefix one of the declared labels. Hallucinated output categories are impossible at
the VM level.
Quantum-Ready System — Linear Types
4.1 The qstate Modifier
A variable declared with qstate enters the compiler's
linear-type borrow checker. Linear types guarantee a value is consumed
exactly once — it cannot be copied, aliased, or read after being passed to a gate
function. This directly encodes the No-Cloning Theorem: an arbitrary
unknown quantum state cannot be duplicated.
Compiler Rules
- A
qstatevariable may appear as an argument to a gate function at most once after its declaration. - Any gate function accepting a
qstateparameter consumes it. Subsequent references are compile-time errors. qstatevariables may not be captured by closures or assigned to non-qstatebindings.Quantum.measure()collapses aqstateregister into a classicalboolean. This is a consuming operation.
4.2 Quantum Gate API
| Method | Input | Output | Description |
|---|---|---|---|
Quantum.register(n) | int | qstate | Allocates an n-qubit register in |0⟩. |
Quantum.applyHadamard(q) | qstate (consumed) | qstate | Hadamard gate; puts qubit into superposition. |
Quantum.applyCNOT(ctrl, tgt) | two qstates (consumed) | qstate | Controlled-NOT; entangles two qubits. |
Quantum.applyPhase(q, theta) | qstate (consumed), float | qstate | Phase rotation by θ radians. |
Quantum.measure(q) | qstate (consumed) | boolean | Collapses state; returns classical measurement. |
4.3 Hybrid Quantum–Classical Example
module com.example.quantum.demo; pub class QuantumDecisionGate { pub static string evaluatePath(string workflowId) { // Allocate a 2-qubit register — both qubits in |0⟩ qstate reg = Quantum.register(2); // Hadamard — reg is consumed, q1 produced qstate q1 = Quantum.applyHadamard(reg); // Split into single-qubit handles — q1 consumed on first .qubit() call qstate ctrl = q1.qubit(0); qstate tgt = q1.qubit(1); // Entangle — ctrl and tgt consumed, entangled pair produced qstate entangled = Quantum.applyCNOT(ctrl, tgt); // Measure — collapses to classical boolean; entangled is consumed boolean outcome = Quantum.measure(entangled.qubit(0)); // Classical branching on quantum measurement result if (outcome) { WorkflowEngine.route(workflowId, "PATH_ALPHA"); return "PATH_ALPHA"; } else { WorkflowEngine.route(workflowId, "PATH_BETA"); return "PATH_BETA"; } } }
qstate reg = Quantum.register(1); qstate a = Quantum.applyHadamard(reg); qstate b = Quantum.applyHadamard(reg); // E0041 — reg already consumed
E0041: use of moved qstate variable 'reg' at line 3.
Linear type constraint: qstate may only be consumed once.
AI-Assisted Authoring
Prime is designed to be written by models as well as by people. A strict grammar, a type checker, native tests and a sandboxed VM make every piece of machine-written code checkable: it either compiles, passes its tests and runs within its limits, or it is rejected with a structured reason. Four mechanisms build on that: constrained decoding (§5.1) keeps generated code valid, the error loop (§5.2) lets a model repair it, verified training data (§5.3) teaches a model to write Prime, and code mode (§5.4) lets agents act through Prime programs instead of individual tool calls.
Prime standardizes the interfaces — what valid code is, how it is checked, what a verified example looks like, how an agent submits code — not the models or the training methods behind them. Prompt formats, tokenizers and fill-in-the-middle tokens belong to the model and its tooling and are not part of the language.
5.1 Grammar-Constrained Decoding
Prime's CFG is made available to the inference subsystem in compiled form. At each
decoding step, the set of grammatically valid next tokens is computed from the CFG,
and all other vocabulary entries have their logits set to -∞ before
softmax. This means the model cannot emit:
- Keywords from other languages (
def,fn,func,lambda). - API names not registered in PrimeVM's type registry for the active module.
- Type combinations that would be caught by the type-checker.
- Unclosed
qstatelinear variables.
The CFG used for masking is the same prime.cfg artefact shipped with the
compiler. A version mismatch between compiler and VM is a fatal startup error.
5.2 Compiler / VM Error Feedback Loop
When a generated snippet fails compilation, PrimeVM emits a machine-readable JSON error document fed back into the model's self-correction loop.
Error JSON Schema
{
"prime_error": {
"schema_version": "1.0",
"source_file": "string",
"stage": "LEXER | PARSER | TYPE_CHECK | BYTECODE | VM_RUNTIME",
"errors": [
{
"code": "string", // e.g. "E0041"
"message": "string",
"line": "integer", // 1-based
"character": "integer", // 1-based
"end_line": "integer",
"end_char": "integer",
"context": "string", // source line text
"hint": "string | null" // repair suggestion
}
],
"fatal": "boolean"
}
}
Concrete Error Example
{
"prime_error": {
"schema_version": "1.0",
"source_file": "scoreContract.prime",
"stage": "TYPE_CHECK",
"errors": [
{
"code": "E0041",
"message": "use of moved qstate variable 'reg' after consumption at line 8",
"line": 10,
"character": 9,
"end_line": 10,
"end_char": 11,
"context": " qstate b = Quantum.applyHadamard(reg);",
"hint": "qstate variables are linear; split the register before passing to gates"
}
],
"fatal": false
}
}
Self-Correction Loop Protocol
- The model generates a candidate: a whole file, or the code between a given prefix and suffix.
- PrimeVM checks the assembled source and runs its tests. On success, the code is presented to the developer or agent.
- On failure, the JSON error document is passed back with the original context and the model generates a correction. After at most 3 iterations the error is shown to the developer.
- Every attempt is logged; failed attempts with their corrections become repair samples (§5.3).
5.3 Verified Training Data
A model learns to write Prime from examples, and Prime can prove an example correct. The toolchain therefore defines one sample format and one verification pipeline that every Prime training set uses, whether it comes from human code, generated code or the correction log of §5.2. Training itself — pretraining, supervised fine-tuning, reinforcement learning — runs in standard ML frameworks outside Prime; this section fixes only what goes in and how it is checked.
| Sample kind | Content | Teaches |
|---|---|---|
verified | Task, accepted source, its tests | Writing correct Prime from a request (SFT) |
repair | Failing source, its diagnostics, corrected source | Fixing code from compiler and test errors |
completion | Prefix, suffix and the accepted middle | Editor completion; the trainer chooses the token format |
Sample Record (JSON Lines, one sample per line)
{
"schema": "prime-sample/1",
"kind": "verified | repair | completion",
"task": "string", // natural-language request, may be empty
"hosts": ["demo.weather"], // host modules the code may use
"source": "string", // accepted Prime source (the target)
"broken": "string | null", // repair: the failing source
"diagnostics": [ ... ], // repair: §5.2 errors of "broken"
"prefix": "string | null", // completion: code before the gap
"suffix": "string | null", // completion: code after the gap
"verification": {
"compiler": "prime 0.1.0",
"fingerprint": "sha256 of the sources",
"tests_passed": 6,
"tests_failed": 0,
"admitted": true,
"instructions": 18342
}
}
Verification Pipeline
- Check —
prime checkwith the declared host modules. Samples that do not parse or type-check are kept only as thebrokenside of a repair sample. - Test —
prime testruns the sample's tests in the sandbox with fixture data; averifiedsample needs at least one test and no failures. - Admit — the admission rule of §6 must accept every report in the sample.
- Deduplicate — samples with the same compiled fingerprint are stored once.
- Record — the compiler version and results are written into
verification, so a set can be re-verified when the compiler changes.
Reward for Reinforcement Learning
The same pipeline scores a model's output, so reinforcement learning needs no learned reward model. A candidate is checked and then run against tests the model cannot see or change:
| Outcome | Reward |
|---|---|
| Does not parse | 0.0 |
| Parses, fails type checking | 0.1 |
| Type-checks; p of n hidden tests pass | 0.2 + 0.6 × p / n |
| All hidden tests pass and admitted | 1.0 |
5.4 Prime for Agents (Code Mode)
An agent that needs several tool calls to answer a request can instead write one Prime program that makes those calls, and submit it to PrimeVM. The program is type-checked against the tools it may use, runs under a fixed budget, and returns one result or one structured error. Tools are host modules: the host declares their functions and types, and a program can call nothing else.
// Written by an agent for the request: // "On which days of this period did it rain more than 20 mm at the station?" module agent.wet_days; import std.math; import demo.weather; @Report(id = "agent_wet_days", title = "Days over 20 mm", mobile = false) pub class WetDays { const float LIMIT_MM = 20.0; pub static void run(ReportContext ctx) { int days = 0; for (date day : ctx.period.days()) { float mm = rainfall(ctx.station, day); if (mm > LIMIT_MM) { ctx.out.row(day, metric("rainfall", Math.round(mm, 1), Unit.MM)); days += 1; } } ctx.out.total(metric("days_over_limit", days, Unit.NONE)); } }
Tools as Host Modules
Host modules are declared in JSON (as hosts/demo.weather.json). A
tool described for the Model Context Protocol (MCP) maps onto a host function, so
existing MCP servers can be offered to Prime programs without new code:
| MCP tool | Prime host function |
|---|---|
name | function name in a host module (one module per MCP server) |
description | description, shown to the model with the declaration |
inputSchema properties | typed parameters: string, integer → int, number → float, boolean, array → list<T>, object → a declared host class |
| result content | return type, decoded and type-checked at the call |
| tool error | runtime error E0405 at the calling line |
Run Protocol
// Agent → PrimeVM
{
"sources": [{ "name": "wet_days.prime", "text": "..." }],
"grant": ["demo.weather"], // host modules this run may use
"limits": { "fuel": 20000000, "memory": 67108864, "timeout_ms": 5000 },
"run": { "report": "agent_wet_days", "subject": 42, "from": "2026-10-26", "to": "2026-11-01" }
// or { "function": "module.Main.main" }
}
// PrimeVM → Agent
{
"ok": true,
"errors": [], // §5.2 errors when ok is false
"output": [], // lines written with print
"tests": [], // results of the program's own @Test methods
"result": [ ... ], // report rows, or the returned value
"instructions": 18342
}
| Guarantee | How PrimeVM enforces it |
|---|---|
| Capability | Only granted host modules type-check; there is no other I/O. |
| Budget | Instruction, memory, call-depth and time limits per run (E0501–E0504). |
| Determinism | The standard library reads no clock or randomness; the same data gives the same result. |
| Repairability | Every failure is a §5.2 error with a position, fed back to the agent. |
| Audit | Each run is identified by the fingerprint of its compiled code and logged with its result. |
Native Test Framework
6.1 Annotations
| Annotation | Target | Behaviour |
|---|---|---|
@TestSpecification | Class | Marks the class as a test suite. The VM sandbox instantiates it before module load. |
@Test | Method | Declares a test case. Must return void with no parameters. |
@Test(timeout = n) | Method | Fails if execution exceeds n milliseconds. |
@MockInfer(label, conf) | Method | Within this test, all infer() calls return the given label and confidence without invoking the model. |
6.2 Assertion API
| Method | Description |
|---|---|
Assert.equals(expected, actual) | Fails if values are not equal. |
Assert.notEquals(a, b) | Fails if values are equal. |
Assert.isTrue(condition) | Fails if condition is false. |
Assert.isFalse(condition) | Fails if condition is true. |
Assert.confidenceAbove(probVar, threshold) | Fails if probVar.confidence < threshold. |
Assert.tensorEquals(a, b, epsilon) | Fails if any element differs by more than epsilon. |
Assert.throws(ErrorType, lambda) | Fails if the lambda does not throw the specified error type. |
6.3 Pre-Admission Gate
The PrimeVM sandbox executes all @TestSpecification blocks before
a .primevm module is admitted to the production execution environment. This
is mandatory for any module containing an infer() call or a
qstate variable. All AuditStore and queue writes inside the
sandbox are transactional and rolled back after the suite completes.
6.4 Concrete Test Suite
module com.example.compliance.triage.tests; @TestSpecification pub class CaseTriageTests { @Test @MockInfer(label = "APPROVE", conf = 0.97) pub void highConfidenceApproveTakesDirectPath() { string result = CaseTriage.triageCase("Customer meets all KYC criteria.", 1001); Assert.equals("APPROVE", result); } @Test @MockInfer(label = "REJECT", conf = 0.95) pub void highConfidenceRejectIsLogged() { string result = CaseTriage.triageCase("Sanctioned entity match detected.", 1002); Assert.equals("REJECT", result); Assert.isTrue(AuditStore.contains(1002)); } @Test @MockInfer(label = "ESCALATE", conf = 0.55) pub void lowConfidenceRoutesToReviewQueue() { string result = CaseTriage.triageCase("Ambiguous counterparty relationship.", 1003); Assert.equals("PENDING_REVIEW", result); Assert.isTrue(ReviewQueue.contains(1003)); } @Test pub void tensorRiskScoreIsCorrect() { tensor<float, 2, 2> a = [[1.0, 2.0], [3.0, 4.0]]; tensor<float, 2, 2> b = [[0.5, 0.5], [0.5, 0.5]]; tensor<float, 2, 2> product = a * b; tensor<float, 2, 2> expected = [[1.5, 1.5], [3.5, 3.5]]; Assert.tensorEquals(expected, product, 0.0001); } @Test(timeout = 500) @MockInfer(label = "APPROVE", conf = 0.99) pub void triageCompletesWithinSLA() { string result = CaseTriage.triageCase("SLA stress test narrative.", 9999); Assert.equals("APPROVE", result); } }
EBNF Grammar Fragment
The following EBNF productions are normative. The prime.cfg artefact
shipped with the compiler toolchain is generated from this specification. Notation:
[ X ] = optional, { X } = zero or more,
( X | Y ) = alternation, terminals in "double quotes".
(* ─── Module Header ─── *)
module_decl = "module" qualified_name ";" ;
import_decl = "import" qualified_name ";" ;
(* ─── Type Expressions ─── *)
type_expr = primitive_type | prob_type | tensor_type | qstate_type | class_type ;
primitive_type = "int" | "float" | "string" | "boolean" | "byte" | "void" ;
prob_type = "prob" "<" type_expr ">" ;
tensor_type = "tensor" "<" primitive_type { "," integer_literal } ">" ;
qstate_type = "qstate" ;
(* ─── Variable Declarations ─── *)
var_decl = type_expr identifier "=" expr [ confidence_clause ] ";" ;
confidence_clause = "confidence" float_literal ;
(* ─── Expressions ─── *)
expr = infer_expr | tensor_expr | binary_expr | unary_expr
| method_call | field_access | identifier | literal ;
(* ─── infer() ─── *)
infer_expr = "infer" "(" expr ")" [ classifying_clause ] [ as_clause ] ;
classifying_clause = "classifying" "[" string_literal { "," string_literal } "]" ;
as_clause = "as" primitive_type ;
(* ─── Tensor Literal ─── *)
tensor_expr = "[" tensor_row { "," tensor_row } "]" ;
tensor_row = "[" numeric_literal { "," numeric_literal } "]" | numeric_literal ;
(* ─── Binary Operators ─── *)
binary_expr = expr ( "+" | "-" | "*" | "@" | "==" | "!="
| "<" | ">" | "<=" | ">=" | "&&" | "||" ) expr ;
(* ─── Quantum ─── *)
qstate_decl = "qstate" identifier "=" quantum_expr ";" ;
quantum_expr = "Quantum" "." quantum_call ;
quantum_call = "register" "(" integer_literal ")"
| "applyHadamard" "(" identifier ")"
| "applyCNOT" "(" identifier "," identifier ")"
| "applyPhase" "(" identifier "," expr ")"
| "measure" "(" quantum_qubit_expr ")" ;
quantum_qubit_expr = identifier | identifier "." "qubit" "(" integer_literal ")" ;
(* ─── Annotations ─── *)
annotation = "@" identifier [ "(" annotation_args ")" ] ;
annotation_args = annotation_arg { "," annotation_arg } ;
annotation_arg = identifier "=" literal | literal ;
(* ─── Test Declarations ─── *)
test_class = "@TestSpecification" "pub" "class" identifier "{" { test_method } "}" ;
test_method = { annotation } "pub" "void" identifier "(" ")" block ;
(* ─── Statements ─── *)
statement = var_decl | qstate_decl | return_stmt | if_stmt | method_call ";" ;
if_stmt = "if" "(" expr ")" block [ "else" block ] ;
block = "{" { statement } "}" ;
return_stmt = "return" [ expr ] ";" ;
(* ─── Class & Method Declarations ─── *)
class_decl = { annotation } access_mod [ "static" ] "class" identifier "{" { member_decl } "}" ;
member_decl = method_decl ;
method_decl = { annotation } access_mod [ "static" ] type_expr identifier
"(" [ param_list ] ")" block ;
param_list = param { "," param } ;
param = type_expr identifier ;
access_mod = "pub" | "priv" | "prot" ;
(* ─── Terminals ─── *)
qualified_name = identifier { "." identifier } ;
identifier = letter { letter | digit | "_" } ;
float_literal = digit { digit } "." { digit } ;
integer_literal = digit { digit } ;
string_literal = '"' { character } '"' ;
numeric_literal = float_literal | integer_literal ;
End-to-End Enterprise Use Case
The following complete .prime file implements a production-grade
Customer Risk Assessment Pipeline. It ingests customer workflow data,
classifies intent via infer(), computes a tensor-based multi-factor risk
score, runs a quantum-simulated optimisation gate for high-exposure decisions, and
validates all logic with an embedded test suite — all in one self-contained module.
module com.example.risk.assessment; import com.example.quantum.Gates; import com.example.store.AuditStore; import com.example.store.ReviewQueue; import com.example.workflow.WorkflowEngine; import std.time.Timestamp; // ── Data transfer objects ───────────────────────────────────────────────────── pub class CustomerWorkflow { pub int customerId; pub string narrative; pub float requestedExposure; pub string jurisdiction; pub int accountAgeDays; } pub class AssessmentResult { pub string disposition; // "APPROVE" | "ESCALATE" | "REJECT" | "PENDING_REVIEW" pub float riskScore; // composite 0.0–1.0 pub float aiConfidence; pub string quantumPath; // "DETERMINISTIC" | "Q_STANDARD" | "Q_BIFURCATED" pub string auditTimestamp; } // ── Main pipeline ───────────────────────────────────────────────────────────── pub class RiskAssessmentPipeline { // Segment weight matrix: 3 segments × 4 risk dimensions // Dimensions: [credit_history, exposure_ratio, jurisdiction_risk, tenure_score] // Segments: [retail, institutional, sovereign] priv static tensor<float, 3, 4> SEGMENT_WEIGHTS = [ [0.35, 0.25, 0.20, 0.20], [0.20, 0.40, 0.25, 0.15], [0.10, 0.30, 0.45, 0.15] ]; pub static AssessmentResult assess(CustomerWorkflow wf, int segmentIdx) { // ── Step 1: AI Intent Classification ──────────────────────────────────── prob<string> intent = infer(wf.narrative) classifying ["APPROVE", "ESCALATE", "REJECT"]; if (intent.confidence < 0.65) { ReviewQueue.enqueue(wf.customerId, intent.confidence); AssessmentResult r; r.disposition = "PENDING_REVIEW"; r.riskScore = -1.0; r.aiConfidence = intent.confidence; r.quantumPath = "N/A"; r.auditTimestamp = Timestamp.now(); return r; } // ── Step 2: Tensor Multi-Factor Risk Score ────────────────────────────── // Normalise four customer features into a 1×4 vector and dot-product // with the selected segment weight column to get a scalar risk score. float creditNorm = CustomerData.getCreditNorm(wf.customerId); float exposureNorm = wf.requestedExposure / CustomerData.getLimit(wf.customerId); float jurisdRisk = JurisdictionTable.getRiskScore(wf.jurisdiction); float tenureNorm = Math.min(1.0, wf.accountAgeDays / 1825.0); tensor<float, 1, 4> features = [[creditNorm, exposureNorm, jurisdRisk, tenureNorm]]; tensor<float, 4, 1> weightCol = SEGMENT_WEIGHTS.row(segmentIdx).T; // (1×4) * (4×1) → (1×1) tensor<float, 1, 1> scoreTensor = features * weightCol; float compositeRisk = scoreTensor.scalar(); // ── Step 3: Quantum Optimisation Gate ─────────────────────────────────── // High-exposure requests (risk > 0.60) pass through a Hadamard-entangled // decision gate modelling portfolio diversification under uncertainty. string quantumPath = "DETERMINISTIC"; if (compositeRisk > 0.60) { qstate reg = Quantum.register(2); qstate superposed = Quantum.applyHadamard(reg); qstate ctrl = superposed.qubit(0); qstate tgt = superposed.qubit(1); qstate entangled = Quantum.applyCNOT(ctrl, tgt); boolean qDecision = Quantum.measure(entangled.qubit(0)); if (qDecision) { compositeRisk = compositeRisk * 1.15; quantumPath = "Q_BIFURCATED"; } else { quantumPath = "Q_STANDARD"; } } // ── Step 4: Final Disposition ──────────────────────────────────────────── string disposition; if (intent.value == "REJECT" || compositeRisk > 0.85) { disposition = "REJECT"; } else if (intent.value == "ESCALATE" || compositeRisk > 0.55) { disposition = "ESCALATE"; } else { disposition = "APPROVE"; } // ── Step 5: Audit and Return ───────────────────────────────────────────── AuditStore.write(wf.customerId, disposition, compositeRisk, intent.confidence, Timestamp.now()); AssessmentResult result; result.disposition = disposition; result.riskScore = compositeRisk; result.aiConfidence = intent.confidence; result.quantumPath = quantumPath; result.auditTimestamp = Timestamp.now(); return result; } } // ── Embedded test suite ─────────────────────────────────────────────────────── @TestSpecification pub class RiskAssessmentPipelineTests { priv static CustomerWorkflow retailWorkflow(float exposure, int ageDays) { CustomerWorkflow w; w.customerId = 88001; w.narrative = "Standard retail credit line application."; w.requestedExposure = exposure; w.jurisdiction = "EU-DE"; w.accountAgeDays = ageDays; return w; } @Test @MockInfer(label = "APPROVE", conf = 0.96) pub void lowRiskRetailCustomerIsApproved() { CustomerWorkflow w = retailWorkflow(5000.0, 2190); AssessmentResult r = RiskAssessmentPipeline.assess(w, 0); Assert.equals("APPROVE", r.disposition); Assert.isTrue(r.riskScore < 0.55); Assert.equals("DETERMINISTIC", r.quantumPath); } @Test @MockInfer(label = "APPROVE", conf = 0.91) pub void highExposureTriggersQuantumGate() { CustomerWorkflow w = retailWorkflow(980000.0, 365); AssessmentResult r = RiskAssessmentPipeline.assess(w, 0); Assert.isTrue(r.quantumPath == "Q_BIFURCATED" || r.quantumPath == "Q_STANDARD"); } @Test @MockInfer(label = "REJECT", conf = 0.98) pub void aiRejectOverridesLowTensorRisk() { CustomerWorkflow w = retailWorkflow(1000.0, 3650); AssessmentResult r = RiskAssessmentPipeline.assess(w, 0); Assert.equals("REJECT", r.disposition); Assert.isTrue(AuditStore.contains(88001)); } @Test @MockInfer(label = "APPROVE", conf = 0.50) pub void veryLowConfidenceRoutesToReviewQueue() { CustomerWorkflow w = retailWorkflow(20000.0, 730); AssessmentResult r = RiskAssessmentPipeline.assess(w, 0); Assert.equals("PENDING_REVIEW", r.disposition); Assert.isTrue(ReviewQueue.contains(88001)); } @Test pub void segmentWeightsFormProbabilitySimplex() { tensor<float, 3, 4> w = [ [0.35, 0.25, 0.20, 0.20], [0.20, 0.40, 0.25, 0.15], [0.10, 0.30, 0.45, 0.15] ]; Assert.equals(1.0, w.row(0).sum(), 0.001); Assert.equals(1.0, w.row(1).sum(), 0.001); Assert.equals(1.0, w.row(2).sum(), 0.001); } @Test(timeout = 300) @MockInfer(label = "APPROVE", conf = 0.93) pub void fullPipelineCompletesWithinSLA() { CustomerWorkflow w = retailWorkflow(15000.0, 1095); AssessmentResult r = RiskAssessmentPipeline.assess(w, 0); Assert.isTrue(r.disposition != ""); } }
com.example.risk.assessment module is admitted to the production
execution context. A single failure halts deployment and emits a structured error
report to the CI/CD pipeline.
Playground
Run Prime in this page. The playground compiles and executes code with the real PrimeVM,
built to WebAssembly from the same Rust crates as the prime command, entirely
in your browser. Choose an example or write your own: a class Main with
pub static void main() is run and what it writes with print is
shown, and every @Test is run and the admission rule (§6) applied.
spec/prime-core-v0.1.md. Probabilistic types, tensors, infer(),
qstate and the other features of §2–§4 are reserved keywords there and are
rejected by the compiler. Host functions (data of the embedding application) are not available in the browser.
The output shows the lines written with print, test results and admission verdicts,
and diagnostics with phase, code, line and column (Prime Core §14). Each run gets
20 million instructions and 3 seconds; nothing leaves the page.