Главная » Basic » ПРИМЕР РАЗРАБОТКИ

0

Деятельность в области искусственного интеллекта насчитывает много попыток использования ЭВМ для   написания связного   текста,   рассказов   и    даже   новелл.   До   сих  пор   они  оказывались несостоятельными, тем не менее ниже приводится короткая программа, которая пытается связать несколько сотен слов в рассказ. Результаты оказываются довольно любопытными, причем  способ конструирования предложений гарантирует их грамматическую правильность1.

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

"PERSON VT POSSESSIVE ADJ NOUN"

Обычные   слова   одного   и     того   же   типа  указываются   в   одной   строке,   начинающейся   с соответствующего ключевого слова, например:

"NOUN: JAGUAR, ROVER 3500, COAT, CAT, TROUSERS"

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

"PERHAPS PERSON WILL PREP THE NOUN"

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

В программе используются следующие части речи:

Существительные                                              NOUN

.     Притяжательные местоимения                       POSSESSIVE Личные местоимения                                       PERSON Переходные глаголы (прошедшее время)     VT Непереходные глаголы(настоящее время)    VI

Предлоги                                                           PREP Прилагательные                                                ADJ Наречия                                                             ADV

Общий образ действий программы таков: выбирается образец предложения и  просматривается в поисках ключевых слов NOUN, POSSESSIVE, PERSON и т. д. Если обнаружено ключевое слово, то берется соответствующий  список обычных слов и  одно из них извлекается  случайным образом для замещения ключевого слова.

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

Уровень 1

Инициировать требуемые переменные и функции.

Заполнить соответствующие массивы строк символов образцами предложений и списками слов.

Выбрать N — число предложений, которые надо составить.

Образовать и напечатать N предложений.

Вся работа выполняется в последнем из приведенных  выше элементов.  Его можно выполнить в виде подпрограммы.

Детализация 1.1. Образовать и напечатать N предложений. Пока требуются новые предложения,

выбрать случайный образец предложения,

образовать  предложение в   соответствии     с выбранным образцом,

напечатать полученное предложение. Конец цикла.

Уровень 2

Описание уровня 2 образуется описанием уровня 1 и  детализацией 1.1. Выберем основной объект, требующий дальнейшего  развития    и  находящийся в   детализации  1.1,  и   развернем его  в   виде подпрограммы.

Детализация2.1. Образовать предложение в соответствии  с выбранным образцом

Пока еще остались списки слов (правила), просмотреть предложение и заменить в нем

каждое вхождение ключевого слова на одно из обычных слов списка. Конец цикла.

Уровень 3

Описание  уровня 3 образуется из описания   уровня 2 и  детализации  2.1. Оно достаточно ясно, и только операция "просмотреть предложение …" требует расшифровки.  Развернем эту операцию в подпрограмму.

Детализация 3.1. Просмотреть предложение и заменить в нем каждое вхождение ключевого слова на одно из  обычных слов списка Извлечь тип слова из  начала списка слов (правила) . Найти  число

вхождений этого ключевого слова (типа слова)

в предложение.

Пока еще остались вхождения,

извлечь  случайным образом обычное слово из  списка, заменить вхождение  на это слово. Конец цикла.

Уровень 4

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

Детализация 4.1. Извлечь случайным образом слово из списка.  Найти число обычных слов  в списке

(правиле) . Получить случайное число. Извлечь по этому числу соответствующее  слово.

Уровень 5

Таким образом, мы достигли уровня 5. На этом этапе большинство из описанных  действий находится достаточно близко к окончательным программным операторам. Это обеспечивает непосредственный перевод в  операторы Бейсика после  одной дополнительной итерации,  на  которой надо  принять определенные конкретные решения о требуемых строковых функциях, об именах и об использовании важных переменных.

Перед выполнением этой работы надо включить   в описание   одну очень полезную модификацию. Возвратимся к детализации 1.1; в ней после образования предложения дается инструкция "напечатать полученное  предложение", которая  должна  превратиться  в   простой  оператор  PRINT.  Однако  в результате столь безыскусной печати  слова  в конце строк экрана ВТУ могут обрываться посередине и   заканчиваться  на  следующих строках.  В  принципе  это  может  оказаться приемлемым, но  для придания выводу хорошего вида вместо  этого оператора надо использовать подпрограмму. Детализация 1.2. Напечатать полученное предложение.

Используя   строковую  переменную   в    качестве  буфера,   добавить предложение  к   текущему содержимому буфера.

Если число символов в буфере меньше длины строки ВТУ, то выйти из подпрограммы,

