/// <summary>
        /// Построение полинома Жегалкина по набору коэффициентов с учетом порядка переменных.
        /// </summary>
        /// <param name="coefficients">Коэффициенты полинома Жегалкина</param>
        /// <param name="variables">Набор переменных в заданном формулой порядке.</param>
        /// <returns>Формула для заданного набора коэффициентов</returns>
        public static BooleanFormula ZhegalkinPolynomial(bool[] coefficients, List <BooleanVariable> variables)
        {
            if (coefficients.Length == 0)
            {
                throw new Exception("Длина набора коэффициентов должна быть степенью двойки!");
            }
            BooleanFormula result;
            //создать список монотонных конъюнкций
            List <BooleanFormula> monomials = new List <BooleanFormula>();

            for (int index = 1; index < coefficients.Length; index++)
            {
                //если коэффициент равен 1 создаем моном
                if (coefficients[index])
                {
                    result = null;
                    //определяем список переменных, входящих в моном
                    for (int j = 0; j < variables.Count; j++)
                    {
                        if (((index >> j) & 1) == 1)
                        {
                            //(variableCount - j)-ая переменная из списка variables входит в моном
                            if (result == null)
                            {
                                result = variables[variables.Count - j - 1].ShallowClone();
                            }
                            else
                            {
                                result = new BinaryOperation(BooleanOperations.AND, variables[variables.Count - j - 1].ShallowClone(), result);
                            }
                        }
                    }
                    monomials.Add(result);
                }
            }
            //отсортировать по длине
            monomials.Sort((f1, f2) => f1.Depth.CompareTo(f2.Depth));
            //свободный член как вырожденный случай монотонной конъюнкции обрабатываем отдельно
            if (coefficients[0])
            {
                monomials.Insert(0, new BooleanConstant(true));
            }
            //если список пуст, добавить константу 0
            if (monomials.Count == 0)
            {
                monomials.Add(new BooleanConstant(false));
            }
            //соединить связкой XOR
            result = monomials[monomials.Count - 1];
            for (int i = monomials.Count - 2; i >= 0; i--)
            {
                result = new BinaryOperation(BooleanOperations.XOR, result, monomials[i]);
            }
            return(result);
        }
        /// <summary>
        /// Совершенная КНФ для булевой функции на заданном наборе переменных.
        /// </summary>
        /// <param name="function">Булева функция</param>
        /// <param name="variables">Набор переменных, определяющий порядок и имена переменных</param>
        /// <returns>Совершенная КНФ булевой функции</returns>
        public static BooleanFormula PerfectCNF(BooleanFunction function, List <BooleanVariable> variables)
        {
            if (function.VariableCount > variables.Count)
            {
                throw new Exception("Недостаточно переменных в списке!");
            }
            BooleanFormula result;
            //создать список элементарных конъюнкций
            List <BooleanFormula> disjunctions = new List <BooleanFormula>();
            int length = 1 << function.VariableCount;

            for (int index = 0; index < length; index++)
            {
                //если значение на наборе равно 1 создаем эл. конъюнкцию
                if (!function[index])
                {
                    //отдельно последняя переменная (инициализация)
                    if ((index & 1) == 0)
                    {
                        result = variables[variables.Count - 1].ShallowClone();
                    }
                    else
                    {
                        result = new UnaryOperation(variables[variables.Count - 1].ShallowClone());
                    }
                    //определяем какие переменные с отрицанием, какие - без
                    for (int j = 1; j < function.VariableCount; j++)
                    {
                        if (((index >> j) & 1) == 0)
                        {
                            //(variableCount - j)-ая переменная из списка variables входит без отрицания
                            result = new BinaryOperation(BooleanOperations.OR, variables[variables.Count - j - 1].ShallowClone(), result);
                        }
                        else//с отрицанием
                        {
                            result = new BinaryOperation(BooleanOperations.OR, new UnaryOperation(variables[variables.Count - j - 1].ShallowClone()), result);
                        }
                    }
                    disjunctions.Add(result);
                }
            }
            //если список пуст, добавить константу 1
            if (disjunctions.Count == 0)
            {
                disjunctions.Add(new BooleanConstant(true));
            }
            //соединить связкой AND
            result = disjunctions[disjunctions.Count - 1];
            for (int i = disjunctions.Count - 2; i >= 0; i--)
            {
                result = new BinaryOperation(BooleanOperations.AND, disjunctions[i], result);
            }
            return(result);
        }
