Verified numerical code generation.

C Note is an agentic notebook. Describe what you need and an agent writes the code. C Proof then checks every property you state: it proves it, tests it on samples when no proof applies, or returns the input that breaks it.

C Proof created Chelis, the verified tensor language for agent-written code, and builds C Note on it. Open source on GitHub (MIT).

  1. You ask

    Present value of a payment that grows at rate g, discounted at rate r. It must stay positive whenever r is greater than g.

  2. The agent writes

    -- Gordon present value is positive under the convergence condition r > g.
    def gordon_pv(d: f32, r: f32, g: f32) -> f32 = (d / (r - g))
    @property gordon_pv_positive forall(d: f32, r: f32, g: f32) where d > 0.0, r > g:
      (gordon_pv(d, r, g) > 0.0)
  3. C Proof returns

    Proven (SMT)

    gordon_pv_positive

    Proved by an SMT solver over the real numbers, for every input with d > 0 and r > g, without sampling.

How generated code is checked

Generated code goes through these steps in order. Each example below is real output from the Chelis compiler or C Note.

  1. Dimension errors

    The agent writes Chelis, where shapes, precision, effects and ownership are part of every type. Adding two vectors whose dimensions have different names is a compile error, reported in a form the agent can read and fix.

    Type check

    $ chelis check combine_exposure.ch
    def combine_exposure[book, hedge](exposure: tensor[book, f32], offset: tensor[hedge, f32]) -> tensor[book, f32] = exposure |> add(offset)
    DimensionMismatchdistinct declared dim parameters `book` and `hedge` were unified by the function body in declaration `combine_exposure`: authored dimension binders are rigid and must remain distinct (spec/04-type-system.md §3.1.3 [04-INF-6])
  2. Proofs

    Each property you state goes to an SMT solver, an automated prover for arithmetic. A proof holds for every input its condition allows, over the real numbers. Floating-point effects such as rounding and overflow are outside its scope.

    See the proof record

    Proven (SMT)

    gordon_pv_positive

    Method: SMT proof over the real numbers, not 32-bit floats.

    Goal:

    forall(d: f32, r: f32, g: f32) where d > 0.0, r > g: (gordon_pv(d, r, g) > 0.0)

    A property the SMT solver proves over the reals, with no sampling.

  3. Sampled tests

    When no proof applies, the property runs on seeded samples, and the result is labeled as sampled, never as proven.

    See the validation record

    Sampled, not proven

    bs_call_positive

    Method: sampling

    Goal:

    forall(s: f32, k: f32, r: f32, sigma: f32, t: f32) where s > 0.0, k > 0.0, sigma > 0.0, t > 0.0, r >= 0.0: (bs_call(s, k, r, sigma, t) > 0.0)

    Validated by sampling only, not an SMT proof.

  4. Counterexamples

    When a property fails, C Note shows the input that breaks it, replayed at machine precision.

    See the counterexample

    Disproved 1 counterexample

    crr_nodisc_call_upper_bound

    Break inside the stated region

    Call price 1.125 exceeds spot 1.0, so the undiscounted pricing model admits arbitrage.

    Counterexample:

    s = 1.0 (spot), k = 0.5 (strike), u = 2.0 (up factor), d = 0.5 (down factor), q = 0.5 (up probability)

    Machine-precision replay confirms the violation.

Three layers

C Note runs on the C Proof Engine, and both are built on Chelis, the language the agent writes.

C Note

The notebook where you work with the agent and read every result.

The C Proof Engine

Type-checks each property, then proves it by SMT, using certified envelopes for transcendental functions where they cover the goal. A property no proof reaches is tested on seeded samples and labeled.

  1. Type check
  2. SMT proof
  3. Sampled validation
Chelis

Our open-source language. The compiler checks shapes, precision, effects and ownership before code runs. chelis.ch

Quantitative finance

C Note includes checked examples for pricing and risk, from present-value formulas to option pricing, with properties such as no-arbitrage bounds and put-call parity already stated.

Try it on your own code

Open an account, start from a checked example or describe your own problem, and check its first property.

Bring numerical code your team already runs. We map the properties it must satisfy and set C Note up inside your environment.