773 . a machine-check result
884 . a certificate binding the spec, code, and proof bundle together
99
10- This guide covers the shortest path from install to a verified run.
10+ This guide covers the shortest path from install to a verified run, then
11+ walks through a complete example verifying a sorting function.
1112
1213## Install
1314
@@ -59,6 +60,167 @@ export DEEPSEEK_API_KEY=...
5960If you do not pass a provider explicitly in Python, the top-level ` verify() `
6061path defaults to the Anthropic provider.
6162
63+ ## Walkthrough: Verifying a Sorting Function
64+
65+ This section walks through verifying a sorting function end-to-end, from
66+ writing the spec to inspecting the proof certificate.
67+
68+ ### Step 1: Write the specification
69+
70+ Create a file called ` sort_spec.yaml ` :
71+
72+ ``` yaml
73+ description : >
74+ Sort a list of integers in non-decreasing order.
75+ The output must be a permutation of the input.
76+ The function must handle empty lists and single-element lists.
77+ function_name : sort
78+ input_types :
79+ lst : list[int]
80+ output_type : list[int]
81+ preconditions : []
82+ postconditions :
83+ - " is_sorted(result)"
84+ - " is_permutation(result, lst)"
85+ edge_cases :
86+ - " lst == []"
87+ - " len(lst) == 1"
88+ ` ` `
89+
90+ The specification tells ` vericode` exactly what the function must satisfy.
91+ Postconditions are the properties the formal proof will encode.
92+
93+ # ## Step 2: Run verification from the CLI
94+
95+ ` ` ` bash
96+ vericode verify --spec sort_spec.yaml --lang python --backend lean4
97+ ` ` `
98+
99+ `vericode` will :
100+
101+ 1. Parse the YAML spec into a structured `Spec` object.
102+ 2. Send the spec to the LLM, which generates both a Python implementation and
103+ a Lean 4 proof in a single pass.
104+ 3. Compile the proof with the Lean 4 toolchain.
105+ 4. If the proof fails, feed the compiler errors back to the LLM for refinement.
106+ 5. Repeat up to `--max-iterations` times (default 5).
107+
108+ On success you will see output like :
109+
110+ ` ` `
111+ vericode
112+ Function: sort
113+ Language: python
114+ Backend: lean4
115+ Provider: anthropic
116+
117+ Verification successful!
118+ Iterations: 2
119+
120+ Implementation
121+ def sort(lst: list[int]) -> list[int]:
122+ ...
123+
124+ Proof
125+ theorem sort_correct :
126+ ...
127+
128+ Proof Receipt
129+ {
130+ "spec_hash": "a1b2c3...",
131+ "code_hash": "d4e5f6...",
132+ "proof_hash": "789abc...",
133+ "backend": "lean4",
134+ "timestamp": "2026-03-30T12:00:00+00:00",
135+ "verified": true
136+ }
137+ ` ` `
138+
139+ # ## Step 3: Run the same verification from Python
140+
141+ ` ` ` python
142+ import asyncio
143+ from vericode import Spec, verify
144+
145+
146+ async def main() -> None:
147+ spec = Spec(
148+ description=(
149+ "Sort a list of integers in non-decreasing order. "
150+ "The output must be a permutation of the input."
151+ ),
152+ function_name="sort",
153+ input_types={"lst": "list[int]"},
154+ output_type="list[int]",
155+ postconditions=[
156+ "is_sorted(result)",
157+ "is_permutation(result, lst)",
158+ ],
159+ edge_cases=["lst == []", "len(lst) == 1"],
160+ )
161+
162+ result = await verify(
163+ spec,
164+ language="python",
165+ backend="lean4",
166+ )
167+
168+ print(f"Verified: {result.verified}")
169+ print(f"Iterations: {result.iterations}")
170+
171+ if result.verified:
172+ print(f"\n --- Implementation ---\n {result.code}")
173+ print(f"\n --- Proof ---\n {result.proof}")
174+ print(f"\n --- Certificate ---\n {result.certificate.to_json()}")
175+ else:
176+ for err in result.errors:
177+ print(f"Error: {err}")
178+
179+
180+ asyncio.run(main())
181+ ` ` `
182+
183+ # ## Step 4: Check the complexity score
184+
185+ Before running verification, you can estimate how hard the spec is to verify
186+ using `complexity_score()` :
187+
188+ ` ` ` python
189+ score = spec.complexity_score()
190+ print(f"Complexity: {score:.2f}")
191+ # A score above 0.5 suggests the spec may need more refinement iterations.
192+ ` ` `
193+
194+ # ## Step 5: Inspect the proof certificate
195+
196+ The certificate binds the spec, implementation, and proof together via SHA-256
197+ hashes. You can re-verify it later :
198+
199+ ` ` ` python
200+ from vericode.verifier import ProofCertificate
201+
202+ valid = ProofCertificate.verify_certificate(
203+ result.certificate,
204+ spec,
205+ result.code,
206+ result.proof,
207+ )
208+ print(f"Certificate valid: {valid}")
209+ ` ` `
210+
211+ If anyone changes the code or the spec after verification, the certificate will
212+ no longer validate.
213+
214+ # ## Step 6: Verify existing code with `prove`
215+
216+ If you already have an implementation and just want a proof :
217+
218+ ` ` ` bash
219+ vericode prove --code sort.py --spec "output is sorted and is a permutation of input"
220+ ` ` `
221+
222+ This tells the LLM to keep the implementation fixed and only generate a proof.
223+
62224# # Fastest CLI Path
63225
64226Verify a natural-language prompt :
@@ -85,6 +247,12 @@ Batch a directory of YAML specs:
85247vericode batch --specs specs/ --output verified/
86248` ` `
87249
250+ Batch with a progress bar :
251+
252+ ` ` ` bash
253+ vericode batch --specs specs/ --output verified/ --progress
254+ ` ` `
255+
88256` batch` defaults the implementation language from the backend unless `--lang`
89257is supplied :
90258
@@ -168,13 +336,31 @@ postconditions:
168336- `code` : generated or preserved implementation
169337- `proof` : backend-specific proof text
170338- `verified` : final machine-check status
171- - `iterations` : refinement rounds taken by the proof engine
339+ - `iterations` : refinement rounds taken by the proof engine (0 if cached)
172340- `backend` : backend name used for the run
173341- `certificate` : ` ProofCertificate` binding the spec, code, and proof bundle
174342
175343The certificate is designed to be machine-checkable later; it stores hashes of
176344the canonicalized spec, implementation, and bound proof source.
177345
346+ # # Verification Cache
347+
348+ Successful verification results are cached by default, keyed by a SHA-256 hash
349+ of the spec, backend, and provider. Subsequent runs with identical inputs skip
350+ the LLM and proof-assistant pipeline entirely.
351+
352+ To bypass the cache :
353+
354+ ` ` ` bash
355+ vericode verify "sort a list" --no-cache
356+ ` ` `
357+
358+ Or in Python :
359+
360+ ` ` ` python
361+ result = await verify(spec, backend="lean4", use_cache=False)
362+ ` ` `
363+
178364# # `verify` vs `prove`
179365
180366- ` verify` starts from a natural-language or YAML spec and asks the model to
0 commit comments