class Frame: def __init__(self, summary: Optional[Sequence[Expr]] = None) -> None: if summary is None: summary = [TrueExpr] self._summary = MySet(summary) def summary(self) -> Sequence[Expr]: return self._summary.l def strengthen(self, conjunct: Expr) -> None: self._summary.add(conjunct) def __str__(self) -> str: return str([str(x) for x in self._summary])
def find_predecessor( self, j: int, diag_or_expr: Union[Diagram, Expr] ) -> Tuple[CheckSatResult, Union[Optional[MySet[int]], Tuple[DefinitionDecl, Trace]]]: pre_frame = self[j] prog = syntax.the_program solver = self.solver t = self.solver.get_translator(2) if utils.args.use_z3_unsat_cores: core: Optional[MySet[int]] = MySet() else: core = None def to_z3() -> z3.ExprRef: if isinstance(diag_or_expr, Diagram): return diag_or_expr.to_z3(t, new=True) else: return t.translate_expr(New(diag_or_expr)) def trackers() -> List[z3.ExprRef]: if isinstance(diag_or_expr, Diagram): return diag_or_expr.trackers else: return [] with solver.new_frame(), solver.mark_assumptions_necessary(): for f in pre_frame.summary(): solver.add(t.translate_expr(f)) solver.add(to_z3()) for ition in prog.transitions(): with solver.new_frame(): solver.add(t.translate_expr(ition.as_twostate_formula(prog.scope))) if (res := solver.check(trackers())) == sat: m = Z3Translator.model_to_trace(solver.model(trackers()), 2) state = m.as_state(0) src = self.currently_blocking assert src is not None steps_from_cex = src.known_absent_until_frame + 1 - j + src.num_steps_to_bad bstate = BackwardReachableState(len(self.backwards_reachable_states), state, steps_from_cex) self.record_backwards_reachable_state(bstate) return (sat, (ition, m)) elif res == unsat: if utils.args.use_z3_unsat_cores and isinstance(diag_or_expr, Diagram): assert core is not None # carefully retrieve the unsat core before calling check again uc = solver.unsat_core() res = solver.check([diag_or_expr.trackers[i] for i in core]) if res == unsat: continue for x in sorted(uc, key=lambda y: y.decl().name()): assert isinstance(x, z3.ExprRef) core.add(int(x.decl().name()[1:])) else: for e in solver.assertions(): print(e) assert False, ('z3 returned unknown', res)
def __init__( self, phases: Sequence[Phase], summaries: Optional[Dict[Phase, Sequence[Expr]]] = None) -> None: self._summary_by_pred: Dict[Phase, MySet[Expr]] = OrderedDict() if summaries is None: summaries = {} for phase in phases: self._summary_by_pred[phase] = MySet( summaries.get(phase, [TrueExpr]))
def find_predecessor( self, pre_frame: Frame, current_phase: Phase, diag: Diagram ) -> Tuple[z3.CheckSatResult, Union[Optional[MySet[int]], Tuple[ PhaseTransition, Tuple[Phase, Diagram]]]]: t = self.solver.get_translator(KEY_NEW, KEY_OLD) if utils.args.use_z3_unsat_cores: core: Optional[MySet[int]] = MySet() else: core = None with self.solver: with self.solver.mark_assumptions_necessary(): self.solver.add(diag.to_z3(t)) transitions_into = self.automaton.transitions_to_grouped_by_src( current_phase) for src in self._predecessor_precedence( current_phase, list(transitions_into.keys())): transitions = transitions_into[src] assert transitions utils.logger.debug( "check predecessor of %s from %s by %s" % (current_phase.name(), src.name(), transitions)) (sat_res, pre_diag) = self.find_predecessor_from_src_phase( t, pre_frame, src, transitions, diag, core) if sat_res == z3.unsat: continue return (sat_res, pre_diag) if utils.args.use_z3_unsat_cores: assert core is not None ret_core: Optional[MySet[int]] = MySet(sorted(core)) else: ret_core = None return (z3.unsat, ret_core)
def __init__(self, summary: Optional[Sequence[Expr]] = None) -> None: if summary is None: summary = [TrueExpr] self._summary = MySet(summary)
# carefully retrieve the unsat core before calling check again uc = solver.unsat_core() res = solver.check([diag_or_expr.trackers[i] for i in core]) if res == unsat: continue for x in sorted(uc, key=lambda y: y.decl().name()): assert isinstance(x, z3.ExprRef) core.add(int(x.decl().name()[1:])) else: for e in solver.assertions(): print(e) assert False, ('z3 returned unknown', res) if utils.args.use_z3_unsat_cores: assert core is not None ret_core: Optional[MySet[int]] = MySet(sorted(core)) else: ret_core = None return (unsat, ret_core) def clause_implied_by_transitions_from_frame( self, pre_frame: Frame, c: Expr, solver: Optional[Solver] = None, minimize: Optional[bool] = None ) -> Optional[Tuple[z3.ModelRef, DefinitionDecl]]: if solver is None: solver = self.solver return logic.check_two_state_implication_all_transitions( solver, pre_frame.summary(), c, minimize=minimize