4. Подловченко Р. И. Иерархия моделей программ // Программирование. 1981. № 2. С. 3-14.
5. Янов Ю.И. О логических схемах алгоритмов // Проблемы кибернетики. Вып. 1. М.: Физматлит, 1958. С. 75-121.
6. Подловченко Р. И. Полугрупповые модели программ // Программирование. 1981. № 4. С. 3-13.
7. Захаров В. А. Быстрые алгоритмы разрешения эквивалентности операторных программ на уравновешенных шкалах // Математические вопросы кибернетики. Вып. 7. М.: Физматлит, 1998. С. 303-324.
8. Захаров В. А. Быстрые алгоритмы разрешения эквивалентности пропозициональных операторных программ на упорядоченных полугрупповых шкалах // Вестн. Моск. ун-та. Сер. 15. Вычисл. матем. и киберн. 1999. № 3. С. 29-35.
9. Летичевский A.A. Эквивалентность автоматов относительно полугрупп с сокращением // Проблемы кибернетики. Вып. 27. М.: Наука, 1973. С. 195-212.
10. Захаров В. А. Об одной алгебраической модели программ, связанной с обработкой прерываний //Мат-лы VIII Междунар. семинара "Дискретная математика и ее приложения". М.: МАКС Пресс, 2004. С. 129-131.
Поступила в редакцию 04.04.07
УДК 519.6
Х. Рамиль Альварес
АЛГОРИТМЫ ДЕЛЕНИЯ И ИЗВЛЕЧЕНИЯ КВАДРАТНОГО КОРНЯ В ТРОИЧНОЙ СИММЕТРИЧНОЙ СИСТЕМЕ
(лаборатория ЭВМ факультета ВМиК, e-mail: [email protected])
Предложена модификация алгоритма деления Брусенцова для троичной симметричной системы, основанного на использовании половины модуля делителя. Рассмотрен алгоритм извлечения квадратного корня в этой системе на базе известного метода в "столбик" и применения алгоритма деления.
В работах [1, 2], в которых описана созданная в 1840 г. английским изобретателем Томасом Фау-лером троичная механическая вычислительная машина, приведены примеры деления в троичной симметричной системе. Однако в них не рассмотрены самые тонкие моменты процесса, вследствие чего их нельзя считать описанием алгоритма. Поэтому следует признать, что первые алгоритмы точного вычисления частного в троичной симметричной системе предложены Н.П. Брусенцовым в [3]. Алгоритмы деления предполагают, что значения делимого и делителя — нормализованные троичные числа, определенные в [4], т. е. они равны нулю или их абсолютные величины принадлежат интервалу (0,5; 1,5).
1. Модификация алгоритма деления Брусенцова. Рассмотрим первый из предложенных алгоритмов [3] divisionl,, результат которого выдается в виде пары чисел — нормализованной мантиссы е и порядка q, соответствующих представлению частного в виде е • З9. Точность, с которой вычисляется мантисса е, задается целочисленным параметром к, указывающим количество троичных разрядов в представлении е.
procedure divisionl (с, d, е, g, к);
value к; integer к, q; real с, d; integer array e;
comment с — делимое и d — делитель равны нулю или их абсолютные величины принадлежат интервалу (0,5; 1,5). Частное представляется посредством мантиссы е[1 : к] и порядка q в виде
begin integer р; se, sd; real g;
prepare(c, d, e, q, k, sd);
comment Обнуление массива е. Удвоение делимого (с) и вычисление модуля (d) и знака (sd) делителя d;
for р := 1 step 1 until k
begin if с > 0 then se : if д > О then begin efp] с := с * 3
end
end división 1;
Приведем описание процедуры prepare, которая заранее определяет значение порядка q и корректирует значение делимого с или делителя d так, что вычисляемая мантисса частного е получается нормализованной:
procedure prepárele, d, е, q, к, sd); valué к; integer к, q, sd; integer array e; real c, d; comment Оператор stop прерывает процедуру, если d = 0; begin integer p;
if d > 0 then sd := 1 else if d < 0 then sd := — 1 else stop; d := abs(d); с := с + с; for p := 1 step 1 until к do e[p] := 0; if abs(c) — d * 3 > 0 then begin q := 1; d := d * 3 end else if abs(c) — d > 0 then q := 0
else begin q := — 1; с := с * 3 end
end prepare;
Отметим, что в алгоритме используется удвоенное значение делимого, из которого на каждом шаге вычитается делитель, результат сравнивается с нулем и при необходимости из результата снова вычитается делитель.
Предлагаемая модификация алгоритма (процедура terndiv) основана на том, что первоначально вычисляется половина делителя и в дальнейшем на каждом шаге производится сравнение промежуточного делимого с этой половиной делителя и при необходимости из делимого производится вычитание полного делителя.
procedure terndiv (с, d, е, q, к);
valué к; integer к, q; integer array e; real c, d;
comment с — делимое, d — делитель, равны нулю или их абсолютные величины принадлежат интервалу (0,5; 1,5). Частное представляется посредством мантиссы е[1 : к] и порядка q в виде
З^-Еер'З1^;
begin integer i, se, sd; real m;
preparel (c, d, e, q, k, sd);
comment Обнуление массива е. Вычисление модуля (d) и знака (sd) делителя d. Вычисление т, равного половине модуля делителя d; for i := 1 step 1 until k do
begin if с < 0 then se := —1 else se := 1;
if compar(c, se, m) > 0 then comment compar — сравнение с и m с учетом знака se, т. е. sign(c * se — т)\ begin e[i) : se* sd; с := с — se * d end; с := с * 3
end
end terndiv;
Процедура preparel по сравнению с процедурой prepare включает вычисление половины модуля делителя. Следует отметить, что процедура compar (с, se, т) — сравнение с и т с учетом знака se, т. е. sign(c * se — т), сводится к поразрядному сравнению слева направо до первого несовпадающего, что существенно проще, чем вычитание.
procedure preparel (с, d, е, q, k, sd); valué k; integer k, q, sd; integer array e; real c, d; comment Оператор stop прерывает процедуру, если d = 0; begin integer p;
if d > 0 then sd := 1 else if d < 0 then sd := — 1 else stop;
= 1 else se : —1; g := с * se — d;
:= se * sd; с := (g — d) * se end;
d := abs(d); media(d,m, к); comment Вычисление т, равного d/2;
for р := 1 step 1 until к do е[р] := 0;
if abs(c) — m * 3 > 0 then begin q := I; d := d * 3; m := m * 3 end else if abs(c) — m > 0 then q := 0
else begin q := — 1; с := с * 3 end
end preparel;
Приведем описание процедуры получения половины делителя (т = d/2) для троичной симметричной системы. Алгоритм деления на 2 является частным случаем общего алгоритма деления. При этом учитывается то, что d > 0 и не требуется вычислять половину делителя, так как это 1. Описание процедуры media(d,m,k) лучше привести в предположении, что операнд d и результат т являются массивами тритов.
procedure media(d,m,k);
value к; integer к; integer array d, m;
comment Для d принадлежит интервалу (0,5; 1,5);
begin integer i, sd, di;
for i := 1 step 1 until к do m[i) := 0; di := 0;
for i := 1 step 1 until к do begin di := di * 3 + d[i);
if d,i < 0 then sd := —1 else sd := 1;
if sd * di > 1 or (sd * di = 1 and sign(d, i + 1) = sd) then comment Функция sign(d,i + 1) определяет знак числа d начиная с (i + 1 )-го разряда;
begin m[i) := sd;
if sd > 0 then d,i := di — 2 else di := di + 2
end
end;
end media;
2. Алгоритм извлечения квадратного корня. Рассмотрим алгоритм извлечения квадратного корня известным методом в "столбик" [5]. Использование алгоритма деления в алгоритме извлечения квадратного корня позволяет упростить его.
Приведем алгоритм извлечения квадратного корня для системы счисления с основанием S и с неотрицательными значениями цифр от 0 до 5 — 1. Предварительно подкоренное выражение N разбивается на пары цифр влево и вправо от запятой. Обозначим через Щ целое число, получаемое из первых слева направо i пар цифр, А^ — целое значение корня из этого числа, Dj — i-я пара цифр, di — значение i-й цифры результата.
Алгоритм извлечения квадратного корня в "столбик" можно описать следующими формулами:
Ni = Ai + Ви B1 = D1- dl Ai = d i,
Bi+1 = (Bi ■ S2 + A+i) - (2 • Ai ■ S + di+1) ■ di+1, A-i+i = Ai • S + d^|_i,
где di-|-i — наибольшее значение, при котором Bi+i неотрицательно. Отметим, что действия производятся над целыми числами, а запятая в результате будет поставлена после к-й цифры, если в подкоренном выражении она стояла после к-й пары.
Приведенные формулы были использованы в [6] для разработки двоичного устройства извлечения квадратного корня.
Заметим, что (Bi • S2 + -C^+i) ПРИ ручном использовании алгоритма является приписыванием справа к значению В, двух цифр пары а 2 • Л / • S + (¿¿+i и Л,- • S + (¿¿+i — приписыванием цифры
di-|_i к числам соответственно 2 • Л, и Л,.
Для троичной симметричной системы (S = 3) формулы для вычисления квадратного корня можно записать в виде
c"i+1 = Bi ■ З2 + di-|_i,
('i ■ l = | ('i ■ 11 — 2 • Л, ■ 3 • d,. i — '//. i.
где di-|_i равно 0 или 1,
Bi+1 = Ci+1 •sign(C-+1), Ai+1 = Ai ■ 3 + sign(C'i+1) -di+1.
Формулу для Cj_|_i можно записать при dj+i, равном 1, в виде
Ci+i = (\C'i+11 — 1) — 2 • Ai • 3 • di.|_i.
Отсюда d^|_i есть частное от деления |Сг'+1| - I па 2 • Л, • 3. т. о. вследствие алгоритма деления в троичной системе dj+i равно единице, если
2-(И+1| - 1) ^ 2- Ai-3,
или проще
|Сг+11 > ^-г ' 3.
Однако в случае | — Ai ■ 3 имеем
1
Сг+1 = | (. 1 I — 2 • Ai ■ -
Поэтому если щ+1 (остаток необработанной части числа N, рассматриваемой как число с запятой перед первой цифрой) больше 1/4, то необходимо принять значение (¿¿+i равным единице. Равенство невозможно, так как 1/4 в троичной симметричной системе точно не представимо.
Описание процедуры вычисления квадратного корня приведено в предположении, что операнд а и результат b являются массивами тритов.
procedure ternsqrt(a,b,k,l);
value а, к, I; integer к, I; integer array а, b;
comment Вычисление квадратного корня, а[ 1 : k] — b[ 1 : 1} принадлежат интервалу (0,5; 1,5) или равны нулю и представляются посредством мантиссы т[ 1 : п] в виде ' 31 '. т\ = 1;
begin integer i, j. Is, sc. g; Is := 0; b[ 1] := 1; for i := 1 step 1 until / — 1 do begin Is := Is * 9; j := 2 * i;
if j ^ к then Is := Is + a[j) * 3; if j + 1 ^ к then Is := Is + a[j + 1]; if Is < 0 then sc := — 1 else sc := 1; g := Is * sc — tern(i) * 3;
comment tern(i) — функция вычисления значения массива b с 1-го по г-й разряды как целого;
if g > 0 or (g = 0 and trinary(i + 1) > 0,25) then comment trinary(i) — функция вычисления остатка массива а, начиная с г-го разряда, как дробного; begin b[i + 1] := sc; Is := (g — tern(i) * 3) * sc — 1 end else b[i + 1] := 0;
end
end ternsqrt;
Реализация функций tern(i) и trinary(i) очевидна. Следует заметить, что выражение trinary(i + 1) > 0,25 может быть реализовано как последовательное сравнение пары к-го и (к + 1)-го тритов массива в с 11 (1 обозначает трит, равный минус единице) до первого несовпадения и знак этой разницы и будет значением выражения.
СПИСОК ЛИТЕРАТУРЫ
1. Clusker М., Hogan D., Vass P. The ternary calculating machine of Thomas Fowler // IEEE Annals of the History of Computing. 2005. 27. N 3. P. 4-22.
2. http://www.mortati.com/glusker/fowler/ternary.htm
3. Брусенцов H. П. Алгоритмы деления для троичного кода с цифрами 0, 1, — 1 // Вычислительная техника и вопросы кибернетики. Вып. 10. JL: Изд-во ЛГУ, 1974. С. 39-44.
4. Брусенцов Н. П., Маслов С. П. и др. Малая цифровая вычислительная машина "Сетунь". М.: Изд-во МГУ, 1965.
5. Гусев В. А., Мордкович А. Г. Математика: Справочные материалы. М.: Просвещение, 1990.
6. Карцев М. А. Арифметика цифровых машин. М.: Наука, 1969.
Поступила в редакцию 10.09.07
УДК 519.6
А.В. Чередниченко
ИНСТРУМЕНТАЛЬНАЯ СИСТЕМА ДЛЯ ИНТЕГРАЦИИ КОМПОНЕНТОВ ЛИНГВИСТИЧЕСКОГО ПРОЦЕССОРА. ОПИСАНИЕ И СПОСОБЫ ПРИМЕНЕНИЯ
(кафедра алгоритмических языков факультета ВМиК, e-mail: [email protected])
В данной статье рассмотрены основные механизмы работы реализованной инструментальной системы для интеграции компонентов лингвистического процессора. Описываемая в данной статье реализованная инструментальная система позволяет использовать уже существующие компоненты лингвистических процессоров в рамках целевой системы автоматической обработки текстов. Также данная инструментальная система дает возможность сравнить уже подключенные компоненты на одинаковых наборах текстов на естественном языке. После проведения сравнительного анализа компонентов можно определить точный состав модулей и словарей, которые можно будет наиболее эффективно использовать для создания отдельной системы автоматической обработки текстов для решения конкретной специфической задачи.
1. Введение. В настоящее время создание различных систем автоматической обработки текстов на естественном языке (АОТ-систем) является актуальной практической задачей. Исследованием различных аспектов (теоретических, алгоритмических, программистских), связанных с реализацией АОТ-систем, занимается одна из компьютерных наук — компьютерная лингвистика.
Как правило, АОТ-система в той или иной степени включает в свой состав лингвистический процессор (ЛП) — комплекс программ, осуществляющих автоматический анализ и синтез входного текста на естественном языке. Традиционно ЛП, построенный по модульному принципу, состоит из следующих компонент: морфологического, синтаксического, семантического и прагматического. С каждым компонентом связана своя лингвистическая база знаний (словари, грамматики, таблицы), имеющая определенную структуру [1].
При создании АОТ-систем необходимо определить, какие конкретно компоненты ЛП будут использоваться в качестве внешних, какими структурами данных будет оперировать система, какой подход будет выбран для решения поставленной задачи. Важными факторами являются как язык реализации системы, так и механизмы для хранения обрабатываемых данных и результатов обработки.
Несмотря на большое количество реализаций аналогичных компонентов лингвистического процессора, при попытке подключения какого-либо из них к реализуемой системе возникают следующие проблемы:
• несоответствие структур данных, используемых в системе и в подключаемом компоненте;
• отсутствие поддержки со стороны разработчика компонента;
• возможное несоответствие решаемой задаче лексического состава словаря, которым оперирует внешний компонент;