コード例 #1
0
ファイル: FormulaSystem.cs プロジェクト: thisiscam/formula
        protected override void AddControllerOverflow(Microsoft.Z3.Context ctx, Microsoft.Z3.Solver solver, string varName)
        {
            FixedPointNumber var  = discreteVariablesByName[varName];
            FixedPointNumber expr = assigns[varName];

            solver.Assert(expr.overflow);
        }
コード例 #2
0
ファイル: FPExtension.cs プロジェクト: thisiscam/formula
        static public BoolExprWithOverflow MkFPSBetween(this Context ctx, FixedPointNumber E, FixedPointNumber L, FixedPointNumber U)
        {
            var calc     = ctx.MkAnd(ctx.MkFPSGE(E, L).bv, ctx.MkFPSLE(E, U).bv);
            var overflow = ctx.MkOr(E.overflow, L.overflow, U.overflow);

            return(new BoolExprWithOverflow(calc, overflow, String.Format("{0}<={1}<={2}", L.Expr, E.Expr, U.Expr)));
        }
コード例 #3
0
ファイル: FormulaSystem.cs プロジェクト: thisiscam/formula
        /// <summary>
        /// Add controller code for output/memory variable 'var'
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="solver"></param>
        /// <param name="variable"></param>
        protected override void AddController(Microsoft.Z3.Context ctx, Microsoft.Z3.Solver solver, string varName)
        {
            FixedPointNumber     var    = discreteVariablesByName[varName];
            FixedPointNumber     expr   = assigns[varName];
            BoolExprWithOverflow assert = ctx.MkFPEq(var, expr);

            solver.Assert(assert.bv);
        }
コード例 #4
0
ファイル: FPExtension.cs プロジェクト: thisiscam/formula
        static public FixedPointNumber MkFPMax(this Context ctx, FixedPointNumber A, FixedPointNumber B)
        {
            Contract.Requires(A != null);
            Contract.Requires(B != null);
            Contract.Requires(A.bits == B.bits);
            Contract.Requires(A.decimals == B.decimals);
            var overflow = ctx.MkOr(A.overflow, B.overflow);

            return(new FixedPointNumber(A.bits, A.decimals, (BitVecExpr)ctx.MkITE(ctx.MkBVSGE(A.bv, B.bv), A.bv, B.bv), overflow, String.Format("max({0},{1})", A.Expr, B.Expr)));
        }
コード例 #5
0
ファイル: FPExtension.cs プロジェクト: thisiscam/formula
        static public BoolExprWithOverflow MkFPSGT(this Context ctx, FixedPointNumber A, FixedPointNumber B)
        {
            Contract.Requires(A != null);
            Contract.Requires(B != null);
            Contract.Requires(A.bits == B.bits);
            Contract.Requires(A.decimals == B.decimals);
            var calc     = ctx.MkBVSGT(A.bv, B.bv);
            var overflow = ctx.MkOr(A.overflow, B.overflow);

            return(new BoolExprWithOverflow(calc, overflow, String.Format("{0}>{1}", A.Expr, B.Expr)));
        }
コード例 #6
0
ファイル: FormulaSystem.cs プロジェクト: thisiscam/formula
        protected override Dictionary <string, DoubleInterval> Hold(State q)
        {
            Dictionary <string, DoubleInterval> result = new Dictionary <string, DoubleInterval>();

            foreach (var kvp in hold)
            {
                VAR c = kvp.Value;
                FixedPointNumber fp = kvp.Key;
                int i = Array.FindIndex(q.discreteNames, x => x.Equals(fp.Expr));
                result.Add(c.name, q.discreteState.axes[i].ToDoubleInterval());
            }
            return(result);
        }
