def is_sufficient(self, button=None): """ Check if the active conjecture is sufficient to imply the current CTI conjecture at the next step TODO: this has a lot in common with check_inductiveness, should refactor common parts out """ import ivy_transrel import ivy_solver from proof import ProofGoal from ivy_logic_utils import Clauses, and_clauses, dual_clauses from random import randrange with self.ui_parent.run_context(): conj = self.get_selected_conjecture() target_conj = self.parent.current_conjecture ag = self.parent.new_ag() pre = State() pre.clauses = and_clauses(conj, *self.parent.conjectures) pre.clauses.annot = ia.EmptyAnnotation() action = ia.env_action(None) post = ag.execute(action, pre) post.clauses = ilu.true_clauses(annot=ia.EmptyAnnotation()) assert target_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 clauses = dual_clauses(target_conj, witness) clauses.annot = ia.EmptyAnnotation() res = ivy_trace.check_final_cond(ag, post, clauses, [], True) text = '(1) ' + str(conj.to_formula()) + '\n(2) ' + str( target_conj.to_formula()) if res is not None: self.ui_parent.text_dialog( '(1) does not imply (2) at the next time. View counterexample?', text, command_label='View', command=lambda: self.ui_parent.add(res)) return False else: self.ui_parent.text_dialog('(1) implies (2) at the next time:', text, on_cancel=None) return True
def is_inductive(self, button=None): """ Check if the active conjecture implies itself at the next step TODO: this has a lot in common with check_inductiveness and is_sufficient, should refactor common parts out """ import ivy_transrel import ivy_solver from proof import ProofGoal from ivy_logic_utils import Clauses, and_clauses, dual_clauses from random import randrange with self.ui_parent.run_context(): conj = self.get_selected_conjecture() target_conj = conj ag = self.parent.new_ag() pre = State() pre.clauses = and_clauses(conj, *self.parent.conjectures) action = im.module.actions['ext'] post = ag.execute(action, pre, None, 'ext') post.clauses = ilu.true_clauses() assert target_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 clauses = dual_clauses(target_conj, witness) res = ag.bmc(post, clauses) text = '(1) ' + str(conj.to_formula()) if res is not None: self.ui_parent.text_dialog( '(1) is not relatively inductive. View counterexample?', text, command_label='View', command=lambda: self.ui_parent.add(res)) return False else: self.ui_parent.text_dialog('(1) is relatively inductive:', text, on_cancel=None) return True
def is_sufficient(self, button=None): """ Check if the active conjecture is sufficient to imply the current CTI conjecture at the next step TODO: this has a lot in common with check_inductiveness, should refactor common parts out """ import ivy_transrel import ivy_solver from proof import ProofGoal from ivy_logic_utils import Clauses, and_clauses, dual_clauses from random import randrange with self.ui_parent.run_context(): conj = self.get_selected_conjecture() target_conj = self.parent.current_conjecture ag = self.parent.new_ag() pre = State() pre.clauses = and_clauses(conj, *self.parent.conjectures) action = im.module.actions['ext'] post = ag.execute(action, pre, None, 'ext') post.clauses = ilu.true_clauses() assert target_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 clauses = dual_clauses(target_conj, witness) res = ag.bmc(post, clauses) text = '(1) ' + str(conj.to_formula()) + '\n(2) ' + str(target_conj.to_formula()) if res is not None: self.ui_parent.text_dialog('(1) does not imply (2) at the next time. View counterexample?', text,command_label='View',command = lambda: self.ui_parent.add(res)) return False else: self.ui_parent.text_dialog('(1) implies (2) at the next time:',text,on_cancel=None) 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 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