private void AddBinaryConfigurationsToConstraintSystem(VariabilityModel vm, ConstraintSystem s, Configuration configurationToExclude, Dictionary <BinaryOption, CspTerm> elemToTerm)
        {
            List <BinaryOption> allBinaryOptions = vm.BinaryOptions;

            List <CspTerm> positiveTerms = new List <CspTerm>();
            List <CspTerm> negativeTerms = new List <CspTerm>();

            foreach (BinaryOption binOpt in allBinaryOptions)
            {
                if (configurationToExclude.BinaryOptions.ContainsKey(binOpt) && configurationToExclude.BinaryOptions[binOpt] == BinaryOption.BinaryValue.Selected)
                {
                    positiveTerms.Add(elemToTerm[binOpt]);
                }
                else
                {
                    negativeTerms.Add(elemToTerm[binOpt]);
                }
            }

            if (negativeTerms.Count > 0)
            {
                positiveTerms.Add(s.Not(s.And(negativeTerms.ToArray())));
            }

            s.AddConstraints(s.Not(s.And(positiveTerms.ToArray())));
        }
Exemplo n.º 2
0
        static void Main(string[] args)
        {
            ConstraintSystem s1 = ConstraintSystem.CreateSolver();

            // () and ()
            CspTerm p1 = s1.CreateBoolean("p1");
            CspTerm p2 = s1.CreateBoolean("p2");
            CspTerm p3 = s1.CreateBoolean("p3");
            CspTerm p4 = s1.CreateBoolean("p4");

            var x = new CspDomain();

            CspTerm test = s1.And(s1.Or(p1, s1.And(s1.Neg(p3)), s1.Neg(p1)), s1.And(p2, s1.Neg(s1.Difference(p1, p2))));

            CspTerm tOr12 = s1.Or(s1.Neg(t1), s1.Neg(t2));
            CspTerm tOr13 = s1.Or(s1.Neg(t1), s1.Neg(t3));
            CspTerm tOr14 = s1.Or(s1.Neg(t1), s1.Neg(t4));

            CspTerm tOr23 = s1.Or(s1.Neg(t2), s1.Neg(t3));
            CspTerm tOr24 = s1.Or(s1.Neg(t2), s1.Neg(t4));

            CspTerm tOr34 = s1.Or(s1.Neg(t3), s1.Neg(t4));

            CspTerm tOr = s1.Or(t1, t2, t3, t4);

            s1.AddConstraints(tOr12);
            s1.AddConstraints(tOr13);
            s1.AddConstraints(tOr14);
            s1.AddConstraints(tOr23);
            s1.AddConstraints(tOr24);
            s1.AddConstraints(tOr34);
            s1.AddConstraints(tOr);

            ConstraintSolverSolution solution1 = s1.Solve();

            if (solution1.HasFoundSolution)
            {
                Console.WriteLine("Is Satisfiable");
            }
            else
            {
                Console.WriteLine("Not satisfiable");
            }

            Console.ReadKey();
        }
