Verify all ``assert_refined`` calls in *fn* hold given its refinements. 1. Inspect *fn*'s type annotations → create ``defop(int)`` per param + preconditions from ``Gt`` / ``Ge`` metadata. 2. Execute *fn* symbolically → collect VC ``Term``s from ``assert_refined``. 3. Convert each
(fn, lib, kernel)
| 181 | |
| 182 | |
| 183 | def verify_function(fn, lib, kernel) -> list[VerificationResult]: |
| 184 | """Verify all ``assert_refined`` calls in *fn* hold given its refinements. |
| 185 | |
| 186 | 1. Inspect *fn*'s type annotations → create ``defop(int)`` per param + |
| 187 | preconditions from ``Gt`` / ``Ge`` metadata. |
| 188 | 2. Execute *fn* symbolically → collect VC ``Term``s from ``assert_refined``. |
| 189 | 3. Convert each VC to a ``Lean.Expr`` tree and a display string. |
| 190 | 4. Send Expr to Lean (``goalFromExpr`` + ``intros; omega``). |
| 191 | """ |
| 192 | hints = get_type_hints(fn, include_extras=True) |
| 193 | params = inspect.signature(fn).parameters |
| 194 | |
| 195 | # Create symbolic vars and extract preconditions. |
| 196 | var_ops: dict[str, Operation] = {} |
| 197 | var_names: list[str] = [] |
| 198 | precond_terms = [] |
| 199 | |
| 200 | for name in params: |
| 201 | var_op = defop(int, name=name) |
| 202 | var_ops[name] = var_op |
| 203 | var_names.append(name) |
| 204 | |
| 205 | annotation = hints.get(name) |
| 206 | if hasattr(annotation, "__metadata__"): |
| 207 | for meta in annotation.__metadata__: |
| 208 | if isinstance(meta, Gt): |
| 209 | precond_terms.append(var_op() > meta.n) |
| 210 | elif isinstance(meta, Ge): |
| 211 | precond_terms.append(var_op() >= meta.n) |
| 212 | |
| 213 | # Execute symbolically and collect VCs. |
| 214 | vc_terms: list = [] |
| 215 | |
| 216 | def _handle_assert(value, refinement): |
| 217 | if isinstance(refinement, Gt): |
| 218 | vc_terms.append(value > refinement.n) |
| 219 | elif isinstance(refinement, Ge): |
| 220 | vc_terms.append(value >= refinement.n) |
| 221 | |
| 222 | with handler({assert_refined: _handle_assert}): |
| 223 | fn(**{name: var_ops[name]() for name in params}) |
| 224 | |
| 225 | # Convert each VC to Lean.Expr + description string, then verify. |
| 226 | eb = ExprBuilder(lib) |
| 227 | results: list[VerificationResult] = [] |
| 228 | for vc_term in vc_terms: |
| 229 | desc = _build_lean_str(vc_term, var_names, var_ops, precond_terms) |
| 230 | lean_expr = _build_vc_expr(eb, vc_term, var_names, var_ops, precond_terms) |
| 231 | ok = _verify_expr(lib, kernel, lean_expr) |
| 232 | results.append(VerificationResult(desc, ok)) |
| 233 | |
| 234 | return results |
| 235 | |
| 236 | |
| 237 | # --------------------------------------------------------------------------- |
no test coverage detected