Язык

Изучение вопроса о сущности и механизмах мышления мы начали с попытки написать программу, в которой мог бы использоваться английский или любой другой «естественный» язык. Нам хотелось, чтобы эта программа могла понимать напечатанное слово, т. е. выяснять его смысл, переводить его на другой язык и отвечать на различные вопросы, касающиеся этого слова. Однако мы тотчас заметили, что люди обычно понимают гораздо больше непосредственного лексического значения слова. Например, большинство людей не сомневаются, что предложение «Джон купил машину» имеет отношение к деньгам, хотя слово «деньги» в нем отсутствует. Следовательно, любая программа, способная понять смысл данного предложения, должна ответить «да» на вопрос: «Потратил ли Джон деньги?».

Но каким образом программа может узнать это? Один способ сообщить программе такую информацию заключается в том, чтобы связать слово «деньги» со словом «купил», т. е. программа должна знать, что «покупать» это значит «тратить деньги на что-либо». При таком подходе смысл предложения складывается из смысла входящих в него слов. В общем это верно, но возникает и ряд трудностей. Во-первых, слова могут иметь неоднозначный смысл, что часто приводит к неправильным выводам о смысле предложения. Например, слово «покупать» не всегда означает, что какие-то деньги переходят из рук в руки, как, скажем, это имеет место в предложении «Джон купил свою свободу ценою измены». Неоднозначность слов — столь частое явление, что любая программа должна иметь средства для ее разрешения.

Еще одна трудность связана с тем, что скрытый смысл не вытекает из определений слов, взятых из словаря. Рассмотрим такой короткий рассказ: «Джон пришел в кафе. Он заказал сандвич. Официант быстро принес его, поэтому он дал большие чаевые». Из рассказа ясно, что Джон съел сандвич и заплатил за него. Но ведь эти действия не вытекают ни из одного употребленного в рассказе слова. Как же может машина сделать такой вывод? Для этого ей необходимо сообщить сведения о том, чтб обычно люди делают в кафе. Человек, прослушав этот рассказ, может, кроме того, сказать, что Джон, вероятно, сел за стол, просмотрел меню, что на кухне приготовили сандвич и т. д. Программа должна быть способна заполнять пропуски в тексте заложенной в ней информацией об описываемых событиях.

Обе задачи решаемы; для этого программе нужно постоянно строить прогноз относительно дальнейшего хода событий. Ведь у людей неоднозначность почти никогда не вызывает затруднений, так как из контекста ясно, какое значение слова подходит в том или ином конкретном случае. Чтобы справляться с неоднозначностью, программе также придется строить «контекст». Другими словами, программа должна предвидеть последующий ход событий на основании того, что уже произошло, и того, что она знает о подобных ситуациях. Прогнозы подсказывают не только дальнейшие события, но и смысл слов; например, фраза «Бармен плеснул виски на лед» однозначно определяет смысл слова «лед»: в данном случае подразумевается, что это кубики льда в стакане.

Прогноз помогает восполнять пропуски в рассказе. Обычно мы прогнозируем сразу много вещей. Когда в рассказе упоминается кафе, мы ожидаем, что речь пойдет об определенном наборе объектов, событий, людей. Программисты называют это пакетом ожиданий. В нашем рассказе он включает меню, клиента, который просматривает меню, что-то выбирает и заказывает официанту, затем ждет исполнения заказа, ест, после чего со стола убирают и приносят чек; клиент оплачивает чек, оставляет чаевые и уходит. Из приведенного примера видно, что пакет ожиданий вызывается программой в нужном месте анализа текста, помогая ей сделать вывод о том, что «Джон съел сандвич». Если ожидание оправдалось, программа делает и другой вывод — что предыдущие ожидания, вероятно, тоже оправдались. Знания об обычном ходе событий помогают людям прогнозировать свое поведение и поведение других людей. Невозможно понимать язык без того, чтобы хоть что-то не знать об описываемых событиях.

Для создания программы, позволяющей проверить эти идеи, необходимо точно выяснить, какие бывают ожидания и как они используются людьми. Мы начали с изучения поведения. Люди постоянно делают прогнозы на различных уровнях детализации. Прогнозируем, какой слог будет произнесен следующим, достраивая отдельные неясные звуки до однозначно понимаемого слова. С учетом лексики строим прогнозы относительно того, какие слова или классы слов должны быть сказаны. Мы прогнозируем наступление наиболее вероятных событий; строим множество прогнозов по различным поводам: о целях других людей, планах и контрпланах, которые они разрабатывают на пути достижения своих целей, об эмоциональных реакциях на события.

Затем мы стали думать, как же все это организовать в программе. В каком-то смысле любая традиционная программа, анализирующая естественный язык, тоже строит прогноз. Разница между традиционным, строго синтаксическим, анализатором и нашим, концептуальным,— в источнике прогноза.

Синтаксический анализатор использует только знания о грамматике, тогда как концептуальный черпает информацию из многих источников, в том числе и из грамматики языка. Для традиционного анализатора синтаксический анализ предшествует всем другим видам анализа, а в нашем анализаторе текст одновременно подвергается обработке по нескольким линиям анализа.

Многие прогнозы, а именно прогнозы низкого уровня, берутся из словаря, дающего значения слов. Некоторые из наших  программ  представляют значения слов с помощью концептуальных зависимостей (КЗ). Основная структура КЗ такова: в ней имеются слоты для хранения действий, действующих лиц, объектов и для компонентов направления («к» или «от») (Слот—это распространенный в специальной литературе термин, обозначающий ячейку, отведенную в формальной схеме, в которую предполагается заносить информацию вполне определенного типа).

