> 1 <

Автор Сообщение

Stanley Ipkiss

Members


Статус

2 сообщений

Где: Russia
Род занятий: Студент
Возраст: 30

#5338   2011-12-14 18:02 GMT+3 часа(ов)      
Доброго времени суток!
Требуется помощь знающих людей =)
Задача: Напишите предикат от аргументов атома и списка, определяющий наличие элемента-атома в простом шестиэлементном списке, совпадающих с данным атомом.
Попробовал сам, но функция не работает(
 
(DEFUN PROVERKA (X Y)
(COND ((NULL Y) NIL)
((EQL X (CAR Y)) 'N)
((EQL X (CADR Y)) 'N2)
((EQL X (CADDR Y)) 'N3)
((EQL X (CADDDR Y)) 'N4)
((EQL X (CAR(CADDDR Y))) 'N5)
((EQL X (CADR(CADDDR Y))) 'N6)))
 


Вызов функции:
 
(DEFUN PROVERKA (X Y)
(COND ((NULL Y) NIL)
((EQL X (CAR Y)) 'N)
((EQL X (CADR Y)) 'N2)
((EQL X (CADDR Y)) 'N3)
((EQL X (CADDDR Y)) 'N4)
((EQL X (CAR(CADDDR Y))) 'N5)
((EQL X (CADR(CADDDR Y))) 'N6)))
PROVERKA
(SETQ X 'A)
A
(SETQ Y '(A B C D E F))
(A B C D E F)
(PROVERKA '(X Y))
error: too few arguments
 


Каких именно аргументов ему не хватает, на какую встроенную функцию он ругается?
Помогите =)

VH

Members


Статус

289 сообщений

Где: ---
Род занятий:
Возраст:

#5339   2011-12-14 19:23 GMT+3 часа(ов)      
Предикат - это функция с логическим значением (то есть ее вызов должен возвращать значение "истина" или "ложь").
Можно рассмотреть такой вариант (для сколькоугодноэлементного списка):
(defun F (X Y)
(cond
((null Y) nil)
((equal (car Y) X))
((F X (cdr Y)))))

Ах, да - вызов этой функции выполняется так, например:
(F 'A '(A B C D E F))

Stanley Ipkiss

Members


Статус

2 сообщений

Где: Russia
Род занятий: Студент
Возраст: 30

#5340   2011-12-14 20:00 GMT+3 часа(ов)      
Спасибо, конечно, только я всё равно понять не могу(

При вызове

 
(F 'B '(A B C D E F))
 


тоже возвращается T. Я думал, что он выдаст NIL, ведь мы сравниваем атом B с головой нашего списка, то есть с атомом A, и они не должны совпасть. Или я что-то не так понял?
И ещё, можно вопрос, что происходит в этом месте:
 
((F X (cdr Y)))))
 

?

VH

Members


Статус

289 сообщений

Где: ---
Род занятий:
Возраст:

#5341   2011-12-14 21:08 GMT+3 часа(ов)      
В «этом месте» и происходит то, что является <в отличие от остальных языков> основой LISPа (и почему препод не соизволил начать с основы?) - рекурсивный вызов той же функции с <в определенном смысле> "упрощенным" набором аргументов.
Данное определение функции изображает следующие (скажем так) вычисления:
формальный параметр X связывается с атомом-"образцом", переданном в первом аргументе вызова, а формальный параметр Y - со списком, переданном во втором аргументе;
<специальная> форма (cond) вычисляет первый элемент первого списка своего вызова - это выражение (null Y). Если результатом вычисления этого выражения является T, то это означает, что список <уже> кончился, а совпавших с X атомов <пока> не нашлось - то есть дальнейший поиск невозможен, и вызов функции должен вернуть nil (то есть LISPовское представление понятия "ложь");
если список пока не пуст, форма (cond) выполняет вычисление первого элемента следующего списка своего вызова - это выражение (equal (car Y) X), а результатом вычисления может быть либо T (что означает совпадение очередного «первого» элемента списка с атомом-"образцом"), либо nil;
так как во втором списке формы (cond) больше элементов нет, то при совпадении атомом возвращается значение T (что, собственно, нам и надо);
если очередной «первый» элемент списка не совпал с атомом-"образцом" - можно (и нужно) снова выполнить вызов функции, но уже с укороченным списком, так чтобы следующий элемент списка стал «первым» и функция уже его сравнивала с "образцом";
так как и в третьем списке формы (cond) больше элементов нет, то рекурсивный вызов функции вернет либо T (если с какого-нибудь более глубокого уровня рекурсии вернется значение T) либо nil (при исчерпании списка на самом глубоком уровне - см.выше).
> 1 <


Онлайн :

0 пользователь(ей), 43 гость(ей) :