示例#1
0
文件: logic.py 项目: lkuper/mypyvy
def check_bmc(s: Solver, safety: Expr, depth: int, preconds: Optional[Iterable[Expr]] = None,
              minimize: Optional[bool] = None) -> Optional[Trace]:
    prog = syntax.the_program

    if preconds is None:
        preconds = (init.expr for init in prog.inits())

    t = s.get_translator(depth + 1)

    with s.new_frame():
        for precond in preconds:
            s.add(t.translate_expr(precond))

        s.add(t.translate_expr(syntax.New(syntax.Not(safety), depth)))

        for i in range(depth):
            s.add(t.translate_expr(New(safety, i)))
            assert_any_transition(s, t, i, allow_stutter=False)

        res = s.check()
        if res == solver.sat:
            z3m = s.model(minimize=minimize)
            m = Z3Translator.model_to_trace(z3m, depth + 1)
            return m
        elif res == solver.unknown:
            print('unknown!')
        return None
 def translate_transition(self,
                          t: syntax.DefinitionDecl,
                          index: int = 0) -> z3.ExprRef:
     new_decl = relativize_decl(t,
                                self._active_rels_mapping,
                                self._active_scope,
                                inline_relax_actives=True)
     # TODO: hack! relativize_decl doesn't do this, so the expression can be non-closed.
     # TODO: Should it generate & use an extended scope?
     typechecker.typecheck_declcontainingexpr(self._active_scope, new_decl)
     res = self._t.translate_expr(
         syntax.New(new_decl.as_twostate_formula(self._active_scope),
                    index))
     return res
def relax_actives_action_chunk(scope: syntax.Scope, actives: Dict[syntax.SortDecl, syntax.RelationDecl]) \
        -> Tuple[Tuple[syntax.ModifiesClause, ...], List[Expr]]:
    new_mods = []
    new_conjs = []

    for sort, active_rel in actives.items():
        name = scope.fresh(sort.name[0].upper())
        ap = syntax.Apply(active_rel.name, (syntax.Id(name), ))
        expr = syntax.Forall((syntax.SortedVar(name, None), ),
                             syntax.Implies(syntax.New(ap), ap))
        new_conjs.append(expr)
        new_mods.append(syntax.ModifiesClause(actives[sort].name))

    return tuple(new_mods), new_conjs
示例#4
0
def is_rel_blocking_relax_step(
        trns: Trace, idx: int,
        derived_rel: Tuple[List[Tuple[syntax.SortedVar, str]], Expr]
) -> bool:
    # TODO: probably can obtain the sort from the sortedvar when not using pickle
    free_vars, derived_relation_formula = derived_rel
    free_vars_active_clause = syntax.And(*(active_var(v.name, sort_name) for (v, sort_name) in free_vars))

    diffing_formula = syntax.Exists([v for (v, _) in free_vars],
                                    syntax.And(syntax.And(free_vars_active_clause,
                                                          derived_relation_formula),
                                               syntax.New(syntax.And(free_vars_active_clause,
                                                                     syntax.Not(derived_relation_formula)))))

    with syntax.the_program.scope.fresh_stack():
        with syntax.the_program.scope.n_states(2):
            diffing_formula.resolve(syntax.the_program.scope, syntax.BoolSort)

    res = trns.eval(diffing_formula, idx)
    assert isinstance(res, bool)
    return cast(bool, res)
def relaxation_action_def(prog: syntax.Program,
                          actives: Optional[Dict[syntax.SortDecl,
                                                 syntax.RelationDecl]] = None,
                          fresh: bool = True) -> syntax.DefinitionDecl:
    decrease_name = (prog.scope.fresh('decrease_domain')
                     if fresh else 'decrease_domain')
    mods: Tuple[syntax.ModifiesClause, ...] = ()
    conjs: List[Expr] = []
    if actives is None:
        actives = active_rel_by_sort(prog)

    # a conjunct allowing each domain to decrease
    new_mods, new_conjs = relax_actives_action_chunk(prog.scope, actives)
    mods += new_mods
    conjs += new_conjs

    # constants are active
    for const in prog.constants():
        conjs.append(
            syntax.New(
                syntax.Apply(
                    actives[syntax.get_decl_from_sort(const.sort)].name,
                    (syntax.Id(const.name), ))))

    # functions map active to active
    for func in prog.functions():
        names: List[str] = []
        func_conjs = []
        for arg_sort in func.arity:
            arg_sort_decl = syntax.get_decl_from_sort(arg_sort)
            name = prog.scope.fresh(arg_sort_decl.name[0].upper(),
                                    also_avoid=names)
            names.append(name)
            func_conjs.append(
                syntax.New(
                    syntax.Apply(actives[arg_sort_decl].name,
                                 (syntax.Id(name), ))))
        ap_func = syntax.Apply(func.name,
                               tuple(syntax.Id(name) for name in names))
        name = prog.scope.fresh('y', also_avoid=names)
        active_func = syntax.Let(
            syntax.SortedVar(name, func.sort), ap_func,
            syntax.New(
                syntax.Apply(
                    actives[syntax.get_decl_from_sort(func.sort)].name,
                    (syntax.Id(name), ))))
        conjs.append(
            syntax.Forall(
                tuple(syntax.SortedVar(name, None) for name in names),
                syntax.Implies(syntax.And(*func_conjs), active_func)))

    # (relativized) axioms hold after relaxation
    for axiom in prog.axioms():
        if not syntax.is_universal(axiom.expr):
            conjs.append(syntax.relativize_quantifiers(actives, axiom.expr))

    # derived relations have the same interpretation on the active domain
    for rel in prog.derived_relations():
        names = []
        rel_conjs = []
        for arg_sort in rel.arity:
            arg_sort_decl = syntax.get_decl_from_sort(arg_sort)
            name = prog.scope.fresh(arg_sort_decl.name[0].upper(),
                                    also_avoid=names)
            names.append(name)
            rel_conjs.append(
                syntax.Apply(actives[arg_sort_decl].name, (syntax.Id(name), )))
        ap_rel = syntax.Apply(rel.name,
                              tuple(syntax.Id(name) for name in names))
        conjs.append(
            syntax.Forall(
                tuple(syntax.SortedVar(name, None) for name in names),
                syntax.Implies(syntax.And(*rel_conjs),
                               syntax.Iff(syntax.New(ap_rel), ap_rel))))

    return syntax.DefinitionDecl(is_public_transition=True,
                                 num_states=2,
                                 name=decrease_name,
                                 params=(),
                                 mods=mods,
                                 expr=syntax.And(*conjs))