I am trying to write a function that will simplify an arbitrary list of boolean expressions, but my function fails certain tests.
(defn sim
[expression]
(if (some true? expression)
true
(if (= (count expression) 2)
(if (some false? expression)
false
(if (map simple-symbol? expression)
(if (= (count expression) 2)
(drop 1 expression)
expression)))
(if (some simple-symbol? (drop 1 expression))
(filter simple-symbol? expression)))))
When I call using (sim '(or x false))
I expect the output to be (x)
, but instead it returns (or x)
. Conversely, when I call using (sim '(or x))
my output is (x)
as expected.
How about something along these lines? This is only for or
, but I'm sure we can do the same for and
and other boolean operators.
(defn simplify-or [exp]
(let [op (first exp)
args (rest exp)]
(when (= op 'or)
(let [nf-args (filter #(symbol? %) args)]
(if (some true? args)
true
(case (count nf-args)
0 false
1 (first nf-args)
(concat (list op) nf-args)))))))
Results:
(simplify-or '(or false))
=> false
(simplify-or '(or true))
=> true
(simplify-or '(or x true y false))
=> true
(simplify-or '(or x y false))
=> (or x y)