Remix.run Logo
wren6991 9 hours ago

Z3 struggles with larger problems. CVC5 or Bitwuzla do a lot better once you get into anything complex.

If you're familiar with the Z3 Python API, you'll find the CVC5 one familiar.

Caveat: I mostly do logic design, maybe there are some software verification tasks where Z3 comes out ahead. I've never seen one though.

neel_k 7 hours ago | parent | next [-]

I do software verification. In my experience, Z3 is consistently but noticeably better than CVC5 at the kinds of problems we generate, though the two tools are close enough that you definitely want to architect your verification tool to be able to use either one (or both at once, in case you hit a problem which is pathological in one but not the other).

One place where Z3 exposes a superior interface to CVC5 is when you want to do term simplification. CVC5 does not have any real analogue to Z3's simplification tactics (like ctx-solver-simplify), so if you want to take a term and simplify it with respect to a set of assumptions, Z3 is your only choice. I think CVC5 has all the machinery you need to implement that stuff inside of it, but as a user you can't access it.

The place where CVC5 really pulls ahead of Z3 is when you want to produce proofs (eg, to integrate SMT solving into a proof assistant like Lean, HOL, or Rocq). Both tools have support for generating proofs, but CVC5's are noticeably less buggy, to the point that Lean's SMT integration uses CVC5, even though Leo de Moura (Lean's designer) was also the original designer of Z3.

humam_alhusaini 11 minutes ago | parent | prev | next [-]

I'm curious as to why Z3 is so much more popular than CVC5 if CVC5 is better for solving complex problems. Is it because Z3 is older?

y1n0 3 hours ago | parent | prev | next [-]

That’s interesting. I’m a logic designer too. How do you make use of it?

wren6991 2 hours ago | parent [-]

One of two cases: pushing Verilog through yosys-smtbmc to check design assertions/properties, or writing a lil Python model of some optimisation trick and checking it's equivalent to a more direct implementation.

For the former it's useful when there's already a well-defined contract at some interface, like "this bus interface follows these basic AHB5 manager rules" or "if x_valid is asserted, it remains asserted until x_ready is asserted, and the other x_foobar are stable during that time" or "a FIFO is never both empty and full".

Simple properties + exhaustive checking is good bang-for-buck because it often teases out subtle tangential issues without having to write checks for implementation details. This isn't "formal verification" per se but using formal checks in a lightweight way to help find bugs and inconsistencies in your design.

algo_trader 6 hours ago | parent | prev [-]

What would u recommend for freight/trucking optimiser? not real time.

(scaling to 100s-1000s of units)