lisp中的析取分布属性

时间:2013-02-13 15:47:08

标签: functional-programming lisp

基本上我需要在下面将此属性表示为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个参数的情况下设计一个函数,但如果它有更多参数我不知道怎么做。

2 个答案:

答案 0 :(得分:0)

所以,你已经有一个函数f可以将((a b) (c d))转换为((a c) (a d) (b c) (b d))(我省略了andor 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))
  • 然后制作所有收集的集合的dekart-product(Cartesian product
  • 并输入表达式,只需添加'or'and,其中包含