Search code examples
clojureexpressionsimplify

Simplifying function output not exactly as expected


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.


Solution

  • 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)