def _to_list_rep(self, node): if node is None: return None children = node.children if len(children) == 2: if node.children[0].predicate.symtype.symbolic_eq( node.children[1].predicate.symtype): left = node.children[0] if node.children[ 0].predicate.result else node.children[1] right = node.children[1] if not node.children[ 1].predicate.result else node.children[0] return [ pred_to_smt(left.predicate), self._to_list_rep(left), self._to_list_rep(right) ] else: raise ValueError( "Two children of a constraint should have the same predicate!" ) elif len(node.children) == 1: return [ pred_to_smt(node.children[0].predicate), self._to_list_rep(node.children[0]), None ] elif len(children) == 0: return node.effect raise ValueError( "Should not be possible! Can't have more than two children.")
def solve_constraint(self, selected): #TODO Check if we already have a solution to it first #TODO Do local search if we have an almost solution? asserts, query = selected.get_asserts_and_query() assumptions = [self.mod] + [pred_to_smt(p) for p in asserts ] + [Not(pred_to_smt(query))] self.solver.solve(assumptions) logging.debug("SOLVING: %s", assumptions) return self.solver.last_result
def which_branch(self, branch, symbolic_type): """ This function acts as instrumentation. Branch can be either True or False.""" if self.max_depth > 0 and self.current_constraint.get_length( ) >= self.max_depth: logging.debug("Max Depth (%d) Reached", self.max_depth) return if self.shadowing: return # add both possible predicate outcomes to constraint (tree) p = Predicate(symbolic_type, branch) p.negate() cneg = self.current_constraint.find_child(p) p.negate() c = self.current_constraint.find_child(p) if c is None: asserts = [ pred_to_smt(p) for p in self.current_constraint.get_asserts() ] if self.mod is not None and not is_sat( And(self.mod, pred_to_smt(p), *asserts)): logging.debug("Path pruned by mod (%s): %s %s", self.mod, c, p) return c = self.current_constraint.add_child(p) # we add the new constraint to the queue of the engine for later processing logging.debug("New constraint: %s", c) self.add_constraint(c) # check for path mismatch # IMPORTANT: note that we don't actually check the predicate is the # same one, just that the direction taken is the same if self.expected_path != None and self.expected_path != []: expected = self.expected_path.pop() # while not at the end of the path, we expect the same predicate result. # At the end of the path, we expect a different predicate result done = self.expected_path == [] logging.debug("DONE: %s; EXP: %s; C: %s", done, expected, c) if ( not done and expected.result != c.predicate.result or \ done and expected.result == c.predicate.result ): logging.info("Replay mismatch (done=%s)", done) logging.info(expected) logging.info(c.predicate) if cneg is not None: # We've already processed both cneg.processed = True c.processed = True logging.info("Processed constraint: %s", c) self.current_constraint = c
def _find_counterexample(self, asserts, query): assumptions = [pred_to_smt(p) for p in asserts] + [Not(pred_to_smt(query))] logging.debug("SOLVING: %s", assumptions) self.solver.solve(assumptions)