public void CreateTermTest() { CommonTree ast = null; // TODO: Initialize to an appropriate value bool treeHasRealVars = false; // TODO: Initialize to an appropriate value Expr expected = null; // TODO: Initialize to an appropriate value Expr actual; actual = LogicalExpression.CreateTerm(ast, treeHasRealVars); Assert.AreEqual(expected, actual); Assert.Inconclusive("Verify the correctness of this test method."); }
/// <summary> /// Parse a user supplied assumption: also asserts it into Z3 /// </summary> /// <param name="reader"></param> public static void ParseAssumption(XmlTextReader reader) { String assump = reader.GetAttribute(AssumptionAttributes.equn.ToString()); String type = reader.GetAttribute(AssumptionAttributes.type.ToString()); AssumptionTypes atype; if (type != null) { atype = (AssumptionTypes)Enum.Parse(typeof(AssumptionTypes), type, true); } else { atype = AssumptionTypes.none; } if (assump.Length > 0) { Antlr.Runtime.Tree.CommonTree tmptree = math.Expression.Parse(assump); Expr assumpTerm = LogicalExpression.CreateTerm(tmptree); switch (atype) { case AssumptionTypes.safety: case AssumptionTypes.inductive_invariant: { // assert the assumption Expr assumpTermPrime = assumpTerm; Controller.Instance.Z3.primeAllVariables(ref assumpTermPrime); Expr assumpTermImplies = Controller.Instance.Z3.MkImplies((BoolExpr)assumpTerm, (BoolExpr)assumpTermPrime); // inductive part Controller.Instance.Z3.Assumptions.Add((BoolExpr)assumpTerm); // invariant part Controller.Instance.Z3.Assumptions.Add((BoolExpr)assumpTermPrime); //Controller.Instance.Z3.AssertCnstr(assumpTerm & assumpTermPrime); //Controller.Instance.Z3.AssertCnstr(assumpTermImplies); break; } case AssumptionTypes.invariant: case AssumptionTypes.none: default: { // assert the assumption Controller.Instance.Z3.Assumptions.Add((BoolExpr)assumpTerm); break; } } } }
/// <summary> /// Parse the guard of a transition /// </summary> /// <param name="reader"></param> /// <param name="t"></param> public static void ParseGuard(XmlTextReader reader, Transition t) { if (t == null) { throw new System.ArgumentNullException("Error parsing transition: transition not specified properly before reaching guard."); } String guard = reader.GetAttribute(GuardAttributes.equn.ToString()); if (guard.Length > 0) { Antlr.Runtime.Tree.CommonTree tmptree = math.Expression.Parse(guard); t.Guard = LogicalExpression.CreateTerm(tmptree); } }
public VariableParameter(string name, VarType type, VarUpdateType update_type, string assumption) : base(name, "", type, update_type, assumption) { Expr param = null; // TODO: refactor all these switches in the constructors into common variable parent class switch (type) { case VarType.index: param = Controller.Instance.Z3.MkIntConst(name); // todo: vs Controller.Instance.IndexType break; case VarType.integer: param = Controller.Instance.Z3.MkIntConst(name); break; case VarType.real: param = Controller.Instance.Z3.MkRealConst(name); break; } if (param != null) { if (!Controller.Instance.Params.ContainsKey(name)) { Controller.Instance.Params.Add(name, param); } } else { throw new System.Exception("Parameter term not created."); } if (assumption != null && assumption.Length > 0) { Antlr.Runtime.Tree.CommonTree tmptree = passel.controller.parsing.math.Expression.Parse(assumption); //Expression.FixTypes(ref tmptree); Expr passump = LogicalExpression.CreateTerm(tmptree); if (!Controller.Instance.ParamsAssumps.ContainsKey(name)) { Controller.Instance.ParamsAssumps.Add(name, passump); Controller.Instance.Z3.Assumptions.Add((BoolExpr)passump); } } }
public Property(String f, PropertyType t, String post, String template) { this.FormulaStr = f; this._type = t; this.Status = StatusTypes.toProcess; switch (this._type) { // todo next: change for abstraction, using for inductive invariant checking now case Property.PropertyType.eventually: // todo: break; case Property.PropertyType.bad: // neg invariant case Property.PropertyType.unreachable: // neg invariant FormulaStr = "!(" + this.FormulaStr + ")"; // negate break; // do nothing case Property.PropertyType.invariant: // invariant case Property.PropertyType.safety: // invariant break; } if (this._formula == null && f != null) { Antlr.Runtime.Tree.CommonTree tmptree = Expression.Parse(this.FormulaStr); Expression.FixTypes(ref tmptree); this._formula = LogicalExpression.CreateTerm(tmptree); } if (post == null) { post = f; } if (post != null) { //Antlr.Runtime.Tree.CommonTree tmptree = Expression.Parse(post); //this.Post = LogicalExpression.CreateTerm(tmptree); //Controller.Instance.Z3.primeAllVariables(ref this.Post); // prime all variables in post-state formula this.Post = primeAllByValue(this.Formula); } switch (this.Type) { case PropertyType.termination: // pass through case PropertyType.eventually: { if (template != null) { Enum.TryParse <RankingTemplateType>(template, false, out this.TemplateType); } switch (this.TemplateType) { default: { // todo: generalize for indexed variables // todo: make 2nd argument be the tuple-length we are currently add (needs another parsing input) List <BoolExpr> ts = new List <BoolExpr>(); // todo: temporarily, we will make the tuple be the length of the number of variables for (int i = 0; i < Controller.Instance.GlobalVariables.Count; i++) { ts.Add(Controller.Instance.Z3.MkGe((ArithExpr)this.generateAffineTemplate(Controller.Instance.GlobalVariables, "i", i, false), Controller.Instance.RealZero)); // template >= 0 } this.Formula = Controller.Instance.Z3.MkAnd(ts.ToArray()); // todo: detect size; actually, we should override this in MkAnd to not actually do a mkand if length is 1 Expr lhs = this.generateAffineTemplate(Controller.Instance.GlobalVariables, "c", 0, true); Expr rhs = this.generateAffineTemplate(Controller.Instance.GlobalVariablesPrimed, "c", 0, true); // todo: assumes GlobalVariables and GlobalVariablesPrimed are in the same order this.FormulaRankLhs = lhs; this.FormulaRankRhs = rhs; break; } } break; } case Property.PropertyType.safety_weak: { // do nothing, already has post set break; } case Property.PropertyType.invariant: case Property.PropertyType.safety: default: { break; } } }
/// <summary> /// Parse a HyXML formatted file /// /// Notes: /// 1) Assumes guards and invariants are formatted as infix strings (e.g., 5 + x >= y is a valid guard or invariant, whereas (>= (+ 5 x) y) is not) /// 2) Assumes resets are formatted as: varToReset' = expr /// 3) Assumes differential inclusions are formatted as: x1_dot >= a and x1_dot <= b; more generally, any relations are okay, we just don't support x1_dot \in [a, b] /// /// 1) Eventually modify HyLink to generate HyXML using MathML for guards, invariants, and resets /// </summary> /// <param name="path"></param> public static void ParseInputFile(String path) { Controller.Instance.Sys = new Holism(); ConcreteHybridAutomaton h = null; Transition t = null; ConcreteLocation l = null; ElementNames n = ElementNames.parameter; if (!File.Exists(path)) { throw new FileNotFoundException("Input file not found: " + path); } XmlTextReader reader = new XmlTextReader(path); while (reader.Read()) { try { switch (reader.NodeType) { case XmlNodeType.Element: { n = (ElementNames)(Enum.Parse(typeof(ElementNames), reader.Name, true)); switch (n) { case ElementNames.parameter: { Variable p = ParseVariableParameter(reader); break; } case ElementNames.predicate: { break; } // since properties can refer to elements of the automata, we save their strings and parse them after all automata have been fully constructed case ElementNames.property: { ParseProperty(reader); break; } case ElementNames.assumption: { ParseAssumption(reader); break; } case ElementNames.action: { ParseReset(reader, t); break; } case ElementNames.automaton: { String name = reader.GetAttribute(AutomatonAttributes.name.ToString()); h = new ConcreteHybridAutomaton(Controller.Instance.Sys, name); break; } case ElementNames.dai: { ParseDAI(reader, h, l); break; } case ElementNames.guard: { ParseGuard(reader, t); break; } case ElementNames.uguard: { if (t == null) { throw new System.Exception("Error parsing transition: transition not specified properly before reaching universally quantified guard."); } String uguard = reader.GetAttribute(GuardAttributes.equn.ToString()); if (uguard.Length > 0) { Antlr.Runtime.Tree.CommonTree tmptree = math.Expression.Parse(uguard); t.UGuard = LogicalExpression.CreateTerm(tmptree); } break; } case ElementNames.initial: { if (h == null) { throw new System.Exception("Error parsing initial: automaton not specified properly before reaching initial."); } String init = reader.GetAttribute(InitialAttributes.equn.ToString()); if (init.Length > 0) { h.InitialString = init; } break; } case ElementNames.invariant: { if (l == null) { throw new System.Exception("Error parsing transition: location not specified properly before reaching invariant."); } String inv = reader.GetAttribute(InvariantAttributes.equn.ToString()); if (inv.Length > 0) { Antlr.Runtime.Tree.CommonTree tmptree = math.Expression.Parse(inv); l.Invariant = LogicalExpression.CreateTerm(tmptree); } break; } case ElementNames.stop: { if (l == null) { throw new System.Exception("Error parsing transition: location not specified properly before reaching stopping condition."); } String stop = reader.GetAttribute(StopAttributes.equn.ToString()); if (stop.Length > 0) { Antlr.Runtime.Tree.CommonTree tmptree = math.Expression.Parse(stop); l.Stop = LogicalExpression.CreateTerm(tmptree); } break; } case ElementNames.mode: { l = ParseLocation(reader, h); break; } case ElementNames.transition: { t = ParseTransition(reader, h, l); break; } case ElementNames.variable: { ParseVariable(reader, h); break; } case ElementNames.holism: { // todo break; } default: { throw new Exception("Bad element specified (uncrecognized)."); break; } } break; } // destroy temporary arguments case XmlNodeType.EndElement: { n = (ElementNames)(Enum.Parse(typeof(ElementNames), reader.Name, true)); switch (n) { case ElementNames.parameter: { break; } case ElementNames.action: { break; } case ElementNames.automaton: { h.finishConstruction(); // finish building the concrete automaton: create equations for initial conditions, assert constraints on locations, etc. Controller.Instance.Sys.addHybridAutomaton(h); foreach (var v in Controller.Instance.Sys.Variables) { if (v.UpdateType == Variable.VarUpdateType.discrete && v.Type == Variable.VarType.index) { Controller.Instance.Z3.Assumptions.Add(Controller.Instance.Z3.MkLe((ArithExpr)Controller.Instance.IntZero, (ArithExpr)Controller.Instance.GlobalVariables[v.Name])); Controller.Instance.Z3.Assumptions.Add(Controller.Instance.Z3.MkLe((ArithExpr)Controller.Instance.GlobalVariables[v.Name], (ArithExpr)Controller.Instance.Params["N"])); Controller.Instance.Z3.Assumptions.Add(Controller.Instance.Z3.MkLe((ArithExpr)Controller.Instance.IntZero, (ArithExpr)Controller.Instance.GlobalVariablesPrimed[v.Name])); Controller.Instance.Z3.Assumptions.Add(Controller.Instance.Z3.MkLe((ArithExpr)Controller.Instance.GlobalVariablesPrimed[v.Name], (ArithExpr)Controller.Instance.Params["N"])); } } h = null; break; } case ElementNames.dai: { break; } case ElementNames.guard: { break; } case ElementNames.invariant: { break; } case ElementNames.mode: { ParseHyXML.ParseLocationEnd(reader, h, l); l = null; break; } case ElementNames.transition: { //l.addTransition(t); // todo: search the locations by id to find the prestate and poststate locations t = null; break; } case ElementNames.variable: { break; } default: { break; } } break; } default: { break; } } } catch (NoViableAltException ex) { System.Console.WriteLine("ERROR: parser error"); System.Console.WriteLine("Line " + reader.LineNumber + " position " + reader.LinePosition + " element name " + reader.Name); } catch (Exception ex) { System.Console.WriteLine("ERROR: parser error"); System.Console.WriteLine("Line " + reader.LineNumber + " position " + reader.LinePosition + " element name " + reader.Name); } } reader.Close(); }
/// <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); } }
public void ToConcreteTest() { uint N; uint TN; N = 0; TN = 0; List <SymmetricType> types = new List <SymmetricType>(); types.Add(new SymmetricType(TN, Controller.Instance.Z3.MkTrue())); SymmetricState target = new SymmetricState(N, types.ToArray()); Expr expected = null; Expr actual; actual = target.ToConcrete(); //Assert.AreEqual(expected, actual); N = 1; TN = 1; types = new List <SymmetricType>(); Holism sys = new Holism(); ConcreteHybridAutomaton h = new ConcreteHybridAutomaton(sys, "test"); ConcreteLocation aloc; ConcreteLocation bloc; StringReader tr; XmlTextReader reader; tr = new StringReader("<holism><mode id='0' name='aloc' initial='True'></mode><mode id='0' name='bloc' initial='False'></mode></holism>"); reader = new XmlTextReader(tr); reader.Read(); reader.Read(); aloc = ParseHyXML.ParseLocation(reader, h); reader.Read(); ParseHyXML.ParseLocationEnd(reader, h, aloc); reader.Read(); bloc = ParseHyXML.ParseLocation(reader, h); reader.Read(); ParseHyXML.ParseLocationEnd(reader, h, bloc); expected = LogicalExpression.CreateTerm("q[1] == aloc"); types.Add(new SymmetricType(TN, LogicalExpression.CreateTerm("q[i] == aloc"))); target = new SymmetricState(N, types.ToArray()); actual = target.ToConcrete(); //expected = expected.Substitute(Controller.Instance.Indices["i"], Controller.Instance.Z3.MkInt(1)); //Assert.AreEqual(expected, actual); Assert.IsTrue(Controller.Instance.Z3.ProveEqual(actual, expected)); expected = LogicalExpression.CreateTerm("q[1] == aloc and q[2] == aloc"); types = new List <SymmetricType>(); types.Add(new SymmetricType(2, LogicalExpression.CreateTerm("q[i] == aloc"))); target = new SymmetricState(2, types.ToArray()); actual = target.ToConcrete(); Assert.IsTrue(Controller.Instance.Z3.ProveEqual(actual, expected)); expected = LogicalExpression.CreateTerm("q[1] == aloc and q[2] == aloc and q[3] == aloc"); types = new List <SymmetricType>(); types.Add(new SymmetricType(3, LogicalExpression.CreateTerm("q[i] == aloc"))); target = new SymmetricState(3, types.ToArray()); actual = target.ToConcrete(); Assert.IsTrue(Controller.Instance.Z3.ProveEqual(actual, expected)); //target.visit(0, 3); List <uint> ids = new List <uint>(); ids.Add(1); ids.Add(2); ids.Add(3); ids.Add(4); var perms = SymHelp.Permutations(ids); //ids.Add(5); //ids.Add(6); /* * IEnumerable<uint> t1 = SymmetricState.Combinations(ids, 1); * String s = ""; * foreach (var v in t1) * { * s += v + ", "; * } * IEnumerable<uint> t2 = SymmetricState.Combinations(ids, 2); * foreach (var v in t2) * { * s += v + ", "; * } * IEnumerable<uint> t3 = SymmetricState.Combinations(ids, 3); * foreach (var v in t3) * { * s += v + ", "; * } * IEnumerable<uint> t4 = SymmetricState.Combinations(ids, 4); * foreach (var v in t4) * { * s += v + ", "; * }*/ /* * uint T1 = 2; * uint T2 = 2; * uint T3 = (uint)(ids.Count - (T1 + T2)); * var ids_t1 = SymHelp.Combinations(ids, (int)T1); * //s = ""; * string s = ""; * foreach (var v in ids_t1) * { * List<uint> vt = new List<uint>(v); * var ids_t2 = SymHelp.Combinations(ids.FindAll(id => !vt.Contains(id)), (int)T2); * * * //foreach (var stmp in v) * //{ * // s += stmp; * // } * // s += ", "; * * foreach (var v2 in ids_t2) * { * List<uint> vt2 = new List<uint>(v2); * var ids_t3 = SymHelp.Combinations(ids.FindAll(id => !vt.Contains(id) && !vt2.Contains(id)), (int)T3); * * foreach (var v3 in ids_t3) * { * List<uint> idset = new List<uint>(v); * idset.AddRange(v2); * idset.AddRange(v3); * * foreach (var stmp in idset) * { * s += stmp; * } * s += ", "; * } * } * }*/ //IEnumerable<uint> combinations = ; expected = LogicalExpression.CreateTerm("(q[1] == aloc and q[2] == bloc) or (q[1] == bloc and q[2] == aloc)"); types = new List <SymmetricType>(); types.Add(new SymmetricType(1, LogicalExpression.CreateTerm("q[i] == aloc"))); types.Add(new SymmetricType(1, LogicalExpression.CreateTerm("q[i] == bloc"))); target = new SymmetricState(2, types.ToArray()); actual = target.ToConcrete(); Assert.IsTrue(Controller.Instance.Z3.ProveEqual(actual, expected)); }