我必须构建一个函数来确定我是否具有以这种方式构建的格式良好的公式的结合:
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)))))
最佳答案
假设一个工作 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
才是正确的做法首先。
另外,请注意,这些都没有真正涉及递归,因为您只是在询问如何将谓词应用于列表并获取结果的结合。
关于lisp - Lisp 中的递归函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14835549/