Re[17]: Welcome to C# 9.0
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.06.20 10:11
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

Ну, то есть как это работает: допустим, у меня есть таблица для некоторых ParameterExpression, которая задаёт их пределы.
Типа {minA} <= {a} <= {maxA}.
Теперь у меня есть выражение типа (a + 1 > 0).
Я пытаюсь его свернуть. Как это делается?
При помощи правила, которое сопоставляет выражениям вида {a} > e вот такую кракозяблу (({a} > e) || (minA > e)) && (maxA > e)). (1)
Перед этим надо превратить (a + 1 > 0) в (a > -1). (2)
Но вот у меня правило, которое вызвалось на выражении LessThan(Add(var e, Constant(int x))), Constant(int y)), вернуло оно (a > -1) и всё, поезд ушёл. Трансформатор поехал выше.
Допустим, я запихал правило 2 в первую фазу, а правило 1 — во вторую фазу трансформации.
Теперь, скажем, когда у нас в качестве minA указан {0}, а maxA — {h}, мы получаем (({a} > {-1}) || ({0} > {-1})) && ({h} > {-1}))
Тут надо заново начинать трансформацию, т.к. {0} > {-1} => {true}, ({a} > {-1}) || {true})=>{true}, {true} && ({h} > {-1}) => ({h} > {-1}). Ок, это у нас была фаза трансформации №3 — свёртка AndAlso и OrElse с конст-аргументами.
Но теперь, получается, надо заново применять вторую фазу, т.к. из той же таблицы фактов мы знаем, что {h} >= {0}, и мы должны свернуть выражение в {true}.
Итого — либо мы гоняем цикл
expr = expr.TransformEx(FoldConstants);
expr = expr.TransformEx(FoldRanges);

до достижения стационарного состояния, либо в правиле свёртки диапазонов надо возвращать не AndAlso, а AndAlso(...).TransformEx(...).
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Отредактировано 02.06.2020 10:13 Sinclair . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.