Пример #1
0
def sandbox(s: Solver) -> None:
    ####################################################################################
    # SANDBOX for playing with relaxed traces

    import pickle
    trns: logic.Trace = pickle.load(open("paxos_trace.p", "rb"))

    diff_conjunctions = relaxed_traces.derived_rels_candidates_from_trace(
        trns, [], 1, 3)

    print("num candidate relations:", len(diff_conjunctions))
    for diffing_conjunction in diff_conjunctions:
        # print("relation:")
        # for conj in diffing_conjunction:
        #     print("\t %s" % str(conj))
        print(diffing_conjunction[1])

    derrel_name = syntax.the_program.scope.fresh("nder")
    (free_vars, def_expr) = diff_conjunctions[0]
    def_axiom = syntax.Forall(
        free_vars,
        syntax.Iff(
            syntax.Apply(derrel_name,
                         [syntax.Id(None, v.name) for v in free_vars]),
            # TODO: extract pattern
            def_expr))

    derrel = syntax.RelationDecl(
        tok=None,
        name=derrel_name,
        arity=[syntax.safe_cast_sort(var.sort) for var in free_vars],
        mutable=True,
        derived=def_axiom,
        annotations=[])

    # TODO: this irreversibly adds the relation to the context, wrap
    derrel.resolve(syntax.the_program.scope)
    syntax.the_program.decls.append(
        derrel
    )  # TODO: hack! because RelationDecl.resolve only adds to prog.scope
    s.mutable_axioms.extend([
        def_axiom
    ])  # TODO: hack! currently we register these axioms only on solver init

    print("Trying derived relation:", derrel)

    # the new decrease_domain action incorporates restrictions that derived relations remain the same on active tuples
    new_decrease_domain = relaxed_traces.relaxation_action_def(
        syntax.the_program, fresh=False)
    new_prog = relaxed_traces.replace_relaxation_action(
        syntax.the_program, new_decrease_domain)
    new_prog.resolve()
    print(new_prog)

    syntax.the_program = new_prog

    trace_decl = next(syntax.the_program.traces())
    trns2_o = bmc_trace(new_prog, trace_decl, s,
                        lambda s, ks: logic.check_solver(s, ks, minimize=True))
    assert trns2_o is not None
    trns2 = cast(logic.Trace, trns2_o)
    print(trns2)
    print()
    print(
        trns2.as_state(relaxed_traces.first_relax_step_idx(trns2) +
                       1).rel_interp[derrel])
    assert not relaxed_traces.is_rel_blocking_relax(
        trns2, relaxed_traces.first_relax_step_idx(trns2),
        ([(v, str(syntax.safe_cast_sort(v.sort)))
          for v in free_vars], def_expr))

    diff_conjunctions = list(
        filter(
            lambda candidate: relaxed_traces.is_rel_blocking_relax(
                trns2, relaxed_traces.first_relax_step_idx(trns2),
                ([(v, str(syntax.safe_cast_sort(v.sort)))
                  for v in free_vars], def_expr)), diff_conjunctions))
    print("num candidate relations:", len(diff_conjunctions))
    for diffing_conjunction in diff_conjunctions:
        # print("relation:")
        # for conj in diffing_conjunction:
        #     print("\t %s" % str(conj))
        print(diffing_conjunction)

    print()

    assert False
Пример #2
0
def relax(s: Solver) -> None:
    prog = syntax.the_program

    new_decls: List[syntax.Decl] = [d for d in prog.sorts()]

    actives: Dict[syntax.SortDecl, syntax.RelationDecl] = {}
    for sort in prog.sorts():
        name = prog.scope.fresh('active_' + sort.name)
        r = syntax.RelationDecl(
            None,
            name,
            arity=[syntax.UninterpretedSort(None, sort.name)],
            mutable=True,
            derived=None,
            annotations=[])
        actives[sort] = r
        new_decls.append(r)

    # active relations initial conditions: always true
    for sort in prog.sorts():
        name = prog.scope.fresh(sort.name[0].upper())
        expr = syntax.Forall([syntax.SortedVar(None, name, None)],
                             syntax.Apply(actives[sort].name,
                                          [syntax.Id(None, name)]))
        new_decls.append(syntax.InitDecl(None, name=None, expr=expr))

    for d in prog.decls:
        if isinstance(d, syntax.SortDecl):
            pass  # already included above
        elif isinstance(d, syntax.RelationDecl):
            if d.derived_axiom is not None:
                expr = syntax.relativize_quantifiers(actives, d.derived_axiom)
                new_decls.append(
                    syntax.RelationDecl(None, d.name, d.arity, d.mutable, expr,
                                        d.annotations))
            else:
                new_decls.append(d)
        elif isinstance(d, syntax.ConstantDecl):
            new_decls.append(d)
        elif isinstance(d, syntax.FunctionDecl):
            new_decls.append(d)
        elif isinstance(d, syntax.AxiomDecl):
            new_decls.append(d)
        elif isinstance(d, syntax.InitDecl):
            new_decls.append(d)
        elif isinstance(d, syntax.DefinitionDecl):
            assert not isinstance(d.body, syntax.BlockStatement), \
                "relax does not support transitions written in imperative syntax"
            mods, expr = d.body
            expr = syntax.relativize_quantifiers(actives, expr, old=d.twostate)
            if d.public:
                guard = syntax.relativization_guard_for_binder(actives,
                                                               d.binder,
                                                               old=True)
                expr = syntax.And(guard, expr)
            new_decls.append(
                syntax.DefinitionDecl(None,
                                      d.public,
                                      d.twostate,
                                      d.name,
                                      params=d.binder.vs,
                                      body=(mods, expr)))
        elif isinstance(d, syntax.InvariantDecl):
            expr = syntax.relativize_quantifiers(actives, d.expr)
            new_decls.append(
                syntax.InvariantDecl(None,
                                     d.name,
                                     expr=expr,
                                     is_safety=d.is_safety,
                                     is_sketch=d.is_sketch))
        else:
            assert False, d

    new_decls.append(
        relaxed_traces.relaxation_action_def(prog, actives=actives,
                                             fresh=True))
    print(Program(new_decls))
