Beispiel #1
0
    def __init__(self, solver: Solver) -> None:
        self.solver = solver
        prog = syntax.the_program

        if utils.args.automaton:
            automaton = prog.the_automaton()
            if automaton is None:
                utils.print_error_and_exit(
                    None, 'updr --automaton requires the file to '
                    'declare an automaton')
        else:
            the_phase = 'the_phase'
            pcs: List[syntax.PhaseComponent] = []
            for t in prog.transitions():
                pcs.append(
                    syntax.PhaseTransitionDecl(None, t.name, None, the_phase))
            for inv in prog.safeties():
                pcs.append(inv)

            automaton = AutomatonDecl(None, [
                syntax.InitPhaseDecl(None, the_phase),
                syntax.PhaseDecl(None, the_phase, pcs)
            ])

            automaton.resolve(prog.scope)

        self.automaton = PhaseAutomaton(automaton)
        self.fs: List[Frame] = []
        self.push_cache: List[Dict[Phase, Set[Expr]]] = []
        self.counter = 0
        self.predicates: List[Expr] = []
        self.state_count = 0
Beispiel #2
0
def check_automaton_init(s: Solver, a: AutomatonDecl) -> None:
    utils.logger.always_print('checking automaton init:')

    prog = syntax.the_program

    t = s.get_translator(KEY_ONE)

    init_decl = a.the_init()
    assert init_decl is not None  # checked by resolver
    init_phase = prog.scope.get_phase(init_decl.phase)
    assert init_phase is not None  # checked by resolver

    with s:
        for init in prog.inits():
            s.add(t.translate_expr(init.expr))

        for inv in init_phase.invs():
            with s:
                s.add(z3.Not(t.translate_expr(inv.expr)))

                if inv.tok is not None:
                    msg = ' on line %d' % inv.tok.lineno
                else:
                    msg = ''
                utils.logger.always_print('  implies phase invariant%s... ' %
                                          msg,
                                          end='')
                sys.stdout.flush()

                logic.check_unsat([
                    (inv.tok,
                     'phase invariant%s may not hold in initial state' % msg)
                ], s, [KEY_ONE])
Beispiel #3
0
def check_automaton_edge_covering(s: Solver, a: AutomatonDecl) -> None:
    utils.logger.always_print('checking automaton edge covering:')

    prog = syntax.the_program

    t = s.get_translator(KEY_NEW, KEY_OLD)

    for phase in a.phases():
        utils.logger.always_print('  checking phase %s:' % phase.name)
        with s:
            for inv in phase.invs():
                s.add(t.translate_expr(inv.expr, old=True))

            for trans in prog.transitions():
                if any(delta.transition == trans.name and delta.precond is None for delta in phase.transitions()):
                    utils.logger.always_print('    transition %s is covered trivially.' % trans.name)
                    continue

                utils.logger.always_print('    checking transition %s is covered... ' % trans.name, end='')

                with s:
                    s.add(t.translate_transition(trans))
                    s.add(z3.And(*(z3.Not(t.translate_precond_of_transition(delta.precond, trans))
                                   for delta in phase.transitions() if trans.name == delta.transition)))

                    logic.check_unsat([(phase.tok, 'transition %s is not covered by this phase' %
                                        (trans.name, )),
                                       (trans.tok, 'this transition misses transitions from phase %s' % (phase.name,))],
                                      s, [KEY_OLD, KEY_NEW])
Beispiel #4
0
    def __init__(self, solver: Solver) -> None:
        self.solver = solver
        prog = syntax.the_program

        if utils.args.automaton:
            automaton = prog.the_automaton()
            if automaton is None:
                utils.print_error_and_exit(
                    None, 'updr --automaton requires the file to '
                    'declare an automaton')
        else:
            the_phase = 'the_phase'
            pcs: List[syntax.PhaseComponent] = []
            for t in prog.transitions():
                pcs.append(
                    syntax.PhaseTransitionDecl(None, t.name, None, the_phase))
            for inv in prog.safeties():
                pcs.append(inv)

            automaton = AutomatonDecl(None, [
                syntax.InitPhaseDecl(None, the_phase),
                syntax.PhaseDecl(None, the_phase, pcs)
            ])

            automaton.resolve(prog.scope)

        self.automaton = PhaseAutomaton(automaton)
        self.fs: List[Frame] = []
        self.push_cache: List[Dict[Phase, Set[Expr]]] = []
        self.counter = 0
        self.predicates: List[Expr] = []
        self.state_count = 0

        self.inductive_invariant: Set[int] = set(
        )  # indices into predicates of currently inductive predicates
        self.human_invariant = tuple(
            itertools.chain(*(syntax.as_clauses(inv.expr)
                              for inv in prog.invs()
                              if not inv.is_safety)))  # convert to CNF
        self.human_invariant_to_predicate: Dict[int, int] = dict(
        )  # dict mapping index of human_invariant to index of predicates
        self.human_invariant_proved: Set[int] = set(
        )  # indices into human_invariant that are implied by the current inductive_invariant
        self.human_invariant_implies: Set[int] = set(
        )  # indices into predicates of predicates that are implied by the human invariant

        self._first_frame()
Beispiel #5
0
def check_automaton_inductiveness(s: Solver, a: AutomatonDecl) -> None:
    utils.logger.always_print('checking automaton inductiveness:')

    prog = syntax.the_program
    t = s.get_translator(KEY_NEW, KEY_OLD)

    for phase in a.phases():
        utils.logger.always_print('  checking phase %s:' % phase.name)

        with s:
            for inv in phase.invs():
                s.add(t.translate_expr(inv.expr, old=True))

            for delta in phase.transitions():
                trans = prog.scope.get_definition(delta.transition)
                assert trans is not None
                precond = delta.precond
                target = prog.scope.get_phase(
                    delta.target) if delta.target is not None else phase
                assert target is not None

                trans_pretty = '(%s, %s)' % (trans.name, str(precond) if
                                             (precond is not None) else 'true')
                utils.logger.always_print('    checking transition: %s' %
                                          trans_pretty)

                with s:
                    s.add(t.translate_transition(trans, precond=precond))
                    for inv in target.invs():
                        with s:
                            s.add(z3.Not(t.translate_expr(inv.expr)))

                            if inv.tok is not None:
                                msg = ' on line %d' % inv.tok.lineno
                            else:
                                msg = ''
                            utils.logger.always_print(
                                '      preserves invariant%s... ' % msg,
                                end='')
                            sys.stdout.flush()

                            logic.check_unsat([
                                (inv.tok,
                                 'invariant%s may not be preserved by transition %s in phase %s'
                                 % (msg, trans_pretty, phase.name)),
                                (delta.tok,
                                 'this transition may not preserve invariant%s'
                                 % (msg, ))
                            ], s, [KEY_OLD, KEY_NEW])
Beispiel #6
0
    def __init__(self, automaton_decl: AutomatonDecl) -> None:
        self.automaton_decl = automaton_decl

        self._phases: Dict[str, Phase] = OrderedDict()
        for p in self.automaton_decl.phases():
            self._phases[p.name] = Phase(p)

        self._transitions = [
            PhaseTransition(
                self._phases[p.name],
                self._phases[(delta.target
                              if delta.target is not None else p.name)], delta)
            for p in self.automaton_decl.phases() for delta in p.transitions()
        ]

        init_decl = automaton_decl.the_init()
        assert init_decl is not None
        self._init_phase = self._phases[init_decl.phase]

        self.nontrivial = len(self._phases) > 1