Number to words — spell out integers 0..999
Composes English number words from ones/teens/tens tables. Demonstrates list-literal lookup tables indexed by digit, integer division with floor, and string assembly with trim to drop stray spaces. Run: soma run number_to_words.cell --signal spell 342
A Soma program from the text part of the verified corpus: 66 lines, cells NumberToWords, NumberToWordsTest. It passes soma check with soma 3.2.4.
How it is built
The cell NumberToWords declares 1 signal in its face: spell(n: Int) -> String. Handlers: spell (line 41). Private helpers: _ones, _teens, _tens and _two_digits.
The file also holds 1 test cell (NumberToWordsTest) with 8 assertions, run by soma test.
The source
number_to_words.cell
// ============================================================================
// Number to words — spell out integers 0..999
// ============================================================================
//
// Composes English number words from ones/teens/tens tables. Demonstrates
// list-literal lookup tables indexed by digit, integer division with floor,
// and string assembly with trim to drop stray spaces.
//
// Run: soma run number_to_words.cell --signal spell 342
cell NumberToWords {
face {
signal spell(n: Int) -> String
}
on _ones(d: Int) {
let t = list("zero","one","two","three","four","five","six","seven","eight","nine")
return t[d]
}
on _teens(d: Int) {
let t = list("ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen")
return t[d]
}
on _tens(d: Int) {
let t = list("","","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety")
return t[d]
}
// Spell 0..99
on _two_digits(n: Int) {
if n < 10 { return _ones(n) }
if n < 20 { return _teens(n - 10) }
let tens = floor(n / 10)
let ones = n % 10
if ones == 0 { return _tens(tens) }
return _tens(tens) + "-" + _ones(ones)
}
on spell(n: Int) {
if n == 0 { return "zero" }
if n < 100 { return _two_digits(n) }
let hundreds = floor(n / 100)
let rest = n % 100
let out = _ones(hundreds) + " hundred"
if rest > 0 {
out = out + " " + _two_digits(rest)
}
return out
}
}
cell test NumberToWordsTest {
rules {
assert spell(0) == "zero"
assert spell(7) == "seven"
assert spell(13) == "thirteen"
assert spell(20) == "twenty"
assert spell(42) == "forty-two"
assert spell(100) == "one hundred"
assert spell(342) == "three hundred forty-two"
assert spell(905) == "nine hundred five"
}
}What the toolchain says
$ soma check number_to_words.cell
✓ All checks passed.$ soma test number_to_words.cell
test NumberToWordsTest ...
✓ assert spell(0) == "zero"
✓ assert spell(7) == "seven"
✓ assert spell(13) == "thirteen"
✓ assert spell(20) == "twenty"
✓ assert spell(42) == "forty-two"
✓ assert spell(100) == "one hundred"
✓ assert spell(342) == "three hundred forty-two"
✓ assert spell(905) == "nine hundred five"
8 tests: 8 passed, 0 failed$ soma verify number_to_words.cell
Verifying number_to_words.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)