dol 0.8.1

DOL (Design Ontology Language) - A declarative specification language for ontology-first development
// Effect System Test: Pure Recursive Functions
// =============================================
//
// What this test validates:
//   - Recursive pure functions are correctly inferred as pure
//   - Self-recursion maintains purity
//   - Mutual recursion between pure functions maintains purity
//   - Base cases and recursive cases both pure -> function is pure
//
// Expected effect inference results:
//   - factorial(n) -> Pure
//   - fibonacci(n) -> Pure
//   - gcd(a, b) -> Pure (Euclidean algorithm)
//   - is_even(n) -> Pure (mutual recursion)
//   - is_odd(n) -> Pure (mutual recursion)
//   - sum_range(start, end) -> Pure

gene Math.Recursive @0.1.0 {
    """
    Recursive pure functions demonstrating that recursion
    does not introduce effects when the function body is pure.
    """

    // Pure: classic factorial with recursion
    // Base case and recursive case both pure
    fn factorial(n: Int) -> Int {
        if n <= 1 {
            1
        } else {
            n * factorial(n - 1)
        }
    }

    // Pure: Fibonacci sequence
    // Multiple recursive calls, still pure
    fn fibonacci(n: Int) -> Int {
        if n <= 0 {
            0
        } else if n == 1 {
            1
        } else {
            fibonacci(n - 1) + fibonacci(n - 2)
        }
    }

    // Pure: Greatest Common Divisor (Euclidean algorithm)
    // Recursive with modulo operation
    fn gcd(a: Int, b: Int) -> Int {
        if b == 0 {
            a
        } else {
            gcd(b, a % b)
        }
    }

    // Pure: Mutual recursion - is_even
    fn is_even(n: Int) -> Bool {
        if n == 0 {
            true
        } else {
            is_odd(n - 1)
        }
    }

    // Pure: Mutual recursion - is_odd
    fn is_odd(n: Int) -> Bool {
        if n == 0 {
            false
        } else {
            is_even(n - 1)
        }
    }

    // Pure: Sum of range [start, end)
    fn sum_range(start: Int, end: Int) -> Int {
        if start >= end {
            0
        } else {
            start + sum_range(start + 1, end)
        }
    }

    // Pure: Ackermann function (deeply recursive)
    fn ackermann(m: Int, n: Int) -> Int {
        if m == 0 {
            n + 1
        } else if n == 0 {
            ackermann(m - 1, 1)
        } else {
            ackermann(m - 1, ackermann(m, n - 1))
        }
    }
}

// Test assertions for effect inference
test effects {
    assert_pure(Math.Recursive.factorial);
    assert_pure(Math.Recursive.fibonacci);
    assert_pure(Math.Recursive.gcd);
    assert_pure(Math.Recursive.is_even);
    assert_pure(Math.Recursive.is_odd);
    assert_pure(Math.Recursive.sum_range);
    assert_pure(Math.Recursive.ackermann);
}