Skip to main content

Monogate Forge

PyPI License: MIT Python

Forge is the EML language and compiler. Write a math kernel once, compile it to 36 backends — all of them emitting locally from the CLI, no license and no account — with chain-order analysis, and contracts (requires, ensures, refinement types) that the Lean, Coq and Isabelle targets state as theorems wherever a function declares them. Whether another target checks a contract at run time depends on the target, and several emit nothing: see the per-target table. The catalog spans software, GPU shaders, compiler IRs, FPGA RTL, manufacturing artifacts, formal-verification proofs, safety-critical avionics, gaming and EVM. The tables below list every one, and what each needs in your source to fire.


Quick start

pip install monogate-forge

Create hello.eml:

module hello;

fn pid(error: Real, integral: Real, derivative: Real) -> Real
    where chain_order <= 0
    requires (-1.0 <= error && error <= 1.0)
    ensures  (-1.5 * 1.0 <= result && result <= 1.5 * 1.0)
{
    let kp = 1.0;
    let ki = 0.2;
    let kd = 0.3;
    kp * error + ki * integral + kd * derivative
}

Compile to every target at once:

eml-compile hello.eml --target all -o build/

You now have build/hello.c, build/hello.rs, build/hello.py, build/hello.lean, build/hello.v, build/hello.hlsl, build/hello.metal, build/hello.swift, … one file per target. Pick a single target instead:

eml-compile hello.eml --target rust -o hello.rs
eml-compile hello.eml --target c    -o hello.c
eml-compile hello.eml --target lean -o Hello.lean

A snippet of hello.rs:

use monogate_sys::*;

/// pid
/// Pfaffian chain count (eml-cost pfaffian_r): 0     Cost class: p0-d2-w0-c0
/// EML depth:   2  Symbolic band: LOW (from pfaffian_r only)
/// Numerical:   cancellation exposure NONE  (no mixed-sign subtraction)
/// source obligations for pid: {O1}
///   O1 [a99a5a5c258f] -> PRESERVED (equivalent)  assert! before the tail expression
///        build: unconditional -- assert! is kept in release builds -- only debug_assert! is compiled out
/// Dynamics:    0 osc, 0 decay  (predicted_r=0)
/// FPGA est:   2 MAC, 0 exp, 0 ln, 0 trig -> 4 cy @ 32-bit
pub fn pid(error: f64, integral: f64, derivative: f64) -> f64 {
    assert!((((-1.0) <= error) && (error <= 1.0)), "pid: requires ((((-1.0) <= error) && (error <= 1.0)))");
    let kp: f64 = 1.0;
    let ki: f64 = 0.2;
    let kd: f64 = 0.3;
    let result = (((kp * error) + (ki * integral)) + (kd * derivative));
    assert!(((((-1.5) * 1.0) <= result) && (result <= (1.5 * 1.0))), "pid: ensures violated");
    result
}

