Андрей!

«Головная ячейка представления скобочного терма может быть прокси, то есть 
ссылкой на окончательное представление или снова на прокси.»
«Одновременно спрямлять ссылки.»

Получаем лес непересекающихся множеств:

https://ru.wikipedia.org/wiki/Лес_непересекающихся_множеств

У этого метода самая лучшая временна́я сложность после константы — обратная 
функция Аккермана. Недостаток — требуется дополнительное поле ранга для выбора 
чего чему присваивать. Но ранг вроде тоже небольшой (в книжке Кормена, 
Лейзерсона и др. вроде про это есть), скорее всего байта хватит.

 

С уважением,
Александр Коновалов 

 

From: Andrei Klimov andrei_AT_klimov.net <refal@botik.ru> 
Sent: Wednesday, February 13, 2019 2:11 PM
To: refal@botik.ru
Subject: Re: Коллапсируюшее представление данных

 

Александр, еще раз добрый день!

 

Я понял, о чем вы писали и зачем требуется отношение порядка. Объясню своими 
словами на подвешенных скобках.

 

Пусть (eX) и (eY) входят в два выражения e1(eX)e2 и e3(eY)e4, и при их 
сравнении выяснилось, что (eX) = (eY).

И пусть на представления (eX) и (eY) есть еще ссылки из других выражений.

Тогда замена ссылки на (eX) в первом выражении на ссылку на (eY) не освобождает 
память представления (eX).

И наоборот, замена ссылки на (eY) во втором на ссылку на (eX) не освобождает 
память представления (eY).

Более того, теряется информация про равенство (eX), или соответственно (eY), 
равным термам в других выражениях.

 

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

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

А если есть отношение порядка между представлениями, то можно выбирать 
наименьшее.

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

Но все равно процесс "затягивания" ссылок на самое "тяжелое" представление 
будет медленным и плохо предсказуемым.

 

Чтобы не терять информацию об уже обнаруженных равенствах термов, лучший (как 
мне помнится) вариант, который был придуман такой:

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

Тогда при выяснении равенства (eX) и (eY) в вышеприведенном примере головная 
ячейка, скажем, (eY) становится прокси, ссылающимся на головную ячейку (eX). 
Подмена ссылки в выражении тоже делается.

 

Теперь при каждом вхождении в скобки нужно проверять, не на прокси ли мы 
попали, и, если да, идти дальше. Одновременно спрямлять ссылки.

 

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

Теперь я вспомнил, что отсутствие "идеальных" решений и есть главная причина, 
из-за которой идея не пошла в массы = в реализации Рефала.

Спасибо, вот сейчас мы нечаянно на них вышли и запротоколировали.

Может, где-то когда-то кому-то пригодится.

 

И по-прежнему, интересно узнать, использовалось ли такое коллапсирование или 
обсуждавшаяся табуляция в каких-нибудь системах.

Если кто наткнется или уже знает, напишите, пожалуйста.

 

Всего наилучшего,

Андрей

 

On Wed, Feb 13, 2019 at 1:08 PM Andrei Klimov andrei.klimov_AT_gmail.com 
<http://andrei.klimov_AT_gmail.com>  <refal@botik.ru <mailto:refal@botik.ru> > 
wrote:

Александр, тогда я видимо совсем вас не понял – ни псевдокод, ни объяснение 
словами в предыдущем письме:

 

ср, 13 февр. 2019 г., 0:18 Александр Коновалов a.v.konovalov87_AT_mail.ru 
<http://a.v.konovalov87_AT_mail.ru>  <refal@botik.ru <mailto:refal@botik.ru> >:
Добрый вечер, Сергей!
> 2.  Наконец, если нам пришлось делать длинное сравнение и в конце выяснилось, 
> что термы таки равны, то мы делаем "коллапсирующие джунгли" -- делаем 
> присваивание: p2 = p1, L2=L1 (второе лишнее, но пусть будет).  Тут и память 
> освободилась и следующий раз сравнение на равенство пройдет быстрее ;-)
А если у нас в поле зрения есть несколько экземпляров одинаковых пар (p1, L1), 
(p2, L2). В первый раз сравниваются пары в порядке (p1, L1) == (p2, L2) и мы 
присвоили p1 := p2. В другой раз (другие экземпляры) сравнились в порядке (p2, 
L2) == (p1, L1) и коллапсировались уже p2 := p1. Тогда память не освободится. 
Такое может быть?

 

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

И я тоже виноват, что не пояснил, что подразумевал. Договорю.

 

