.mbt + .mbtp moonc prove Why3 + Z3
┌────────────┐ ┌──────────────┐ ┌──────────────┐
│ Source code │ ───► │ Generate │ ───► │ Prove goals │
│ + predicates│ │ WhyML (.mlw) │ │ via SMT │
└────────────┘ └──────────────┘ └──────────────┘predicate in_bounds(xs : FixedArray[Int], i : Int) {
(0 <= i) && (i < xs.length())
}
predicate sorted(xs : FixedArray[Int]) {
i : Int, j : Int,
((in_bounds(xs, i)) && (in_bounds(xs, j)) && (i <= j))
xs[i] <= xs[j]
}pub fn lower_bound(xs : FixedArray[Int], key : Int) -> Int {
proof_require: sorted(xs),
proof_ensure: result => lower_bound_ok(xs, key, result),
} {
for lo = 0, hi = xs.length(); lo < hi; {
let mid = lo + (hi - lo) / 2
if xs[mid] < key {
continue mid + 1, hi
} else {
continue lo, mid
}
} {
lo
} {
proof_invariant: 0 <= lo,
proof_invariant: lo <= hi,
proof_invariant: hi <= xs.length(),
proof_invariant: all_less_before(xs, key, lo),
proof_invariant: all_geq_from(xs, key, hi),
}
}| MoonBit | WhyML |
|---|---|
| FixedArray[Int] | array int |
| xs.length() | xs.length |
| xs[i] | xs[i] |
| && / \|\| | /\ / \/ |
| ∀ x : Int, | forall x : int. |
| → | -> |
| for loop | while loop with ref variables |
| loop invariants | invariant { ... } clauses |
| proof_require / proof_ensure | requires { ... } / ensures { ... } |
Z3 @ 0.2s, 1000 MB → quick wins
Z3 @ 1s, 1000 MB → moderate goals
compute_specified → unfold definitions
split_vc → break conjunction goals apart
Z3 @ 2s, 4000 MB → harder goalsmoon proveInstall
Download zip