(де)Сереалзиация логичесого условия языка программирования?
От: Time Россия  
Дата: 06.06.07 10:09
Оценка:
Всем привет!
Этот топик в моём мозу является логическим продолжением топика Помогите реализовать в объектах
Автор: Time
Дата: 04.06.07
. В принципе для понимания предыдущий пост можно не читать.
Хочется реалзиовать логические услвия.
Так вот в языке программирования как ни странно логические условия уже есть
 if(a && b .... ((()))....(())

Элементарными условиями я могу сделать классы с интерфейсом IUslovie в котором есть метод Check() возвращающий true или false, короче сделать чтобы a, b (см. пример кода) были реалзованы проблем нет . Проблема в том что мне надо как то хранить все то что записано в скобке.
Идеальным в псеводкоде могу изобразить для себя следующий вариант:

 if(DataBase.GiveMeNeededUslovie())
   Action.DoIt();


Вот если бы в БД можно было сохраить прям в текстовом виде строку
a && b || (c && !d) (в общем все изыски и прелести условий языка программирования)
а потом медод DataBase.GiveMeNeededUslovie эту строку читал и проверил подставив в if, то было всё классно.
Вопрос: как это релизовать?

З.Ы.: для тех кто читал предыдущий пост: а картинки потом из этой строки распарсив можно нарисовать

Всем спасибо, простите за сумбур!
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: (де)Сереалзиация логичесого условия языка программирован
От: lazymf Россия  
Дата: 06.06.07 10:35
Оценка:
Здравствуйте, Time, Вы писали:

T>Всем спасибо, простите за сумбур!


Вот с сумбуром перебор, приходится угадывать что требуется. Представить выражение в виде дерева и научить узлы сериализоваться рекурсивно вызывая сериализацию нижележащих выражений — что-то такое? Тогда что не ясно?
... <<np: silent>>
Re: (де)Сереалзиация логичесого условия языка программирован
От: ZevS  
Дата: 06.06.07 11:15
Оценка: 2 (1)
Здравствуйте, Time, Вы писали:

Да харни хоть в XMLе. Построить по нему дерево объектов — не пороблема.
Паттерны Composite, Interpreter — у GoF есть пример прямо того что тебе нужно.
Re: (де)Сереалзиация логичесого условия языка программирован
От: SergH Россия  
Дата: 06.06.07 12:03
Оценка: 2 (1)
Здравствуйте, Time, Вы писали:

T> Элементарными условиями я могу сделать классы с интерфейсом IUslovie в котором есть метод Check() возвращающий true или false, короче сделать чтобы a, b (см. пример кода) были реалзованы проблем нет . Проблема в том что мне надо как то хранить все то что записано в скобке.


Нужно сделать фабрику, которая будет создавать новый объект IUslovie, создавая его из двух старых и операции (и/или/что-тебе-ещё-понадобится). Сереализовать такое проще всего в обратной польской записи.
Делай что должно, и будь что будет
Re: (де)Сереалзиация логичесого условия языка программирован
От: GlebZ Россия  
Дата: 06.06.07 12:26
Оценка: 3 (1)
Здравствуйте, Time, Вы писали:

Примерное (и сокращенное) решение:


    public interface IBasePredicate
    {
    }
    public interface IBinary<T>:IBasePredicate
    {
        bool Compare(T x);
    }
    public interface ILogical<T> : IBasePredicate where T : IComparable<T>
    {
        List<FormulaCalculate<T>> Calculations{get;}
        IEnumerable<T> Execute(IEnumerable<T> source);
    }
    [Serializable]
    public class FormulaCalculate<T> where T:IComparable<T>
    {
        [Serializable]
        public class EqualFilter<V>:IBinary<V> where V:IComparable<V>
        {
            V _compareValue;
            public EqualFilter(V compareValue)
            {
                _compareValue = compareValue;
            }
            public bool Compare(V x)
            {
                return (_compareValue.CompareTo(x)==0);
            }
        }
        [Serializable]
        public class OrExecuter<V>:ILogical<V> where V:IComparable<V>
        {
            List<FormulaCalculate<V>> FormulaCalculate=new List<FormulaCalculate<V>>();
            public List<FormulaCalculate<V>> Calculations
            {
                get{
                    return FormulaCalculate;
                }
            }
            public IEnumerable<V> Execute(IEnumerable<V> source)
            {
                List<V> result=new List<V>();
                Dictionary<V, int> union=new Dictionary<V,int>();
                foreach(FormulaCalculate<V> calc in Calculations)
                {
                    IEnumerable<V> calculated=calc.Execute(source);
                    foreach(V t in calculated)
                        if (!union.ContainsKey(t))
                        {
                            union.Add(t, 0);
                            result.Add(t);
                        }
                }
                return result;
            }
        }

        private List<IBasePredicate> _predicates = new List<IBasePredicate>();
        public List<IBasePredicate> Predicates { get { return _predicates; } }
        private List<T> ExecuteBinary(IEnumerable<T> source, IBinary<T> predicate)
        {
            return ((List<T>)source).FindAll(predicate.Compare);
        }
        public IEnumerable<T> Execute(IEnumerable<T> source)
        {
            IEnumerable<T> valuesCollection = new List<T>();
            foreach (IBasePredicate obj in Predicates)
            {
                if (obj is IBinary<T>) valuesCollection = ExecuteBinary(valuesCollection, obj as IBinary<T>);
                else 
                if (obj is ILogical<T>) valuesCollection = (obj as ILogical<T>).Execute(valuesCollection);
            }
            return valuesCollection;
        }
        public FormulaCalculate<T> Equal(T x)
        {
            Predicates.Add(new EqualFilter<T>(x));
            return this;
        }
        public FormulaCalculate<T> Or(FormulaCalculate<T> elem1, FormulaCalculate<T> elem2)
        {
            OrExecuter<T> orExecuter=new OrExecuter<T>();
            orExecuter.Calculations.Add(elem1);
            orExecuter.Calculations.Add(elem2);
            Predicates.Add(orExecuter);
            return this;
        }
    //    ....
    
}

Здесь идет фильтрация коллекции, но можешь изменить на то, что тебе нужно и добавить различные условия.
Использование:
int[] a={10,20,30}
FormulaCalculate<int> dest = 
               new FormulaCalculate<int>().Or(
                          new FormulaCalculate<int>().Equal(10), 
                          new FormulaCalculate<int>().Equal(20));
IEnumerable<int> l=dest.Execute(list);

Объект сериализуемый. Если нужно сериализовать в xml — то легко дописать.
Re: (де)Сереалзиация логичесого условия языка программирован
От: MatFiz Россия  
Дата: 06.06.07 13:00
Оценка: 1 (1)
Здравствуйте, Time, Вы писали:

Возможно, в твоем случае удобным окажется применение IronPython.
Там можно задать словарь локальных переменных (перечислить, что a = 3; b = 7.3; c = true).
После в контексте заданных локальных переменных вычислить значение выражения.
Я так делал почти год назад.
Писал что-то вроде
using IronPython;

// ... код, код, код
PythonEngine evaluator = new PythonEngine();
Dictionary<string, object> localVariables = new Dictionary<string, object>();
localVariables["a"] = 3;
localVariables["b"] = 7.3;
bool result = (bool)evaluator.Evaluate("a + b > 10", localVariables);



Можно также применить компилятор шарпа или любого другого подходящего языка, но тогда выражение придется оборачивать методом, а метод — классом, компилить код в сборку, загружать сборку и через рефлекшен дергать сгенеренный метод.
Хотя может быть можно и без этого .
How are YOU doin'?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.