基本上我需要在下面将此属性表示为lisp
中的函数(p和q)或(r和t)=(p或r)和(p或t)和(q或r)和(q或t)
函数distribute-or(fbf)将类型的公式作为参数
(or (and a b) c )
并在(and (or a c) (or b c))
但是,问题是你不知道or-formula可以有多少个参数,哪些是leterals,哪些是leterals的连接。 它可以是以下任何一个例子
(or a b)
保持原样
(or a b c (and d e f)
应该成为(and (or a b c d) (or a b c e) (or a b c f)
(or (and a b) (and d e))
将其转为(and (or a d) (or a e) (or b d) (or b e))
我只能在“或”有2个参数的情况下设计一个函数,但如果它有更多参数我不知道怎么做。
答案 0 :(得分:0)
所以,你已经有一个函数f
可以将((a b) (c d))
转换为((a c) (a d) (b c) (b d))
(我省略了and
和or
s。
您需要一个将((a b) (c d) (e f))
转换为((a c e) (a c f) (a d e) (a d f) (b c e) (b c f) (b d e) (b d f))
的函数。
这似乎是reduce
的明显案例:(reduce #'f mylist)
。
答案 1 :(得分:0)
由于您没有编写distribute-or
版本,我建议使用此变体,它采用任何长度的fbf,但不能深入工作。
(defun dekart-product (sets)
(if (null sets)
(list '())
(let ((prod (dekart-product (cdr sets))))
(mapcan #'(lambda (lst)
(mapcar #'(lambda (el) (cons el lst))
(car sets)))
prod))))
(defun collect-ands (l)
(mapcar #'(lambda (el)
(if (and (consp el)
(eq 'and (car el)))
(cdr el)
(list el)))
l))
(defun distribute-or (fbf)
(if (and (consp fbf)
(eq 'or (car fbf)))
(cons 'and (mapcar #'(lambda (lst) (cons 'or lst))
(dekart-product
(collect-ands (cdr fbf)))))
fbf))
结果是:
(distribute-or '(or a b c (and d e f)))
;=> (AND (OR A B C D) (OR A B C E) (OR A B C F))
它的工作方式很简单:
(or (and a b c) (and e f) g)
- > ((a b c) (e f) (g))
'or
和'and
,其中包含