define [-- ?x] {}

define [form ?x ?y] {
    define ?x ?y
}

define [rule ?x ?y] {
    define ?x ?y
}

define [?x -> ?y] {
    define ?x ?y
}

[(?x) = (?x)] -> {
    true
}

[(?x) = (?y)] -> {
    false
}

[false or false] -> {
    false
}

[true or false] -> {
    true
}

[false or true] -> {
    true
}

[true  or true] -> {
    true
}

[quote ?x] -> {
    quote ?x
}

[unquote (quote ?x)] -> {
    ?x
}

form [
    if ?condition
            ?true
        else
            ?false
]
{
    if/else ?condition {
        quote ?true
    } {
        quote ?false
    }
}

form [
    if ?condition
        ?branch
]
{
    if/q ?condition {
        quote ?branch
    }
}

rule [
    if/q (true)
        ?branch
]
{
    unquote ?branch
}

rule [
    if/q (false)
        ?branch
]
{}

rule [
    if/else (true)
        ?true
        ?false
]
{
    unquote ?true
}

rule [
    if/else (false)
        ?true
        ?false
]
{
    unquote ?false
}


[factorial (?x)] -> {
    if ((?x) = (1)) {
        1
    }
    else {
        ?x * factorial (?x - 1)
    }
}

[fibonacci (?number)] -> {
    if((?number) = (0) or (?number) = (1)) {
        ?number
    }
    else {
        fibonacci (?number - 1) + fibonacci (?number - 2)
    }
}

[range (?low) (?high)] -> {
    if((?low) = (?high + 1)) {
        nil
    }
    else {
        ?low : range (?low + 1) (?high)
    }
}

[fold (?operation) (?initial) (nil)] -> {
    ?initial
}

[fold (?operation) (?initial) (?head : ?tail)] -> {
    ?operation ?head (fold (?operation) (?initial) ?tail)
}

[sum ?list] -> {
    fold (add) (0) ?list
}