def check_final_cond(ag, post, final_cond, rels_to_min=[], shrink=False, handler_class=None): history = ag.get_history(post) axioms = im.module.background_theory() clauses = history.post clauses = lut.and_clauses(clauses, axioms) model = slv.get_small_model(clauses, lg.uninterpreted_sorts(), rels_to_min, final_cond=final_cond, shrink=shrink) if model is not None: failed = ([final_cond] if not isinstance(final_cond, list) else [c.cond() for c in ffcs if c.failed]) mclauses = lut.and_clauses(*([clauses] + failed)) vocab = lut.used_symbols_clauses(mclauses) handler = (handler_class(mclauses, model, vocab) if handler_class is not None else Trace(mclauses, model, vocab)) assert all(x is not None for x in history.actions) # work around a bug in ivy_interp actions = [ im.module.actions[a] if isinstance(a, str) else a for a in history.actions ] action = act.Sequence(*actions) act.match_annotation(action, clauses.annot, handler) handler.end() return handler return None
def satisfy(self, axioms, _get_model_clauses=None): """ Produce a state sequence if the symbolic history contains one. Returns the sort universes and a sequence of states, or None if the history is vacuous. """ if _get_model_clauses is None: _get_model_clauses = lambda cls: get_small_model( cls, ivy_logic.sig.sorts.values(), []) # A model of the post-state embeds a valuation for each time # in the history. post = and_clauses(self.post, axioms) # print "post: {}".format(post) print "bounded check {" model = _get_model_clauses(post) print "} bounded check" if model == None: # print "core = {}".format(unsat_core(post,true_clauses())) return None # we reconstruct the sub-model for each state composing the # recorded renamings in reverse order. Here "renaming" maps # symbols representing a past time onto current time skolems renaming, states, maps = {}, [], reversed(self.maps) while True: # ignore all symbols except those representing the given past time img = set(renaming[s] for s in renaming if not s.is_skolem()) ignore = lambda s: self.ignore(s, img, renaming) # get the sub-mode for the given past time as a formula clauses = clauses_model_to_clauses(post, ignore=ignore, model=model, numerals=True) # map this formula into the past using inverse map clauses = rename_clauses(clauses, inverse_map(renaming)) # remove tautology equalities, TODO: not sure if this is correct here clauses = Clauses( [f for f in clauses.fmlas if not is_tautology_equality(f)], clauses.defs) states.append(clauses) try: # update the inverse map by composing it with inverse # of the next renaming (in reverse order) renaming = compose_maps(next(maps), renaming) except StopIteration: break return model.universes(numerals=True), [ pure_state(clauses) for clauses in reversed(states) ]
def satisfy(self, axioms, _get_model_clauses=None): """ Produce a state sequence if the symbolic history contains one. Returns the sort universes and a sequence of states, or None if the history is vacuous. """ if _get_model_clauses is None: _get_model_clauses = lambda cls: get_small_model(cls,ivy_logic.sig.sorts.values(),[]) # A model of the post-state embeds a valuation for each time # in the history. post = and_clauses(self.post,axioms) print "post: {}".format(post) print "bounded check {" model = _get_model_clauses(post) print "} bounded check" if model == None: # print "core = {}".format(unsat_core(post,true_clauses())) return None # we reconstruct the sub-model for each state composing the # recorded renamings in reverse order. Here "renaming" maps # symbols representing a past time onto current time skolems renaming,states,maps = {},[],reversed(self.maps) while True: # ignore all symbols except those representing the given past time img = set(renaming[s] for s in renaming if not s.is_skolem()) ignore = lambda s: self.ignore(s,img,renaming) # get the sub-mode for the given past time as a formula clauses = clauses_model_to_clauses(post,ignore = ignore, model = model, numerals = True) # map this formula into the past using inverse map clauses = rename_clauses(clauses,inverse_map(renaming)) # remove tautology equalities, TODO: not sure if this is correct here clauses = Clauses( [f for f in clauses.fmlas if not is_tautology_equality(f)], clauses.defs ) states.append(clauses) try: # update the inverse map by composing it with inverse # of the next renaming (in reverse order) renaming = compose_maps(next(maps),renaming) except StopIteration: break return model.universes(numerals=True), [pure_state(clauses) for clauses in reversed(states)]
def check_vc(clauses, action, final_cond=None, rels_to_min=[], shrink=False, handler_class=None): model = slv.get_small_model(clauses, lg.uninterpreted_sorts(), rels_to_min, final_cond=final_cond, shrink=shrink) if model is not None: failed = ([] if final_cond is None else [final_cond] if not isinstance(final_cond, list) else [c.cond() for c in ffcs if c.failed]) mclauses = lut.and_clauses(*([clauses] + failed)) vocab = lut.used_symbols_clauses(mclauses) handler = (handler_class(mclauses, model, vocab) if handler_class is not None else Trace(mclauses, model, vocab)) act.match_annotation(action, clauses.annot, handler) handler.end() return handler return None
def small_model_clauses(cls, final_cond=None, shrink=True): # Don't try to shrink the integers! return get_small_model(cls, ivy_logic.uninterpreted_sorts(), [], final_cond=final_cond, shrink=shrink)
def check_inductiveness(self, button=None): import ivy_transrel from ivy_solver import get_small_model from proof import ProofGoal from ivy_logic_utils import Clauses, and_clauses, dual_clauses from random import randrange with self.ui_parent.run_context(): ag = self.new_ag() pre = State() pre.clauses = and_clauses(*self.conjectures) action = im.module.actions['ext'] with EvalContext(check=False): # don't check safety post = ag.execute(action, pre, None, 'ext') post.clauses = ilu.true_clauses() to_test = list(self.conjectures) + [None] # None = check safety while len(to_test) > 0: # choose randomly, so the user can get another result by # clicking again conj = to_test.pop(randrange(len(to_test))) assert conj == None or conj.is_universal_first_order() used_names = frozenset(x.name for x in il.sig.symbols.values()) def witness(v): c = lg.Const('@' + v.name, v.sort) assert c.name not in used_names return c # TODO: this is still a bit hacky, and without nice error reporting if self.relations_to_minimize.value == 'relations to minimize': self.relations_to_minimize.value = ' '.join(sorted( k for k, v in il.sig.symbols.iteritems() if (type(v.sort) is lg.FunctionSort and v.sort.range == lg.Boolean and v.name not in self.transitive_relations and '.' not in v.name ) )) if conj == None: # check safety clauses = ilu.true_clauses() rels_to_min = [il.sig.symbols[x] for x in self.relations_to_minimize.value.split()] else: clauses = dual_clauses(conj, witness) history = ag.get_history(post) rels_to_min = [ # TODO: this is still a bit hacky, and without nice error reporting history.maps[0].get(relation, relation) for x in self.relations_to_minimize.value.split() for relation in [il.sig.symbols[x]] ], _get_model_clauses = lambda clauses, final_cond=False: get_small_model( clauses, sorted(il.sig.sorts.values()), rels_to_min, final_cond = final_cond ) if conj == None: print "check safety" res = ag.check_bounded_safety(post, _get_model_clauses) else: res = ag.bmc(post, clauses, None, None, _get_model_clauses) if res is not None: self.current_conjecture = conj assert len(res.states) == 2 # self.set_states(res.states[0], res.states[1]) # self.cti = self.ui_parent.add(res) self.g = res self.rebuild() self.view_state(self.g.states[0], reset=True) self.show_used_relations(clauses) #self.post_graph.selected = self.get_relevant_elements(self.post_state[2], clauses) if conj == None: self.ui_parent.ok_dialog('An assertion failed. A failing state is displayed. You can decompose\nthe failing action observe the failing execution. ') else: self.ui_parent.text_dialog('The following conjecture is not relatively inductive:', str(conj.to_formula()),on_cancel=None) self.have_cti = True return False # self.set_states(False, False) self.ui_parent.text_dialog('Inductive invariant found:', '\n'.join(str(conj) for conj in self.conjectures)) self.have_cti = False return True
def check_inductiveness(self, button=None): import ivy_transrel from ivy_solver import get_small_model from proof import ProofGoal from ivy_logic_utils import Clauses, and_clauses, dual_clauses from random import randrange with self.ui_parent.run_context(): ag = self.new_ag() pre = State() pre.clauses = and_clauses(*self.conjectures) action = im.module.actions['ext'] with EvalContext(check=False): # don't check safety post = ag.execute(action, pre, None, 'ext') post.clauses = ilu.true_clauses() to_test = list(self.conjectures) + [None] # None = check safety while len(to_test) > 0: # choose randomly, so the user can get another result by # clicking again conj = to_test.pop(randrange(len(to_test))) assert conj == None or conj.is_universal_first_order() used_names = frozenset(x.name for x in il.sig.symbols.values()) def witness(v): c = lg.Const('@' + v.name, v.sort) assert c.name not in used_names return c # TODO: this is still a bit hacky, and without nice error reporting if self.relations_to_minimize.value == 'relations to minimize': self.relations_to_minimize.value = ' '.join( sorted(k for k, v in il.sig.symbols.iteritems() if ( type(v.sort) is lg.FunctionSort and v.sort.range == lg.Boolean and v.name not in self.transitive_relations and '.' not in v.name))) if conj == None: # check safety clauses = ilu.true_clauses() rels_to_min = [ il.sig.symbols[x] for x in self.relations_to_minimize.value.split() ] else: clauses = dual_clauses(conj, witness) history = ag.get_history(post) rels_to_min = [ # TODO: this is still a bit hacky, and without nice error reporting history.maps[0].get(relation, relation) for x in self.relations_to_minimize.value.split() for relation in [il.sig.symbols[x]] ], _get_model_clauses = lambda clauses, final_cond=False: get_small_model( clauses, sorted(il.sig.sorts.values()), rels_to_min, final_cond=final_cond) if conj == None: print "check safety" res = ag.check_bounded_safety(post, _get_model_clauses) else: res = ag.bmc(post, clauses, None, None, _get_model_clauses) if res is not None: self.current_conjecture = conj assert len(res.states) == 2 # self.set_states(res.states[0], res.states[1]) # self.cti = self.ui_parent.add(res) self.g = res self.rebuild() self.view_state(self.g.states[0], reset=True) self.show_used_relations(clauses) #self.post_graph.selected = self.get_relevant_elements(self.post_state[2], clauses) if conj == None: self.ui_parent.ok_dialog( 'An assertion failed. A failing state is displayed. You can decompose\nthe failing action observe the failing execution. ' ) else: self.ui_parent.text_dialog( 'The following conjecture is not relatively inductive:', str(conj.to_formula()), on_cancel=None) self.have_cti = True return False # self.set_states(False, False) self.ui_parent.text_dialog( 'Inductive invariant found:', '\n'.join(str(conj) for conj in self.conjectures)) self.have_cti = False return True
def small_model_clauses(cls,final_cond=None): # Don't try to shrink the integers! return get_small_model(cls,ivy_logic.uninterpreted_sorts(),[],final_cond=final_cond)
def small_model_clauses(cls): return get_small_model(cls,ivy_logic.sig.sorts.values(),[])
def small_model_clauses(cls): return get_small_model(cls, ivy_logic.sig.sorts.values(), [])