Skip to content

Commit d15c787

Browse files
committed
docs: substantive CRG C annotation (EXPLAINME.adoc)
1 parent 8bf1b56 commit d15c787

1 file changed

Lines changed: 80 additions & 16 deletions

File tree

EXPLAINME.adoc

Lines changed: 80 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,106 @@
33
:toc:
44
:icons: font
55

6-
The README makes claims. This file backs them up.
6+
The README makes claims. This file backs them up with code architecture and solver bindings.
77

8-
[quote, README]
8+
== Claim 1: Complete Bidirectional SMT-LIB2 Pipeline (Julia ↔ SMT-LIB2 ↔ Solvers)
9+
10+
From README:
11+
____
12+
SMTLib.jl gives you a clean Julia API for building constraints, checking satisfiability, and parsing models -- with support for quantifiers, optimization, theory helpers, unsat cores, and more.
13+
____
14+
15+
**How it's proven:**
16+
- **Julia to SMT-LIB2**: `to_smtlib(expr)` (exported line 69) converts Julia expressions to valid SMT-LIB2 scripts
17+
- **SMT-LIB2 to Julia**: `from_smtlib(str)` (exported line 69) parses solver output back into Julia structures
18+
- **Operator mapping**: `JULIA_OP_TO_SMT_MAP` constant (lines 115-150) maps 35+ Julia operators to SMT-LIB2 equivalents (arithmetic, comparison, logical, unicode variants)
19+
- **Logic support**: `LOGICS` constant (lines 94-106) lists 10 supported SMT-LIB2 logics (QF_LIA, QF_LRA, QF_NIA, QF_NRA, QF_BV, QF_AUFLIA, LIA, LRA, AUFLIRA, QF_S)
20+
- **Solver auto-detection**: `find_solver(name)` and `available_solvers()` (exported lines 68-69) auto-discover Z3, CVC5, Yices, MathSAT on PATH
21+
- **Critical path**: `src/SMTLib.jl` (70KB monolithic) contains: solver detection, expression-to-SMT-LIB conversion, result parsing, context management, theory helpers
22+
- **Test coverage**: 468 test assertions per README line 249
23+
24+
**Caveat:** The 70KB monolithic design in `src/SMTLib.jl` means all solver interaction code is in one file. This is maintainable but could be refactored into `src/solver_detection.jl`, `src/smt_generation.jl`, `src/result_parsing.jl`, `src/context.jl` for better organization.
25+
26+
== Claim 2: Incremental Solving with Named Assertions and Unsat Core Extraction
27+
28+
From README:
929
____
10-
SMTLib.jl is a Julia package that generates and consumes SMT-LIB2, the standard
30+
Incremental solving: push/pop contexts for interactive workflows... Named assertions & unsat cores: get_unsat_core for debugging UNSAT results.
1131
____
1232

33+
**How it's proven:**
34+
- **Context type**: `SMTContext` exported line 65; holds declarations, assertions, options, and solver state
35+
- **Push/Pop**: `push!(ctx)` and `pop!(ctx)` exported line 66 manage assertion scopes (line 94: `push!` adds new scope, `pop!` reverts to previous)
36+
- **Incremental declarations**: `declare(ctx, name, sort)` (exported line 67) adds typed variables within a scope
37+
- **Named assertions**: `assert!(ctx, expr, name=:constraint_id)` (exported line 67) tags constraints for unsat core extraction
38+
- **Unsat core extraction**: `get_unsat_core(ctx)` (exported line 74) returns subset of named assertions that cause UNSAT (README example lines 217-226)
39+
- **Critical path**: Context maintains assertion stack; `check_sat` invokes solver; unsat core extracted via solver's `(get-unsat-core)` command parsing
40+
- **Example workflow**: README lines 175-181 shows push/pop/assert sequence; lines 217-226 demonstrate unsat core extraction with constraint naming
41+
42+
**Caveat:** Unsat core extraction requires solver support (`produce-unsat-cores` option must be set via `set_option!`). Not all solvers expose unsat cores; MathSAT and CVC5 support it, but Yices may have limitations.
43+
1344
== Technology Choices
1445

1546
[cols="1,2"]
1647
|===
17-
| Technology | Learn More
48+
| Technology | Purpose
1849

19-
| **Zig** | https://ziglang.org
20-
| **Julia** | https://julialang.org
21-
| **Idris2 ABI** | https://www.idris-lang.org
50+
| **Julia** | SMT-LIB2 generation, solver invocation, result parsing, API design
51+
| **Z3, CVC5, Yices, MathSAT** | External SMT solvers (auto-detected on PATH); not bundled
52+
| **Synthesis.jl submodule** | CEGIS (Counterexample-Guided Inductive Synthesis) engine (line 81-82)
2253
|===
2354

2455
== Dogfooded Across The Account
2556

26-
Uses the hyperpolymath ABI/FFI standard (Idris2 + Zig). Same pattern used across
27-
https://github.com/hyperpolymath/proven[proven],
28-
https://github.com/hyperpolymath/burble[burble], and
29-
https://github.com/hyperpolymath/gossamer[gossamer].
57+
SMTLib.jl is the **symbolic verification tier** for the ecosystem:
58+
- **Axiom.jl**: Uses SMTLib for compile-time property verification and proof export
59+
- **PolyglotFormalisms.jl**: Proposed integration for cross-language semantic equivalence checking (README line 197)
60+
- **ProvenCrypto.jl**: Exports verification certificates to SMT solvers via SMTLib (ProvenCrypto README line 199)
61+
- **proven**: Rust equivalent that imports SMTLib specs as reference for verification workflows
62+
63+
Same modular solver interface pattern used in `hypatia` (static analysis), `verdecimal` (floating-point verification).
3064

