Beispiel #1
0
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])
Beispiel #2
0
    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)
Beispiel #3
0
 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]))
Beispiel #4
0
    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)
Beispiel #5
0
 def __init__(self, summary: Optional[Sequence[Expr]] = None) -> None:
     if summary is None:
         summary = [TrueExpr]
     self._summary = MySet(summary)
Beispiel #6
0
                            # 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