/// <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); }
/// <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; }
/// <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; }