Whole-known-network
<p><span class="h-card" translate="no"><a href="https://ublog.thirdlaw.net/users/sree" class="u-url mention">@<span>sree</span></a></span> <span class="h-card" translate="no"><a href="https://hachyderm.io/@unlambda" class="u-url mention">@<span>unlambda</span></a></span> <span class="h-card" translate="no"><a href="https://mastodon.social/@regehr" class="u-url mention">@<span>regehr</span></a></span> <span class="h-card" translate="no"><a href="https://types.pl/@lenary" class="u-url mention">@<span>lenary</span></a></span> so one tricky bit is that the loop count is "forever" and the state of the loop is the only state in the system</p>
@whitequark@mastodon.social @unlambda@hachyderm.io @regehr@mastodon.social @lenary@types.pl I don't know how the loops in your language work, but if you can feasibly enumerate all the states the loop will pass through (e.g. it is independent of the actual values in the vector and the length of the vector), then you won't need an inductive invariant.
If the loop count is dependent on the length of the vector, then you will need one, though you could usually run the equivalence check for some limited vector lengths.
But it's easy to start and check with direct SMT-LIB if it will work.
<p><span class="h-card" translate="no"><a href="https://mastodon.social/@whitequark" class="u-url mention">@<span>whitequark</span></a></span> <span class="h-card" translate="no"><a href="https://types.pl/@lenary" class="u-url mention">@<span>lenary</span></a></span> <span class="h-card" translate="no"><a href="https://hachyderm.io/@unlambda" class="u-url mention">@<span>unlambda</span></a></span> </p><p>so the best reference here is the Alive2 paper where we describe the refinement check in a lot of detail.</p><p>but let me take a stab...</p><p>an equivalence check is easy: you ask the solver whether there exists a valuation of the inputs that makes source and target behave differently.</p><p>then, the refinement check is basically asking the solver whether there exist inputs that cause target to have a behavior not seen in source. target can have fewer behaviors but not more.</p>
<p><span class="h-card" translate="no"><a href="https://ublog.thirdlaw.net/users/sree" class="u-url mention">@<span>sree</span></a></span> <span class="h-card" translate="no"><a href="https://hachyderm.io/@unlambda" class="u-url mention">@<span>unlambda</span></a></span> <span class="h-card" translate="no"><a href="https://mastodon.social/@regehr" class="u-url mention">@<span>regehr</span></a></span> <span class="h-card" translate="no"><a href="https://types.pl/@lenary" class="u-url mention">@<span>lenary</span></a></span> the way loops go is that i start with a base case (reset state) and for every possible input vector, output vector must be the same between two functions i'm considering</p><p>unrolling it won't work, i need induction if i'm to get anywhere, i think</p>
@whitequark@mastodon.social @unlambda@hachyderm.io @regehr@mastodon.social @lenary@types.pl Okay, that makes sense. Then if it's all bounded loops, unrolling and direct SMT-LIB is almost always good enough.
<p><span class="h-card" translate="no"><a href="https://ublog.thirdlaw.net/users/sree" class="u-url mention">@<span>sree</span></a></span> <span class="h-card" translate="no"><a href="https://hachyderm.io/@unlambda" class="u-url mention">@<span>unlambda</span></a></span> <span class="h-card" translate="no"><a href="https://mastodon.social/@regehr" class="u-url mention">@<span>regehr</span></a></span> <span class="h-card" translate="no"><a href="https://types.pl/@lenary" class="u-url mention">@<span>lenary</span></a></span> i do feel that my domain is an incredibly close match for `QF_BV` or `BV` which simplifies things a lot. i could lower my IR to SMT-LIB in one evening</p>
<p><span class="h-card" translate="no"><a href="https://mastodon.social/@regehr" class="u-url mention">@<span>regehr</span></a></span> <span class="h-card" translate="no"><a href="https://types.pl/@lenary" class="u-url mention">@<span>lenary</span></a></span> <span class="h-card" translate="no"><a href="https://hachyderm.io/@unlambda" class="u-url mention">@<span>unlambda</span></a></span> yeah i'm totally expecting that</p><p>can you tell me more about quantifiers? i feel like i don't understand most of the the nuances</p>
<p><span class="h-card" translate="no"><a href="https://mastodon.social/@regehr" class="u-url mention">@<span>regehr</span></a></span> <span class="h-card" translate="no"><a href="https://types.pl/@lenary" class="u-url mention">@<span>lenary</span></a></span> <span class="h-card" translate="no"><a href="https://hachyderm.io/@unlambda" class="u-url mention">@<span>unlambda</span></a></span> </p><p>ok so the problem I'm solving is: suppose you have inputs i, outputs o, states s and s', and combinational boolean functions f, f'</p><p>given relation s',o = f(s,i), rewrite f to smaller f'</p><p>so `forall s,i; f(s,i) == f'(s,i)` is easy but once you no longer require s/s' to match between the functions, just the observable behavior for evolution from the base case and identical `i`, it gets way harder</p>
@regehr@mastodon.social @whitequark@mastodon.social @lenary@types.pl @unlambda@hachyderm.io As an alternative, although we also use CVC5/Z3 directly in our compiler verification efforts, I've always wanted to move towards using a verification IL like Why3 instead of directly using a SMT solver. Boogie used to be very popular, and I think it's being developed again, and I've always felt you could save time with a verification language.