我是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))))))
答案 0 :(得分:2)
这看起来像是家庭作业,所以让我邀请您从另一个角度考虑问题。
在Clojure中,
and
表达式是以符号'and
开头的表达式列表(或其他序列); or
表达式是以。开头的表达式列表
符号'or
; 表达式也可以是
true
或false
。 simplify
表达式:
seq?
进行测试),simplify
参数(列表的所有元素,但first
- rest
将为您提供这些参数)。您可以使用map
进行递归调用。first
元素)是and
符号,
false
个文字(你可以使用
some
要对此进行测试),请将整个表达式替换为false
。remove
任何true
文字。 这些简化可能为其他人开辟道路。例如,
(and)
只是true
和(and x)
只是x
。无论你做什么,都要在开发时测试你的功能,确保它完成你认为的功能。在一个案例中,我被抓住了将操作员留下。我摔倒了(and x)
案件。
还有什么可以帮助您确定表达式有效的方式和距离。
备注的
(or x y z)
替换(or x (or y z))
。这实现了
没有,并使用额外的令牌:与简化相反。false
和nil
除外,它们在逻辑上都是假的。是否
这与你的问题有关,我不知道。and
的方式
or
表示您忽略的文字(true
和
分别是false
),你结束的那个,以及你返回的那个
什么时候没有争论。整个问题被认为是棘手的。如果你找到一个有效的解决方案,你将成为举世闻名的!