Ejemplo n.º 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="h"></param>
        public static void ParseVariable(XmlTextReader reader, AHybridAutomaton h)
        {
            if (h == null && Controller.Instance.Sys == null)
            {
                throw new System.Exception("Variable expression for automaton or entire system not well defined (appeared outside of automaton or system declaration).");
            }
            else
            {
                String name        = reader.GetAttribute(VariableAttributes.name.ToString());
                String type        = reader.GetAttribute(VariableAttributes.type.ToString());
                String update_type = reader.GetAttribute(VariableAttributes.update_type.ToString());
                String initially   = reader.GetAttribute(VariableAttributes.initially.ToString());

                if (h != null) // local variable
                {
                    // todo: generalize to the actual general parser? we don't really want to allow such complex declarations of variables, but why not...?
                    if (name.Contains("[") && name.Contains("]")) // indexed variable
                    {
                        String[] split     = name.Split('[', ']');
                        String   varName   = split[0];
                        String   indexName = split[1];

                        h.addIndexedVariable(varName, (Variable.VarType)Enum.Parse(typeof(Variable.VarType), type, true), (Variable.VarUpdateType)Enum.Parse(typeof(Variable.VarUpdateType), update_type, true), initially);
                        // todo: parse the variables
                    }
                }
                else if (Controller.Instance.Sys != null) // global variable
                {
                    Variable v = new VariableGlobal(name, "", (Variable.VarType)Enum.Parse(typeof(Variable.VarType), type, true), (Variable.VarUpdateType)Enum.Parse(typeof(Variable.VarUpdateType), update_type, true), initially);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Parse a location (mode)
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="h"></param>
        /// <returns></returns>
        public static ConcreteLocation ParseLocation(XmlTextReader reader, AHybridAutomaton h)
        {
            if (h == null)
            {
                throw new System.ArgumentNullException("Error parsing transition: hybrid automaton not specified properly before reaching location.");
            }
            uint    value   = UInt32.Parse(reader.GetAttribute(LocationAttributes.id.ToString()));
            String  label   = reader.GetAttribute(LocationAttributes.name.ToString());
            Boolean initial = Boolean.Parse(reader.GetAttribute(LocationAttributes.initial.ToString()));

            // dynamically create label name if none specified
            if (label.Length == 0)
            {
                label = "loc" + loc_counter;
                loc_counter++;
            }
            if (!Controller.Instance.LocationNumToName.ContainsKey(value))
            {
                Controller.Instance.LocationNumToName.Add(value, label);
            }
            if (!Controller.Instance.LocationNameToNum.ContainsKey(label))
            {
                Controller.Instance.LocationNameToNum.Add(label, value);
            }
            ConcreteLocation l = new ConcreteLocation(h, label, value, initial);

            // bound control location variable values: 0 <= q_i <= # states, 0 <= q_j <= # states, 0 <= q_k <= # states

            return(l);
        }
Ejemplo n.º 3
0
        public AState(AHybridAutomaton h, String label, UInt32 value, Boolean initial)
        {
            this.Parent   = h;
            this._label   = label;
            this._value   = value;
            this._initial = initial;

            //this.ValueTerm = Controller.Instance.Z3.MkInt(value); // TODO: location type... Instance.LocType
            this.ValueTerm = Controller.Instance.Z3.MkConst(label, Controller.Instance.LocType);

            this.LabelExpr = this.ValueTerm;

            this.BitVectorExpr = Controller.Instance.Z3.MkBV(value, Controller.Instance.LocSize);

            //Controller.Instance.Z3.Assumptions.Add(Controller.Instance.Z3.MkEq(this.ValueTerm, Controller.Instance.Z3.MkInt(value)));

            this._statePredicate = Controller.Instance.Z3.MkEq(Controller.Instance.IndexedVariables[new KeyValuePair <string, string>("q", "i")], this.ValueTerm);

            // add label to value map
            if (label == "")
            {
                label = "mode" + value.ToString();
            }
            Controller.Instance.Locations.Add(label, this.ValueTerm);

            Controller.Instance.LocationNumTermToName.Add(this.ValueTerm, label);
        }
Ejemplo n.º 4
0
 public AState(AHybridAutomaton h, String label, UInt32 value, Boolean initial, List <Transition> transitions)
 {
     this.Parent       = h;
     this._label       = label;
     this._value       = value;
     this._initial     = initial;
     this._transitions = transitions;
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Parse a transition
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="h"></param>
        /// <param name="l"></param>
        /// <returns></returns>
        public static Transition ParseTransition(XmlTextReader reader, AHybridAutomaton h, ConcreteLocation l)
        {
            Transition t;


            // todo: refactor: check and throw if null on either, but also while checking if parent of l is not null (e.g., these transitions may be local or global)
            if (Controller.Instance.Sys != null || h != null)
            {
                t = new Transition(l); // l is null for global transitions, no parent

                if (h == null)
                {
                    Controller.Instance.Sys.addTransition(t);
                }
                else
                {
                    String des = reader.GetAttribute(TransitionAttributes.destination.ToString());
                    String src = reader.GetAttribute(TransitionAttributes.source.ToString());
                    String prs = reader.GetAttribute(TransitionAttributes.processes.ToString());

                    List <String> dess      = new List <String>();
                    List <String> srcs      = new List <String>();
                    List <String> processes = new List <string>();

                    if (!src.Contains(","))
                    {
                        srcs.Add(src);
                    }
                    else
                    {
                        srcs.AddRange(src.Split(','));
                    }

                    bool toSelf = false;
                    if (des != null && des.Length > 0)
                    {
                        if (!des.Contains(","))
                        {
                            dess.Add(des);
                        }
                        else
                        {
                            dess.AddRange(des.Split(','));
                        }
                    }
                    else
                    {
                        toSelf = true; // only self-loops
                        des    = src;
                        dess   = srcs;
                    }

                    t.Indices.Add("h");                        // do not have to include h by default, as it is always the process moving
                    t.Indices.AddRange(processes);             // assume process h always included
                    t.Indices = t.Indices.Distinct().ToList(); // ensure distinct

                    List <AState> from = new List <AState>();  // have to find the frome state as well, because in hyxml syntax, transitions are not associated with locations
                    foreach (AState s in h.Locations)
                    {
                        uint desParsed = 0;
                        uint srcParsed = 0;

                        foreach (String stmp in srcs)
                        {
                            UInt32.TryParse(stmp, out srcParsed);

                            if (s.Label == stmp || (srcParsed != null && Regex.IsMatch(stmp, @"^[0-9]+$") && s.Value == UInt32.Parse(stmp)))
                            {
                                from.Add(s);
                            }
                        }

                        foreach (String dtmp in dess)
                        {
                            UInt32.TryParse(dtmp, out desParsed);

                            if (s.Label == dtmp || (desParsed != null && Regex.IsMatch(dtmp, @"^[0-9]+$") && s.Value == UInt32.Parse(dtmp)))
                            {
                                t.NextStates.Add(s);
                            }
                        }
                    }


                    if (from.Count > 0)
                    {
                        foreach (AState ftmp in from)
                        {
                            t.Parent = (ConcreteLocation)ftmp;
                            if (toSelf) // only self-loops
                            {
                                t.NextStates = new List <AState>();
                                t.NextStates.Add(ftmp);
                            }
                            ftmp.addTransition(t);
                        }
                    }
                    else
                    {
                        throw new System.Exception("Error parsing transition: could not find the source location.");
                    }
                }
            }
            else
            {
                throw new System.Exception("Error parsing transition: either holism or hybrid automaton not specified properly before reaching transition.");
            }
            return(t);
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Parse location end tag
 /// </summary>
 /// <param name="l"></param>
 public static void ParseLocationEnd(XmlTextReader reader, AHybridAutomaton h, ConcreteLocation l)
 {
     h.addLocation(l);
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Parse an ODE
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="h"></param>
        /// <param name="l"></param>
        public static void ParseDAI(XmlTextReader reader, AHybridAutomaton h, ConcreteLocation l)
        {
            if (h == null)
            {
                throw new System.ArgumentNullException("Error parsing transition: hybrid automaton not specified properly before reaching differential equation.");
            }

            if (l == null)
            {
                throw new System.ArgumentNullException("Error parsing transition: location not specified properly before reaching differential equation.");
            }

            // todo: this currently has a lot of assumptions about how the diffeq should appear
            // todo: probably the easiest way to accomodate this would be to require a different <dai> block in the xml file for each variable
            //       but obviously this could have limitations for linear / affine dynamics, but... maybe not?
            //       let's think about it more

            String variable = reader.GetAttribute(FlowAttributes.variable.ToString());
            String flow     = reader.GetAttribute(FlowAttributes.equn.ToString());

            if (variable != null && flow != null && variable.Length > 0 && flow.Length > 0)
            {
                Antlr.Runtime.Tree.CommonTree tmptree = math.Expression.Parse(flow);
                List <String> vars      = LogicalExpression.findContinuousVars(tmptree);
                List <String> pvars     = LogicalExpression.findParams(tmptree);
                List <String> constants = LogicalExpression.findAllRealConstants(tmptree);
                Expr          expr      = LogicalExpression.CreateTerm(tmptree);
                List <Expr>   flows     = new List <Expr>();
                Expr          t1        = Controller.Instance.Z3.MkRealConst("t_1");

                Flow f = new Flow();

                // indexed if the variable appears e.g., as x[i], else assume global, e.g., x
                if (variable.Contains("[") && variable.Contains("]"))
                {
                    String[] vns          = variable.Split('[');
                    String   variableName = vns[0];                 // todo: error handling

                    f.Variable = h.GetVariableByName(variableName); // todo: error handling

                    // prime all variables
                    switch (Controller.Instance.DataOption)
                    {
                    case Controller.DataOptionType.array:
                    {
                        expr = expr.Substitute(Controller.Instance.DataA.IndexedVariableDecl[variableName], Controller.Instance.DataA.IndexedVariableDeclPrimed[variableName]);
                        break;
                    }

                    case Controller.DataOptionType.uninterpreted_function:
                    default:
                    {
                        Controller.Instance.Z3.replaceFuncDecl(ref expr, expr, Controller.Instance.DataU.IndexedVariableDecl[variableName], Controller.Instance.DataU.IndexedVariableDeclPrimed[variableName], false);
                        break;
                    }
                    }

                    // todo: rewrite in more general form for timed vs. rectangular
                    if (constants.Count + pvars.Count < 1)
                    {
                        f.DynamicsType = Flow.DynamicsTypes.timed;
                    }
                    else if (constants.Count + pvars.Count == 1)
                    {
                        f.DynamicsType = Flow.DynamicsTypes.timed;
                        if (pvars.Count == 1)
                        {
                            f.RectRateA = Controller.Instance.Params[pvars[0]];
                            f.RectRateB = Controller.Instance.Params[pvars[0]]; // \dot{x} \in [a,a]
                        }
                        if (constants.Count == 1)
                        {
                            f.RectRateA = Controller.Instance.Z3.MkReal(constants[0]);
                            f.RectRateB = Controller.Instance.Z3.MkReal(constants[0]);
                        }
                    }
                    else if (constants.Count + pvars.Count == 2)
                    {
                        f.DynamicsType = Flow.DynamicsTypes.rectangular;
                        // todo: generalize
                        if (pvars.Count >= 1)
                        {
                            f.RectRateA = Controller.Instance.Params[pvars[0]];
                        }
                        if (pvars.Count >= 2)
                        {
                            f.RectRateB = Controller.Instance.Params[pvars[1]];
                        }
                        if (constants.Count >= 1)
                        {
                            f.RectRateA = Controller.Instance.Z3.MkReal(constants[0]);
                        }
                        if (constants.Count >= 2)
                        {
                            f.RectRateB = Controller.Instance.Z3.MkReal(constants[1]);
                        }
                    }

                    if (pvars.Count > 0)
                    {
                        foreach (var y in pvars)
                        {
                            // todo: generalize, this is pretty nasty, and currently only supports dynamics of the form: v[i] R y, where R is an order/equivalence relation (e.g., >, <, >=, <=, =, etc.)
                            Expr addDeltaMin = Controller.Instance.Z3.MkAdd((ArithExpr)Controller.Instance.IndexedVariables[new KeyValuePair <string, string>(variableName, "i")], Controller.Instance.Z3.MkMul((ArithExpr)Controller.Instance.Params[y], (ArithExpr)t1));
                            expr = expr.Substitute(Controller.Instance.Params[y], addDeltaMin);
                        }
                    }
                    else if (constants.Count > 0)
                    {
                        foreach (var cs in constants)
                        {
                            int    cint = (int)float.Parse(cs);
                            String cstr = float.Parse(cs).ToString();

                            if (cint == 1)
                            {
                                Expr c           = Controller.Instance.Z3.MkReal(cstr);
                                Expr addDeltaMin = Controller.Instance.Z3.MkAdd((ArithExpr)Controller.Instance.IndexedVariables[new KeyValuePair <string, string>(variableName, "i")], (ArithExpr)t1);
                                expr = expr.Substitute(c, addDeltaMin);
                            }
                            else if (cint == -1) // todo: constants will never be negative currently due to the way findRealConstants function works (- is a unary term, so the constants are always positive with another unary minus outside)
                            {
                                Expr c           = Controller.Instance.Z3.MkReal(cstr);
                                Expr addDeltaMin = Controller.Instance.Z3.MkSub((ArithExpr)Controller.Instance.IndexedVariables[new KeyValuePair <string, string>(variableName, "i")], (ArithExpr)t1);
                                expr = expr.Substitute(c, addDeltaMin);
                            }
                            else if (cint < 0)
                            {
                                Expr c           = Controller.Instance.Z3.MkReal(cstr);
                                Expr addDeltaMin = Controller.Instance.Z3.MkSub((ArithExpr)Controller.Instance.IndexedVariables[new KeyValuePair <string, string>(variableName, "i")], Controller.Instance.Z3.MkMul((ArithExpr)c, (ArithExpr)t1));
                                expr = expr.Substitute(c, addDeltaMin);
                            }
                            else
                            {
                                Expr c           = Controller.Instance.Z3.MkReal(cstr);
                                Expr addDeltaMin = Controller.Instance.Z3.MkAdd((ArithExpr)Controller.Instance.IndexedVariables[new KeyValuePair <string, string>(variableName, "i")], Controller.Instance.Z3.MkMul((ArithExpr)c, (ArithExpr)t1));
                                expr = expr.Substitute(c, addDeltaMin);
                            }
                        }
                    }
                }
                else // global variables
                {
                    String variableName = variable;
                    f.Variable = Controller.Instance.Sys.GetVariableByName(variableName);

                    // prime the continuous variable occurrences
                    expr = expr.Substitute(Controller.Instance.GlobalVariables[variableName], Controller.Instance.GlobalVariablesPrimed[variableName]);

                    if (pvars.Count > 0)
                    {
                        foreach (var y in pvars)
                        {
                            // todo: generalize, this is pretty nasty, and currently only supports dynamics of the form: v[i] R y, where R is an order/equivalence relation (e.g., >, <, >=, <=, =, etc.)
                            Expr addDeltaMin = Controller.Instance.Z3.MkAdd((ArithExpr)Controller.Instance.Params[variableName], Controller.Instance.Z3.MkMul((ArithExpr)Controller.Instance.Params[y], (ArithExpr)t1));
                            expr = expr.Substitute(Controller.Instance.Params[y], addDeltaMin);
                        }
                    }
                    else if (constants.Count > 0)
                    {
                        foreach (var cs in constants)
                        {
                            int    cint = (int)float.Parse(cs);
                            String cstr = float.Parse(cs).ToString();
                            f.DynamicsType = Flow.DynamicsTypes.timed;
                            if (cint == 1)
                            {
                                Expr c = Controller.Instance.Z3.MkReal(cstr);
                                f.RectRateA = c;
                                Expr addDeltaMin = Controller.Instance.Z3.MkAdd((ArithExpr)Controller.Instance.GlobalVariables[variableName], (ArithExpr)t1);
                                expr = expr.Substitute(c, addDeltaMin);
                            }
                            else if (cint == -1)
                            {
                                Expr c = Controller.Instance.Z3.MkReal(cstr);
                                f.RectRateA = c;
                                Expr addDeltaMin = Controller.Instance.Z3.MkSub((ArithExpr)Controller.Instance.GlobalVariables[variableName], (ArithExpr)t1);
                                expr = expr.Substitute(c, addDeltaMin);
                            }
                            else if (cint < 0)
                            {
                                Expr c = Controller.Instance.Z3.MkReal(cstr);
                                f.RectRateA = c;
                                Expr addDeltaMin = Controller.Instance.Z3.MkSub((ArithExpr)Controller.Instance.GlobalVariables[variableName], Controller.Instance.Z3.MkMul((ArithExpr)c, (ArithExpr)t1));
                                expr = expr.Substitute(c, addDeltaMin);
                            }
                            else
                            {
                                Expr c = Controller.Instance.Z3.MkReal(cstr);
                                f.RectRateA = c;
                                Expr addDeltaMin = Controller.Instance.Z3.MkAdd((ArithExpr)Controller.Instance.GlobalVariables[variableName], Controller.Instance.Z3.MkMul((ArithExpr)c, (ArithExpr)t1));
                                expr = expr.Substitute(c, addDeltaMin);
                            }
                        }
                    }
                }

                // todo: generalize: we assume anything with a 0 in it is constant dynamics
                //if (!Controller.Instance.Z3.findTerm(expr, Controller.Instance.RealZero, true))
                if (!(f.RectRateA == Controller.Instance.RealZero || f.RectRateB == Controller.Instance.RealZero))
                {
                    f.Value = expr;

                    /*
                     * // todo: move zero diffeq detection to this part, as currently we may be removing some actual diffeqs if any of them are 0
                     * if (l.Flow != null)
                     * {
                     *  l.Flow = l.Flow & expr;
                     * }
                     * else
                     * {
                     *  l.Flow = expr; // todo: this doesn't work properly if we have multiple variables, due to the way we replace the flow in stopping conditions and invariants
                     *  // one solution is to use a list of flows
                     *  // another is to create a flow object, which is the more natural choice, and keep a list of flow objects (so they may have different types, e.g., timed vs rect vs linear)
                     * }
                     */
                }
                else
                {
                    f.DynamicsType = Flow.DynamicsTypes.constant; // no change
                    f.RectRateA    = Controller.Instance.RealZero;
                    f.RectRateB    = Controller.Instance.RealZero;
                    Expr atmp = Controller.Instance.IndexedVariables[new KeyValuePair <string, string>(f.Variable.Name, "i")];
                    Expr btmp = Controller.Instance.IndexedVariablesPrimed[new KeyValuePair <string, string>(f.Variable.Name + Controller.PRIME_SUFFIX, "i")];
                    f.Value = Controller.Instance.Z3.MkEq(atmp, btmp);
                }

                l.Flows.Add(f);
            }
        }
Ejemplo n.º 8
0
 public ConcreteLocation(AHybridAutomaton h, String label, UInt32 value, Boolean initial)
     : base(h, label, value, initial)
 {
 }