Every emitted function carries its EML profile (eml-cost's pfaffian_r, cost class, EML depth, symbolic band, cancellation exposure, FPGA cycle estimate) and its obligation map in the doc-comment header, so a reviewer can see the analysis without leaving the file. The requires and ensures contracts from the EML source become runtime assert!s, which release builds keep. tests/test_doc_emission_samples.py holds this snippet to what the Rust backend prints for the hello.eml above.

Five-minute tour: docs/quickstart.md. Full tutorial: monogate.dev/learn/eml/intro.


What you get

36 targets. All local. All free. Every backend in the tables below emits from eml-compile on your machine — there is no Free/Pro split, no license token, and no hosted step in the path. What a target needs is not a tier but an annotation: the RTL family wants a @target(fpga, ...) function, the circuit family wants @spice_* components, and the proof family wants a @verify(lean, ...) block. Ask for a target the source has nothing to feed and the compiler says so instead of emitting a stub. The Requires column below records exactly that. Per-target notes — flag, file extension, what the output is for — are in docs/backends.md.

What each target's toolchain accepts

Emitting is not compiling, and compiling is not synthesizing. This table is what was measured, not what is supported:

Measured by the corpus gate over every tracked .eml file (350): each file is emitted for each target and read by that target's own toolchain (compiled, linked, run or validated: see tools/scripts/corpus_checks/). Emits is how many files the target produced an artifact for; the rest it refused with a stated reason (a missing @target(fpga), @spice_* or @verify annotation is a refusal). Accepted is how many of those the toolchain accepted; Broken were rejected. Broken files are listed by name in tools/corpus_compile_baseline.json, each target's list may only shrink, and each broken target carries an owner and an expiry date there.

Target Checked Emits Accepted Broken Contract-stopped Not measured
c every push 350 of 350 350 of 350 0 of 350 0 —
cpp nightly 345 of 350 345 of 345 0 of 345 0 execution
rust every push 345 of 350 345 of 345 0 of 345 0 execution
python nightly 345 of 350 345 of 345 0 of 345 44 —
go nightly 345 of 350 345 of 345 0 of 345 0 execution
java nightly 345 of 350 345 of 345 0 of 345 0 execution
kotlin nightly 345 of 350 345 of 345 0 of 345 0 execution
csharp nightly 345 of 350 345 of 345 0 of 345 0 execution
javascript nightly 340 of 350 340 of 340 0 of 340 44 —
wasm nightly 339 of 350 339 of 339 0 of 339 0 execution
matlab nightly 340 of 350 340 of 340 0 of 340 44 —
lean nightly 282 of 350 279 of 282 3 of 282 (owner agent-maestro, expires 2026-10-16) 0 proofs: a sorry theorem compiles (tools/scripts/lean_discharge_census.py counts discharge)
zkproof nightly 29 of 350 29 of 29 0 of 29 0 —
verilog every push 178 of 350 178 of 178 0 of 178 0 synthesis is not gated (yosys synthesized every linted design on 2026-09-16, about an hour); simulation against C only for the demo kernels
systemverilog nightly, advisory (not gating) 214 of 350 80 of 214 134 of 214 0 synthesis and simulation (Verilator lint only)
vhdl nightly 170 of 350 170 of 170 0 of 170 0 synthesis and simulation (GHDL analysis and elaboration only)
chisel nightly, advisory (not gating) 214 of 350 20 of 214 194 of 214 0 synthesis (compiled and elaborated to CHIRRTL only)
llvm nightly 339 of 350 339 of 339 0 of 339 0 execution
hlsl nightly 338 of 350 338 of 338 0 of 338 0 not run on a GPU (glslang, not DXC)
glsl nightly 338 of 350 338 of 338 0 of 338 0 not run on a GPU
glsles nightly 338 of 350 338 of 338 0 of 338 0 not run on a GPU
wgsl nightly 344 of 350 344 of 344 0 of 344 0 not run on a GPU
metal not covered: Apple's Metal shader compiler (xcrun metal) ships only for macOS and Windows; no Linux build exists, none is on this box, and compiling MSL as C++ would not apply Metal's rules — — — — everything
swift nightly 345 of 350 345 of 345 0 of 345 0 execution
ada nightly 334 of 350 334 of 334 0 of 334 0 execution
autosar nightly 344 of 350 344 of 344 0 of 344 0 AUTOSAR XSD conformance and an RTE generator run
aadl not covered: no AADL front end is installed: osate, ocarina and aadl-inspector are all absent from PATH (measured 2026-09-16), and the target's output is AADL text that only such a tool can name-resolve and legality-check. OSATE is an Eclipse RCP download and Ocarina builds from source with GNAT; neither is here. — — — — everything
ros2 nightly 339 of 350 339 of 339 0 of 339 0 real rclcpp (compiled against a stub of the API it uses)
coq nightly 282 of 350 282 of 282 0 of 282 0 proofs: an Admitted theorem compiles
isabelle nightly 282 of 350 281 of 282 1 of 282 (owner agent-maestro, expires 2026-10-24) 0 proofs: a sorry theorem compiles
solidity nightly 340 of 350 339 of 340 1 of 340 (owner agent-maestro, expires 2026-10-22) 0 execution on an EVM (compiled only)
luau nightly 340 of 350 340 of 340 0 of 340 44 —
gdscript nightly 338 of 350 338 of 338 0 of 338 0 execution (Godot --check-only)
spice nightly 7 of 350 7 of 7 0 of 7 0 the circuit's behaviour against the kernel
kicad not covered: kicad-cli here is 7.0.11 and the backend emits KiCad 8 (version 20231120): measured 2026-09-16, kicad-cli sch export netlist refuses all 7 emitted corpus schematics unmodified with Failed to load schematic file (rc 3). A dialect shim (software/backends/tests/test_kicad_schematic_actually_loads.py) loads 6 of 7, but that checks a transformation, not the artifact; examples/maglev/driver.eml fails even shimmed, cause undetermined without KiCad 8. — — — — everything
jlcpcb nightly 7 of 350 7 of 7 0 of 7 0 manufacturability at the fab

Contract-stopped files emitted and ran, but every probe input fired one of the kernel's own contract checks, so the body past it never ran: not a failure, and not a full run either.

Whether every target computes the same number

Accepting an artifact is not computing the right value. Every wrong number found in the week before the differential gate existed compiled, linted or synthesized cleanly. This table is what one kernel's own functions actually returned, target against target, bit for bit:

Measured by the differential gate (tools/scripts/differential.py) over every tracked .eml file (350): 1037 of 1110 functions are in round-1 scope (Real/f64 arguments, a Real/f64 or tuple return, no state, no extern), each is called with up to 48 generated inputs -- contract boundaries and one ulp either side, IEEE specials, seeded draws -- and every result is compared with the c artifact's by bits: 47849 calls per target. Agree means identical bits on every call (a NaN is one value; both sides firing the same contract counts). Every other function is listed by name in tools/differential_baseline.json, which may only shrink.

Target Agree Signed zero Ulp Wrong Contract differs Contract unchecked Target error Refused Burn-down
ada 1011 of 1024 0 11 0 2 0 0 13 owner agent-maestro, expires 2026-10-17
c 1037 of 1037 0 0 0 0 0 0 0 —
cpp 1026 of 1037 0 10 0 1 0 0 0 owner agent-maestro, expires 2026-10-17
csharp 1023 of 1037 0 13 0 1 0 0 0 owner agent-maestro, expires 2026-10-17
gdscript 999 of 1031 0 27 5 3 0 0 6 owner agent-maestro, expires 2026-10-17
go 789 of 1037 0 240 42 6 0 0 0 owner agent-maestro, expires 2026-10-17
java 841 of 1037 0 187 11 4 0 0 0 owner agent-maestro, expires 2026-10-17
javascript 869 of 1037 0 160 8 4 0 0 0 owner agent-maestro, expires 2026-10-17
kotlin 839 of 1037 0 189 13 5 0 0 0 owner agent-maestro, expires 2026-10-17
llvm 315 of 1037 0 0 0 0 722 (disclosed) 0 0 —
luau 1018 of 1035 0 16 0 1 0 0 2 owner agent-maestro, expires 2026-10-17
matlab 1022 of 1035 0 10 0 3 0 0 2 owner agent-maestro, expires 2026-10-17
python 1026 of 1037 0 11 0 0 0 0 0 —
rust 892 of 1037 0 137 7 3 0 0 0 owner agent-maestro, expires 2026-10-17
swift 1026 of 1037 0 10 0 1 0 0 0 owner agent-maestro, expires 2026-10-17
wasm 315 of 1037 0 0 0 0 722 (disclosed) 0 0 —

Counts are FUNCTIONS, not calls. Signed zero, Ulp and Contract unchecked are tolerated classes, not defects: signed zero is equal except the sign of a zero; ulp is within 4 ulps, and the function reaches a libm call (glibc's exp/log/pow are not correctly rounded, and a target with its own libm is no less right); contract unchecked is the reference's contract fired and the target returned the body's value, on a target docs/verify-guide.md records as checking no contract.

Contract unchecked is why llvm and wasm agree on a minority of functions, and it is not a failure rate. docs/verify-guide.md's contract table records both targets as checking neither requires nor ensures (LLVM IR lowers a requires to an llvm.assume, a promise to the optimizer, and drops ensures; WebAssembly is built from that IR), so where the reference refuses an input they return the value the body computed. That comparison did not happen; it is disclosed, recorded and shrink-only, and no value difference hides behind it -- their Wrong and Contract differs columns are the same 0 as any agreeing target's.

Not covered. 73 of 1110 functions are outside round-1 scope and are refused with a stated reason per function in the baseline (state across calls, a Vec/Mat/Int parameter, an extern the host supplies), never counted as agreement. Refused above is a module that target's own toolchain would not emit or build at all. Every other target Forge has (lean, zkproof, verilog, systemverilog, vhdl, chisel, hlsl, glsl, glsles, wgsl, metal, autosar, aadl, ros2, coq, isabelle, solidity, spice, kicad, jlcpcb) executes nothing here: they are compared by the corpus gate's own checkers, which ask whether the toolchain ACCEPTS the artifact -- a different question, and the one the table above this answers.

Software (general-purpose)

Target Flag Requires
C99 --target c —
C++17 --target cpp —
Rust --target rust —
Python 3 --target python —
Go --target go —
Java --target java —
Kotlin --target kotlin —
C# --target csharp —
JavaScript --target javascript —
MATLAB --target matlab —
Swift --target swift —

Compiler IRs

Target Flag Requires
WebAssembly --target wasm —
LLVM IR --target llvm —

GPU shaders

Target Flag Requires
HLSL (DirectX) --target hlsl —
GLSL (desktop) --target glsl —
GLSL ES --target glsles —
WGSL (WebGPU) --target wgsl —
Metal (Apple) --target metal —

Hardware (FPGA / ASIC)

Target Flag Requires
Verilog --target verilog @target(fpga) fn
SystemVerilog --target systemverilog @target(fpga) fn
VHDL --target vhdl @target(fpga) fn
Chisel / FIRRTL --target chisel @target(fpga) fn

Manufacturing / circuits

Target Flag Requires
spice --target spice @spice_* components
kicad --target kicad @spice_* components
jlcpcb --target jlcpcb @spice_* components

Formal verification

Target Flag Requires
Lean 4 --target lean @verify(lean) block
Coq --target coq @verify(lean) block
Isabelle/HOL --target isabelle @verify(lean) block

Safety-critical

Target Flag Requires
Ada/SPARK --target ada —
AUTOSAR C --target autosar —
AADL --target aadl —
ROS 2 / C++ --target ros2 —

Gaming

Target Flag Requires
Luau (Roblox) --target luau —
GDScript (Godot) --target gdscript —

Blockchain

Target Flag Requires
Solidity (PRBMath SD59x18) --target solidity —

Zero-knowledge

Target Flag Requires
Plonky2 ZK circuits (research) --target zkproof —

Every target above is free and emits locally. The Free/Pro split that earlier releases shipped is retired: ALL_TIERS_FREE in tools/license/verifier.py is True, so load_license reads nothing, target_allowed passes everything, and no token is checked on any path. The signing machinery stays in the tree because deleting it would be a bigger change than parking it, not because it gates anything. If a target refuses to emit, the reason is in the Requires column — a missing annotation in your source, which the error message names.


VS Code extension

Monogate Forge on the VS Code Marketplace

ext install Monogate.monogate-forge-vscode

LSP features:

  • Chain-order on hover — every function shows its profiled chain order, cost class, and node count.
  • Completions — keywords (fn, let, where, requires, ensures, module, use), builtins (exp, ln, sin, cos, sqrt, tanh, pow, clamp, eml, …), stdlib modules.
  • Diagnostics — type errors, unbound identifiers, chain-order violations, contract failures.
  • FPGA status bar — for any function annotated @target(fpga), the status bar shows estimated LUT / DSP / latency for the selected device.
  • Format on save — canonical layout via eml-fmt.

Marketplace listing: Monogate.monogate-forge-vscode.


Why Forge

Industrial automation today is stuck on ladder logic — Boolean rungs from the 1960s that can't express transcendental functions, can't prove correctness, can't optimize node count, and treat PID loops as black boxes. Structured Text is marginally better but still opaque. MATLAB/Simulink + HDL Coder will get you to FPGA, but the math hides inside vendor library calls and you have no formal proof of precision.

EML makes every mathematical operation visible and measurable. Every expression is an EML tree and every function carries a chain order. A contract a function declares is stated as a Lean theorem unless translation loses it, which the obligation map reports as LOST. Whether that theorem is then proved is a separate question, answered by #print axioms. The same source compiles to your laptop, your microcontroller, your FPGA, your Solidity contract, and your formal proof. The FPGA targets compute in Q-format fixed point, so they do not agree bit for bit with the IEEE-754 software targets.


Documentation

  • Quickstart — pip install to first compile in 5 minutes.
  • Language reference — every keyword, builtin, type, and annotation.
  • Backends — every compilation target with its CLI flag, file extension, and what it needs in your source.
  • Verify guide — @verify, requires/ensures, Lean output, MachLib integration.
  • FPGA guide — @target(fpga), LUT/DSP estimates, precision selection, vendor support.

External:


Contributing

See CONTRIBUTING.md. Bug reports and feature requests via GitHub issues.

License

Compiler is MIT (see LICENSE). Specific algorithmic methods covered by patents — open implementation, but commercial re-implementations may need a license. See patents/index.md.

Built by Mosa Creates LLC.

Release files for monogate-forge 0.17.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for monogate-forge 0.17.0
File Size Uploaded
monogate_forge-0.17.0.tar.gz 2.3 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for monogate-forge 0.17.0
File Interpreter ABI Platform
monogate_forge-0.17.0-py3-none-any.whl Python 3 none any Details

Total release size: 4.3 MB

Release files / monogate_forge-0.17.0.tar.gz

Download URL monogate_forge-0.17.0.tar.gz
Size 2.3 MB
Tags Source
SHA-256 checksum
How to use checksums
259589d78eb342f5ef104d22cbb1069c20a778dc54fa316a0dd37101b65627c3
BLAKE2b-256 checksum
How to use checksums
0a7608e6c59ebc8b27c35f7b66cd9a9e999817f6eb72fe946a5fe777ad53b098
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release files / monogate_forge-0.17.0-py3-none-any.whl

Download URL monogate_forge-0.17.0-py3-none-any.whl
Size 2.0 MB
Tags Python 3
SHA-256 checksum
How to use checksums
9f287e206270779522b5ceb385ed8d02bf1614269430d4c96ee6afce2e2340ba
BLAKE2b-256 checksum
How to use checksums
1b50a2ce534322ea71b879034bc2266e275b3d1ec9c1d097427c53234573be8e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.17.0 This release

2 release files

0.16.0

2 release files

0.15.0

2 release files

0.14.0

2 release files

0.13.0

2 release files

0.12.1

2 release files

0.2.0

2 release files

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page