public override Operator toExplicit() { BinaryOperator o = new OperatorOr(); o.setLeftOperand(m_left.toExplicit()); o.setRightOperand(m_left.toExplicit()); return o; }
/** * Constructs an Operator based on a string. With the exception of possible * superfluous parentheses and whitespace, the resulting operator is such * that getFromString(s).toString() == s. The input string must respect the * following BNF grammar (which corresponds to LTL + first-order; * parentheses are important): * <ol> * <li>string := atom | binary_op | unary_op | quantified * <li>binary_op := (string) bin_operator (string) * <li>unary_op := un_operator (string) * <li>quantified := [qualif_var] (string) | <qualif_var> (string) * <li>bin_operator := & | -> | the "pipe" character | U | = | < | * > | - * <li>un_operator := ! | G | X | F * <li>qualif_var := atom qualif (there is a whitespace character between * atom and qualif) * <li>atom := any literal composed of alphanumerical characters, with the * exception of reserved sequences such as operators * <li>qualif:= any literal composed of alphanumerical characters, with the * exception of reserved sequences such as operators * </ol> * * @param s * The input string * @param domains * A map from a set of paths to a set of values (atoms), providing * finite domains for quantifiers. This parameter is facultative; * domains need to be provided only when quantifiers need to be * expanded into explicit conjunctions/disjunctions of values, or * when messages must be generated (instead of monitored). * * @return An Operator equivalent to the string passed as an argument, null * if the string does not correspond to a valid Operator. */ public static Operator parseFromString(string s, IDictionary<string, HashSet<Constant>> domains) { bool flag = false; int quantRight = 0, parLeft = 0; Operator o = null, o2 = null; FOQuantifier foq = null; UnaryOperator uo = null; BinaryOperator bo = null; Atom a = null; // First removes/converts extra whitespace s = LTLStringParser.formatString(s); string sTrim = s.Trim(); if (sTrim.Length == 0) { return null; } // Handles first-order quantifiers flag = false; if (sTrim[0] == '[') { foq = new FOForAll(); quantRight = sTrim.IndexOf("]"); flag = true; } if (sTrim[0] == '<') { foq = new FOExists(); quantRight = sTrim.IndexOf(">"); flag = true; } if (flag) { Regex r = new Regex("^(\\w+)\\s*(.*)$"); MatchCollection m = r.Matches(sTrim.Substring(1, quantRight - 1)); if (m.Count > 0) { Match m2 = m[0]; GroupCollection g = m2.Groups; Atom qvar = new Atom(g[1].ToString()); string qualifier = g[2].ToString(); foq.setQuantifiedVariable(qvar); foq.setQualifier(qualifier); if (domains != null) { // If a domain is provided, attaches it to the quantifier HashSet<Constant> dom = new HashSet<Constant>(); foreach (KeyValuePair<string, HashSet<Constant>> con in domains) { if (con.Key == qualifier) { dom = con.Value; } } foq.setDomain(dom); } } //foq.setQualifiedVariable(sTrim.substring(1, quantRight)); parLeft = sTrim.IndexOf("(", (quantRight + 1)); //parRight = sTrim.indexOf(")", parLeft); o = parseFromString(sTrim.Substring((parLeft + 1), sTrim.Length - 1 - (parLeft + 1)), domains); foq.setOperand(o); return foq; } // Handles unary operators flag = false; if (sTrim.Substring(0, 1) == "!") { uo = new OperatorNot(); flag = true; } if (sTrim.Substring(0, 1) == "F") { uo = new OperatorF(); flag = true; } if (sTrim.Substring(0, 1) == "G") { uo = new OperatorG(); flag = true; } if (sTrim.Substring(0, 1) == "X") { uo = new OperatorX(); flag = true; } if (sTrim.Length >= 2) { // This is for CTL, nothing to do here } if (flag) { parLeft = sTrim.IndexOf("("); o = parseFromString(sTrim.Substring((parLeft + 1), sTrim.Length - 1 - (parLeft + 1)), domains); uo.setOperand(o); return uo; } // Handles binary operators flag = false; if (sTrim[0] == '(') { // At this point in the method, if first char is a "(", // the formula is necessarily a binary operator int parNum = 0; string sLeft = "", sRight = ""; string binaryOp = ""; Regex r = new Regex("(\\(|\\))"); MatchCollection m = r.Matches(sTrim); int mend = -1; for (int i = 0; i < m.Count; i++) { Match m2 = m[i]; mend = m[i].Groups[0].Index + m[i].Groups[0].Length; GroupCollection g = m2.Groups; if (g[0].ToString().Equals("(")) { parNum++; } else { parNum--; } if (parNum == 0) { sLeft = sTrim.Substring(1, mend - 1 - 1); break; } } parLeft = sTrim.IndexOf("(", mend); int left_var = mend + 1; binaryOp = sTrim.Substring(left_var, parLeft - left_var - 1).Trim(); sRight = sTrim.Substring(parLeft + 1, sTrim.Length - 1 - (parLeft + 1)).Trim(); o = parseFromString(sLeft, domains); o2 = parseFromString(sRight, domains); if (binaryOp == "&") { bo = new OperatorAnd(); flag = true; } if (binaryOp == "|") { bo = new OperatorOr(); flag = true; } if (binaryOp == "=") { bo = new OperatorEquals(o, o2); flag = true; } if (binaryOp == "->") { bo = new OperatorImplies(o, o2); flag = true; } if (binaryOp == "-") { bo = new OperatorMinus(o, o2); flag = true; } if (binaryOp == "<") { bo = new OperatorSmallerThan(o, o2); flag = true; } if (binaryOp == "<=") { bo = new OperatorSmallerThan(o, o2, true); flag = true; } if (binaryOp == ">") { bo = new OperatorGreaterThan(o, o2); flag = true; } if (binaryOp == ">=") { bo = new OperatorGreaterThan(o, o2, true); flag = true; } if (binaryOp == "U") { bo = new OperatorU(o, o2); flag = true; } if (binaryOp == "V") { bo = new OperatorV(o, o2); flag = true; } if (flag) { return bo; } } else { // At this point, the only case left is that of a single atom // (either a constant or a variable) if (sTrim[0] == '{') { // Constants are surrounded by braces a = new Constant(sTrim.Substring(1, sTrim.Length - 1 - 1)); } else if (sTrim[0] == '/') { // XPaths are surrounded by forward slashes a = new ConstantPath(sTrim.Substring(1, sTrim.Length - 1 - 1)); } else { // Otherwise, we have an atom a = new Atom(sTrim); } return a; } // Down there, none of the previous cases has fired: return o, which is // null System.Diagnostics.Debug.Assert (false); return o; }
public override Operator toExplicit() { if (m_domain == null || m_domain.Count == 0) { return null; } BinaryOperator bo = new OperatorOr(); bool first = true; foreach (Atom a in m_domain) { Operator o = m_operand.evaluate(m_quantifiedVariable, a); if (m_domain.Count == 1) { return o; } if (first) { first = false; bo.setLeftOperand(o); continue; } if (bo.getRightOperand() == null) { bo.setRightOperand(o); } else { BinaryOperator newbo = new OperatorOr(); newbo.setLeftOperand(bo); newbo.setRightOperand(o); bo = newbo; } } return bo; }
public HashSet<GeneratorNode> spawn(OperatorOr op) { HashSet<GeneratorNode> spawnedSet, outSet = new HashSet<GeneratorNode>(); // Do for left operand GeneratorNode wn = new GeneratorNode(this); Operator o2 = op.getLeftOperand(); wn.addToGamma(o2); spawnedSet = wn.spawn(); foreach (GeneratorNode gn in spawnedSet) { outSet.Add(gn); } // Do for right operand wn = new GeneratorNode(this); o2 = op.getRightOperand(); wn.addToGamma(o2); spawnedSet = wn.spawn(); if (spawnedSet != null) { foreach (GeneratorNode gn in spawnedSet) { outSet.Add(gn); } } return outSet; }