Re[20]: Welcome to C# 9.0
От: rameel https://github.com/rsdn/CodeJam
Дата: 02.06.20 14:10
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Есть искушение, к примеру, задавить на первом проходе все Subtract в Add(a, Negate(b)), чтобы сократить объём правил.

S>И так же LessThan в Not(GreaterThanOrEqual).

Можно еще попробовать сделать реассоциацию выражений, в приниципе, ты это и предложил только еще с перестановкой, чтобы b + a ==> a + b и b < a ==> в a > b, чтобы сократить количество правил, чтобы вот такое ((a + c1) + b) + c2 превратить в такое c2 + c1 + a + b, что обнаружится при constant folding

S>Кстати, чего я не понял — зачем такой огромный switch в TransformInternal.

S>Там же можно просто по типам свитчится, а не по NodeType.

Наверное можно было бы, но свитч по типам он последовательный, а свитч на enum по таблице переходов работает, там 22-23 ветки, хотя да код подсократился бы
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[20]: Welcome to C# 9.0
От: rameel https://github.com/rsdn/CodeJam
Дата: 02.06.20 14:26
Оценка: 74 (1)
Здравствуйте, Sinclair, Вы писали:

S>Прикрутил. Вроде работает.




S>Теперь надо научиться сворачивать выражения типа ((i+1)-(i+2)+1).


Гугл подсказывает такие ссылки Reassociation according to Muchnick и https://llvm.org/doxygen/Reassociate_8cpp_source.html

Google book: Advanced Compiler Design Implementation
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[17]: Welcome to C# 9.0
От: rameel https://github.com/rsdn/CodeJam
Дата: 02.06.20 14:36
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

R>>Хотелось бы, чтобы смелее смотрели на то, что вокруг сделано и как.


НС>А с чего ты взял что они не смотрят? Language design process у шарпа сейчас более менее открытый.


Ключевое слово смелее. А так да, хорошо что не стоят на месте

НС>А делать из него экспериментальный никто не будет, не то назначение у языка.


Сейчас они и так экпериментируют, те же шейпы взять
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[21]: Welcome to C# 9.0
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.06.20 14:59
Оценка:
Здравствуйте, rameel, Вы писали:

R>Можно еще попробовать сделать реассоциацию выражений, в приниципе, ты это и предложил только еще с перестановкой, чтобы b + a ==> a + b и b < a ==> в a > b, чтобы сократить количество правил, чтобы вот такое ((a + c1) + b) + c2 превратить в такое c2 + c1 + a + b, что обнаружится при constant folding

Вот тут я пока не очень понимаю, как это сделать. Ну, то есть я могу выделять константы — правило про (e1 + c1) + (e2 + c2) => (e1 + e2) + {c1+c2} и подобные есть.
А вот для ((a + c1) + b) + c2 правила нету, и такие выражения остаются как есть.
S>>Кстати, чего я не понял — зачем такой огромный switch в TransformInternal.
S>>Там же можно просто по типам свитчится, а не по NodeType.

R>Наверное можно было бы, но свитч по типам он последовательный, а свитч на enum по таблице переходов работает, там 22-23 ветки, хотя да код подсократился бы
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[18]: Welcome to C# 9.0
От: Ночной Смотрящий Россия  
Дата: 02.06.20 19:50
Оценка:
Здравствуйте, rameel, Вы писали:

НС>>А делать из него экспериментальный никто не будет, не то назначение у языка.

R>Сейчас они и так экпериментируют, те же шейпы взять

Те же шейпы из релиза убрали, потому что дизайн их недостаточно готов для релиза. В этом ключевое отличие от Немерли, где каждый тащит в язык что хочет.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[21]: Welcome to C# 9.0
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.06.20 02:52
Оценка:
Здравствуйте, rameel, Вы писали:

R>Гугл подсказывает такие ссылки Reassociation according to Muchnick и https://llvm.org/doxygen/Reassociate_8cpp_source.html

Спасибо. Помогло. Хотя Мучниковские правила какие-то избыточные — R9 и R10 не нужны:
R1:  c1 + c2 = c1+c2
R3:  c1 * c2 = c1*c2
R5:  c1 - c2 = c1-c2

R2:  t + c  = c + t
R4:  t * c  = c * t
R6:  t - c  = (-c) + t

R7:  t1 + (t2 + t3) = (t1 + t2) + t3
R8:  t1 * (t2 * t3) = (t1 * t2) * t3 

R9:  (c1 + t) + c2 = (c1+c2) + t
R10: (c1 * t) * c2 = (c1*c2) * t

Выражения слева матчатся, соответственно, правилами R2 и R4; константы уезжают налево: c2 ~ (c1 ~ t); дальше срабатывают правила R7 и R8, получая как раз (c2 ~ c1) ~ t, оттуда по правилам R1/R3 получаем финальное выражение из константы и нашего терма.
Хорошо, что такие вещи вылавливает сразу компилятор C#.

