【发布时间】:2017-03-07 23:42:35
【问题描述】:
我是 Clojure 的新手,正在尝试编写一个旨在简化逻辑表达式的程序。例如:
(or x false) => x
(or true x) => true
(or x y z) => (or x(or y z))
我相信,我已经想出了如何将表达式简化为最多两个参数。但是,我不知道如何简化包含两个以上参数的表达式。我尝试使用第 n 个函数来尝试对表达式进行分区,但这似乎使事情变得更加复杂:
(defn pre-simplify [expression n]
(cond
(= n 0) (nth expression 0)
(= n 1) (nth expression 1)
(= n 2) (nth expression 2)
(= n 3) (nth expression 3)
)
)
这是简化函数的代码:
(defn simplify
([op arg1]
(cond
(and (= arg1 'true) (= op 'not)) false
(and (= arg1 'false) (= op 'not)) true
(= arg1 'true) true
(= arg1 'false) false)
;not not x -> x
)
([op arg1 arg2]
(cond
(seq? arg1) (let [arg1 (simplify op arg1)]))
(cond
(seq? arg2) (let [arg2 (simplify op arg2)]))
(cond
(= op 'or) (
(cond
(and (= arg1 'false) (= arg2 'false)) false
(or (= arg1 'true) (= arg2 'true)) true
(and (= arg1 'false) (and (not= arg2 'false) (not= arg2 'true))) arg2
(and ((not= arg1 'false) (not= arg1 'true)) (= arg2 'false)) arg1
)
)
(= op 'and') (
(cond
(and (= arg1 'true) (= arg2 'true)) true
(or (= arg1 'false) (= arg2 'false)) false
(and (= arg1 'false) (and (not= arg2 'false) (not= arg2 'true))) arg2
(and ((not= arg1 'false) (not= arg1 'true)) (= arg2 'false)) arg1
)
)
)
)
另外,我正在考虑在前两个参数之后对列表的其余部分使用递归。例如,这就是我试图在两个以上的参数上这样做的方式:
([op arg1 arg2 & rest]
(simplify op (list (op arg1 (op arg2 rest))))))
【问题讨论】:
-
连续 3 个
conds 应该做什么?我可能累了,但前 2 个应该对任何事情产生 0 影响。您正在创建arg1和arg2的本地阴影,然后将其丢弃。 -
你是不是偶然从命令式编程中走出来的?
标签: clojure functional-programming logic