в   противном   случае  напечатать  часть  строки вплоть до  конца  подходящего  слова и   удалить напечатанные символы  из буфера.

Теперь уже в  уровень 2 войдут две детализации:  1.1 и  1.2. Этот новый вариант  все еще требует определенной доработки.

Детализация 2.2. Напечатать полученное предложение.

Добавить предложение к текущему содержимому буфера.

Если число символов в буфере < длина строки, то выйти из подпрограммы,

в противном случае положить "длина" = длина строки.

Пока в позиции  "длина" находится символ, не являющийся пробелом, уменьшать "длина" на 1.

Конец цикла.

Напечатать символы  из буфера в количестве "длина".

Удалить  из буфера напечатанные символы, а также пробелы, оказавшиеся после этого ведущими. Перед  тем  как  приступить  к  описанию  уровня  6,  вернемся к  уровню 1  и   переработаем  его  в операторы  основной  программы.  При  этом   для   большинства систем  потребуется  генератор случайных чисел  в диапазоне 1 … N.

Уровень 6

Определить функцию, генерирующую случайные числа  в диапазоне 1 … N.

Определить необходимые  массивы строк символов. Занести образцы предложений в массив  S$( ) Занести списки слов (правила)  в массив R$( ) .

Получить случайное число N в диапазоне 15 … 25 для использования в

качестве числа предложений в  абзаце. Вызвать детализацию (1.1) для получения N предложений.

Закончить исполнение.

(Подпрограмма, отвечающая детализации (1.1)) Занести в буфер В$( ) пустую строку. Для J от 1 до N

выбрать в качестве образца предложения

S$(случайное число) и занести его в Т$,

вызвать детализацию (2.1) для преобразования Т$ в настоящее предложение,

вызвать детализацию (2.2) для вывода предложения  Т$ в хорошем виде. Следующий  проход цикла.

Возврат.

(Подпрограмма, отвечающая детализации (2.2)) Для I от 1 до R ( до числа правил) положить  В1 $

равным правилу S$ (I),

вызвать детализацию (3.1) для замены каждого ключевого слова обычным словом.

Следующий проход цикла Возврат (Подпрограмма, отвечающая детализации (3.1)) Найти положение ( : ) в В1$.

Переписать в WS ключевое слово правила, находящееся слева от ( : ). Переписать в S$ список обычных слов, находящийся справа от ( : ) Найти число О вхождений ключевого слова W$ в предложение Т$.

Для I1 от 1 до 0 вызвать детализацию  (4.1), возвращающую случайное слово  в В1$.

Следующий проход цикла Возврат (Подпрограмма, отвечающая детализации (4.1)) Занести в О число  слов в списке  S$,

подсчитать  число запятых в  этом списке. Получить случайное число в  диапазоне 1 … О. Найти по запятым соответствующее слово в списке  S$.

Занести это слово  в В1$. Возврат.

(Подпрограмма, отвечающая детализации (2.2)) Добавить предложение  T$ в  буфер В$. Занести в  L число  символов  в В$. Если L < = длина строки (40) , то возврат,  в противном случае положить L = 40. Пока L-й символ строки В$ отличается от пробела,

L = L-1. Конец цикла.

Напечатать L первых символов строки В$. Пока L-й символ строки В$ является пробелом, L = L+1. Конец цикла.

Сдвинуть содержимое буфера В$ влево, удалив L первых символов. Возврат.  Конец программы.

Одна из  причин,   по которой приходится  выполнять так много операций со строками символов, состоит  в том, что элементы образцов предложений и правил  имеют  переменную длину, вследствие чего  при извлечении    и  замещении  элементов приходится подсчитывать занятые  и   пробелы  и определять позиции.  Можно было бы упростить  программу, если бы каждый из  этих элементов хранился в отдельном элементе массива строк символов, например,  за счет применения двумерных массивов  S$(I,J)  и   RS(I,  J)  .  Однако  при таком  подходе  становится  труднее  изменять образцы предложений и  списки слов, и  одним  из достоинств  разработанной выше программы является простота экспериментирования с различными списками слов и образцами предложений.

Обратите внимание  на  то,  что  подпрограмма,  соответствующая детализации  (2.2),  может  быть использована и   во    многих других приложениях как  процедура  вывода текста  по  словам. В действительности и вся эта программа может быть использована для других приложений, так как она просто размещает объекты по  образцам. Такими  объектами, например, могут быть графические элементы; в  списках вместо слов  можно указывать команды управления  перемещением курсора, обеспечивающие вычерчивание каких-либо фигур. Созданные предложения послужат образцами для изображения рисунков на всем экране или на его части — машина станет художником. Аналогично, если имеется звуковой  генератор, можно разработать систему для получения машинной музыки. Используя  строковые функции Бейсика Microsoft,  уровень 6  можно  перевести в   следующую законченную программу:

