Skip to content

quint-refinementsYour code does what your Quint model says.

Write the model and the implementation. Everything between them is generated, and every guard and state change is checked against what the code actually did.

my-check
$ npx quint-refinements new my-check
created my-check
$ cd my-check && cargo run
✓ counter.incrementRun refined 1 obligations

# edit model.qnt, then
$ npx quint-refinements compile
$ cargo run
✗ bank.withdrawRun:withdraw next:
  assign state diverged at state.balance
  expected Int(6), observed Int(14)

From model to verdict ​

You own two files. The compiler owns the two between them.

1

Write the model

Ordinary Quint. Mark the runs your code must follow with /// @conformance.

2

Compile

quint-refinements compile writes the scenario file and a Rust trait with one method per action.

3

Implement and run

Implement the trait for your real type. cargo run passes, or prints the exact divergence.

quint
module bank {
  type BankState = { balance: int }

  var state: BankState

  action init = all {
    state' = { balance: 10 },
  }

  action withdraw(amount) = all {
    amount > 0,
    state.balance >= amount,
    state' = { balance: state.balance - amount },
  }

  /// @conformance
  run withdrawRun = init
    .then(withdraw(4))
    .then(all {
      assert(state.balance == 6),
      state' = state,
    })
}
rust
impl Implementation for Bank {
    type Evidence = Snapshot;

    fn from_initial_state(initial_state: &RuntimeValue) -> Result<Self, String> { /* ... */ }
    fn snapshot(&self) -> Snapshot { /* ... */ }

    // Generated from `action withdraw(amount)`. The scenario supplies the 4.
    fn withdraw(&mut self, arguments: &[RuntimeValue]) -> Result<(), String> {
        let [RuntimeValue::Int(amount)] = arguments else {
            return Err(format!("withdraw expects one integer: {arguments:?}"));
        };
        self.withdraw(*amount)
    }
}
text
bank.withdrawRun refined 3 obligations; final balance 6
text
bank.withdrawRun:withdraw next: assign state diverged at state.balance expected Int(6), observed Int(14)

Released under the MIT License.