如何在lisp中解决格式错误的lambda?

时间:2015-12-08 21:33:54

标签: lisp common-lisp

我正试图在lisp中检查列表是否具有山峰方面。 例如:1,5,9,6,4,3

l是我的列表,aux是0 - l或1的升序部分 - 列表的下降部分。 muntemain只是从aux = 0开始调用munte,升序部分

我的错误是:

 Badly formed lambda: (AND (< (CAR L) (CAR (CDR L))) (EQ AUX 0))

我看不出问题。有人可以帮忙吗?

(defun munte (l aux)
      (cond 
          ((and (atom l) (null aux)) NIL)
          ((and (null l) (null aux)) NIL)
          ((and (atom l) (eq aux 1)) T)
          ((and (null l) (eq aux 1) T)
          ((and (< (car l) (car(cdr l))) (eq aux 0)) (munte(cdr l) 0))
          ((and (or (> (car l) (cadr l)) (= (car l) (cadr l))) (eq aux 0))(munte(cdr l) 1))
          ( and (> (car l) (cadr l)) (eq aux 1)) (munte(cdr l) 1))
          (T NIL)
)
)

(defun muntemain (l)
(cond 
         ((> (car l) (cadr l)) NIL)
         ((< (length l) 2) NIL)
         (T (munte l 0))
)
)

1 个答案:

答案 0 :(得分:2)

格式

作为noted by Barmar,您确实需要使用编辑器来帮助您使用括号。有许多安装Emacs + Slime的教程。花些时间安装合适的工具。

不要将EQ用于数字和字符

  

允许实施制作&#34;副本&#34;人物和   任何时候的数字。效果是Common Lisp不保证   即使它的论点都是&#34;同样的事情&#34;如果   那个东西是一个字符或数字。

分解测试

    ((and (atom l) (null aux)) NIL)
    ((and (null l) (null aux)) NIL)
    ((and (atom l) (eq aux 1)) T)
    ((and (null l) (eq aux 1) T)

根据atom的定义,NIL是一个原子,因此您不需要(null L)aux的不同案例也可以分组。以下条款足以说明以上所有内容:

    ((atom L) (eql aux 1))

但是我不明白为什么aux首先不是布尔值,如果你总是把它绑定到0或1.只需使用tnil并返回上述条款中的aux

使用有意义的功能

(< (car l) (car(cdr l)))

当然,(car(cdr ..))被称为(cadr ..),但也称为second。上述测试相当于:

(< (first L) (second L))

如果您的列表没有第二个元素怎么办?您将比较一个数字与nil并发出错误信号(不是您想要的)。你需要更多的测试。在muntemain中,当长度低于2时,您似乎有一个特殊情况,但仅当前一个返回nil时才进行测试,如果发出错误信号则不会发生。

迭代替代

这是一种完全不同的方法来解决问题,只是为了给你一些想法。

(lambda (list)
  (loop
    ;; memories
    for px = nil then x
    for pdx = nil then dx

    ;; current element
    for x in list

    ;; first and second "derivatives" (signs only)
    for dx = 1 then (signum (- x px))
    for ddx = 0 then (signum (- dx pdx))

    ;; checks
    sum ddx into total
    always (and (<= dx 0) (<= -1 total 0))
    finally (return (= total -1))))