10 REM СОЧИНЕНИЕ КОМПЬЮТЕРА

20 REM ФУНКЦИЯ FNA ГЕНЕРИРУЕТ СЛУЧАЙНОЕ ЧИСЛО

22 REM В ДИАПАЗОНЕ ОТ 1 ДО N

30 DEF FNA(N) = INT(N*RND+1)

40 REM

58 DIM S$(5) ,R$(10) ,Р1(20)

60 S=5

70 S$(1)="PERSON VT POSSESSIVE ADJ NOUN."

80 S$(2)="PERHAPS PERSON WILL VI PREP THE NOUN."

90 S$(3)="ADV. PERSON VT THE NOUN."

100 S$(4)="PREP THE ADJ NOUN PERSON VT."

110 S$(5)="VI THAT, PERSON WILL ADV VI THE ADJ NOUN."

120 REM

130 R=8

140 R$(1)="NOUN:BLACK HOLE,STARSHIP,PLANET,MOON,SUN"

150 R$(2)="POSSESSIVE:HIS,HER,THEIR"

160 R$(3)=;"PERSON: THE GALACTIC LORD,THE DARK ONE,HE,SHE"

170 R$(4)="VT:HIT,TURNED,WENT.FLEW,STOPPED,LEFT"

180 R$(5)="VI:LOOK,STOP,LEAVE,NOTICE,RUN,DESTROY"

190 R$(6)="PREP:UNDER,THROUGH,ROUND,ON,NEAR,CLOSE TO"

200 S (7)="ADJ:BRIGHT,PULSING,LONELY,FEEBLE"

210 R$(8)="ADV:SLOWLY,QUIETLY,SWIFTLY,SUDDENLY"

220 REM

230   N=15+FNA(10)

240   GOSUB 270

250  STOP

260   REM

270   REM ПОДПРОГРАММА ВЫВОДА N ПРЕДЛОЖЕНИЙ

280   PRINT

290   B$=""

300   FOR J=l TO N

310   T$=S$(FNA(S))

320   GOSUB 390

330   GOSUB 720 340   NEXT J

350   PRINT B$

360   PRINT

370   RETURN

380   REM

390   REM ПОДПРОГРАММА ПОДСТАНОВКИ СЛОВ В Т$ ПО ПРАВИЛАМ

395   REM В R$ ).

400   REM ВХОД: Т$ В КАЧЕСТВЕ ОБРАЗЦА ПРЕДЛОЖЕНИЯ.

405   REM ВЫХОД: РЕЗУЛЬТАТ ПОДСТАНОВКИ В Т$.

410   FOR I=1 ТО R

420   B1$=R$(I)

430   GOSUB 470

440 NEXT I

450 RETURN

460 REM

470 REM ПОДПРОГРАММА ЧАСТИЧНОЙ ПОДСТАНОВКИ СЛОВ В Т$

475 REM СОГЛАСНО ПРЕДПИСАНИЮ, СОДЕРЖАЩЕМУСЯ В В1$

480 REM ВХОД: T$,B1$

485 REM ВЫХОД: T$ С ЧАСТИЧНО ПОДСТАВЛЕННЫМИ СЛОВАМИ

490 C=INSTR(B1$,":")

500 W$=LEFT$(B1$,C-1)

510 S$=RIGHT$(Bl$ ,LEN(B1$)-C)

520 REM W$ СОДЕРЖИТ КЛЮЧ (НАЗВАНИЕ ЧАСТИ РЕЧИ),

525 REM A S$ СПИСОК СЛОВ

530 Y$=T$

540 XS=W$

550 GOSUB 900

560 FOR 11=1 TO 0

570   GOSUB 630

580   P=INSTR(T$,W$)

590   T$=LEFT$(T$,P-1)+B1$+RIGHT$(T$,LEN(T$)-P-LEN(W$)+1)

600 NEXT I1

610 RETURN

620 REM

630 REM ПОДПРОГРАММА СЛУЧАЙНОГО ВЫБОРА ИЗ СПИСКА СЛОВ

640 REM ВХОД S$, ВЫХОД СЛОВО В B1$

650 Y$=","+S$+","

660 X$="."

670 GOSUB 900

