Minesweeper — compute the neighbour-mine board from a mine layout mines is a flat row-major r×c list of 0/1
annotate() returns a board where each non-mine cell holds its count of adjacent mines (0..8) and each mine cell holds -1. reveal_safe() reports whether a click is safe. Run: soma run minesweeper.cell --signal demo Test: soma test minesweeper.cell
A Soma program from the games part of the verified corpus: 77 lines, cells Minesweeper, MinesweeperTests. It passes soma check with soma 3.2.4.
How it is built
The cell Minesweeper declares 4 signals in its face: count_adjacent(mines: List, r: Int, c: Int, y: Int, x: Int) -> Int, annotate(mines: List, r: Int, c: Int) -> List, is_safe(mines: List, c: Int, y: Int, x: Int) -> Bool and demo() -> List. Handlers: count_adjacent (line 20), annotate (line 36), is_safe (line 50) and demo (line 54).
The file also holds 1 test cell (MinesweeperTests) with 9 assertions, run by soma test.
The source
soma.toml
[package]
name = "games-corpus"
version = "0.1.0"
description = "Training corpus: games & simulations"
# The turn/phase machine is intentionally cyclic (a game loops through
# phases each round) with a `* -> over` escape, so we verify only that no
# reachable state deadlocks — liveness to a terminal is not the contract here.
[verify]
deadlock_free = trueminesweeper.cell
// ============================================================================
// Minesweeper — compute the neighbour-mine board from a mine layout
// ============================================================================
//
// mines is a flat row-major r×c list of 0/1. annotate() returns a board where
// each non-mine cell holds its count of adjacent mines (0..8) and each mine
// cell holds -1. reveal_safe() reports whether a click is safe.
//
// Run: soma run minesweeper.cell --signal demo
// Test: soma test minesweeper.cell
cell Minesweeper {
face {
signal count_adjacent(mines: List, r: Int, c: Int, y: Int, x: Int) -> Int
signal annotate(mines: List, r: Int, c: Int) -> List
signal is_safe(mines: List, c: Int, y: Int, x: Int) -> Bool
signal demo() -> List
}
on count_adjacent(mines: List, r: Int, c: Int, y: Int, x: Int) {
let n = 0
for dy in range(-1, 2) {
for dx in range(-1, 2) {
if dy != 0 || dx != 0 {
let ny = y + dy
let nx = x + dx
if ny >= 0 && ny < r && nx >= 0 && nx < c {
n = n + mines[ny * c + nx]
}
}
}
}
return n
}
on annotate(mines: List, r: Int, c: Int) {
let out = []
for y in range(0, r) {
for x in range(0, c) {
let v = -1
if mines[y * c + x] == 0 {
v = count_adjacent(mines, r, c, y, x)
}
out = push(out, v)
}
}
return out
}
on is_safe(mines: List, c: Int, y: Int, x: Int) {
return mines[y * c + x] == 0
}
on demo() {
// 3x3 with a single mine in the centre
return annotate([0,0,0, 0,1,0, 0,0,0], 3, 3)
}
}
cell test MinesweeperTests {
rules {
// single centre mine → every border cell counts 1, centre is -1
assert annotate([0,0,0, 0,1,0, 0,0,0], 3, 3)[0] == 1
assert annotate([0,0,0, 0,1,0, 0,0,0], 3, 3)[4] == -1
assert annotate([0,0,0, 0,1,0, 0,0,0], 3, 3)[1] == 1
// a corner mine touches exactly 3 cells
assert count_adjacent([1,0,0, 0,0,0, 0,0,0], 3, 3, 1, 1) == 1
assert annotate([1,0,0, 0,0,0, 0,0,0], 3, 3)[4] == 1
assert annotate([1,0,0, 0,0,0, 0,0,0], 3, 3)[8] == 0
// two adjacent mines
assert count_adjacent([1,1,0, 0,0,0, 0,0,0], 3, 3, 1, 0) == 2
// safety check
assert is_safe([0,0,0, 0,1,0, 0,0,0], 3, 1, 1) == false
assert is_safe([0,0,0, 0,1,0, 0,0,0], 3, 0, 0) == true
}
}What the toolchain says
$ soma check minesweeper.cell
✓ All checks passed.$ soma test minesweeper.cell
test MinesweeperTests ...
✓ assert annotate([0,0,0, 0,1,0, 0,0,0], 3, 3)[0] == 1
✓ assert annotate([0,0,0, 0,1,0, 0,0,0], 3, 3)[4] == -1
✓ assert annotate([0,0,0, 0,1,0, 0,0,0], 3, 3)[1] == 1
✓ assert count_adjacent([1,0,0, 0,0,0, 0,0,0], 3, 3, 1, 1) == 1
✓ assert annotate([1,0,0, 0,0,0, 0,0,0], 3, 3)[4] == 1
✓ assert annotate([1,0,0, 0,0,0, 0,0,0], 3, 3)[8] == 0
✓ assert count_adjacent([1,1,0, 0,0,0, 0,0,0], 3, 3, 1, 0) == 2
✓ assert is_safe([0,0,0, 0,1,0, 0,0,0], 3, 1, 1) == false
✓ assert is_safe([0,0,0, 0,1,0, 0,0,0], 3, 0, 0) == true
9 tests: 9 passed, 0 failed$ soma verify minesweeper.cell
Verifying minesweeper.cell...
No state machine in this program: nothing to prove beyond `soma check` (invariants and lifecycles are what verify proves).
VERIFY OK (vacuous — no state machine)