Esempio n. 1
0
        public IDictionary <string, List <object> > Solve()
        {
            Dictionary <string, List <object> > variableValues = new Dictionary <string, List <object> >(StringComparer.CurrentCultureIgnoreCase);

            new Model.ViewModelLocator().MainModel.AddDisplayText("Z3 Solve");
            Solver s = this.z3Context.MkSolver();

            foreach (BoolExpr sa in this.solverAssertions)
            {
                s.Assert(sa);
            }

            Console.WriteLine(s.Check());
            new Model.ViewModelLocator().MainModel.AddDisplayText(s.Check().ToString());

            Microsoft.Z3.Model m = s.Model;
            foreach (FuncDecl d in m.Decls)
            {
                string varName  = d.Name.ToString();
                Expr   valExpr  = m.ConstInterp(d);
                string varValue = valExpr.ToString();
                if (valExpr is FPExpr)
                {
                    FPExpr fp  = (FPExpr)valExpr;
                    FPNum  fn  = (FPNum)fp;
                    double val = Convert.ToDouble(fn.Significand);
                    val = val * System.Math.Pow(2, fn.ExponentInt64);

                    if (fn.Sign)
                    {
                        val = val * -1;
                    }

                    varValue = val.ToString();

                    if (valExpr.ToString() == "+zero")
                    {
                        varValue = "0.01";
                    }
                    if (valExpr.ToString() == "-zero")
                    {
                        varValue = "-0.01";
                    }
                }


                string message = varName + " -> " + varValue;
                new Model.ViewModelLocator().MainModel.AddDisplayText(message);

                if (!variableValues.ContainsKey(varName))
                {
                    variableValues.Add(varName, new List <object>());
                }

                variableValues[varName].Add(varValue);
            }
            return(variableValues);
        }
Esempio n. 2
0
        public void Test_FPTools_BV_2_Doubles()
        {
            Context ctx      = new Context(); // housekeeping OK!
            Solver  solver   = ctx.MkSolver();
            FPSort  fpSort64 = ctx.MkFPSort64();

            FPExpr[] values_FP = new FPExpr[] { ctx.MkFP(2, fpSort64), ctx.MkFP(4, fpSort64) };

            BitVecExpr value_BV = ToolsFloatingPoint.FP_2_BV(values_FP, ctx);

            Console.WriteLine(ToolsZ3.ToStringBin(ToolsZ3.GetTvArray(value_BV, 128, solver, ctx)));

            IList <FPExpr> results_FP = new List <FPExpr>(ToolsFloatingPoint.BV_2_Doubles(value_BV, ctx));

            for (int i = 0; i < values_FP.Length; ++i)
            {
                string expected = ToolsZ3.ToStringBin(ToolsZ3.GetTvArray(ctx.MkFPToIEEEBV(values_FP[i]), 64, solver, ctx));
                string actual   = ToolsZ3.ToStringBin(ToolsZ3.GetTvArray(ctx.MkFPToIEEEBV(results_FP[i]), 64, solver, ctx));
                Assert.AreEqual(expected, actual);
            }
            ctx.Dispose();
        }
Esempio n. 3
0
        private static Expr TranslateMixedConstraint(InfluenceFunction influenceFunction, Dictionary <BinaryOption, Expr> optionMapping, Context context, Dictionary <ConfigurationOption, Expr> optionToTerm)
        {
            string[] expression = influenceFunction.getExpressionTree();

            if (expression.Length == 0)
            {
                return(null);
            }

            Stack <Expr> expressionStack = new Stack <Expr>();

            for (int i = 0; i < expression.Length; i++)
            {
                if (!InfluenceFunction.isOperatorEval(expression[i]))
                {
                    double value;
                    if (Double.TryParse(expression[i], out value))
                    {
                        expressionStack.Push(context.MkFPNumeral(value, context.MkFPSortDouble()));
                    }
                    else
                    {
                        ConfigurationOption option = GlobalState.varModel.getOption(expression[i]);
                        Expr expr = null;
                        if (option is BinaryOption && optionMapping.ContainsKey((BinaryOption)option))
                        {
                            expr = optionMapping[(BinaryOption)option];
                        }
                        else
                        {
                            expr = optionToTerm[option];
                        }

                        expressionStack.Push(expr);
                    }
                }
                else
                {
                    // Be aware of the rounding mode
                    FPRMExpr roundingMode = context.MkFPRoundNearestTiesToEven();
                    switch (expression[i])
                    {
                    case "+":
                        FPExpr left  = (FPExpr)expressionStack.Pop();
                        FPExpr right = (FPExpr)expressionStack.Pop();

                        expressionStack.Push(context.MkFPAdd(roundingMode, left, right));
                        break;

                    case "-":
                        FPExpr leftSub  = (FPExpr)expressionStack.Pop();
                        FPExpr rightSub = (FPExpr)expressionStack.Pop();

                        expressionStack.Push(context.MkFPSub(roundingMode, leftSub, rightSub));
                        break;

                    case "/":
                        FPExpr leftDiv  = (FPExpr)expressionStack.Pop();
                        FPExpr rightDiv = (FPExpr)expressionStack.Pop();

                        expressionStack.Push(context.MkFPDiv(roundingMode, leftDiv, rightDiv));
                        break;

                    case "*":
                        FPExpr leftMul  = (FPExpr)expressionStack.Pop();
                        FPExpr rightMul = (FPExpr)expressionStack.Pop();

                        expressionStack.Push(context.MkFPMul(roundingMode, leftMul, rightMul));
                        break;

                    // Note that the logarithm function is not supported by z3.
                    default:
                        throw new ArgumentException("The operator " + expression[i] + " is currently not supported in mixed constraints by z3.");
                    }
                }
            }

            return(expressionStack.Pop());
        }