Каждое действие в КЗ накладывает семантические ограничения на элементы, которыми можно заполнять слоты КЗ. Например, действие  «есть» требует, чтобы объект был съедобный, а действующее лицо — одушевленным. Когда в тексте появляется какой-либо синоним, обозначающий это действие, слушающий ожидает узнать о чем-то съедобном (обычно после слова, обозначающего действие «есть») и об одушевленном действующем лице (обычно перед этим словом). Обратите внимание, что порождаемые КЗ ожидания имеют как семантический (прогноз значения слова), так и синтаксический (прогноз, где это слово может встретиться в предложении) характер. Но даже на уровне действия в структуре КЗ может возникнуть неоднозначность. В этом случае программа сохраняет все ожидания и затем выбирает из них то действие, при котором выполняются ожидания для других слов в рассказе. Этот же метод позволяет различать два значения слова «купил» в приведенном ранее примере, где слово «купил» порождает два множества ожиданий: одно, относящееся к рыночному товару, а другое — к ценной, но уже в переносном смысле, категории, товаром не являющейся. Как только удовлетворяется одно такое множество ожиданий, второе программа перестает рассматривать.

Есть и другие способы разрешения неоднозначности. Более сложные схемы прогноза значительно информативнее. Вернемся опять к рассказу о посещении кафе: «...Официант быстро принес его, поэтому он дал большие чаевые». В этом тексте встречается неоднозначное местоимение «он». Стандартные правила соотнесения местоимения со значимыми частями речи здесь не помогают: во-первых, число и род у всех существительных, которые могут претендовать на соотнесение с этим местоимением, одинаковы; во-вторых, мы понимаем, что «он дал» говорится не об официанте, хотя, согласно стандартным правилам, местоимению обычно приписывают значение ближайшего в тексте существительного, имеющего тот же род и используемого в том же числе. Единственное, что подсказывает нам правильное понимание этого местоимения,—это ожидание, указывающее, что клиент обычно оставляет чаевые обслуживающему персоналу. Можно было, конечно, пойти другим путем и связать эту информацию со словом «чаевые», но понятия «клиент» и «обслуживающий персонал» не являются хорошими семантическими ограничениями для значений соответствующих слотов, так как в одной ситуации Джон может быть клиентом, а в другой—обслуживать кого-то. Ожидания «клиент— обслуживающее лицо—чаевые» и идентификация Джона как клиента на самом деле следуют из пакета ожиданий, касающегося кафе.

Начав использовать в программах пакеты ожиданий, мы обнаружили следующее. Во-первых, любые рассказы о жизненных ситуациях адресуются одновременно ко многим пакетам, и между этими пакетами существует множество связей. Пакеты объединяются в группы (например, «свидание»=«поездка», «ресторан», «поездка», «кинотеатр», «поездка»); они могут заполнять слоты в других пакетах (например, слот «оплачиваемая работа» в пакете «ресторан» заполняется действием «мытье посуды»). Действия могут протекать одновременно (скажем, «есть» и «лететь в самолете») или, наоборот, быть несовместимыми («ехать в машине» и «лететь в самолете»). Пакеты могут иметь прямую связь со значениями слов. В пакете «ресторан» слово «чай» в сочетании «на чай» имеет совсем другое значение, чем название напитка. Эти связи, впрочем, не решают полностью проблемы неоднозначности, но могут быть весьма полезными.

Метод пакетов порождает свои трудности. Каким образом программа решает, какой пакет следует вызвать в каждом конкретном случае? Для этой цели каждый пакет характеризуется определенными условиями активации, т. е. условиями, при которых он считается относящимся к текущей ситуации. Наши первые программы просто перебирали все пакеты в поисках подходящего условия. Когда число пакетов существенно увеличилось, нам пришлось усовершенствовать их организацию, ибо стало невозможным перебирать ззее пакеты, чтобы в нужный момент отыскать соответствующий. Когда мы стали давать нашим программам реальные сообщения о событиях (телеграфные сообщения агентства ЮПИ), обнаружилось, что иногда ожидания оказывались неверными, причем часто такие неудачи соответствовали очень интересным событиям. Мы стали сравнивать эти «неудачи» с теми, когда ожидания вообще не удавалось найти, поскольку программа не могла сделать никакого прогноза по тексту.

Еще одна проблема заключалась в том, какую информацию можно выбрать в качестве пакета, а какую — нет. Так, например, в ситуации «еда дома» многое совпадает с ситуацией «еда в кафе». Поэтому не ясно, стоит ли сводить эти ситуации в один сценарий или хранить в разных? А что можно сказать о еде в разных кафе и ресторанах? Нам была нужна теория, которая позволяла бы организовывать и выявлять группы ожиданий.

Короче говоря, чтобы создать программу, которая могла бы читать небольшой текст из нескольких предложений и отвечать на вопросы по этому тексту, мы начали с изучения языка. Вскоре мы обнаружили, что для наших целей следует строить ожидания, касающиеся существа вопроса, о котором идет речь. Эти ожидания основываются на различных источниках и объединяются в пакеты. Здесь перед нами встали вопросы: что помещать в эти пакеты, как их организовать и как ими пользоваться? То, что начиналось как изучение языка, постепенно превратилось в теорию познания и организации знаний, т. е. по существу в исследование памяти.