Exemple #1
0
def diagram_trace_to_explicitly_relaxed_trace(trace: RelaxedTrace, safety: Sequence[syntax.InvariantDecl]) -> None:
    relaxed_prog = relaxed_program(syntax.the_program)

    with syntax.prog_context(relaxed_prog):
        s = Solver()

        end_expr = syntax.Not(syntax.And(*(invd.expr for invd in safety)))
        with syntax.the_program.scope.n_states(1):
            end_expr.resolve(syntax.the_program.scope, syntax.BoolSort)
        trace_decl = diagram_trace_to_explicitly_relaxed_trace_decl(trace, end_expr)
        with syntax.the_program.scope.n_states(1):
            trace_decl.resolve(syntax.the_program.scope)

        print(trace_decl)

        res = bmc_trace(relaxed_prog, trace_decl, s, lambda slvr, ks: logic.check_solver(slvr, ks, minimize=True))
        print(res)
        assert False
Exemple #2
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
def load_relaxed_trace_from_updr_cex(prog: Program, s: Solver) -> logic.Trace:
    import xml.dom.minidom  # type: ignore
    collection = xml.dom.minidom.parse(
        "paxos_derived_trace.xml").documentElement

    components: List[syntax.TraceComponent] = []

    xml_decls = reversed(collection.childNodes)
    seen_first = False

    for elm in xml_decls:
        if isinstance(elm, xml.dom.minidom.Text):  # type: ignore
            continue
        if elm.tagName == 'state':
            diagram = parser.parse_expr(elm.childNodes[0].data)
            typechecker.typecheck_expr(prog.scope, diagram, syntax.BoolSort)
            assert isinstance(
                diagram, syntax.QuantifierExpr) and diagram.quant == 'EXISTS'
            active_clauses = [
                relaxed_traces.active_var(v.name, str(v.sort))
                for v in diagram.get_vs()
            ]

            if not seen_first:
                # restrict the domain to be subdomain of the diagram's existentials
                seen_first = True
                import itertools  # type: ignore
                for sort, vars in itertools.groupby(
                        diagram.get_vs(),
                        lambda v: v.sort):  # TODO; need to sort first
                    free_var = syntax.SortedVar(
                        syntax.the_program.scope.fresh("v_%s" % str(sort)),
                        None)

                    # TODO: diagram simplification omits them from the exists somewhere
                    consts = list(
                        filter(lambda c: c.sort == sort, prog.constants()))
                    els: Sequence[Union[syntax.SortedVar, syntax.ConstantDecl]]
                    els = list(vars)
                    els += consts
                    restrict_domain = syntax.Forall(
                        (free_var, ),
                        syntax.Or(*(syntax.Eq(syntax.Id(free_var.name),
                                              syntax.Id(v.name))
                                    for v in els)))
                    active_clauses += [restrict_domain]

            diagram_active = syntax.Exists(
                diagram.get_vs(), syntax.And(diagram.body, *active_clauses))
            typechecker.typecheck_expr(prog.scope, diagram_active,
                                       syntax.BoolSort)

            components.append(syntax.AssertDecl(expr=diagram_active))
        elif elm.tagName == 'action':
            action_name = elm.childNodes[0].data.split()[0]
            tcall = syntax.TransitionCalls(
                calls=[syntax.TransitionCall(target=action_name, args=None)])
            components.append(syntax.TraceTransitionDecl(transition=tcall))
        else:
            assert False, "unknown xml tagName"

    trace_decl = syntax.TraceDecl(components=components, sat=True)
    migrated_trace = bmc_trace(
        prog,
        trace_decl,
        s,
        lambda s, ks: logic.check_solver(s, ks, minimize=True),
        log=False)

    assert migrated_trace is not None
    import pickle
    pickle.dump(migrated_trace, open("migrated_trace.p", "wb"))
    return migrated_trace