Clojure:使用多个参数简化逻辑表达式
我是Clojure的新手,试图编写一个简化逻辑表达式的程序。例如:Clojure:使用多个参数简化逻辑表达式,clojure,functional-programming,logic,Clojure,Functional Programming,Logic,我是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) (n
(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)
)
)
这是Simplify函数的代码:
(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))))))
这看起来像是家庭作业,所以让我请你从另一个角度考虑这个问题。 在Clojure
表达式是以符号和
开头的表达式列表(或其他序列)李>和
表达式是以开头的表达式列表 符号或
或
李>
- 李>
- 参数或其他本地名称的符号,或
- 文本
或true
李>false
- 如果它是一个序列(使用
来测试它),seq?
简化它的 参数(列表中除
-第一个
之外的所有元素都将提供这些参数)。您可以使用其余
进行递归调用map
- 然后,例如,如果操作符(第一个
元素)是
和
符号,
- 如果操作数中存在任何
文字(您可以使用false
要测试这一点,请将整个表达式替换为some
false
- 如果不是,则删除
任何
文字李>true
- 如果操作数中存在任何
只是(and)
和正确
只是(和x)
x
(和x)
箱子上
还有一个需要考虑的问题是,您需要验证表达式是否有效以及验证的程度
- 未知操作符呢
- 您是否需要验证符号是否引用了某些内容。如果是,, 怎么做
- 我假设我们可以忽略副作用:表达式所做的只是 返回一个值
- 我不会用
替换(或x(或y z))
。这实现了 什么都不做,使用一个额外的标记:与简化相反(或x(或y z)
- 任何Clojure值——一个数字,甚至是一个函数——都在逻辑上起作用
true,除了逻辑上为false的
和false
。是否 这和你的问题有关,我不知道nil
- 如果您觉得自己很聪明,您可能能够参数化
和和
根据您忽略的文字(或
和true
),您结束时使用的和返回的 当没有争论的时候分别为false
整个问题被认为是难以解决的。如果你能找到一个有效的解决方案,你将举世闻名 一行中的3个
cond
s应该做什么?我可能很累,但前两个应该对任何事情都没有影响。您正在创建一个arg1
和arg2
的局部阴影,然后将其丢弃。您是偶然从命令式编程中获得的吗?