コード例 #7
0
ファイル: FPExtension.cs プロジェクト: thisiscam/formula
        static public FixedPointNumber MkFPNeg(this Context ctx, FixedPointNumber A)
        {
            var zero     = ctx.MkBV(0, A.bits);
            var calc     = ctx.MkBVSub(zero, A.bv);
            var o1       = ctx.MkNot(ctx.MkBVSubNoOverflow(zero, A.bv));
            var o2       = ctx.MkNot(ctx.MkBVSubNoUnderflow(zero, A.bv, true));
            var overflow =
                ctx.MkOr(
                    A.overflow,
                    o1, o2);

            return(new FixedPointNumber(A.bits, A.decimals, calc, overflow, String.Format("(-{0})", A.Expr)));
        }
コード例 #8
0
ファイル: FormulaSystem.cs プロジェクト: thisiscam/formula
        protected override Dictionary <string, FPIntegerInterval> Sample(State q)
        {
            Dictionary <string, FPIntegerInterval> result = new Dictionary <string, FPIntegerInterval>();
            Dictionary <string, DoubleInterval>    values = q.ToDictionary();

            foreach (var kvp in sample)
            {
                AST c = kvp.Key;
                FixedPointNumber fp = kvp.Value;
                var valueOfAST      = c.Eval(values);
                result.Add(fp.Expr, Measure(valueOfAST, fp.bits, fp.decimals));
            }
            return(result);
        }
コード例 #9
0
ファイル: FPExtension.cs プロジェクト: thisiscam/formula
        static public FixedPointNumber MkFPSub(this Context ctx, FixedPointNumber A, FixedPointNumber B)
        {
            Contract.Requires(A != null);
            Contract.Requires(B != null);
            Contract.Requires(A.bits == B.bits);
            Contract.Requires(A.decimals == B.decimals);
            var calc     = ctx.MkBVSub(A.bv, B.bv);
            var o1       = ctx.MkNot(ctx.MkBVSubNoOverflow(A.bv, B.bv));
            var o2       = ctx.MkNot(ctx.MkBVSubNoUnderflow(A.bv, B.bv, true));
            var overflow =
                ctx.MkOr(
                    A.overflow, B.overflow,
                    o1, o2);

            return(new FixedPointNumber(A.bits, A.decimals, calc, overflow, String.Format("({0}-{1})", A.Expr, B.Expr)));
        }
コード例 #10
0
ファイル: FPExtension.cs プロジェクト: thisiscam/formula
        static public FixedPointNumber MkFPSDiv(this Context ctx, FixedPointNumber A, FixedPointNumber B)
        {
            Contract.Requires(A != null);
            Contract.Requires(B != null);
            Contract.Requires(A.bits == B.bits);
            Contract.Requires(A.decimals == B.decimals);
            var extA     = ctx.MkSignExt(A.bits, A.bv);
            var extB     = ctx.MkSignExt(A.bits, B.bv);
            var AB       = ctx.MkBVSDiv(ctx.MkBVMul(extA, ctx.MkBV(1 << (int)A.decimals, 2 * A.bits)), extB);
            var calc     = ctx.MkExtract(A.bits - 1, 0, AB);
            int maxV     = (1 << (int)(A.bits - 1)) - 1;
            int minV     = -(1 << (int)(A.bits - 1));
            var overflow =
                ctx.MkOr(
                    A.overflow, B.overflow,
                    ctx.MkBVSGT(AB, ctx.MkBV(maxV, A.bits * 2)),
                    ctx.MkBVSLT(AB, ctx.MkBV(minV, A.bits * 2)));

            return(new FixedPointNumber(A.bits, A.decimals, calc, overflow, String.Format("{0}/{1}*{2}", A.Expr, B.Expr, (1 << (int)A.decimals))));
        }
