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
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