soma.cell

Leaderboard API: submit a score, get the ranked top-N

Keeps the best score per player and returns a sorted slice.

A Soma program from the web part of the verified corpus: 86 lines, cells Leaderboard, LeaderboardTest. It passes soma check with soma 3.2.4.

How it is built

The cell Leaderboard declares 4 signals in its face: request(method: String, path: String, body: String) -> Map, submit(player: String, score: Int) -> Map, leaders(n: Int) -> List and rank(player: String) -> Int; keeps 1 memory slot: scores (Map<String, Int>, persistent and consistent). Handlers: submit (line 17), leaders (line 31), rank (line 42) and request (line 53). Private helpers: _ranked.

The file also holds 1 test cell (LeaderboardTest) with 4 assertions, run by soma test.

Generated from soma describe on this file.

The source

soma.toml

[package]
name = "web-corpus"
version = "0.1.0"
entry = "todo_state.cell"

[verify]
cells = ["TodoService"]
deadlock_free = true
eventually = ["Done", "Cancelled"]

leaderboard.cell

// Leaderboard API: submit a score, get the ranked top-N. Keeps the best
// score per player and returns a sorted slice.

cell Leaderboard {
    face {
        signal request(method: String, path: String, body: String) -> Map
        signal submit(player: String, score: Int) -> Map
        signal leaders(n: Int) -> List
        signal rank(player: String) -> Int
        promise all_persistent
    }

    memory {
        scores: Map<String, Int> [persistent, consistent]
    }

    on submit(player: String, score: Int) {
        let best = scores.get(player)
        if best == () || score > best { scores.set(player, score) }
        return map("player", player, "best", scores.get(player))
    }

    on _ranked() {
        let rows = list()
        for p in scores.keys {
            rows = push(rows, map("player", p, "score", scores.get(p)))
        }
        return rows |> sort_by("score", "desc")
    }

    on leaders(n: Int) {
        let r = _ranked()
        let out = list()
        let i = 0
        while i < n && i < len(r) {
            out = push(out, r[i])
            i = i + 1
        }
        return out
    }

    on rank(player: String) {
        let r = _ranked()
        let i = 0
        let found = 0
        while i < len(r) {
            if r[i].player == player { found = i + 1 }
            i = i + 1
        }
        return found
    }

    on request(method: String, path: String, body: String) {
        let req = map("method", method, "path", path)
        match req {
            {method: "POST", path: "/scores"}    -> {
                let d = from_json(body)
                submit(d.player, d.score)
            }
            {method: "GET",  path: "/top/" + n}  -> leaders(to_int(n))
            _                                    -> response(404, map("error", "no route"))
        }
    }
}

cell test LeaderboardTest {
    rules {
        assert submit("ada", 50).best == 50
        assert submit("ada", 30).best == 50
        assert submit("ada", 80).best == 80
        // self-contained ordering check
        assert _board() == "ada:80,bob:60,cy:40"
    }

    on _board() {
        submit("ada", 80)
        submit("bob", 60)
        submit("cy", 40)
        let parts = list()
        for row in leaders(3) {
            parts = push(parts, concat(row.player, concat(":", to_string(row.score))))
        }
        return parts |> join(",")
    }
}

What the toolchain says

Run on a fresh copy of the program at build time; the outputs are pasted unedited.

$ soma check leaderboard.cell
✓ All checks passed.
$ soma test leaderboard.cell
test LeaderboardTest ...
  ✓ assert submit("ada", 50).best == 50
  ✓ assert submit("ada", 30).best == 50
  ✓ assert submit("ada", 80).best == 80
  ✓ assert _board() == "ada:80,bob:60,cy:40"

4 tests: 4 passed, 0 failed
$ soma verify leaderboard.cell
Verifying leaderboard.cell...
note: soma.toml [verify] cells names 'TodoService', which this file does not define — its properties are not checked here

Leaderboard/termination:

  ⚠ handler `leaders`: while-loop without provable termination bound (write `while [loop_bound(N)] cond { … }`, or a for-loop over a bounded range)
  ⚠ handler `rank`: while-loop without provable termination bound (write `while [loop_bound(N)] cond { … }`, or a for-loop over a bounded range)
  ⚠ `request` calls `Leaderboard.leaders`, which may not terminate

0 passed, 3 warnings, 0 failures
soma.toml: 1 user-defined properties loaded — NONE applies to this file ([verify] cells = ["TodoService"] names no cell of it)
Temporal: 0 passed, 0 failed
VERIFY OK

Builtins used

concat, from_json, join, len, list, map, push, response, sort_by, to_int, to_string

Source file: /corpus/web/leaderboard.cell · examples/corpus/web/leaderboard.cell