コード例 #11
0
ファイル: FormulaSystem.cs プロジェクト: thisiscam/formula
        public void Load(string filename, string modelname)
        {
            Env           env = new Microsoft.Formula.API.Env();
            InstallResult result;

            env.Install(filename, out result);
            if (result.Succeeded)
            {
                ProgramName pname = new ProgramName(filename);
                Task <ObjectGraphResult> resTask;
                Domain.SHSystem_Root.CreateObjectGraph(env, pname, modelname, out resTask);
                resTask.Wait();
                ObjectGraphResult model = resTask.Result;

                var body = Microsoft.Formula.API.Factory.Instance.MkBody();
                var find = Microsoft.Formula.API.Factory.Instance.MkFind(null, Microsoft.Formula.API.Factory.Instance.MkId("conforms"));
                body = Microsoft.Formula.API.Factory.Instance.AddConjunct(body, find);

                List <Microsoft.Formula.API.AST <Microsoft.Formula.API.Nodes.Body> > bodies = new List <AST <Microsoft.Formula.API.Nodes.Body> >();
                bodies.Add(body);
                List <Flag>        flags;
                Task <QueryResult> task;
                Microsoft.Formula.Common.Rules.ExecuterStatistics exeStats;
                if (!env.Query(pname, modelname, bodies, true, true, out flags, out task, out exeStats))
                {
                    throw new Exception(String.Format("Could not start query at {0}/{1}", filename, modelname));
                }
                if (task == null)
                {
                    throw new Exception(String.Format("Could not query {0}/{1}", filename, modelname));
                }
                task.Start();
                task.Wait();
                if (task.Result.Conclusion != LiftedBool.True)
                {
                    throw new Exception(String.Format("Model does not conform at {0}/{1}", filename, modelname));
                }
                //body.Print(Console.Out);

                foreach (var m in model.Objects)
                {
                    if (m is SHSystem_Root.O.DiffEq)
                    {
                        var t   = (SHSystem_Root.O.DiffEq)m;
                        VAR v   = (VAR)ExtractContinuousModel(t.x);
                        AST rhs = ExtractContinuousModel(t.rhs);
                        odes.Add(v.name, rhs);
                    }
                    else if (m is SHSystem_Root.C.Assign)
                    {
                        var t = (SHSystem_Root.C.Assign)m;
                        FixedPointNumber var = ExtractDiscreteModel(t.var);
                        FixedPointNumber rhs = ExtractDiscreteModel(t.rhs);
                        assigns.Add(var.Expr, rhs);
                    }
                    else if (m is SHSystem_Root.Safe)
                    {
                        var t = (SHSystem_Root.Safe)m;
                        safetyFormula.Add(ExtractSafetyFormula(t.formula));
                    }
                    else if (m is SHSystem_Root.Sample)
                    {
                        var t = (SHSystem_Root.Sample)m;
                        AST c = ExtractContinuousModel(t.lhs);
                        FixedPointNumber d = ExtractDiscreteModel(t.rhs);
                        sample.Add(new KeyValuePair <AST, FixedPointNumber>(c, d));
                    }
                    else if (m is SHSystem_Root.Hold)
                    {
                        var t = (SHSystem_Root.Hold)m;
                        FixedPointNumber d = ExtractDiscreteModel(t.lhs);
                        VAR c = (VAR)ExtractContinuousModel(t.rhs);
                        hold.Add(new KeyValuePair <FixedPointNumber, VAR>(d, c));
                    }
                    else if (m is SHSystem_Root.Reset)
                    {
                        var t = (SHSystem_Root.Reset)m;
                        AST d = ExtractContinuousModel(t.lhs);
                        VAR c = (VAR)ExtractContinuousModel(t.rhs);
                        reset.Add(new KeyValuePair <AST, VAR>(d, c));
                    }
                    else if (m is SHSystem_Root.InitialRangeC)
                    {
                        var    t     = (SHSystem_Root.InitialRangeC)m;
                        VAR    v     = (VAR)ExtractContinuousModel(t.var);
                        double lower = ExtractDouble(t.lower);
                        double upper = ExtractDouble(t.upper);
                        cVariables.Add(v, new DoubleInterval(lower, upper));
                    }
                    else if (m is SHSystem_Root.InitialRangeD)
                    {
                        var t = (SHSystem_Root.InitialRangeD)m;
                        FixedPointNumber v = ExtractDiscreteModel(t.var);
                        int lower          = ExtractInteger(t.lower);
                        int upper          = ExtractInteger(t.upper);
                        dVariables.Add(v, new FPIntegerInterval(lower, upper, v.bits, v.decimals));
                    }
                    else if (m is SHSystem_Root.DiscretePeriod)
                    {
                        var t = (SHSystem_Root.DiscretePeriod)m;
                        period = ExtractDouble(t._0);
                    }
                    else if (m is SHSystem_Root.Order)
                    {
                        var t = (SHSystem_Root.Order)m;
                        order = ExtractInteger(t._0);
                    }
                    else if (m is SHSystem_Root.StepBound)
                    {
                        var t = (SHSystem_Root.StepBound)m;
                        stepBound = ExtractInteger(t._0);
                    }
                    else if (m is SHSystem_Root.CutoffThreshold)
                    {
                        var t = (SHSystem_Root.CutoffThreshold)m;
                        cutoffThreshold = ExtractDouble(t.threshold);
                    }
                    else if (m is SHSystem_Root.ErrorEstimate)
                    {
                        var t = (SHSystem_Root.ErrorEstimate)m;
                        errorEstimate = ExtractDouble(t.estimate);
                    }
                    else if (m is SHSystem_Root.SolverStep)
                    {
                        var t = (SHSystem_Root.SolverStep)m;
                        solverStep     = ExtractDouble(t.step);
                        solverMiniStep = ExtractDouble(t.ministep);
                    }
                    else if (m is SHSystem_Root.SearchProcedure)
                    {
                        var    t    = (SHSystem_Root.SearchProcedure)m;
                        string name = (string)t.proc.Symbol;
                        if (name.Equals("BFS"))
                        {
                            searchProcedure = SearchProcedures.BFS;
                        }
                        else if (name.Equals("BFS_exhaustive"))
                        {
                            searchProcedure = SearchProcedures.BFS_exhaustive;
                        }
                        else if (name.Equals("BFS_refinement"))
                        {
                            searchProcedure = SearchProcedures.BFS_refinement;
                        }
                        else if (name.Equals("DFS"))
                        {
                            searchProcedure = SearchProcedures.DFS;
                        }
                        else if (name.Equals("DFS_exhaustive"))
                        {
                            searchProcedure = SearchProcedures.DFS_exhaustive;
                        }
                        else if (name.Equals("DFS_refinement"))
                        {
                            searchProcedure = SearchProcedures.DFS_refinement;
                        }
                    }
                    else if (m is SHSystem_Root.AxisX)
                    {
                        var t = (SHSystem_Root.AxisX)m;
                        axisTitle[0] = (string)t.title.Symbol;
                        if (t.var is SHSystem_Root.UserCnst)
                        {
                            timeAxis = true;
                        }
                        else
                        {
                            axisValue[0] = ExtractContinuousModel(t.var);
                        }
                        axisMin[0] = ExtractDouble(t.minValue);
                        axisMax[0] = ExtractDouble(t.maxValue);
                    }
                    else if (m is SHSystem_Root.AxisY)
                    {
                        var t = (SHSystem_Root.AxisY)m;
                        axisTitle[1] = (string)t.title.Symbol;
                        axisValue[1] = ExtractContinuousModel(t.var);
                        axisMin[1]   = ExtractDouble(t.minValue);
                        axisMax[1]   = ExtractDouble(t.maxValue);
                    }
                    else if (m is SHSystem_Root.AxisZ)
                    {
                        var t = (SHSystem_Root.AxisZ)m;
                        axisTitle[2] = (string)t.title.Symbol;
                        if (t.var is SHSystem_Root.UserCnst)
                        {
                            searchIndexAxis = true;
                        }
                        else
                        {
                            axisValue[2] = ExtractContinuousModel(t.var);
                        }
                        axisMin[2] = ExtractDouble(t.minValue);
                        axisMax[2] = ExtractDouble(t.maxValue);
                    }
                }
            }
            else
            {
                StringBuilder msg = new StringBuilder();
                msg.Append("Could not load ").AppendLine(filename);
                foreach (var flag in result.Flags)
                {
                    msg.AppendFormat("{0} in line {1}, column {2}", flag.Item2.Message, flag.Item2.Span.StartLine, flag.Item2.Span.StartCol).AppendLine();
                }
                throw new Exception(msg.ToString());
            }
        }
