Project

General

Profile

Actions

Feature #4219

closed

Схлопывание константных выражений

Added by Alexander Kamkin over 11 years ago. Updated over 11 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
-
Target version:
Start date:
06/11/2013
Due date:
% Done:

100%

Estimated time:
Published in build:
0.2.2

Description

Можно ли вычислять константные выражения при запуске солвера. Дело в том, что у меня используются свои (неполноценные) классы для Value и Variable. Из-за чего происходит NullPointerException.

см. #4127.

Actions #1

Updated by Sergey Smolov over 11 years ago

  • Status changed from New to Feedback
  • Assignee changed from Sergey Smolov to Alexander Kamkin

Саша, схлопывание константных выражений осуществляется на этапе конструирования объектов-операций (Operation), входящих в состав ограничения (Constraint), т.е. ещё до запуска собственно солвера. Сделано это потому, что все ключевые объекты, составляющие внутреннее представление ограничений в библиотеке (классы Constraint, Syntax, Function, Operation, etc.) фактически, неизменяемы (большинство полей имеет атрибут final), и модифицировать их "потом" нельзя.
Таким образом, схлопывание константных выражений превращается в сугубо внутреннюю оптимизацию библиотеки. По моему мнению, пользователи вообще не должны об этом знать, посему метод performConstant, выполняющий схлопывание, задумывался приватным. То, что сейчас он публичный - мой косяк.

Actions #2

Updated by Alexander Kamkin over 11 years ago

  • Assignee changed from Alexander Kamkin to Sergey Smolov

Мысль понял. Попробую что-нибудь придумать.

P.S. Вычисление константных выражений компиляторщики называют "Constant folding". Предлагаю переименовать метод performConstant в foldConstants.

Actions #3

Updated by Alexander Kamkin over 11 years ago

    @Override
    public int calculate()
    {
        switch(this.getData().getType().getType())
        {
            case LOGIC_INTEGER:
                return (Integer) this.getData().getValue();
            case BIT_VECTOR:
                return ((BigInteger)this.getData().getValue()).intValue();
            case LOGIC_BOOLEAN:
                if ((Boolean) this.getData().getValue())
                    return 1;
                else
                    return 0;
            case LOGIC_REAL:
                return ((Double)this.getData().getValue()).intValue();
            case UNKNOWN:
                break;
        }
        return 0;
    }

Думаю, правильнее вместо этого switch добавить в интерфейс IData метод intValue, осуществляющий конвертацию значения в тип int.

Actions #4

Updated by Alexander Kamkin over 11 years ago

Возможно правильнее использовать не int, а BigInteger.

Actions #5

Updated by Alexander Kamkin over 11 years ago

Кстати, схлопывание констант делается только для параметров (для repeat и подобных конструкций)? Для HDL-кода нужно аккуратно делать вычисление констант, поскольку так в основном битовые вектора, причем с поддержкой неопределенных значений (X, Z). Лучше вычисления делать только для параметров.

Actions #6

Updated by Alexander Kamkin over 11 years ago

Я подозреваю (не проверял), что NullPointerException происходит из-за того, что в моей реализации IVariable метод getData возвращает null (такая задумка - у переменной нет значения). Если в выражении присутствует переменная, схлопывания не должно происходить. Схлопываться должны только выражения, состоящие из значений.

Actions #7

Updated by Alexander Kamkin over 11 years ago

Еще у моих данных getType() возвращает null.

switch(this.getData().getType().getType()) {...}

Это я как-нибудь доделаю. Но причина не только в этом.

Actions #8

Updated by Alexander Kamkin over 11 years ago

Даже если избавиться от NPE возникнет CastException. Так как мой getValue() возвратит объект моего класса, а не Integer и т.п.

Возможное решение у IData сделать метод, получающий значение нужно типа. Нужно обсудить с Андреем.

Actions #9

Updated by Andrei Tatarnikov over 11 years ago

См. таск #4246

Я написал калькулятор для основных стандартных операций EStandardOperation (MINUS, PLUS, ADD, SUB, MUL, DIV, REM, MOD) и API-классы для создания/расширения калькуляторов (см. класс syntax.Calculator). А у класса Operation появился метод для схлопывания подвыражений:

public ISyntaxElement reduce(ICalculator calculator, int flags)

Его можно использовать следующим образом

syntax.addFormula(
    new Formula(
        new Operation(
            EStandardOperation.EQ,
            a,
            new Operation(
                EStandardOperation.ADD,
                new Value(intType.valueOf("2", 10)),
                new Value(intType.valueOf("3", 10))).reduce(CalculatorForStandard.getInstance(), 0)
            )
        )
    );

Данный код помогает упростить выражение (+ 2 3) в число 5.

Actions #10

Updated by Andrei Tatarnikov over 11 years ago

Сергей, посмотри старую релизацию (старые методы calculate в операциях и других классов). Возможно, они больше не нужны.

Actions #11

Updated by Andrei Tatarnikov over 11 years ago

  • % Done changed from 0 to 100

Реализовано. Старый ненужный код удалён. См. r98.

Actions #12

Updated by Andrei Tatarnikov over 11 years ago

  • Status changed from Feedback to Resolved
Actions #13

Updated by Sergey Smolov over 11 years ago

  • Status changed from Resolved to Closed
  • Published in build set to 0.2.2
Actions

Also available in: Atom PDF