Exemplo n.º 3
0
        public override void AddConstaint()
        {
            ConstraintSystem solver     = ConstraintSystemSolver.Instance.Solver;
            CspTerm          constraint = null;

            CspTerm[] inputTerms = new CspTerm[Input.Count];
            for (int i = 0; i < Input.Count; i++)
            {
                inputTerms[i] = Input[i].CspTerm;
            }

            CspTerm outputTerm = Output.CspTerm;

            Type consType = type;

            if (IsNotHealthy)
            {
                // In case the gate is Broken (Not Healthy) - we don't want to add any constraint!!!
                return;

                /*
                 * switch (type)
                 * {
                 *  case Type.and:
                 *      consType = Type.nand;
                 *      break;
                 *  case Type.nand:
                 *      consType = Type.and;
                 *      break;
                 *  case Type.or:
                 *      consType = Type.nor;
                 *      break;
                 *  case Type.nor:
                 *      consType = Type.or;
                 *      break;
                 *  case Type.xor:
                 *      consType = Type.nxor;
                 *      break;
                 *  case Type.nxor:
                 *      consType = Type.xor;
                 *      break;
                 * }
                 */
            }

            lock (ConstraintSystemSolver.Instance.Locker)
            {
                //Debug.WriteLine("SAT IN!");
                switch (consType)
                {
                case Type.and:
                    CspTerm allAndInputs = solver.And(inputTerms);
                    constraint = solver.Equal(allAndInputs, outputTerm);
                    break;

                case Type.nand:
                    CspTerm allNandInputs = solver.And(inputTerms);
                    constraint = solver.Equal(allNandInputs, solver.Not(outputTerm));
                    break;

                case Type.nor:
                    CspTerm allNorInputs = solver.Or(inputTerms);
                    constraint = solver.Equal(allNorInputs, solver.Not(outputTerm));
                    break;

                case Type.or:
                    CspTerm allOrInputs = solver.Or(inputTerms);
                    constraint = solver.Equal(allOrInputs, outputTerm);
                    break;

                case Type.xor:
                    //XOR is also:
                    //http://en.wikipedia.org/wiki/XOR_gate#/media/File:254px_3gate_XOR.jpg

                    CspTerm firstNand = solver.Not(solver.And(inputTerms));
                    CspTerm firstOr   = solver.Or(inputTerms);
                    CspTerm secendAnd = solver.And(firstNand, firstOr);

                    constraint = solver.Equal(secendAnd, outputTerm);
                    break;

                case Type.nxor:
                    //XOR is also:
                    //http://en.wikipedia.org/wiki/XOR_gate#/media/File:254px_3gate_XOR.jpg

                    CspTerm firstNand2 = solver.Not(solver.And(inputTerms));
                    CspTerm firstOr2   = solver.Or(inputTerms);
                    CspTerm secendAnd2 = solver.And(firstNand2, firstOr2);

                    constraint = solver.Equal(secendAnd2, solver.Not(outputTerm));
                    break;
                }

                solver.AddConstraints(constraint);
                //Debug.WriteLine("SAT OUT!");
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Generates a constraint system based on a variability model. The constraint system can be used to check for satisfiability of configurations as well as optimization.
        /// </summary>
        /// <param name="variables">Empty input, outputs a list of CSP terms that correspond to the configuration options of the variability model</param>
        /// <param name="optionToTerm">A map to get for a given configuration option the corresponding CSP term of the constraint system</param>
        /// <param name="termToOption">A map that gives for a given CSP term the corresponding configuration option of the variability model</param>
        /// <param name="vm">The variability model for which we generate a constraint system</param>
        /// <returns>The generated constraint system consisting of logical terms representing configuration options as well as their boolean constraints.</returns>
        internal static ConstraintSystem getConstraintSystem(out List <CspTerm> variables, out Dictionary <BinaryOption, CspTerm> optionToTerm, out Dictionary <CspTerm, BinaryOption> termToOption, VariabilityModel vm)
        {
            //Reusing seems to not work correctely. The problem: configurations are realized as additional constraints for the system.
            //however, when checking for the next config, the old config's constraints remain in the solver such that we have a wrong result.

            /*
             * if (csystem != null && variables_global != null && optionToTerm_global != null && termToOption_global != null && vm != null)
             * {//For optimization purpose
             *  if (vm.BinaryOptions.Count == vm_global.BinaryOptions.Count && vm.Name.Equals(vm_global.Name))
             *  {
             *      variables = variables_global;
             *      optionToTerm = optionToTerm_global;
             *      termToOption = termToOption_global;
             *      return csystem;
             *  }
             * }*/

            ConstraintSystem S = ConstraintSystem.CreateSolver();

            optionToTerm = new Dictionary <BinaryOption, CspTerm>();
            termToOption = new Dictionary <CspTerm, BinaryOption>();
            variables    = new List <CspTerm>();
            foreach (BinaryOption binOpt in vm.BinaryOptions)
            {
                CspDomain domain = S.DefaultBoolean;
                CspTerm   temp   = S.CreateVariable(domain, binOpt);
                optionToTerm.Add(binOpt, temp);
                termToOption.Add(temp, binOpt);
                variables.Add(temp);
            }

            List <List <ConfigurationOption> > alreadyHandledAlternativeOptions = new List <List <ConfigurationOption> >();

            //Constraints of a single configuration option
            foreach (BinaryOption current in vm.BinaryOptions)
            {
                CspTerm cT = optionToTerm[current];
                if (current.Parent == null || current.Parent == vm.Root)
                {
                    if (current.Optional == false && current.Excluded_Options.Count == 0)
                    {
                        S.AddConstraints(S.Implies(S.True, cT));
                    }
                    else
                    {
                        S.AddConstraints(S.Implies(cT, optionToTerm[vm.Root]));
                    }
                }

                if (current.Parent != null && current.Parent != vm.Root)
                {
                    CspTerm parent = optionToTerm[(BinaryOption)current.Parent];
                    S.AddConstraints(S.Implies(cT, parent));
                    if (current.Optional == false && current.Excluded_Options.Count == 0)
                    {
                        S.AddConstraints(S.Implies(parent, cT));//mandatory child relationship
                    }
                }

                //Alternative or other exclusion constraints
                if (current.Excluded_Options.Count > 0)
                {
                    List <ConfigurationOption> alternativeOptions = current.collectAlternativeOptions();
                    if (alternativeOptions.Count > 0)
                    {
                        //Check whether we handled this group of alternatives already
                        foreach (var alternativeGroup in alreadyHandledAlternativeOptions)
                        {
                            foreach (var alternative in alternativeGroup)
                            {
                                if (current == alternative)
                                {
                                    goto handledAlternative;
                                }
                            }
                        }

                        //It is not allowed that an alternative group has no parent element
                        CspTerm parent = null;
                        if (current.Parent == null)
                        {
                            parent = S.True;
                        }
                        else
                        {
                            parent = optionToTerm[(BinaryOption)current.Parent];
                        }

                        CspTerm[] terms = new CspTerm[alternativeOptions.Count + 1];
                        terms[0] = cT;
                        int i = 1;
                        foreach (BinaryOption altEle in alternativeOptions)
                        {
                            CspTerm temp = optionToTerm[altEle];
                            terms[i] = temp;
                            i++;
                        }
                        S.AddConstraints(S.Implies(parent, S.ExactlyMofN(1, terms)));
                        alreadyHandledAlternativeOptions.Add(alternativeOptions);
                        handledAlternative : { }
                    }

                    //Excluded option(s) as cross-tree constraint(s)
                    List <List <ConfigurationOption> > nonAlternative = current.getNonAlternativeExlcudedOptions();
                    if (nonAlternative.Count > 0)
                    {
                        foreach (var excludedOption in nonAlternative)
                        {
                            CspTerm[] orTerm = new CspTerm[excludedOption.Count];
                            int       i      = 0;
                            foreach (var opt in excludedOption)
                            {
                                CspTerm target = optionToTerm[(BinaryOption)opt];
                                orTerm[i] = target;
                                i++;
                            }
                            S.AddConstraints(S.Implies(cT, S.Not(S.Or(orTerm))));
                        }
                    }
                }
                //Handle implies
                if (current.Implied_Options.Count > 0)
                {
                    foreach (List <ConfigurationOption> impliedOr in current.Implied_Options)
                    {
                        CspTerm[] orTerms = new CspTerm[impliedOr.Count];
                        //Possible error: if a binary option impies a numeric option
                        for (int i = 0; i < impliedOr.Count; i++)
                        {
                            orTerms[i] = optionToTerm[(BinaryOption)impliedOr.ElementAt(i)];
                        }
                        S.AddConstraints(S.Implies(optionToTerm[current], S.Or(orTerms)));
                    }
                }
            }

            //Handle global cross-tree constraints involving multiple options at a time
            // the constraints should be in conjunctive normal form
            foreach (string constraint in vm.BinaryConstraints)
            {
                bool     and = false;
                string[] terms;
                if (constraint.Contains("&"))
                {
                    and   = true;
                    terms = constraint.Split('&');
                }
                else
                {
                    terms = constraint.Split('|');
                }

                CspTerm[] cspTerms = new CspTerm[terms.Count()];
                int       i        = 0;
                foreach (string t in terms)
                {
                    string optName = t.Trim();
                    if (optName.StartsWith("-") || optName.StartsWith("!"))
                    {
                        optName = optName.Substring(1);
                        BinaryOption binOpt     = vm.getBinaryOption(optName);
                        CspTerm      cspElem    = optionToTerm[binOpt];
                        CspTerm      notCspElem = S.Not(cspElem);
                        cspTerms[i] = notCspElem;
                    }
                    else
                    {
                        BinaryOption binOpt  = vm.getBinaryOption(optName);
                        CspTerm      cspElem = optionToTerm[binOpt];
                        cspTerms[i] = cspElem;
                    }
                    i++;
                }
                if (and)
                {
                    S.AddConstraints(S.And(cspTerms));
                }
                else
                {
                    S.AddConstraints(S.Or(cspTerms));
                }
            }
            csystem             = S;
            optionToTerm_global = optionToTerm;
            vm_global           = vm;
            termToOption_global = termToOption;
            variables_global    = variables;
            return(S);
        }
        /// <summary>
        /// Generates a constraint system based on a variability model. The constraint system can be used to check for satisfiability of configurations as well as optimization.
        /// </summary>
        /// <param name="variables">Empty input, outputs a list of CSP terms that correspond to the configuration options of the variability model</param>
        /// <param name="optionToTerm">A map to get for a given configuration option the corresponding CSP term of the constraint system</param>
        /// <param name="termToOption">A map that gives for a given CSP term the corresponding configuration option of the variability model</param>
        /// <param name="vm">The variability model for which we generate a constraint system</param>
        /// <returns>The generated constraint system consisting of logical terms representing configuration options as well as their boolean constraints.</returns>
        internal static ConstraintSystem GetGeneralConstraintSystem(out Dictionary <CspTerm, bool> variables, out Dictionary <ConfigurationOption, CspTerm> optionToTerm, out Dictionary <CspTerm, ConfigurationOption> termToOption, VariabilityModel vm)
        {
            ConstraintSystem S = ConstraintSystem.CreateSolver();

            optionToTerm = new Dictionary <ConfigurationOption, CspTerm>();
            termToOption = new Dictionary <CspTerm, ConfigurationOption>();
            variables    = new Dictionary <CspTerm, bool>();

            foreach (ConfigurationOption o in vm.getOptions())
            {
                CspDomain binDomain = S.DefaultBoolean;
                CspTerm   temp;
                if (o is BinaryOption)
                {
                    temp = S.CreateVariable(binDomain, o);
                }
                else
                {
                    NumericOption numOpt = (NumericOption)o;
                    temp = S.CreateVariable(S.CreateIntegerInterval((int)numOpt.Min_value, (int)numOpt.Max_value), o);
                }

                optionToTerm.Add(o, temp);
                termToOption.Add(temp, o);
                if (o is NumericOption)
                {
                    variables.Add(temp, false);
                }
                else
                {
                    variables.Add(temp, true);
                }
            }

            List <List <ConfigurationOption> > alreadyHandledAlternativeOptions = new List <List <ConfigurationOption> >();

            //Constraints of a single configuration option
            foreach (ConfigurationOption current in vm.getOptions())
            {
                CspTerm cT = optionToTerm[current];
                if (current.Parent == null || current.Parent == vm.Root)
                {
                    if ((current is BinaryOption && ((BinaryOption)current).Optional == false && current.Excluded_Options.Count == 0))
                    {
                        S.AddConstraints(S.Implies(S.True, cT));
                    }
                    else
                    {
                        S.AddConstraints(S.Implies(cT, optionToTerm[vm.Root]));
                    }
                }

                if (current.Parent != null && current.Parent != vm.Root)
                {
                    CspTerm parent = optionToTerm[(BinaryOption)current.Parent];
                    S.AddConstraints(S.Implies(cT, parent));
                    if (current is BinaryOption && ((BinaryOption)current).Optional == false && current.Excluded_Options.Count == 0)
                    {
                        S.AddConstraints(S.Implies(parent, cT));//mandatory child relationship
                    }
                }

                // Add numeric integer values
                if (current is NumericOption)
                {
                    NumericOption  numOpt = (NumericOption)current;
                    List <double>  values = numOpt.getAllValues();
                    List <CspTerm> equals = new List <CspTerm>();
                    foreach (double d in values)
                    {
                        equals.Add(S.Equal((int)d, cT));
                    }
                    S.AddConstraints(S.Or(equals.ToArray()));
                }

                //Alternative or other exclusion constraints
                if (current.Excluded_Options.Count > 0 && current is BinaryOption)
                {
                    BinaryOption binOpt = (BinaryOption)current;
                    List <ConfigurationOption> alternativeOptions = binOpt.collectAlternativeOptions();
                    if (alternativeOptions.Count > 0)
                    {
                        //Check whether we handled this group of alternatives already
                        foreach (var alternativeGroup in alreadyHandledAlternativeOptions)
                        {
                            foreach (var alternative in alternativeGroup)
                            {
                                if (current == alternative)
                                {
                                    goto handledAlternative;
                                }
                            }
                        }

                        //It is not allowed that an alternative group has no parent element
                        CspTerm parent = null;
                        if (current.Parent == null)
                        {
                            parent = S.True;
                        }
                        else
                        {
                            parent = optionToTerm[(BinaryOption)current.Parent];
                        }

                        CspTerm[] terms = new CspTerm[alternativeOptions.Count + 1];
                        terms[0] = cT;
                        int i = 1;
                        foreach (BinaryOption altEle in alternativeOptions)
                        {
                            CspTerm temp = optionToTerm[altEle];
                            terms[i] = temp;
                            i++;
                        }
                        S.AddConstraints(S.Implies(parent, S.ExactlyMofN(1, terms)));
                        alreadyHandledAlternativeOptions.Add(alternativeOptions);
                        handledAlternative : { }
                    }

                    //Excluded option(s) as cross-tree constraint(s)
                    List <List <ConfigurationOption> > nonAlternative = binOpt.getNonAlternativeExlcudedOptions();
                    if (nonAlternative.Count > 0)
                    {
                        foreach (var excludedOption in nonAlternative)
                        {
                            CspTerm[] orTerm = new CspTerm[excludedOption.Count];
                            int       i      = 0;
                            foreach (var opt in excludedOption)
                            {
                                CspTerm target = optionToTerm[(BinaryOption)opt];
                                orTerm[i] = target;
                                i++;
                            }
                            S.AddConstraints(S.Implies(cT, S.Not(S.Or(orTerm))));
                        }
                    }
                }
                //Handle implies
                if (current.Implied_Options.Count > 0)
                {
                    foreach (List <ConfigurationOption> impliedOr in current.Implied_Options)
                    {
                        CspTerm[] orTerms = new CspTerm[impliedOr.Count];
                        //Possible error: if a binary option impies a numeric option
                        for (int i = 0; i < impliedOr.Count; i++)
                        {
                            orTerms[i] = optionToTerm[(BinaryOption)impliedOr.ElementAt(i)];
                        }
                        S.AddConstraints(S.Implies(optionToTerm[current], S.Or(orTerms)));
                    }
                }
            }

            //Handle global cross-tree constraints involving multiple options at a time
            // the constraints should be in conjunctive normal form
            foreach (string constraint in vm.BinaryConstraints)
            {
                bool     and = false;
                string[] terms;
                if (constraint.Contains("&"))
                {
                    and   = true;
                    terms = constraint.Split('&');
                }
                else
                {
                    terms = constraint.Split('|');
                }

                CspTerm[] cspTerms = new CspTerm[terms.Count()];
                int       i        = 0;
                foreach (string t in terms)
                {
                    string optName = t.Trim();
                    if (optName.StartsWith("-") || optName.StartsWith("!"))
                    {
                        optName = optName.Substring(1);
                        BinaryOption binOpt     = vm.getBinaryOption(optName);
                        CspTerm      cspElem    = optionToTerm[binOpt];
                        CspTerm      notCspElem = S.Not(cspElem);
                        cspTerms[i] = notCspElem;
                    }
                    else
                    {
                        BinaryOption binOpt  = vm.getBinaryOption(optName);
                        CspTerm      cspElem = optionToTerm[binOpt];
                        cspTerms[i] = cspElem;
                    }
                    i++;
                }
                if (and)
                {
                    S.AddConstraints(S.And(cspTerms));
                }
                else
                {
                    S.AddConstraints(S.Or(cspTerms));
                }
            }
            return(S);
        }