コード例 #12
0
ファイル: FormulaSystem.cs プロジェクト: thisiscam/formula
 public FixedPointNumber ExtractDiscreteModel(Microsoft.Formula.API.Generators.ICSharpTerm model)
 {
     if (model is SHSystem_Root.C.Const)
     {
         var t = (SHSystem_Root.C.Const)model;
         return(ctx.MkFPscaled(ExtractInteger(t.value), (uint)ExtractInteger(t.bits), (uint)ExtractInteger(t.decimals)));
     }
     if (model is SHSystem_Root.C.RConst)
     {
         var t = (SHSystem_Root.C.RConst)model;
         return(ctx.MkFPfromReal(ExtractDouble(t.value), (uint)ExtractInteger(t.bits), (uint)ExtractInteger(t.decimals)));
     }
     else if (model is SHSystem_Root.C.Var)
     {
         var t    = (SHSystem_Root.C.Var)model;
         var name = (string)t.name.Symbol;
         var var  = ctx.MkFPConst(name, (uint)ExtractInteger(t.bits), (uint)ExtractInteger(t.decimals));
         if (!discreteVariablesByName.ContainsKey(name))
         {
             discreteVariablesByName.Add(name, var);
         }
         return(var);
     }
     else if (model is SHSystem_Root.C.Neg)
     {
         var t = (Domain.SHSystem_Root.C.Neg)model;
         return(ctx.MkFPNeg(ExtractDiscreteModel(t.arg1)));
     }
     else if (model is SHSystem_Root.C.Pre)
     {
         var              t    = (Domain.SHSystem_Root.C.Pre)model;
         string           name = ExtractPre(t);
         FixedPointNumber arg1 = ExtractDiscreteModel(t.arg1);
         var              var  = ctx.MkFPConst(name, arg1.bits, arg1.decimals);
         if (!discreteVariablesByName.ContainsKey(name))
         {
             assigns.Add(name, arg1);
             discreteVariablesByName.Add(name, var);
         }
         return(var);
     }
     else if (model is SHSystem_Root.C.Add)
     {
         var t = (Domain.SHSystem_Root.C.Add)model;
         return(ctx.MkFPAdd(ExtractDiscreteModel(t.arg1), ExtractDiscreteModel(t.arg2)));
     }
     else if (model is SHSystem_Root.C.Sub)
     {
         var t = (Domain.SHSystem_Root.C.Sub)model;
         return(ctx.MkFPSub(ExtractDiscreteModel(t.arg1), ExtractDiscreteModel(t.arg2)));
     }
     else if (model is SHSystem_Root.C.Mul)
     {
         var t = (Domain.SHSystem_Root.C.Mul)model;
         return(ctx.MkFPMul(ExtractDiscreteModel(t.arg1), ExtractDiscreteModel(t.arg2)));
     }
     else if (model is SHSystem_Root.C.Div)
     {
         var t = (Domain.SHSystem_Root.C.Div)model;
         return(ctx.MkFPSDiv(ExtractDiscreteModel(t.arg1), ExtractDiscreteModel(t.arg2)));
     }
     else if (model is SHSystem_Root.C.Min)
     {
         var t = (Domain.SHSystem_Root.C.Min)model;
         return(ctx.MkFPMin(ExtractDiscreteModel(t.arg1), ExtractDiscreteModel(t.arg2)));
     }
     else if (model is SHSystem_Root.C.Max)
     {
         var t = (Domain.SHSystem_Root.C.Max)model;
         return(ctx.MkFPMax(ExtractDiscreteModel(t.arg1), ExtractDiscreteModel(t.arg2)));
     }
     else if (model is SHSystem_Root.C.ITE)
     {
         var t = (Domain.SHSystem_Root.C.ITE)model;
         return(ctx.MkFPITE(ExtractDiscreteBoolModel(t.test), ExtractDiscreteModel(t.arg1), ExtractDiscreteModel(t.arg2)));
     }
     throw new Exception(String.Format("Unsupported language element: {0}", model.Symbol));
 }
