Closed stevana closed 4 years ago
The short answer is that models aren't supposed to throw; you should return a (model/inconsistent ...) when asked to perform an inconsistent state transition.
The deeper answer is that Knossos performs some optimization techniques to try and make traversal of the search space more efficient, and one of those techniques is speculatively exploring all possible states and transitions between them (up to some limit), and condensing those states into a compact pointer graph. It's significantly friendlier to cache, since we re-use the same immutable objects constantly rather than constructing new ones, and means we don't actually have to call step
at all during the search process; all your arbitrary step logic essentially gets compiled into an in-memory DAG between enumerated states.
Thanks for the explanation!
I'm confused about why
checker/linearizable
callsstep
in models that are not in the set of valid models produced by applyingreduce step model
to the set of prefixes of the history.Here's an example:
The first test using
reduce
succeeds as expected, but the second usinglinarizable
fails with the errorjava.lang.AssertionError: Assert failed: also never happens
.I don't see why
step (TurnstileModel. :locked) {:f :push}
is ever called, given that there is no prefix of the history in which we would end up in that state?