R>Google book: Advanced Compiler Design Implementation

Да, давненько я не перечитывал Аппеля.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[22]: Welcome to C# 9.0
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.06.20 03:20
Оценка: +1
Здравствуйте, Sinclair, Вы писали:
S>Да, давненько я не перечитывал Аппеля.
Короче, теперь остро не хватает шейпов или вроде того. Потому что все правила с константами приходится повторять для всех числовых типов.
Либо надо допиливать как-то так:
Multiply(Constant(Type t, var x) e, _) when t.IsNumeric && Convert.ToDouble(x) == 0.0 => e,                                // 0 * e => 0
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[22]: Welcome to C# 9.0
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.06.20 12:18
Оценка:
Здравствуйте, Sinclair, Вы писали:
R>>Google book: Advanced Compiler Design Implementation
S>Да, давненько я не перечитывал Аппеля.
В общем, с range checking как-то пока не выходит.
Проблемы с выражениями типа j-1 < w, если известно, что j < w.
Арифметические реассоциации превращают это дело в -1 + j < w
И вот тут начинаются приключения, потому что я хочу одновременно
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[23]: Welcome to C# 9.0
От: rameel https://github.com/rsdn/CodeJam
Дата: 03.06.20 14:38
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>В общем, с range checking как-то пока не выходит.

S>Проблемы с выражениями типа j-1 < w, если известно, что j < w.
S>Арифметические реассоциации превращают это дело в -1 + j < w
S>Надо как-то из этого сделать true.

Можно хранить свойства отношений больше/меньше/равно для каждой переменной. То есть если известно, что j < w то для j заводится информация об этом в отношении w также как для w в отношении j. Далее, если отбросить переполнение типов, то исходить от истинности условий, что j — c < w равно как и j < w + c. Остается прописать правила истинности и проверять это отдельным проходом.
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[3]: Summer of Code ...
От: IT Россия linq2db.com
Дата: 03.06.20 15:32
Оценка: +2
Здравствуйте, VladD2, Вы писали:

VD>Им надо меня с Хардкейсом на работу взять и дать нам человек 5 в подчинение. Будут тогда супер-макросы через год-два.


Боюсь вы опять улетите в дальние дали. Не надо. Пусть C# живёт.
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Welcome to C# 9.0
От: IT Россия linq2db.com
Дата: 03.06.20 15:37
Оценка:
Здравствуйте, vmpire, Вы писали:

V>Про функциональные языки не скажу, но что будет если поменять порядок объявлений в классе? Всё же поедет. А если типы данных поменянных членов совпадут, то ошибка ещё и не сразу вылезет.


Что будет если поменять порядок объявления параметров в методе?
Если нам не помогут, то мы тоже никого не пощадим.
Re[24]: Welcome to C# 9.0
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.06.20 16:12
Оценка:
Здравствуйте, rameel, Вы писали:

R>Можно хранить свойства отношений больше/меньше/равно для каждой переменной. То есть если известно, что j < w то для j заводится информация об этом в отношении w также как для w в отношении j.

Это уже сделано.
R>Далее, если отбросить переполнение типов, то исходить от истинности условий, что j — c < w равно как и j < w + c. Остается прописать правила истинности и проверять это отдельным проходом.
Вот непонятно, что значит "исходить из истинности условий". И что такое "правила истинности". В моём воображении всё работает примерно так: есть правила редукции. В конце концов мы должны прийти к выражению из одних констант, которое свернётся в true. Для range мы подставляем в сравнение минимальное значение — если даже оно заведомо не меньше правой части (редукция в false), то и всё выражение false.
Если при подстановке максимального значения получаем true, то и всё выражение true. Если же нам не удаётся редуцировать границы диапазона таким образом, то, значит, придётся честно вычислять выражение в рантайме.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[18]: Welcome to C# 9.0
От: IT Россия linq2db.com
Дата: 03.06.20 16:16
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Итого — либо мы гоняем цикл


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

ЗЫ. Код был написан на коленке за недельку в качестве изучения новых возможностей ПМ. Так что строго не судите.
Если нам не помогут, то мы тоже никого не пощадим.
Re[18]: Welcome to C# 9.0
От: IT Россия linq2db.com
Дата: 03.06.20 17:20
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Но теперь, получается, надо заново применять вторую фазу, т.к. из той же таблицы фактов мы знаем, что {h} >= {0}, и мы должны свернуть выражение в {true}.


Тебе скорее всего нужен метод, в котором ты сам будешь управлять необходимостью повторных трансформаций, т.к. это напрямую зависит от самих трансформаций.
Если нам не помогут, то мы тоже никого не пощадим.
Re[20]: Welcome to C# 9.0
От: IT Россия linq2db.com
Дата: 03.06.20 17:26
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, rameel, Вы писали:

