Это не ответ в виде кода, поскольку я не хочу делать вашу домашнюю работу за вас.
Прежде всего: ошибка, о которой вы упомянули, явно исходит из некоторого кода, отличного откод в вашем вопросе: всегда хорошая идея проверить код, который, по вашему мнению, вы проверяете .
Во-вторых, для какой цели служит выражение типа (if (f ...) t nil)
? Единственная полезная цель - если вы хотите канонизировать возвращаемое значение от (f ...)
до t
или nil
. Но что (equal a b)
возвращает?
Во-вторых: если вам действительно только разрешено использовать cons
, append
, list
, equal
, defun
,car
, cdr
, cond
t
и nil
, тогда вам не разрешено использовать <
, или =
, или ряд других функций и других операторов, которыеты использовалИтак, у вас есть интересная проблема, которую нужно решить.
Подход к ее решению заключается в написании функции с именем first-in-list
: для этого требуется три аргумента, и вот его спецификация:
(first-in-list a b l)
возвращает, какой бы из a
или b
был первым в l
, по сравнению с equal
или nil
, если ни один из них не является (и вам решать, что он вернет, если a
и b
одинаковы).
Вы можете написать эту функцию с помощью cond
, car
, cdr
, equal
, nil
, t
и вспомогательной функции под названием first-in-list
, который вам нужно будет написать.
Теперь вы можете написать функцию month-before-p
, которая принимает два аргумента ma
и mb
и:
- проверяет, если
ma
равно mb
и возвращает nil
, если это так (это позволяет избежать неоднозначности в спецификации first-in-list
; - проверяет, равно ли
(first-in-list ma mb (list "january" ....))
ma
или mb
; - для добавленной стоимости может проверить, был ли результат вызова
first-in-list
равен nil
, что является ошибкой.
Эта функция также может бытьнаписано с cond
, equal
, t
и nil
, а также с вспомогательной функцией first-in-list
, которую вы уже написали.