Lisp中的递归函数

时间:2013-02-12 15:07:54

标签: lisp conjunctive-normal-form

我必须构建一个函数来确定我是否有以这种方式构建的格式良好的公式:

cong :: ='('和wff wff ...')'

假设我有代码确定公式是否为wff。该函数必须首先检查列表的第一个元素是否为'and,然后如果它们是wff则递归检查其余的子列表。请注意,p也是一个wff,因此不一定必须是子列表。

示例:(and (or a b v) (and a b d) m n)

以下是我尝试过的对我不起作用的内容:

(defun cong (fbf)
    (and (eq (first fbf) 'and )
        (reduce (lambda (x y) (and x y))
            (mapcar #'wff (rest fbf)))))

1 个答案:

答案 0 :(得分:1)

假设工作wff谓词,您的代码将起作用。例如,使用numberp作为谓词:

(defun cong (fbf)
  (and (eq (first fbf) 'and)
       (reduce (lambda (x y) (and x y))
               (mapcar #'numberp (rest fbf)))))

工作正常:

CL-USER> (cong '(and 1 2 3 4 5))
T
CL-USER> (cong '(and 1 2 3 4 foo))
NIL
CL-USER> (cong '(1 2 3 4))
NIL

请注意,这可以更轻松地完成:

(defun cong (fbf)
  (and (eq (first fbf) 'and)
       (every #'wff (cdr fbf))))

另请注意,在CL中,按照惯例,谓词通常应以p结尾。

所以,根据上面的评论,你的问题是wff谓词,它似乎对原子不起作用。既然你提到p满足wff,那么这个谓词是完全错误的,但是如果你使用它(假设这是某种功课),那么检查一下手边的元素是一个缺点:

(defun cong (fbf)
  (and (eq (first fbf) 'and)
       (every #'wff (remove-if-not #'consp (cdr fbf)))))

这假设每个原子都满足wff。因此,他们不会改变一个结合的结果,可以放弃。否则,您必须编写另一个谓词来检查满足wff的原子,或者这是正确的做法,首先修复wff

另外,请注意,这些都不涉及递归,因为您只询问如何将谓词应用于列表并结合结果。