コード例 #13
0
ファイル: FormulaSystem.cs プロジェクト: thisiscam/formula
        public FormulaSystem(string filename, Plot3d plotter)
            : base()
        {
            axisValue[0] = new REAL(0.0);
            axisValue[1] = new REAL(0.0);
            axisValue[2] = new REAL(0.0);
            Load(filename, "M");

            string[]            cNames   = new string[cVariables.Count];
            string[]            dNames   = new string[dVariables.Count];
            DoubleInterval[]    cInitial = new DoubleInterval[cVariables.Count];
            FPIntegerInterval[] dInitial = new FPIntegerInterval[dVariables.Count];
            int i = 0;

            foreach (var kvp in cVariables)
            {
                cNames[i]   = kvp.Key.name;
                cInitial[i] = kvp.Value.Clone();
                i++;
            }
            i = 0;
            foreach (var kvp in dVariables)
            {
                dNames[i]   = kvp.Key.Expr;
                dInitial[i] = kvp.Value.Clone();
                i++;
            }

            // build the ODEs
            ode = new List <AST>();
            foreach (var kvp in cVariables)
            {
                AST f;
                if (odes.TryGetValue(kvp.Key.name, out f))
                {
                    ode.Add(f);
                }
            }

            Print(Log.Output);
            Print(Log.Debug);

            Initialize(cNames, cInitial, dNames, dInitial, order, period);

            if (IsPolynomial)
            {
                Log.WriteLine("Using polynomial solver");
            }
            else if (ContainsSqrt)
            {
                Log.WriteLine("Using approximate Taylor expansion solver");
            }
            else
            {
                Log.WriteLine("Using non-polynomial Taylor model solver");
            }

            // look for lower and upper bounds
            foreach (var kvp in dVariables)
            {
                FixedPointNumber fp = kvp.Key;
                int lo     = -(1 << ((int)fp.bits - 1));
                int up     = (1 << ((int)fp.bits - 1)) - 1;
                var solver = ctx.MkSimpleSolver();
                AddController(ctx, solver, kvp.Key.Expr);
                lo = LowerBound(ctx, solver, fp.Expr, fp.bits, lo, up);
                up = UpperBound(ctx, solver, fp.Expr, fp.bits, lo, up);
                var ival = new FPIntegerInterval(lo, up, fp.bits, fp.decimals);
                controlBounds.Add(fp.Expr, ival);
                Log.Debug.WriteLine("Control variable '{0}' always in {1}", kvp.Key, ival);
            }

            Dictionary <string, DoubleInterval> initialValues = GetSystemState(initialState); // initialState.ToDictionary();

            if (!timeAxis)
            {
                axisInitialValue[0] = axisValue[0].Eval(initialValues);
            }
            axisInitialValue[1] = axisValue[1].Eval(initialValues);
            if (!searchIndexAxis)
            {
                axisInitialValue[2] = axisValue[2].Eval(initialValues);
            }

            this.plotter = plotter;
            if (plotter != null)
            {
                plotter.SetMinMax(axisMin[0], axisMax[0], axisMin[1], axisMax[1], axisMin[2], axisMax[2]);
                plotter.DefaultSettings();
                plotter.DrawEvent += Draw;
            }
        }
コード例 #14
0
ファイル: FPExtension.cs プロジェクト: thisiscam/formula
        static public FixedPointNumber MkFPITE(this Context ctx, BoolExprWithOverflow test, FixedPointNumber A, FixedPointNumber B)
        {
            Contract.Requires(A != null);
            Contract.Requires(B != null);
            Contract.Requires(A.bits == B.bits);
            Contract.Requires(A.decimals == B.decimals);
            var overflow = ctx.MkOr(test.overflow, A.overflow, B.overflow);

            return(new FixedPointNumber(A.bits, A.decimals, (BitVecExpr)ctx.MkITE(test.bv, A.bv, B.bv), overflow, String.Format("ITE({0},{1},{2})", test.Expr, A.Expr, B.Expr)));
        }