На этом шаге мы рассмотрим использование изученного материала для моделирования человеческой деятельности.
С тем, чем мы располагаем к настоящему моменту, нетрудно написать простой вариант программы, которая при взаимодействии с человеком, сидящим за терминалом, напоминает психиатра определенного типа, разговаривающего с пациентом. Эта программа представляет собой цикл с использованием функций COND, содержащих ключевые слова и фразы вместе с соответствующей реакцией на них [1].
Общение с пользователем происходит с помощью функций READ и PRINT. Заметим также, что если встречается слово ЛЕТ, то атом FLAG получает текущее значение T. Тогда позднее, если ничего больше не сработало, то реакция программы
(ВЫ ГОВОРИЛИ О ...)
Предлагаемая программа могла бы быть и была развита с использованием весьма изощренных сценариев, но даже в нашем тривиальном варианте она способна на короткий диалог.
(DEFUN DOCTOR (LAMBDA NIL ; Моделирование психиатра ; (PRINT 'ГОВОРИТЕ!) (SETQ FLAG NIL) (LOOP (SETQ S (READ)) (COND ( (MATCH '(МЕНЯ ВОЛНУЕТ *L) S) (PRINT (APPEND '(КАК ДАВНО ВАС ВОЛНУЕТ) L)) ) ( (MATCH '(* ЛЕТ) S) (SETQ FLAG T) (PRINT (APPEND '(РАССКАЖИТЕ БОЛЬШЕ О) L)) ) ( (MATCH '(* КОМПЬЮТЕРЫ *) S) (PRINT (APPEND '(КОМПЬЮТЕРЫ ПУГАЮТ) L)) ) ( (OR (MATCH '(НЕТ) S) (MATCH '(ДА) S)) (PRINT '(ПОЖАЛУЙСТА НЕ БУДЬТЕ КРАТКИ)) ) ( MOTHER (SETQ FLAG NIL) (PRINT (LIST '(ВЫ ГОВОРИЛИ О) L)) ) ( T (PRINT '(ПРОДОЛЖИМ НАШ ДИАЛОГ!)) ) ) ) )) ; ---------------------- ; (DEFUN MATCH (LAMBDA (P D) (COND ( (AND (NULL P) (NULL D)) T ) ( (OR (NULL P) (NULL D)) NIL ) ( (OR (EQ (CAR P) '?) (EQ (CAR P) (CAR D))) (MATCH (CDR P) (CDR D)) ) ( (AND (ATOM (CAR P)) (EQ (ATOMCAR (CAR P)) '>) (MATCH (CDR P) (CDR D))) (SET (ATOMCDR (CAR P)) (CAR D)) T ) ( (EQ (CAR P) '*) (COND ( (MATCH (CDR P) (CDR D)) ) ( (MATCH P (CDR D))) ) ) ( (AND (ATOM (CAR P)) (EQ (ATOMCAR (CAR P)) '*)) (COND ( (MATCH (CDR P) (CDR D)) (SET (ATOMCDR (CAR P)) (LIST (CAR D))) T) ( (MATCH P (CDR D)) (SET (ATOMCDR (CAR P)) (CONS (CAR D) (EVAL (ATOMCDR (CAR P)))) ) T ) ) ) ) )) ; ---------------------- ; (DEFUN ATOMCAR (LAMBDA (X) ; Выделение первого символа имени литерного атома ; (CAR (UNPACK X)) )) ; ---------------------- ; (DEFUN ATOMCDR (LAMBDA (X) ; Выделение "хвоста" имени литерного атома ; (PACK (CDR (UNPACK X))) )) ; ----------------------------- ; (DEFUN APPEND (LAMBDA (LST1 LST2) ; Функция APPEND возвpащает список, состоящий из ; ; элементов списка LST1, добавленных к списку LST2 ; (COND ( (NULL LST1) LST2 ) ( (NULL LST2) LST1 ) ( T (CONS (CAR LST1) (APPEND (CDR LST1) LST2)) ) ) ))
Тестовый пример:
(ГОВОРИТЕ!) (МЕНЯ ВОЛНУЕТ МОТЯ) (КАК ДАВНО ВАС ВОЛНУЕТ МОТЯ) (5 ЛЕТ) (РАССКАЖИТЕ БОЛЬШЕ О МОТЯ) (ОН И КОМПЬЮТЕРЫ - БОЛЬШИЕ ДРУЗЬЯ!) (КОМПЬЮТЕРЫ ПУГАЮТ МОТЯ) (НЕТ) (ПОЖАЛУЙСТА, НЕ БУДЬТЕ КРАТКИ) (ИЗВИНИТЕ) (ВЫ ГОВОРИЛИ О МОТЯ) (ДА) (ПОЖАЛУЙСТА НЕ БУДЬТЕ КРАТКИ) ...
Важно отметить, что программа DOCTOR в действительности не понимает человека за терминалом. В ней не строится модель обсуждаемых проблем, программа целиком зиждется на поверхностном вылавливании ключевых слов.
Хотя функция DOCTOR должна рассматриваться исключительно как игрушка, она тем не менее показывает, как эффективная функция сопоставления с образцом может упростить программирование. Интересной особенностью варианта DOCTOR является, то, что он показывает, насколько мизерное машинное обеспечение необходимо, чтобы создать иллюзию понимания.
"Доктор", как стали называть "Элизу", исполняющую роль психиатра, вскоре приобрел известность в Массачусетском технологическом институте, где эта программа появилась на свет, главным образом, благодаря простоте ее демонстрации...
Потрясения, которые мне пришлось пережить в процессе роста известности и распространения "Доктора", были связаны в основном с тремя следующими независимыми друг от друга событиями.
В заключении Дж.Вейценбаум выдвигает следующие тезисы: "во-первых, между человеком и машиной существуют принципиальные различия; во-вторых, существуют задачи, выполнение которых не следует поручать вычислительным машинам, независимо от того, можно ли добиться, чтобы вычислительные машины их решали".
Со следующего шага мы начнем рассматривать реализацию сортировки и поиска.