Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Приемы и технологии программирования Пишем генератор мата


Информационный Канал Subscribe.Ru

http://www.mrblack.pp.ru
Приемы и технологии программирования #7

Пишем генератор мата

Одной из задач искусственного интеллекта считают общение с человеком на человеческом языке. Иногда через эту возможность определяется само понятие "искусственный интеллект". Эта задача распадается на две: разбор предложений и построение предложений. Первая задача несравненно сложнее второй. Это я сейчас докажу. Одна и та же мысль может быть представлена бесконечным множеством предложений, или если не бесконечным, то во всяком случае таким, которое ни в какую базу данных не поместится, даже при самом сильном сжатии. Это получается из-за многочисленных синонимов и речевых оборотов, а так же из-за того, что слова в русском языке можно переставлять. Американцам с этим повезло. Кроме того в бытовой речи иногда встречаются неточности, неоднозначности и прочие ошибки, которые не мешают человеку понять сказанное, хотя такая речь является нелитературной. Программа, разбирающая тексты и неспособная с этим справиться, не может претендовать на титул "искусственный интеллект". При формировании же предложений мы выбираем только один из возможных вариантов выражения мысли, хотя для того, чтобы сделать речь живой и разнообразной, необходимо использовать различные выражения с теми частотами, с какими они употребляются в текстах требуемого стиля. Итак, поддержка разнообразных вариантов представления информации при разборе необходима, а при формировании она лишь оживляет стиль речи, что совершенно излишне для текстов научного и делового стилей. Т. о. разбор всегда сложнее, что и требовалось доказать. Кстати, аналогичная ситуация возникает и с обработкой машинных форматов данных, основанных на тексте, как то ХТМЛ и скрипты.

Поскольку формирование предложений проще, я изложу изложение именно с этой темы. Мы разберем простой для понимания код, реализующий построение случайных предложений.

Эта задача имеет интересные приложения. Первое - это генератор мата. Насколько я помню, с них всё началось. Может, кто-то поставит под сомнение интеллектуальность генератора ругательств, зато в нем бесспорно содержится неповторимый русский дух ;). Вот один из таких генераторов: http://damn.ru. Далее следует отметить генераторы поздравлений, например этот. Технически эти приложения нисколько не отличаются друг от друга. Отличаются только наборы используемых слов. Так что один и тот же код, только с разными базами данных может быть генератором "два в одном".

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

В качестве примера кода рассмотрим генератор поздравлений на Subscribe.ru, поскольку он написан на JavaScript, и мы, таким образом, имеем возможность его исследовать. Весь его код помещается внутри страницы по указанному адресу, в функции make_txt().

Генертор достаточно простой. Здесь нет базы данных по отдельным словам, а весь текст составляется из четырех частей, каждая из которых выбирается из 16ти вариантов, так что всего возможно 65536 вариантов поздравления.

function make_txt()
{

var vvod = new Array(15);
var utver = new Array(15);
var predv = new Array(15);
var vivod = new Array(15);

/* проверка выбора пола */
.....

/* ДЛЯ ЖЕНЩИН */
/* варианты вводной части */
vvod[0] = '';
vvod[1] = 'ДОРОГАЯ,';
vvod[2] = 'ТАК СЛУШАЙ ЖЕ:';
vvod[3] = '';
vvod[4] = 'ДОЛЖЕН ПРИЗНАТЬСЯ ТЕБЕ, ЧТО';
....

/* варианты утверждения */
utver[0] = 'ТВОЯ КРАСОТА';
utver[1] = 'НЕИССЯКАЮЩИЙ ИСТОЧНИК ТВОЕГО ОБАЯНИЯ';
....
utver[14] = 'ТВОЙ ЛАСКОВЫЙ ГОЛОС';

/* варианты предварительного умозаключения */
predv[0] = 'ОСТАВЛЯЕТ ВО МНЕ ГЛУБОКИЙ СЛЕД';
predv[1] = 'НАПОЛНЯЕТ КАЖДЫЙ ДЕНЬ МОЕГО СУЩЕСТВОВАНИЯ ОСОБЕННЫМ СМЫСЛОМ';
predv[2] = ' - ЭТО ПУТЕВОДНАЯ ЗВЕЗДА, КОТОРАЯ НЕ ДАЕТ МНЕ СБИТЬСЯ С ПУТИ';
....
predv[14] = 'ПОРАЖАЕТ МОЕ ВООБРАЖЕНИЕ';

/* варианты логического вывода */
vivod[0] = '.';
vivod[1] = ', НАПОЛНЯЯ СМЫСЛОМ ПУСТОЕ ПРОСТРАНСТВО БЫТИЯ.';
vivod[2] = ', ВЫЗЫВАЯ ЖЕЛАНИЕ ПОЗДРАВИТЬ ТЕБЯ.';
.....
vivod[14] = '!';

.....
Опускаю циклы и мудреный алгоритм заполнения массива N случайными числами и привожу основную формулу, по которой формируются поздравления

var koef = i+3*(i-1);
F[i] = vvod[N[koef]] + probel + utver[N[koef+1]] + probel + predv[N[koef+2]] + vivod[N[koef+3]];

}

