private GeneratorNode generateNode() { HashSet<GeneratorNode> spawnedNodes; HashSet<GeneratorNode> newNodes = new HashSet<GeneratorNode>(); int size = 0, atoms = 0; long timeBegin = Stopwatch.GetTimestamp(); // Takes each node and applies its decomposition foreach (GeneratorNode wn in m_nodes) { GeneratorNode wn2 = new GeneratorNode(); wn2.setGamma(wn.getDelta()); spawnedNodes = wn2.spawn(); foreach (GeneratorNode gn in spawnedNodes) { newNodes.Add(gn); } // Shortcut: as soon as one branch returns something, we skip the others if (spawnedNodes.Count > 0) { break; } } long timeEnd = Stopwatch.GetTimestamp(); System.Console.WriteLine("Finished producing the " + newNodes.Count + "nodes " + (timeEnd - timeBegin)); timeBegin = Stopwatch.GetTimestamp(); // Remember the new nodes m_nodes = newNodes; // Updates statistics about maximum number of nodes size = m_nodes.Count; if (size > m_maxNodes) { m_maxNodes = size; } // Updates statistics about total number of formulae size = 0; atoms = 0; foreach (GeneratorNode wn in m_nodes) { size += wn.getSize(); atoms += wn.getAtoms(); } if (size > m_maxFormulae) { m_maxFormulae = size; } if (atoms > m_maxAtoms) { m_maxAtoms = atoms; } // We remove nodes that don't contain any OPlus // (i.e., that don't tell us to do anything) // and check at the same time if at least one node is sound bool hasSound = false; foreach (GeneratorNode wn in m_nodes) { HashSet<OPlus> opluses = wn.getOPluses(); bool contains_element = false; foreach (OPlus op in opluses) { // Remove conditions that only assert path existence if (!op.getOperand().Equals(Operator.m_falseAtom) && !op.getOperand().Equals(Operator.m_trueAtom)) { contains_element = true; } } if (!contains_element) { m_nodes.Remove(wn); } else { if (wn.Sound) { hasSound = true; } } } // Can we produce a new message? if (m_nodes.Count == 0) { // No! return null; } // We remove all nodes whose OPluses are contradictory /*it = m_nodes.iterator(); while (it.hasNext()) { GeneratorNode wn = it.next(); if (wn.containsOPlusContradiction()) it.remove(); }*/ // Is there at least one remaining sound node? if (hasSound) { // Yes: then let's remove any unsound node foreach (GeneratorNode wn in m_nodes) { if (!wn.Sound) { m_nodes.Remove(wn); } } } timeEnd = Stopwatch.GetTimestamp(); System.Console.WriteLine("Finished pruning " + (timeEnd - timeBegin)); // Pick *one* of the nodes randomly long pickIndex = (long)System.Math.Round(new System.Random().NextDouble() * (double)(m_nodes.Count - 1)); int i = 0; GeneratorNode pickedNode = null; foreach (GeneratorNode gn in m_nodes) { if (i == pickIndex) { pickedNode = gn; break; } i++; } // Keep only the selected node for the next state m_nodes = new HashSet<GeneratorNode>(); m_nodes.Add(pickedNode); // Return the picked node return pickedNode; }
public HashSet<GeneratorNode> spawn(OperatorV op) { HashSet<GeneratorNode> spawnedSet, outSet = new HashSet<GeneratorNode>(); // Do for left node GeneratorNode wn = new GeneratorNode(this); Operator o2 = op.getLeftOperand(); wn.addToGamma(o2); o2 = op.getRightOperand(); wn.addToGamma(o2); spawnedSet = wn.spawn(); if (spawnedSet != null) { foreach (GeneratorNode gn in spawnedSet) { outSet.Add(gn); } } // Do for right node wn = new GeneratorNode(this); o2 = op.getRightOperand(); wn.addToGamma(o2); wn.addToDelta(op); spawnedSet = wn.spawn(); if (spawnedSet != null) { foreach (GeneratorNode gn in spawnedSet) { outSet.Add(gn); } } return outSet; }
public HashSet<GeneratorNode> spawn(OperatorX op) { HashSet<GeneratorNode> spawnedSet, outSet = new HashSet<GeneratorNode>(); GeneratorNode wn = new GeneratorNode(this); Operator o2 = op.getOperand(); wn.addToDelta(o2); spawnedSet = wn.spawn(); if (spawnedSet != null) { foreach (GeneratorNode gn in spawnedSet) { outSet.Add(gn); } } return outSet; }
public HashSet<GeneratorNode> spawn(OperatorImplies op) { HashSet<GeneratorNode> spawnedSet, outSet = new HashSet<GeneratorNode>(); // Do for right operand GeneratorNode wn = new GeneratorNode(this); Operator o2 = op.getRightOperand(); wn.addToGamma(o2); spawnedSet = wn.spawn(); if (spawnedSet != null) { foreach (GeneratorNode gn in spawnedSet) { outSet.Add(gn); } } // Do for right operand wn = new GeneratorNode(this); o2 = op.getLeftOperand().getNegated(); wn.addToGamma(o2.getNegatedNormalForm()); spawnedSet = wn.spawn(); if (spawnedSet != null) { foreach (GeneratorNode gn in spawnedSet) { outSet.Add(gn); } } // Do for both (NEW) wn = new GeneratorNode(this); o2 = op.getRightOperand(); wn.addToGamma(o2); o2 = op.getLeftOperand(); wn.addToGamma(o2); spawnedSet = wn.spawn(); if (spawnedSet != null) { foreach (GeneratorNode gn in spawnedSet) { outSet.Add(gn); } } return outSet; }
public HashSet<GeneratorNode> spawn(FOForAll op) { HashSet<GeneratorNode> spawnedSet, outSet = new HashSet<GeneratorNode>(); Atom x = op.getQuantifiedVariable(); string qualifier = op.getQualifier(); // Iterate over domain HashSet<Constant> oplus_domain = getOPlusDomain(qualifier); HashSet<Constant> domain = op.getDomain(); SubsetIterator<Constant> it; if (!m_encounteredQualifiers.Contains(qualifier)) { // We haven't decomposed a For All in the past, so we can // add elements to the message it = new SubsetIterator<Constant>(domain, oplus_domain); } else { // Otherwise, we stick to the elements we already have to // evaluate this quantifier it = new SubsetIterator<Constant>(oplus_domain); } m_encounteredQualifiers.Add(op.getQualifier()); m_decomposedAForAll = true; if (op.isPathNegation()) { // The quantifier asserts the absence of a path GeneratorNode wn = new GeneratorNode(this); OPlus opl = new OPlus(); opl.setQualifier(op.getQualifier()); opl.setOperand(Operator.m_falseAtom); if (!wn.addToOPluses(opl)) { // We can't add this OPlus to the current set. Contradiction! Return the empty set return new HashSet<GeneratorNode>(); } return wn.spawn(); } if (op.isPathAssertion()) { // In negated form, the quantifier may assert the existence of a path GeneratorNode wn = new GeneratorNode(this); OPlus opl = new OPlus(); opl.setQualifier(op.getQualifier()); opl.setOperand(Operator.m_trueAtom); if (!wn.addToOPluses(opl)) { // We can't add this OPlus to the current set. Contradiction! Return the empty set return new HashSet<GeneratorNode>(); } return wn.spawn(); } while (it.hasNext()) { GeneratorNode wn = new GeneratorNode(this); HashSet<Constant> subset = it.next(); foreach (Atom v in subset) { Operator o2 = op.getOperand(); Operator o3 = o2.evaluate(x, v); OPlus opl = new OPlus(qualifier, v); wn.addToGamma(o3); if (!wn.addToOPluses(opl)) { // Contradiction! Skip that branch continue; } } spawnedSet = wn.spawn(); if (spawnedSet != null) { foreach (GeneratorNode gn in spawnedSet) { outSet.Add(gn); } } } return outSet; }
public HashSet<GeneratorNode> spawn(FOExists op) { HashSet<GeneratorNode> outSet = new HashSet<GeneratorNode>(); Atom x = op.getQuantifiedVariable(); string qualifier = op.getQualifier(); if (m_encounteredQualifiers.Contains(qualifier)) { // We add something along a path where a ForAll has already // been evaluated: soundness is no longer guaranteed for this node m_sound = false; } if (op.isAnOPlus()) { // This is an OPlus; return a node with op transferred to the OPlus set GeneratorNode wn = new GeneratorNode(this); if (!wn.addToOPluses(op.toOPlus())) { // We can't add this OPlus to the current set. Contradiction! Return the empty set return new HashSet<GeneratorNode>(); } return wn.spawn(); } if (op.isPathAssertion()) { GeneratorNode wn = new GeneratorNode(); OPlus opl = new OPlus(); opl.setQualifier(op.getQualifier()); opl.setOperand(Operator.m_trueAtom); if (!wn.addToOPluses(opl)) { // We can't add this OPlus to the current set. Contradiction! Return the empty set return new HashSet<GeneratorNode>(); } return wn.spawn(); } // Iterate over domain //HashSet<Constant> oplus_domain = getOPlusDomain(qualifier); HashSet<Constant> domain = op.getDomain(); SubsetIterator<Constant> it = new SubsetIterator<Constant>(domain); //,oplus_domain while (it.hasNext()) { GeneratorNode wn = new GeneratorNode(this); HashSet<Constant> subset = it.next(); foreach (Atom v in subset) { Operator o2 = op .getOperand(); Operator o3 = o2.evaluate(x, v); if (!op.isPathAssertion()) { wn.addToGamma(o3); } OPlus opl = new OPlus(qualifier, v); if (!wn.addToOPluses(opl)) { // We can't add this OPlus to the current set. Contradiction! Skip that branch continue; } } HashSet<GeneratorNode> spawnedSet = wn.spawn(); if (spawnedSet != null) { foreach (GeneratorNode gn in spawnedSet) { outSet.Add(gn); } } } return outSet; }