Пример #3
0
def sandbox(s: Solver) -> None:
    ####################################################################################
    # SANDBOX for playing with relaxed traces
    import pickle
    trns: logic.Trace = pickle.load(open("paxos_trace.p", "rb"))

    diff_conjunctions = relaxed_traces.derived_rels_candidates_from_trace(
        trns, [], 2, 3)

    print("num candidate relations:", len(diff_conjunctions))
    for diffing_conjunction in diff_conjunctions:
        # print("relation:")
        # for conj in diffing_conjunction:
        #     print("\t %s" % str(conj))
        print(diffing_conjunction[1])

    derrel_name = syntax.the_program.scope.fresh("nder")
    (free_vars, def_expr) = diff_conjunctions[0]
    def_axiom = syntax.Forall(
        tuple(free_vars),
        syntax.Iff(
            syntax.Apply(derrel_name,
                         tuple(syntax.Id(v.name) for v in free_vars)),
            # TODO: extract pattern
            def_expr))

    derrel = syntax.RelationDecl(
        name=derrel_name,
        arity=tuple(syntax.safe_cast_sort(var.sort) for var in free_vars),
        mutable=True,
        derived=def_axiom)

    # TODO: this irreversibly adds the relation to the context, wrap
    typechecker.typecheck_statedecl(syntax.the_program.scope, derrel)
    syntax.the_program.decls.append(
        derrel
    )  # TODO: hack! because typecheck_statedecl only adds to prog.scope
    s.mutable_axioms.extend([
        def_axiom
    ])  # TODO: hack! currently we register these axioms only on solver init

    print("Trying derived relation:", derrel)

    # the new decrease_domain action incorporates restrictions that derived relations remain the same on active tuples
    new_decrease_domain = relaxed_traces.relaxation_action_def(
        syntax.the_program, fresh=False)
    new_prog = relaxed_traces.replace_relaxation_action(
        syntax.the_program, new_decrease_domain)
    typechecker.typecheck_program(new_prog)
    print(new_prog)

    syntax.the_program = new_prog

    # TODO: recover this, making sure the candidate blocks the trace
    # trace_decl = next(syntax.the_program.traces())
    # trns2_o = bmc_trace(new_prog, trace_decl, s, lambda s, ks: logic.check_solver(s, ks, minimize=True))
    # assert trns2_o is None

    # migrated_trace = load_relaxed_trace_from_updr_cex(syntax.the_program, s)
    import pickle
    trns2_o = pickle.load(open("migrated_trace.p", "rb"))

    trns2 = cast(logic.Trace, trns2_o)
    print(trns2)
    print()
    assert not relaxed_traces.is_rel_blocking_relax(
        trns2, ([(v, str(syntax.safe_cast_sort(v.sort)))
                 for v in free_vars], def_expr))

    # for candidate in diff_conjunctions:
    #     print("start checking")
    #     print()
    #     if str(candidate[1]) == ('exists v0:node. member(v0, v1) & left_round(v0, v2) '
    #                              '& !vote(v0, v2, v3) & active_node(v0)'):
    #         print(candidate)
    #         assert False
    #         resush = relaxed_traces.is_rel_blocking_relax_step(
    #             trns2, 11,
    #             ([(v, str(syntax.safe_cast_sort(v.sort))) for v in candidate[0]],
    #              candidate[1]))
    #         # res2 = trns2.as_state(0).eval(syntax.And(*[i.expr for i in syntax.the_program.inits()]))
    #
    #         # resush = trns2.as_state(7).eval(syntax.And(*[i.expr for i in syntax.the_program.inits()]))
    #         print(resush)
    #         assert False
    # assert False

    diff_conjunctions = list(
        filter(
            lambda candidate: relaxed_traces.is_rel_blocking_relax(
                trns2, ([(v, str(syntax.safe_cast_sort(v.sort)))
                         for v in candidate[0]], candidate[1])),
            diff_conjunctions))
    print("num candidate relations:", len(diff_conjunctions))
    for diffing_conjunction in diff_conjunctions:
        # print("relation:")
        # for conj in diffing_conjunction:
        #     print("\t %s" % str(conj))
        print(diffing_conjunction[1])

    print()

    assert False