Как видим, вся фишка здесь в том, чтобы выбрать наиболее универсальную структуру предложения и, проявив немного фантазии, придумать варианты для каждого из ее элементов.

Попробуем видоизменить этот простой алгоритм, сделав из него генератор ругательств. Только я буду писать на PHP.

В моем скрипте структура предложения будет такая:

[Прилагательное [прилагательное ...]] существительное, слова_угрозы [действие [, действие ...] и] действие!

Как видите, моя структура более совершенна: она включает в себя повторения элементов случайное количество раз.


/* Выбор случайного элемента из массива */
function rand_sel($massiv) {
return $massiv[rand(0, count($massiv)-1)];
}

/* Выбор случайного количества элементов в случайном порядке из массива и объединение их через пробел */
function rand_slice($MACCuB, $MACKuMyM) {
shuffle($MACCuB);
return implode(" ", array_slice($MACCuB, 0, rand(0, $MACKuMyM?$MACKuMyM:count($MACCuB))));
}

/* Выбор случайного количества (больше нуля) элементов в случайном порядке из массива и объединение их через запятую и союз "и" */
function rand_slice2($MACCuB, $MACKuMyM) {
shuffle($MACCuB);
$c = rand(0, $MACKuMyM?$MACKuMyM:count($MACCuB)-1);
return implode(", ", array_slice($MACCuB, 0, $c)) . ($c?" и ":"") . $MACCuB[$c];
}

/* Генерация ругательства */
function make_damn() {
// прилагательные
$pril = Array(
"сраный", "проклятый" //, ...
);

// существительные-обращения
$obr = Array(
"сукин сын", "ублюдок" //...
);

// слова угрозы
$nachalo = Array(
"ты будешь" // ...
);

// действия
$konets = Array(
"целовать мой зад" // ...
);

/* [Прилагательное [прилагательное...]] существительное, слова_угрозы [действие [, действие ...] и] действие! */
$ctpoka = rand_slice($pril, 3) . " " . rand_sel($obr) . ", " .
rand_sel($nachalo) . " " . rand_slice2($konets, 3) . "!";

/* Убираем лишние пробелы, если таковые есть, и делаем первую букву заглавной */
return ucfirst(trim($ctpoka));
}

// Выводим результат
print make_damn();

?>

Протестировать этот генератор в действии можно на моем сайте.

Продолжение следует...


Объявление

Продолжается голосование "Кто вы". По предварительным итогам, не первом месте находятся прикладники, на втором просто любопытные, а на третьем - "другое". Большинство из "другого" предпочли отметить этот вариант вместо того, чтобы написать мне письмо.

Если результаты не претерпят качественных изменений, то тематика рассылки останется без изменений, поскольку я сам занимаюсь именно прикладным программированием и главным образом именно на эту тему до сих пор писал.

_

2005-08-19

mr. Black <mrblack@pochta.ws>
Аська: 179497623
Сайт: http://www.mrblack.pp.ru/
Программа "Голосовая Почта"
Программа "Simple RAS Dialer"
Статьи о технологиях программирования

Subscribe.Ru
Поддержка подписчиков
Другие рассылки этой тематики
Другие рассылки этого автора
Подписан адрес:
Код этой рассылки: comp.soft.prog.techn
Отписаться
Вспомнить пароль

В избранное