@@ -8896,7 +8896,22 @@ impl State {
88968896 && coin_value(self.coins()[coin_key].exponent)
88978897 + coin_value(self.entries()[entry_key].exponent)
88988898 == amount as nat,
8899- None => true,
8899+ None =>
8900+ // Sharp: no (coin, entry) pair satisfies the cover.
8901+ forall|i: int, k: int|
8902+ 0 <= i < self.coins@.len()
8903+ && 0 <= k < self.entries@.len()
8904+ ==> {
8905+ let c = #[trigger] self.coins@[i];
8906+ let e = #[trigger] self.entries@[k];
8907+ c.purse != p
8908+ || c.state != CoinState::Available
8909+ || e.purse != p
8910+ || e.on_chain != EntryOnChain::Ready
8911+ || e.local != EntryLocal::LocalAvailable
8912+ || (coin_value(c.exponent) + coin_value(e.exponent)
8913+ != amount as nat)
8914+ },
89008915 },
89018916 {
89028917 let nc = self.coins.len();
@@ -8908,6 +8923,21 @@ impl State {
89088923 nc == self.coins.len(),
89098924 ne == self.entries.len(),
89108925 self.invariant(),
8926+ // Outer accumulator: no (coin, entry) pair with coin index < i.
8927+ forall|i1: int, k: int|
8928+ 0 <= i1 < i as int
8929+ && 0 <= k < ne as int
8930+ ==> {
8931+ let c = #[trigger] self.coins@[i1];
8932+ let e = #[trigger] self.entries@[k];
8933+ c.purse != p
8934+ || c.state != CoinState::Available
8935+ || e.purse != p
8936+ || e.on_chain != EntryOnChain::Ready
8937+ || e.local != EntryLocal::LocalAvailable
8938+ || (coin_value(c.exponent) + coin_value(e.exponent)
8939+ != amount as nat)
8940+ },
89118941 decreases nc - i,
89128942 {
89138943 let ci_avail = matches!(self.coins[i].state, CoinState::Available);
@@ -8933,6 +8963,32 @@ impl State {
89338963 vi as nat == coin_value(self.coins@[i as int].exponent),
89348964 vi <= 1073741824u64,
89358965 vi <= amount,
8966+ // Outer accumulator carried.
8967+ forall|i1: int, kk: int|
8968+ 0 <= i1 < i as int
8969+ && 0 <= kk < ne as int
8970+ ==> {
8971+ let c = #[trigger] self.coins@[i1];
8972+ let e = #[trigger] self.entries@[kk];
8973+ c.purse != p
8974+ || c.state != CoinState::Available
8975+ || e.purse != p
8976+ || e.on_chain != EntryOnChain::Ready
8977+ || e.local != EntryLocal::LocalAvailable
8978+ || (coin_value(c.exponent) + coin_value(e.exponent)
8979+ != amount as nat)
8980+ },
8981+ // Inner accumulator: for all checked k2 < k,
8982+ // the pair (i, k2) doesn't satisfy.
8983+ forall|k2: int|
8984+ 0 <= k2 < k as int
8985+ ==>
8986+ (#[trigger] self.entries@[k2]).purse != p
8987+ || self.entries@[k2].on_chain != EntryOnChain::Ready
8988+ || self.entries@[k2].local != EntryLocal::LocalAvailable
8989+ || (coin_value(self.coins@[i as int].exponent)
8990+ + coin_value(self.entries@[k2].exponent)
8991+ != amount as nat),
89368992 decreases ne - k,
89378993 {
89388994 let e = &self.entries[k];
0 commit comments