680 I2=FNA(O-1)

690 B1$=MID$(Y$,P1(12)+2,P1(I2+1)-P1(12)-2)

700 RETURN

710 REM

720 REM ПОДПРОГРАММА КРАСИВОЙ ВЫДАЧИ ТЕКСТА

730 REM ДОБАВЛЯЕТ ПРЕДЛОЖЕНИЕ Т$ В БУФЕР В$

740 REM ДЛЯ ПЕЧАТИ ПРЕДЛОЖЕНИЯ В НЕСКОЛЬКО СТРОК

745 REM НЕ РАЗРЫВАЯ СЛОВА

750 REM ВХОД: ЗАКОНЧЕННОЕ ПРЕДЛОЖЕНИЕ В T$

760 B$=B$+" "+T$

770 L=LEN(B$)+1

780 IF L< = 41 THEN RETURN

790 L=41

800 IF MID$(B$,L,1>=" " THEN 830

810   L=L-1

820   GOTO 800

830 PRINT LEFT$(B$, L-1)

840 IF MID$(B$,L,1)<>" " THEN 870

850   L=L+1

860   GOTO 840

870 B$=RIGHT$(BS,LEN(B$)-L+1)

880 RETURN

890 REM

900 REM ПОДПРОГРАММА ОПРЕДЕЛЕНИЯ ЧИСЛА ВХОЖДЕНИЙ ДЛЯ

905 REM БЕЙСИКА MICROSOFT

910 REM ВХОД: СТРОКА Y$, ОБРАЗЕЦ В Х$ ДЛЯ ПОИСКА B Y$

920 REM ВЫХОД: ЧИСЛО ВХОЖДЕНИЙ В О

930 REM МАССИВ Р1( ) СОДЕРЖИТ ПОЗИЦИИ ВХОЖДЕНИЙ

940 O=0

950 I3=1

96В J3=LEN(Y$)

970 K3=LEN(X$)

980 М3=0

990 P3=INSTR(I3,Y$.X$)

1000 IF P3<>0 THEN 1030

1010   M3=l

1020   GOTO 1070

1030 0=0+1

1040 P1(O)=P3

1050 I3=P3+K3

1060 IF(I3+K3)>J3 THEN M3=l

1070 IF M3<>1 THEN 990

1080 RETURN

1090 END

Последняя   подпрограмма,   образованная  строками  с   900-й   по   1080-ю   представляет    собой модификацию  программы, описанной в  подразд. 4.2.5, и  добавлена здесь ввиду  того, что в  версии Бейсика Microsoft нет стандартной функции, возвращающей  число вхождений вырезки Х$ в строку Y$. Позиции вхождений регистрируются  в массиве   Р1 ( ) для дальнейшего использования. Вызовы этой  процедуры  обеспечиваются  строками 530  .  .  .  550  и   650  ..  .  670.  В  некоторых  системах предусмотрены функции с большими возможностями,  возвращающие за одно обращение к ним как число вхождений, так и позиции этих вхождений,  поэтому окончательные детали реализации уровня 6 зависят от того, какими стандартными функциями располагает Ваша система.

Возвратимся  к  изначальной цели программы. В  результате ее  исполнения  по  команде RUN  Вы получите забавный, но не вполне связный рассказ. Причина  этого проста: ЭВМ хранит правила грамматики и манипулирует  словами, но в основу  рассказа должны быть положены идеи, которыми либо можно,  либо нельзя  манипулировать  случайным образом.  Слова являются лишь внешним проявлением глубинных  идей. Если бы ЭВМ могла манипулировать  идеями, а не словами, то тогда можно было бы получать поразительные результаты.

УПРАЖНЕНИЯ

5.1.       Разработайте и  напишите программу для перевода температуры из  шкалы Цельсия в  шкалу Фаренгейта,  определив   функцию, выполняющую это  преобразование. Исходите из   того,  что признаком конца списка вводимых значений  температуры по шкале Цельсия служит нуль.

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

Программа должна выдавать ряд писем на основе информации, запомненной в  операторах DATA.

Если у Вас нет принтера, то выводите результаты обычным путем на ВТУ.

5.3.     Разработайте и  напишите программу, выдающую список лиц, упорядоченный по возрасту   (от младшего к старшему). Сведения о каждом лице должны иметь формат

ФИО, возраст (например, И. В. СЕМЕНОВ, 24) .

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

Источник: Уолш Б.    Программирование на Бейсике: Пер. с англ. М.: Радио и связь, 1988. 336 с: ил.

По теме:

  • Комментарии