Лучше всего рассмотреть "подвещенные" скобки: скобочный терм (e0) 
представляется ссылкой на представление e0. Это ссылка хранится в месте терма 
(e0) в выражениях, в которые он входит. То есть, 

*       <представление выражение e1(e0)e2> = <представление e1> <ссылка на 
(e0)> <представление e2>

Заметим, что это рассуждение не зависит от того, массивное представление 
выражений или одно- или двунаправленное списочное.

 

Если в процессе отождествления повторных переменных были обнаружены равные 
термы (e0), входящие в два выражения, то в одном из выражений ссылка на (e0) 
заменяется на вторую, а второе представление (e0) может освободиться (сборкой 
мусора или по счетчику ссылок).

 

Александр, тонкость, о которой вы пишите, присутствует в таком представлении с 
такой операцией сравнения?

 

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

 

On Wed, Feb 13, 2019 at 12:17 PM Александр Коновалов a.v.konovalov87_AT_mail.ru 
<http://a.v.konovalov87_AT_mail.ru>  <refal@botik.ru <mailto:refal@botik.ru> > 
wrote:

Доброе утро, Андрей!

Спасибо за интересное письмо!

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

Я имел ввиду другое. Поясню псевдокодом:

def equals(lhs, rhs):
    if lhs.L == 0 && rhs.L == 0:
        return True
    elif lhs.L == rhs.L && strcmp(lhs.p, rhs.p) == 0:
        // коллапсируем
        lhs.p := rhs.p
        return True
    else:
        return False

x1 := (p1, L)
x2 := (p2, L)
x3 := (p1, L)
x4 := (p2, L)

equals(x1, x2)
equals(x4, x3)

Предполагается, что p1 и p2 — указатели на разные строки с одинаковым 
содержимым. После выполнения этого псевдокода будет x1.p ≡ x2.p ≡ p2 и x3.p ≡ 
x4.p ≡ p1. Т.е. память не освободится. Просто переменные поменяются ссылками. 
Поэтому и нужно дополнительное ранжирование. Вроде вот этого:

«То есть в ящиках поддерживаются индексы в некотором отношении линейного 
порядка для последующего быстрого сравнения»

Либо можно сравнивать указатели как числа и присваивать большему меньшее.

 

Я не понял, зачем может понадобится отношение порядка для коллапсирования.

 

«Чтобы экономить память (и надеялись — и время), для системы Сантра Игоря 
Шенкова я ещё в 80-е годы разработал библиотечку ROTAB (References for Order 
Tabulation) для „коллапсирования рефал-выражений в ящики“ (выдаётся ссылка на 
тот же ящик, если уже формировался ящик с таким же содержимым) и табуляции их 
отношения порядка.»

Когда-то я подумывал о похожей системе для Рефала с массивным представлением. 
Поддерживается глобальное хеш-множество для всех скобочных термов в поле 
зрения, и, когда надо построить новый скобочный терм, вместо нового выбирается 
уже существующий. Нашёл, что для этой цели нужно использовать кольцевые хеши 
(rolling hash <https://www.google.ru/search?q=rolling+hash&tbm=isch> ), 
поскольку они образуют группу. Это значит, что если известны хеши двух строк, 
хеш конкатенации вычисляется за константу. Если известен хеш строки и хеш её 
префикса, то хеш суффикса тоже вычисляется за константу (для известного хеша 
суффикса — аналогично). Вообще, я ещё летом поминал в рассылке кольцевые хеши.

Но это были пустые размышления, поскольку тогда у меня не было своей нормальной 
реализации с векторами (нет и сейчас), а также понимал, что оверхед на всё это 
будет больше, чем потенциальная выгода.

 

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

 

Всего наилучшего,

Андрей

  • Кол... Andrei Klimov andrei_AT_klimov . net
    • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
      • ... Andrei Klimov andrei . klimov_AT_gmail . com
        • ... Sergei Romanenko sergei . romanenko_AT_supercompilers . ru
          • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
        • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
          • ... Andrei Klimov andrei_AT_klimov . net
        • ... Andrei Klimov andrei_AT_klimov . net
          • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
            • ... Andrei Klimov andrei_AT_klimov . net
              • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
                • ... Andrei Klimov andrei_AT_klimov . net
                • ... Andrei Klimov andrei_AT_klimov . net
          • ... Anton Orlov orlovan_AT_gmail . com
            • ... Александр Коновалов a . v . konovalov87_AT_mail . ru
    • ... Andrei Klimov andrei_AT_klimov . net

Ответить