def emit_action_gen(header, impl, name, action, classname): global indent_level caname = varname(name) upd = action.update(im.module, None) pre = tr.reverse_image(ilu.true_clauses(), ilu.true_clauses(), upd) pre_clauses = ilu.trim_clauses(pre) pre_clauses = ilu.and_clauses( pre_clauses, ilu.Clauses([df.to_constraint() for df in im.module.concepts])) pre = pre_clauses.to_formula() syms = [ x for x in ilu.used_symbols_ast(pre) if x.name not in il.sig.symbols ] header.append("class " + caname + "_gen : public gen {\n public:\n") for sym in syms: if not sym.name.startswith('__ts') and sym not in pre_clauses.defidx: declare_symbol(header, sym) header.append(" {}_gen();\n".format(caname)) impl.append(caname + "_gen::" + caname + "_gen(){\n") indent_level += 1 emit_sig(impl) for sym in syms: emit_decl(impl, sym) indent(impl) impl.append('add("(assert {})");\n'.format( slv.formula_to_z3(pre).sexpr().replace('\n', '\\\n'))) indent_level -= 1 impl.append("}\n") header.append(" bool generate(" + classname + "&);\n};\n") impl.append("bool " + caname + "_gen::generate(" + classname + "& obj) {\n push();\n") indent_level += 1 pre_used = ilu.used_symbols_ast(pre) for sym in all_state_symbols(): if sym in pre_used and sym not in pre_clauses.defidx: # skip symbols not used in constraint if slv.solver_name(sym) != None: # skip interpreted symbols global is_derived if sym not in is_derived: emit_set(impl, sym) for sym in syms: if not sym.name.startswith('__ts') and sym not in pre_clauses.defidx: emit_randomize(impl, sym) impl.append(""" bool res = solve(); if (res) { """) indent_level += 1 for sym in syms: if not sym.name.startswith('__ts') and sym not in pre_clauses.defidx: emit_eval(impl, sym) indent_level -= 2 impl.append(""" } pop(); obj.___ivy_gen = this; return res; } """)
def backward_image(post_fact, action): """ """ axioms = _ivy_interp.background_theory() return ivy_transrel.reverse_image( post_fact, axioms, action.update(_ivy_interp, None), )
def reverse(state,clauses=None): """ Reverse an update concretely (compute concrete pre). If unsat, throw UnsatCoreWithInterpolant. """ assert(state.pred != None and state.update != None) # can't reverse if no predecessor if clauses == None: clauses = state.clauses axioms = state.domain.background_theory(state.in_scope) return and_clauses(reverse_image(clauses,axioms,state.update), axioms)
def diagram(self): from ivy_solver import clauses_model_to_diagram, get_model_clauses from ivy_transrel import is_skolem, reverse_image if not self.have_cti: if self.check_inductiveness() or len(self.g.states) != 2: return conj = self.current_conjecture post = ilu.dual_clauses(conj) if conj != None else ilu.true_clauses() pre = self.g.states[0].clauses axioms = im.module.background_theory() rev = ilu.and_clauses( reverse_image(post, axioms, self.g.states[1].update), axioms) clauses = ilu.and_clauses(pre, rev) mod = get_model_clauses(clauses) assert mod != None diag = clauses_model_to_diagram(rev, is_skolem, model=mod) self.g.states[0].clauses = diag self.view_state(self.g.states[0], reset=True) self.show_used_relations(diag, both=True)
if x != '=' and x not in inflex)) if __name__ == "__main__": ag = ivy.ivy_init() state = ag.states[0] sig = ag.domain.sig ptc = lu.TseitinContext() actions = [ag.actions[lab] for lab in ag.actions if lab != "error"] # get error states by computing reverse image or error action err_act = ag.actions["error"].update(ag.domain, state.in_scope) axioms = state.domain.background_theory(state.in_scope) error = tr.reverse_image([], err_act) print "error = {}".format(error) # get actions as updates updates = [action.update(ag.domain, state.in_scope) for action in actions] # get all the flexible (updated) variables flex = set(sym for u in updates for sym in u[0]) print "flex = {}".format(flex) # inflex is all non-skolem symbols in signature that are not updated all_syms = sig.symbols inflex = set( sym for sym in all_syms if sym not in flex and not tr.is_new(sym) and not tr.is_skolem(sym)) print "inflex = {}".format(inflex)