|
| 1 | +/- |
| 2 | +Copyright (c) 2025 ArkLib Contributors. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Quang Dao |
| 5 | +-/ |
| 6 | + |
| 7 | +import Mathlib.Data.Set.Defs |
| 8 | + |
| 9 | +/-! |
| 10 | +# Universal constraint system abstraction |
| 11 | +
|
| 12 | +This file introduces a small theory of constraint systems that provides a uniform interface |
| 13 | +for the various concrete systems used across ArkLib (R1CS, Plonkish, lookups, memory |
| 14 | +checking, AIR, CCS, and DSL-level systems such as Clean's `FormalCircuit`). |
| 15 | +
|
| 16 | +The goals are: |
| 17 | +
|
| 18 | +1. **Unify**: capture the common shape `(index, statement, oracle statement, witness, |
| 19 | + satisfies)` so that protocols and compilers can be written once and instantiated for any |
| 20 | + concrete CS. |
| 21 | +2. **Compose**: introduce morphisms `ConstraintSystem.Hom` that transport satisfiability |
| 22 | + along index/statement/witness maps, modelling reductions between constraint systems |
| 23 | + (e.g. Clean gadget → R1CS row block, Plonkish → CCS, Plain R1CS → padded R1CS). |
| 24 | +3. **Extend with behaviour**: add a `BehavioralContract` layer that pairs a CS with |
| 25 | + user-facing I/O contracts (assumptions + spec), in the style of Clean's `FormalCircuit`. |
| 26 | +
|
| 27 | +## Design notes |
| 28 | +
|
| 29 | +- The structure is **indexed**: a single `ConstraintSystem` value packages an entire family |
| 30 | + of concrete relations (one per `Index`), so that, e.g., R1CS of every size is a single |
| 31 | + constraint system rather than one per `(m, n, n_w)`. |
| 32 | +- The statement is split into an **in-the-clear** part (`Stmt`) and a **committed/oracle** |
| 33 | + part (`OStmt`). Use `fun _ => PUnit` for `OStmt` if the system is purely non-oracle. If |
| 34 | + multiple oracle slots are needed (as in R1CS with three matrices), bundle them via a |
| 35 | + dependent function type inside `OStmt`. |
| 36 | +- `satisfies` is a `Prop`, not a `Set`, for ergonomic use inside proofs and reductions. |
| 37 | +- Morphisms are one-way (completeness-preserving). Soundness-reflecting variants |
| 38 | + (extractors, embeddings, isos) are future work. |
| 39 | +-/ |
| 40 | + |
| 41 | +universe u v w |
| 42 | + |
| 43 | +/-- A **constraint system** packages a family of indexed relations into a single bundle. |
| 44 | +
|
| 45 | +For each `i : Index` there is a `Stmt i` (the in-the-clear statement), an `OStmt i` (the |
| 46 | +committed/oracle-accessible statement data; use `PUnit` if absent), and a `Wit i` (the |
| 47 | +private witness). The predicate `satisfies i s o w` asserts that the triple `(s, o, w)` is |
| 48 | +a valid instance at index `i`. -/ |
| 49 | +structure ConstraintSystem : Type (max (u + 1) (v + 1) (w + 1)) where |
| 50 | + /-- Index type parametrising the family of relations (sizes, shape parameters, etc.). -/ |
| 51 | + Index : Type u |
| 52 | + /-- In-the-clear part of the statement at each index. -/ |
| 53 | + Stmt : Index → Type v |
| 54 | + /-- Committed/oracle-accessible part of the statement. Use `fun _ => PUnit` for a |
| 55 | + purely non-oracle constraint system. Multiple oracle slots can be bundled via a |
| 56 | + dependent function type (e.g. `MatrixIdx → Matrix _ _ R` for R1CS). -/ |
| 57 | + OStmt : Index → Type v |
| 58 | + /-- Private witness. -/ |
| 59 | + Wit : Index → Type w |
| 60 | + /-- The satisfiability predicate at each index. -/ |
| 61 | + satisfies : (i : Index) → Stmt i → OStmt i → Wit i → Prop |
| 62 | + |
| 63 | +namespace ConstraintSystem |
| 64 | + |
| 65 | +variable (C : ConstraintSystem.{u, v, w}) |
| 66 | + |
| 67 | +/-- The underlying set-theoretic relation at a given index. -/ |
| 68 | +def relation (i : C.Index) : Set (C.Stmt i × C.OStmt i × C.Wit i) := |
| 69 | + { t | C.satisfies i t.1 t.2.1 t.2.2 } |
| 70 | + |
| 71 | +/-- Existence of valid oracle data and witness for a given in-the-clear statement. -/ |
| 72 | +def IsSatisfiable (i : C.Index) (s : C.Stmt i) : Prop := |
| 73 | + ∃ o w, C.satisfies i s o w |
| 74 | + |
| 75 | +/-- Build a constraint system from a plain indexed relation (no oracle statement slot). -/ |
| 76 | +def ofRelation |
| 77 | + {Idx : Type u} {S : Idx → Type v} {W : Idx → Type w} |
| 78 | + (rel : (i : Idx) → S i → W i → Prop) : ConstraintSystem.{u, v, w} where |
| 79 | + Index := Idx |
| 80 | + Stmt := S |
| 81 | + OStmt := fun _ => PUnit |
| 82 | + Wit := W |
| 83 | + satisfies := fun i s _ w => rel i s w |
| 84 | + |
| 85 | +/-- Build a witness-free constraint system (assertions purely over the public and oracle |
| 86 | +parts of the statement). -/ |
| 87 | +def ofWitnessFree |
| 88 | + {Idx : Type u} {S O : Idx → Type v} |
| 89 | + (rel : (i : Idx) → S i → O i → Prop) : ConstraintSystem.{u, v, 0} where |
| 90 | + Index := Idx |
| 91 | + Stmt := S |
| 92 | + OStmt := O |
| 93 | + Wit := fun _ => PUnit |
| 94 | + satisfies := fun i s o _ => rel i s o |
| 95 | + |
| 96 | +end ConstraintSystem |
| 97 | + |
| 98 | +/-! |
| 99 | +## Morphisms between constraint systems |
| 100 | +
|
| 101 | +A `ConstraintSystem.Hom` transports valid instances of one constraint system to valid |
| 102 | +instances of another. It consists of: |
| 103 | +
|
| 104 | +- `index` — a map of shape indices (e.g. scale the size of an R1CS instance); |
| 105 | +- `stmt`, `oStmt`, `wit` — compatible maps of statement, oracle-statement, and witness |
| 106 | + data that in general may depend on the input in-the-clear statement; |
| 107 | +- `preserves` — the core axiom that maps satisfying triples to satisfying triples. |
| 108 | +
|
| 109 | +Intuitively, `Hom C D` is a *completeness-preserving* reduction from `C` to `D`: if you can |
| 110 | +satisfy `C` at some index, you can satisfy `D` at the image index, with an explicit |
| 111 | +construction of the needed data. Soundness-reflecting morphisms (with extractors) are a |
| 112 | +strict strengthening and are future work. |
| 113 | +
|
| 114 | +The name `Hom` follows Mathlib convention (`RelHom`, `RingHom`, `LinearMap`). A future |
| 115 | +extension can add `ConstraintSystem.Hom.Embedding` or `ConstraintSystem.Iso` without |
| 116 | +renaming anything. |
| 117 | +-/ |
| 118 | + |
| 119 | +namespace ConstraintSystem |
| 120 | + |
| 121 | +/-- A completeness-preserving morphism between constraint systems. -/ |
| 122 | +@[ext] |
| 123 | +structure Hom (C D : ConstraintSystem.{u, v, w}) where |
| 124 | + /-- Map on index types. -/ |
| 125 | + index : C.Index → D.Index |
| 126 | + /-- Map on in-the-clear statements. -/ |
| 127 | + stmt : (i : C.Index) → C.Stmt i → D.Stmt (index i) |
| 128 | + /-- Map on oracle/committed statement data. It may depend on the in-the-clear statement |
| 129 | + as well, which is needed e.g. when the index encodes a global shape and the statement |
| 130 | + fixes public inputs before committed data is computed. -/ |
| 131 | + oStmt : (i : C.Index) → (s : C.Stmt i) → C.OStmt i → D.OStmt (index i) |
| 132 | + /-- Map on witnesses, likewise allowed to depend on the input statement. -/ |
| 133 | + wit : (i : C.Index) → (s : C.Stmt i) → C.Wit i → D.Wit (index i) |
| 134 | + /-- Preservation property: valid instances map to valid instances. -/ |
| 135 | + preserves : ∀ i s o w, |
| 136 | + C.satisfies i s o w → D.satisfies (index i) (stmt i s) (oStmt i s o) (wit i s w) |
| 137 | + |
| 138 | +namespace Hom |
| 139 | + |
| 140 | +/-- The identity morphism on a constraint system. -/ |
| 141 | +def id (C : ConstraintSystem.{u, v, w}) : Hom C C where |
| 142 | + index := _root_.id |
| 143 | + stmt := fun _ => _root_.id |
| 144 | + oStmt := fun _ _ => _root_.id |
| 145 | + wit := fun _ _ => _root_.id |
| 146 | + preserves := fun _ _ _ _ h => h |
| 147 | + |
| 148 | +/-- Composition of two morphisms. Reads right-to-left as usual. -/ |
| 149 | +def comp {C D E : ConstraintSystem.{u, v, w}} (g : Hom D E) (f : Hom C D) : Hom C E where |
| 150 | + index := g.index ∘ f.index |
| 151 | + stmt := fun i s => g.stmt (f.index i) (f.stmt i s) |
| 152 | + oStmt := fun i s o => g.oStmt (f.index i) (f.stmt i s) (f.oStmt i s o) |
| 153 | + wit := fun i s w => g.wit (f.index i) (f.stmt i s) (f.wit i s w) |
| 154 | + preserves := fun i s o w h => |
| 155 | + g.preserves (f.index i) (f.stmt i s) (f.oStmt i s o) (f.wit i s w) (f.preserves i s o w h) |
| 156 | + |
| 157 | +variable {C D E F : ConstraintSystem.{u, v, w}} |
| 158 | + |
| 159 | +@[simp] theorem id_comp (f : Hom C D) : (id D).comp f = f := rfl |
| 160 | + |
| 161 | +@[simp] theorem comp_id (f : Hom C D) : f.comp (id C) = f := rfl |
| 162 | + |
| 163 | +theorem comp_assoc (h : Hom E F) (g : Hom D E) (f : Hom C D) : |
| 164 | + (h.comp g).comp f = h.comp (g.comp f) := rfl |
| 165 | + |
| 166 | +end Hom |
| 167 | + |
| 168 | +/-- Morphisms preserve satisfiability. -/ |
| 169 | +theorem Hom.isSatisfiable_map {C D : ConstraintSystem.{u, v, w}} (f : Hom C D) |
| 170 | + {i : C.Index} {s : C.Stmt i} (hs : C.IsSatisfiable i s) : |
| 171 | + D.IsSatisfiable (f.index i) (f.stmt i s) := by |
| 172 | + obtain ⟨o, w, h⟩ := hs |
| 173 | + exact ⟨f.oStmt i s o, f.wit i s w, f.preserves i s o w h⟩ |
| 174 | + |
| 175 | +end ConstraintSystem |
| 176 | + |
| 177 | +/-! |
| 178 | +## Behavioural contracts |
| 179 | +
|
| 180 | +In DSL-level systems like Clean, a circuit is bundled with a user-facing contract: |
| 181 | +preconditions (`Assumptions`) on the statement and a high-level specification (`Spec`) |
| 182 | +relating statement and witness. A `BehavioralContract` lifts this pattern onto an |
| 183 | +arbitrary constraint system: at a fixed index, one provides such a contract together with |
| 184 | +proofs that the underlying constraints *imply* the spec under the assumptions (soundness |
| 185 | +of the gadget) and that a satisfying witness *exists* under the assumptions (completeness). |
| 186 | +
|
| 187 | +This gives us a clean target for migrating Clean's `FormalCircuit` into ArkLib without a |
| 188 | +Clean-specific protocol bridge. |
| 189 | +-/ |
| 190 | + |
| 191 | +namespace ConstraintSystem |
| 192 | + |
| 193 | +/-- A behavioural contract for a constraint system at a fixed index, consisting of an |
| 194 | +`Assumptions` precondition on the in-the-clear statement and a `Spec` postcondition |
| 195 | +relating statement and witness, together with soundness and completeness proofs tying the |
| 196 | +contract to the underlying satisfiability relation. -/ |
| 197 | +structure BehavioralContract (C : ConstraintSystem.{u, v, w}) (i : C.Index) where |
| 198 | + /-- Precondition on the in-the-clear statement under which the contract applies. -/ |
| 199 | + Assumptions : C.Stmt i → Prop |
| 200 | + /-- High-level specification relating the in-the-clear statement and the witness. -/ |
| 201 | + Spec : C.Stmt i → C.Wit i → Prop |
| 202 | + /-- Soundness: if the assumptions hold and the underlying constraints are satisfied, |
| 203 | + the spec holds for the recovered witness. -/ |
| 204 | + soundness : ∀ s o w, Assumptions s → C.satisfies i s o w → Spec s w |
| 205 | + /-- Completeness: if the assumptions hold, there exist oracle and witness data making |
| 206 | + the underlying constraints satisfied *and* the spec true. -/ |
| 207 | + completeness : ∀ s, Assumptions s → ∃ o w, C.satisfies i s o w ∧ Spec s w |
| 208 | + |
| 209 | +namespace BehavioralContract |
| 210 | + |
| 211 | +variable {C : ConstraintSystem.{u, v, w}} {i : C.Index} (B : BehavioralContract C i) |
| 212 | + |
| 213 | +/-- Under the assumptions, the constraint system is satisfiable at `i` for every statement. |
| 214 | +This is the most immediately useful corollary of `completeness`. -/ |
| 215 | +theorem isSatisfiable_of_assumptions {s : C.Stmt i} (hs : B.Assumptions s) : |
| 216 | + C.IsSatisfiable i s := by |
| 217 | + obtain ⟨o, w, hsat, _⟩ := B.completeness s hs |
| 218 | + exact ⟨o, w, hsat⟩ |
| 219 | + |
| 220 | +end BehavioralContract |
| 221 | + |
| 222 | +end ConstraintSystem |
0 commit comments