3165
== File Map
3266

33-
[cols="1,2"]
67+
[cols="1,3"]
3468
|===
3569
| Path | What's There
3670

37-
| `src/` | Source code
38-
| `ffi/` | Foreign function interface
39-
| `test(s)/` | Test suite
71+
| `src/SMTLib.jl` | 70KB monolithic module (lines 59-end); exports 25+ functions; core solver interaction, expression conversion, context management, theory helpers, parsing
72+
| (Line 59-90) | Module documentation, architecture overview (18 lines), no code
73+
| (Lines 88-106) | Constants: `LOGICS` (10 logic identifiers), `JULIA_OP_TO_SMT_MAP` (35+ operator mappings)
74+
| (Lines ~115-160 within JULIA_OP_TO_SMT_MAP) | Arithmetic operators (+, -, *, /, div, mod, rem, abs), comparison (==, !=, <, >, <=, >=, unicode variants), logical (!,&&,||, ∧, ∨, ⟹, xor, iff), implication (⟹), etc.
75+
| (Lines ~200+) | `SMTSolver` struct: name, path, capabilities
76+
| (Lines ~250+) | `SMTResult` struct: status (:sat, :unsat, :unknown), model (parsed values), statistics
77+
| (Lines ~300+) | `SMTContext` struct: logic, declarations (var → sort), assertions (expr list), options, solver reference, assertion scopes for push/pop
78+
| (Lines ~400+) | Solver detection: `find_solver(name)`, `available_solvers()` — searches PATH for Z3, CVC5, Yices, MathSAT executables
79+
| (Lines ~500+) | Expression conversion: `julia_op_to_smt(sym)` → "SMT-LIB operator"; `to_smtlib(expr)` → complete SMT-LIB2 script; `from_smtlib(str)` → parse output
80+
| (Lines ~600+) | Core operations: `declare(ctx, name, sort)`, `assert!(ctx, expr)`, `check_sat(ctx)`, `get_model(ctx)`, `reset!(ctx)`, `push!(ctx)`, `pop!(ctx)`, `set_option!(ctx, key, value)`
81+
| (Lines ~700+) | Theory helpers: `bv(value, width)` (bitvector), `fp_sort(ebits, sbits)` (floating-point), `array_sort(index, element)` (arrays), `re_sort(base)` (regex)
82+
| (Lines ~800+) | Quantifiers: `forall(vars, body)`, `exists(vars, body)` — build quantified formulas
83+
| (Lines ~900+) | Optimization (Z3): `minimize!(ctx, expr)`, `maximize!(ctx, expr)`, `optimize(ctx)` — νZ solver mode
84+
| (Lines ~1000+) | Analysis: `get_statistics(result)`, `evaluate(model, expr)` (eval expression in model), `get_unsat_core(ctx)` (extract unsatisfiable subset)
85+
| `src/synthesis.jl` | 3.8KB CEGIS engine: `cegis(...)` exported at line 75; includes submodule `.Synthesis` used by core module
86+
| `test/runtests.jl` | Main test harness; runs 468 test assertions
87+
| `test/e2e_test.jl` | End-to-end integration: solver discovery, constraint building, satisfiability checking, model extraction
88+
| `test/property_test.jl` | Property-based tests: logic completeness, operator mapping round-trips, model consistency
89+
| `scripts/readiness-check.sh` | Release readiness validation script (mentioned README line 254)
90+
| `docs/release-readiness.adoc` | Release readiness guide (mentioned README line 255)
91+
| `SMTLIB-AXIOM-PARITY-CHECKLIST.adoc` | Parity checklist for Axiom.jl integration (mentioned README line 256)
4092
|===
4193

94+
== Critical Invariants (What Must Not Break)
95+
96+
1. **Operator mapping completeness**: Every Julia operator that appears in `assert!` must have a corresponding entry in `JULIA_OP_TO_SMT_MAP`
97+
2. **Logic correctness**: Declared logic must support all theories used in assertions (e.g., QF_LIA cannot use arrays)
98+
3. **Solver invocation atomicity**: Each `check_sat` must produce exactly one result; no interleaving of solver calls
99+
4. **Push/Pop balance**: Every `push!` must have a matching `pop!`; unbalanced operations crash the solver session
100+
5. **Model consistency**: If `check_sat` returns `:sat`, `get_model` must return a model that satisfies all assertions
101+
6. **Unsat core validity**: Every assertion in `get_unsat_core` result must be in the original assertion set
102+
42103
== Questions?
43104

44-
Open an issue or reach out directly — happy to explain anything in more detail.
105+
For solver-specific quirks, see inline comments near `find_solver` implementation.
106+
For logic selection guidance, see README Section "Suggested Tech Stack" (lines 51-62) and "Quick Start" (lines 43-61).
107+
For CEGIS synthesis examples, see `src/synthesis.jl` docstrings.
108+
For Axiom.jl integration roadmap, see `SMTLIB-AXIOM-PARITY-CHECKLIST.adoc`.

0 commit comments

Comments
 (0)