soma.cell

Anagram check — same multiset of letters

Two strings are anagrams iff sorting their letters yields the same string. We lowercase, drop spaces, explode into a character list, sort it, and re-join. Demonstrates split/sort/join on character lists. Run: soma run anagram.cell --signal is_anagram "listen" "silent"

A Soma program from the text part of the verified corpus: 41 lines, cells Anagram, AnagramTest. It passes soma check with soma 3.2.4.

How it is built

The cell Anagram declares 2 signals in its face: canonical(s: String) -> String and is_anagram(a: String, b: String) -> Bool. Handlers: canonical (line 18) and is_anagram (line 27).

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

Generated from soma describe on this file.

The source

anagram.cell

// ============================================================================
// Anagram check — same multiset of letters
// ============================================================================
//
// Two strings are anagrams iff sorting their letters yields the same string.
// We lowercase, drop spaces, explode into a character list, sort it, and
// re-join. Demonstrates split/sort/join on character lists.
//
// Run: soma run anagram.cell --signal is_anagram "listen" "silent"

cell Anagram {
    face {
        signal canonical(s: String) -> String
        signal is_anagram(a: String, b: String) -> Bool
    }

    // Sorted, lowercased, space-free signature of a word.
    on canonical(s: String) {
        let low = replace(lowercase(s), " ", "")
        let chars = list()
        for i in range(0, len(low)) {
            chars = push(chars, low[i])
        }
        return join(chars.sort(), "")
    }

    on is_anagram(a: String, b: String) {
        return canonical(a) == canonical(b)
    }
}

cell test AnagramTest {
    rules {
        assert is_anagram("listen", "silent")
        assert is_anagram("triangle", "integral")
        assert is_anagram("Dormitory", "dirty room")
        assert !is_anagram("hello", "world")
        assert canonical("cab") == "abc"
    }
}

What the toolchain says

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

$ soma check anagram.cell
✓ All checks passed.
$ soma test anagram.cell
test AnagramTest ...
  ✓ assert is_anagram("listen", "silent")
  ✓ assert is_anagram("triangle", "integral")
  ✓ assert is_anagram("Dormitory", "dirty room")
  ✓ assert !is_anagram("hello", "world")
  ✓ assert canonical("cab") == "abc"

5 tests: 5 passed, 0 failed
$ soma verify anagram.cell
Verifying anagram.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)

Builtins used

join, len, list, lowercase, push, range, replace

Source file: /corpus/text/anagram.cell · examples/corpus/text/anagram.cell