Esempio n. 4
0
        /// <summary>
        /// The non-boolean constraints are constraints among binary and numeric configuration options.
        /// Currently, these constraints are implemented as inequation of multiplicative terms.
        /// However, z3 does not support the multiplication among boolean variables (i.e., binary configuration options)
        /// and numeric variables (i.e., numeric configuration options).
        /// Thus, the approach is as follows:
        /// (1) Create a numeric variable for each binary configuration option in the mixed constraint and add a constraint
        /// for each of them, so that the numeric variable has the value 1 when the binary configuration option is true; 0 otherwise
        /// (2) Translate the constraints into z3
        /// </summary>
        /// <param name="constr">The <see cref="NonBooleanConstraint"/> to translate.</param>
        /// <param name="optionMapping">The mapping of already used binary options and their <see cref="Expr"/> counterparts.</param>
        /// <param name="context">The z3 <see cref="Context"/> needed for the translatation of these constraints.</param>
        /// <param name="optionToTerm">A mapping that maps the given option to a term.</param>
        /// <returns>A <see cref="BoolExpr"/> that represents this constraint.</returns>
        private static BoolExpr ProcessMixedConstraint(NonBooleanConstraint constr, Dictionary <BinaryOption, Expr> optionMapping, Context context, Dictionary <ConfigurationOption, Expr> optionToTerm)
        {
            List <BoolExpr> constraints = new List <BoolExpr>();

            // Process the binary options in the formula
            HashSet <BinaryOption> binOpts = constr.leftHandSide.participatingBoolOptions;

            foreach (BinaryOption binOpt in constr.rightHandSide.participatingBoolOptions)
            {
                if (!binOpts.Contains(binOpt))
                {
                    binOpts.Add(binOpt);
                }
            }
            foreach (BinaryOption binOpt in binOpts)
            {
                if (!optionMapping.ContainsKey(binOpt))
                {
                    Expr newExpr = GenerateDoubleVariable(context, binOpt.Name + "_num");
                    optionMapping[binOpt] = newExpr;

                    // Add the constraints to ensure that the values of the binary and the numeric variable correspond to each other.
                    BoolExpr constraint = (BoolExpr)optionToTerm[binOpt];
                    constraints.Add(context.MkImplies(constraint, context.MkEq(newExpr, context.MkFPNumeral(1, context.MkFPSortDouble()))));
                    constraints.Add(context.MkImplies(context.MkNot(constraint), context.MkEq(newExpr, context.MkFPNumeral(0, context.MkFPSortDouble()))));
                }
            }

            // Note: The 'require'-tag is ignored here, as it does not make sense when translating the mixed constraints for z3

            // Translate the mixed constraint
            FPExpr leftSide  = (FPExpr)TranslateMixedConstraint(constr.leftHandSide, optionMapping, context, optionToTerm);
            FPExpr rightSide = (FPExpr)TranslateMixedConstraint(constr.rightHandSide, optionMapping, context, optionToTerm);


            // Next, check if the constraint has to evaluate to true or not
            string comparator = constr.comparator;

            if (constr.GetType() == typeof(MixedConstraint) &&
                ((MixedConstraint)constr).negativeOrPositiveExpr.Equals(MixedConstraint.NEGATIVE))
            {
                comparator = GetNegatedInequation(comparator);
            }

            switch (comparator)
            {
            case ">=":
                return(context.MkFPGEq(leftSide, rightSide));

            case "<=":
                return(context.MkFPLEq(leftSide, rightSide));

            case "!=":
                return(context.MkNot(context.MkEq(leftSide, rightSide)));

            case "=":
                return(context.MkEq(leftSide, rightSide));

            case ">":
                return(context.MkFPGt(leftSide, rightSide));

            case "<":
                return(context.MkFPLt(leftSide, rightSide));

            default:
                throw new ArgumentException("The inequation sign " + comparator + " is not supported.");
            }
        }