Example #3
0
 /// <summary>
 /// Совершенная КНФ для булевой функции на заданном наборе переменных.
 /// </summary>
 /// <param name="function">Булева функция</param>
 /// <param name="variables">Набор переменных, определяющий порядок и имена переменных</param>
 /// <returns>Совершенная КНФ булевой функции</returns>
 public static BooleanFormula PerfectCNF(BooleanFunction function, List<BooleanVariable> variables)
 {
     if (function.VariableCount > variables.Count)
         throw new Exception("Недостаточно переменных в списке!");
     BooleanFormula result;
     //создать список элементарных конъюнкций
     List<BooleanFormula> disjunctions = new List<BooleanFormula>();
     int length = 1 << function.VariableCount;
     for (int index = 0; index < length; index++)
         //если значение на наборе равно 1 создаем эл. конъюнкцию
         if (!function[index])
         {
             //отдельно последняя переменная (инициализация)
             if ((index & 1) == 0)
                 result = variables[variables.Count - 1].ShallowClone();
             else
                 result = new UnaryOperation(variables[variables.Count - 1].ShallowClone());
             //определяем какие переменные с отрицанием, какие - без
             for (int j = 1; j < function.VariableCount; j++)
                 if (((index >> j) & 1) == 0)
                     //(variableCount - j)-ая переменная из списка variables входит без отрицания
                     result = new BinaryOperation(BooleanOperations.OR, variables[variables.Count - j - 1].ShallowClone(), result);
                 else//с отрицанием
                     result = new BinaryOperation(BooleanOperations.OR, new UnaryOperation(variables[variables.Count - j - 1].ShallowClone()), result);
             disjunctions.Add(result);
         }
     //если список пуст, добавить константу 1
     if (disjunctions.Count == 0)
         disjunctions.Add(new BooleanConstant(true));
     //соединить связкой AND
     result = disjunctions[disjunctions.Count - 1];
     for (int i = disjunctions.Count - 2; i >= 0; i--)
         result = new BinaryOperation(BooleanOperations.AND, disjunctions[i], result);
     return result;
 }
Example #4
0
 /// <summary>
 /// Построение полинома Жегалкина по набору коэффициентов с учетом порядка переменных.
 /// </summary>
 /// <param name="coefficients">Коэффициенты полинома Жегалкина</param>
 /// <param name="variables">Набор переменных в заданном формулой порядке.</param>
 /// <returns>Формула для заданного набора коэффициентов</returns>
 public static BooleanFormula ZhegalkinPolynomial(bool[] coefficients, List<BooleanVariable> variables)
 {
     if (coefficients.Length == 0)
         throw new Exception("Длина набора коэффициентов должна быть степенью двойки!");
     BooleanFormula result;
     //создать список монотонных конъюнкций
     List<BooleanFormula> monomials = new List<BooleanFormula>();
     for (int index = 1; index < coefficients.Length; index++)
         //если коэффициент равен 1 создаем моном
         if (coefficients[index])
         {
             result = null;
             //определяем список переменных, входящих в моном
             for (int j = 0; j < variables.Count; j++)
                 if (((index >> j) & 1) == 1)
                     //(variableCount - j)-ая переменная из списка variables входит в моном
                     if (result == null)
                         result = variables[variables.Count - j - 1].ShallowClone();
                     else
                         result = new BinaryOperation(BooleanOperations.AND, variables[variables.Count - j - 1].ShallowClone(), result);
             monomials.Add(result);
         }
     //отсортировать по длине
     monomials.Sort((f1, f2) => f1.Depth.CompareTo(f2.Depth));
     //свободный член как вырожденный случай монотонной конъюнкции обрабатываем отдельно
     if (coefficients[0])
         monomials.Insert(0, new BooleanConstant(true));
     //если список пуст, добавить константу 0
     if (monomials.Count == 0)
         monomials.Add(new BooleanConstant(false));
     //соединить связкой XOR
     result = monomials[monomials.Count - 1];
     for (int i = monomials.Count - 2; i >= 0; i--)
         result = new BinaryOperation(BooleanOperations.XOR, result, monomials[i]);
     return result;
 }