S>Тут меня смущает потенциальная непроизводительность — эти трансформации работают в основном на уровне листьев, поэтому перетрансформация отдельной веточки интуитивно дешевле, чем полный проход по дереву.

В linq2db работает версия, которая позволяет останавливать трансформацию вообще. Т.е. в таких вот непонятных случаях мы текущую трансформацию останавливаем, но перед этим запускаем новую с нужного места.

S>С другой стороны, может тут экономиS>Кстати, чего я не понял — зачем такой огромный switch в TransformInternal.


Стырено из linq2db.
Если нам не помогут, то мы тоже никого не пощадим.
Re[23]: Welcome to C# 9.0
От: IT Россия linq2db.com
Дата: 03.06.20 17:41
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Короче, теперь остро не хватает шейпов или вроде того. Потому что все правила с константами приходится повторять для всех числовых типов.


Сделай gemeric метод для трансформаций с этими типами и гоняй по кругу. Ну это так, чтоб совсем не мучиться
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Summer of Code ...
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.06.20 19:12
Оценка:
Здравствуйте, IT, Вы писали:

IT>Боюсь вы опять улетите в дальние дали. Не надо. Пусть C# живёт.


Вот он так и будет жить до нашей пенсии.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Welcome to C# 9.0
От: vmpire Россия  
Дата: 03.06.20 19:31
Оценка:
Здравствуйте, IT, Вы писали:

V>>Про функциональные языки не скажу, но что будет если поменять порядок объявлений в классе? Всё же поедет. А если типы данных поменянных членов совпадут, то ошибка ещё и не сразу вылезет.


IT>Что будет если поменять порядок объявления параметров в методе?

Очевидно, будет ошибка. Представьте, например, метод с двумя строковыми параметрами: строка формата и форматируемое значение.
А потои автор метода решил их поменять местами. При компиляции ничего не развалилось, при выполнении будет неправильный результат.
Re[24]: Welcome to C# 9.0
От: Sinclair Россия https://github.com/evilguest/
Дата: 04.06.20 02:19
Оценка:
Здравствуйте, IT, Вы писали:
IT>Сделай gemeric метод для трансформаций с этими типами и гоняй по кругу. Ну это так, чтоб совсем не мучиться
Ну так возможность сделать генерик-метод как раз ограничена отсутствием шейпов
Мне же надо что-то вроде
Add(Constant(T x), Constant(T y)) => Constant(x+y)


Мысль, которую думал ночью: сделать CalculateBinary(ExpressionType type, MethodInfo method, Constant left, Constant right), в который и делегировать все Binary операции c константами.
Там же надо аккуратно — если есть метод, то вызвать его (все же знают, что "Hello, "+ "world" — это ExpressionType.Add c Method == string.Concat?).
Если нет метода — то уже свитчиться по типу выражения и вычислять его. Если пренебречь checked, то можно просто конвертировать обе константы в дабл, а потом приводить результат обратно к node.Type при помощи Convert.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[21]: Welcome to C# 9.0
От: Sinclair Россия https://github.com/evilguest/
Дата: 04.06.20 02:25
Оценка:
Здравствуйте, IT, Вы писали:

IT>В linq2db работает версия, которая позволяет останавливать трансформацию вообще. Т.е. в таких вот непонятных случаях мы текущую трансформацию останавливаем, но перед этим запускаем новую с нужного места.

Ну, мне в итоге пришлось таки сделать трансформацию в цикле. Иначе приходится писать в разы больше правил для обеспечения протаскивания трансформации вверх.
И трансформацию отдельных подветочек тоже пришлось сделать — лобовой подход с range checking не проходит. Он навешивает на каждое сравнение параметра два дополнительных сравнения, из которых не более одного можно свернуть в константу, в итоге дерево неконтролируемо растёт.
Так что окончательный вариант проверялки диапазона выглядит так:
            Expression CheckRange(Expression node, ParameterExpression left, Expression right)
            {
                var range = variableRanges[left];
                if (range.maxVal != null && Arithmetic.Simplify(MakeBinary(node.NodeType, range.maxVal, right), variableRanges) is ConstantExpression rangeMatch1 && (bool)rangeMatch1.Value == true)
                    return rangeMatch1;
                if (range.minVal != null && Arithmetic.Simplify(MakeBinary(node.NodeType, range.minVal, right), variableRanges) is ConstantExpression rangeMatch2 && (bool)rangeMatch2.Value == false)
                    return rangeMatch2;
                return node;
            }

Вызывается он вот так:
    LessThan(Parameter pe, var e) when variableRanges.ContainsKey(pe) => CheckRange(expr, pe, e),
        LessThanOrEqual(Parameter pe, var e) when variableRanges.ContainsKey(pe) => CheckRange(expr, pe, e),


S>Кстати, чего я не понял — зачем такой огромный switch в TransformInternal.

IT>Стырено из linq2db.
А, ок.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.