soma.cell

Complex numbers — records carrying real and imaginary parts

Soma has no native complex type, so a Complex is a record { re, im }. Addition is componentwise; multiplication uses the FOIL identity (a+bi)(c+di) = (ac−bd) + (ad+bc)i; modulus is sqrt(re²+im²). Records carry a _type field so is_a recognizes them.

A Soma program from the math part of the verified corpus: 63 lines, cells Complex, ComplexTests. It passes soma check with soma 3.2.4.

How it is built

The cell Complex declares 4 signals in its face: cadd(x: Map, y: Map) -> Map, cmul(x: Map, y: Map) -> Map, cmod(x: Map) -> Float and run() -> Map. Handlers: cadd (line 21), cmul (line 25), cmod (line 32) and run (line 36).

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

Generated from soma describe on this file.

The source

complex.cell

// ============================================================================
// Complex numbers — records carrying real and imaginary parts
// ============================================================================
//
// Soma has no native complex type, so a Complex is a record { re, im }.
// Addition is componentwise; multiplication uses the FOIL identity
// (a+bi)(c+di) = (ac−bd) + (ad+bc)i; modulus is sqrt(re²+im²). Records carry
// a _type field so is_a recognizes them.
//
//   soma run complex.cell run
// ============================================================================

cell Complex {
    face {
        signal cadd(x: Map, y: Map) -> Map
        signal cmul(x: Map, y: Map) -> Map
        signal cmod(x: Map) -> Float
        signal run() -> Map
    }

    on cadd(x: Map, y: Map) {
        return Complex { re: x.re + y.re, im: x.im + y.im }
    }

    on cmul(x: Map, y: Map) {
        return Complex {
            re: x.re * y.re - x.im * y.im,
            im: x.re * y.im + x.im * y.re
        }
    }

    on cmod(x: Map) {
        return sqrt(x.re * x.re + x.im * x.im)
    }

    on run() {
        let a = Complex { re: 1.0, im: 2.0 }
        let b = Complex { re: 3.0, im: 0 - 1.0 }
        return map(
            "sum", cadd(a, b),
            "product", cmul(a, b),
            "mod_a", cmod(a)
        )
    }
}

cell test ComplexTests {
    rules {
        // (1+2i) + (3-i) = 4 + i
        assert cadd(Complex { re: 1.0, im: 2.0 }, Complex { re: 3.0, im: 0 - 1.0 }).re == 4.0
        assert cadd(Complex { re: 1.0, im: 2.0 }, Complex { re: 3.0, im: 0 - 1.0 }).im == 1.0
        // (1+2i)(3-i) = 3 - i + 6i - 2i^2 = 5 + 5i
        assert cmul(Complex { re: 1.0, im: 2.0 }, Complex { re: 3.0, im: 0 - 1.0 }).re == 5.0
        assert cmul(Complex { re: 1.0, im: 2.0 }, Complex { re: 3.0, im: 0 - 1.0 }).im == 5.0
        // |3+4i| = 5
        assert cmod(Complex { re: 3.0, im: 4.0 }) == 5.0
        // i^2 = -1
        assert cmul(Complex { re: 0, im: 1.0 }, Complex { re: 0, im: 1.0 }).re == 0 - 1.0
        // records are typed
        assert is_a(Complex { re: 1.0, im: 0 }, "Complex")
    }
}

What the toolchain says

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

$ soma check complex.cell
✓ All checks passed.
$ soma test complex.cell
test ComplexTests ...
  ✓ assert cadd(Complex { re: 1.0, im: 2.0 }, Complex { re: 3.0, im: 0 - 1.0 }).re == 4.0
  ✓ assert cadd(Complex { re: 1.0, im: 2.0 }, Complex { re: 3.0, im: 0 - 1.0 }).im == 1.0
  ✓ assert cmul(Complex { re: 1.0, im: 2.0 }, Complex { re: 3.0, im: 0 - 1.0 }).re == 5.0
  ✓ assert cmul(Complex { re: 1.0, im: 2.0 }, Complex { re: 3.0, im: 0 - 1.0 }).im == 5.0
  ✓ assert cmod(Complex { re: 3.0, im: 4.0 }) == 5.0
  ✓ assert cmul(Complex { re: 0, im: 1.0 }, Complex { re: 0, im: 1.0 }).re == 0 - 1.0
  ✓ assert is_a(Complex { re: 1.0, im: 0 }, "Complex")

7 tests: 7 passed, 0 failed
$ soma verify complex.cell
Verifying complex.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)
$ soma run complex.cell run
{"sum": {"_type": "Complex", "re": 4.0, "im": 1.0}, "product": {"_type": "Complex", "re": 5.0, "im": 5.0}, "mod_a": 2.23606797749979}

Builtins used

is_a, map, sqrt

Source file: /corpus/math/complex.cell · examples/corpus/math/complex.cell