SURA: от нас с Робертом всем -- троекратное, симметричное URA!


Subject: SURA: от нас с Робертом всем -- троекратное, симметричное URA!
From: Sergei M. Abramov (at home) (abram@botik.ru)
Date: Mon May 07 2001 - 18:27:13 MSD


День добрый, всем!

Мы с Робертом сегодня закончили очередную ревизию статьи--пригласили написать
про УРА в журнал со смачным сокращением SCP ;-)
http://www.elsevier.nl/locate/scico/ "Science of Computer Programming".

Статья зовется: ``The Universal Resolving Algorithm and its Correctness:Inverse
Computation in a Functional Language''.

Это наш трудовой подарок В.Ф.Турчину к его замечательному юбилею.

Учитывая (пытаясь) противоречивые требования рецензентов (сократить объем на
5..10 страниц и добавить материала) нам пришлось "открыть закрома
Родины"--пришлось предать гластности штучку, котоую мы давно дискутировали, но в
тайне от народа.

Это потребовало сильно переписать (сильно сократить) Haskell пакет про URA и
сильно переписать (сильно сократить) текст статьи.

Итак--симметричный УРА. На самом деле, штука не сложная, возможно она кому-то
приходила в голову и/или бросалась в народ как идея на наших бурных семинарах.

Обычный УРА умеет решать такие задачи (замечание: здесь и ниже--угловые
скобки--просто скобки):

ura match <[X1, "ABC"],[]> 'Success -- найти такие X1, что (match [X1, "ABC"] =
'Success); ura match <[X1, "ABC"],[]> 'Failure -- найти такие X1, что (match
[X1, "ABC"] = 'Failure);
где match -- некая программа (например, проверка вхождения строки в подстроку),
<[X1, "ABC"],[]> -- класс, описывающий множество входных данных, X1 --
с-переменная, [] -- рестрикция (набор неравенств, тут--пустой) на с-переменные.
То есть, в задачах обычного УРА входные параметры неизвестны (или частично
неизвестны), выходное значение программы--фиксировано.

Симметричный УРА исключает дискриминацию между входным и выходными значениями
программы.

Ему кроме старых задач (1, 2) можно задавать и такие задачки (3-это обычное
вычисление и делается в точности так же эффективно,4 и 5 -- "диаганальный
случай", решение уравнений вида f(x)=x и др. более общих.):
1) ura match <( [X1, "ABC"], 'Success ), []> -- найти X1: match [X1, "ABC"] =
'Success; 2) ura match <( [X1, "ABC"], 'Failure ), []> -- найти X1: match [X1,
"ABC"] = 'Failure;3) ura match <( ["AB", "ABC"], X1 ), []> -- найти X1:
match ["AB", "ABC"] = X1; 4) ura match <( [X1, "ABC"], 'Error:X2), []> --
найти X1, Х2: match [X1, "ABC"] = 'Error:X2;
5) ura match <( [X1, "ABC"], X1 ), []> -- найти X1: match [X1, "ABC"] =
X1;
             ^^^^^^^^^^^^io-class^^^^^^^^^^^^^
Как оказалось, добавление функциональности в УРА приводит к сокращению его кода
и его описания. Кому интересно--смотрите ниже или спрашивайте PDF для
proof-reader-ов ;-)

Удачи

Сергей.

--------------------------------------------------------------------------------

Обычный УРА
Чтобы обсуждать симметричный УРА (SURA) надо договориться о том, что такое
обычный УРА:

Это композиция трех функций:
    a.. PPT получает программу и входной класс, и строит дерево процессов (не
интересно, все знают);
    b.. TAB -- обходит дерево в ширину, тащит через дерево входной класс,
применяя к нему (к класу) по пути все сужения, что написаны на ребрах, дойдя до
листа (пассивной конфигурации), она знает класс достижимости листа (какие данные
придут к этому листу) и какой результат (выражение с c-переменными из этого
класса) получится на выходе программы. Тем самым, строится пары (возможно
бесконечный список пар):

                входной подкласс==> с-выражение-для-результата

    То есть исходная программа преобразуется в бесконечный список правил:
"образец = результат", в терминах рефала. Все входные подклассы (левые части) в
таблице tab -- непересекаются.
    c.. INV -- проссматривает табличное представление программы, сравнивает
(clash) желаемое значение с правой частью предложения из таблицы, если можно
отождествить, то подуживает левую часть (контралируя, что это подужение не
схлопывает правую часть в пусто).
Интересные места (ну, для нас PPT и TAB не интересны ведь!) в Haskell-реализации
выглядили просто (правда буржуям приходится долго втолковывать тривиалные вещи,
типа clash и subClassCntr -- CRA-теорему).
ura :: ProgTSG -> Class -> Dval -> [(CCsub,Restr)]ura p cls out = inv (tab
(ppt p cls) cls) cls out
inv :: Tab -> Class -> Dval -> [(CCsub,Restr)]inv tab cls out = concat (map
ans tab) where ans (cls_i, ce_i) = case (clash [ce_i] [out]) of
(False, _) -> [] (True,sub') -> case cls_i' of
(_, [CONTRA]) -> [] _ -> [(sub, r)]
where cls_i' = cls_i/.sub' (sub, r) =
subClassCntr cls cls_i'

Симметричный УРА
Переходим к симметричному УРА.

Шаг 1. Вводим понятие io-класс: конструкция с с-переменными, описывающая
множество 2D-точек на плоскости "аргумент программы-результат"---просто вот
такая конструкция (и рядом лежащие):
обычный класс:
<ds, r> -- описывает множество входных данных, ds--список с-выражений,
r--рестрикция;
io-класс:
<(ds,d), r> -- описывает множество пар (входное данное, данное), ds--список
с-выражений, d--с-выражение, r--рестрикция.
функции in_ и io -- ничего особенного, конструктор, селектор:
in_ (<(ds,d), r>) =def= <ds, r> /* проекция */
io (<ds, r>, d) =def= <(ds,d), r> /* декартово произведение, если угодно */

Шаг 2. Понимаем, что каждый буржуй (изучавший унификацию, но не изучавший
clash) без объяснений и доказательств понимает, что пересечение классов есть
класс, и делается пересечение при помощи унификации (the most general unifier):

Шаг 3. Понимаем, что вместо старой исходной задачи для УРА: по заданному языку,
программе, входному классу и желаемому результату (константа), найти множетсво
всех тех входных данных, которые:

можно брать симметричную постановку исходной задачи для УРА: по заданному языку,
программе и io-классу, найти множетсво всех тех пар (входные данные-результат),
корторые:

Шаг 4. Четкое осознаем, что старый добрый TAB -- не более чем представление в
виде перечисления io-классов (непересекающихся!) графика функции программы на
входном классе cls_in = in_(cls_io)

Шаг 5. Понимаем, что Inv(...) выписанное выше, не более, чем пересечение
графика программы с исходным |cls_io|

Ну, в общем-то и все! Далее картинка:

И можно сравнить старый вариант УРА на Хаскеле, с новым вариантом (да, кодов PPT
и TAB никто ни сколько не менял):
ura :: ProgTSG -> IOClass -> [ (CCsub,Restr) ]ura p cls_io = inv (tab (ppt p
cls_in) cls_in) cls_io where cls_in = in_ cls_io
inv :: [IOClass] -> IOClass -> [ (CCsub,Restr) ]inv tab clsio = concat (map
((*.) clsio) tab)










This archive was generated by hypermail 2b25 : Mon Oct 25 2004 - 21:24:59 MSD