def k_induction_attempt_inductive(): # Create an smt_switch.SmtSolver with Boolector as the backend # and no logging s = ss.create_btor_solver(False) s.set_opt('produce-models', 'true') s.set_opt('incremental', 'true') prop, fts = build_simple_alu_fts(s) # store sets of states in a dictionary for accessing below states = {str(sv): sv for sv in fts.statevars} # make the property inductive manually prop = pono.Property( s, s.make_term( And, s.make_term(Equal, states['cfg'], s.make_term(0, s.make_sort(BV, 1))), prop.prop)) print( '\n============== Running k-induction on inductively strengthened property ==============' ) print('INIT\n\t{}'.format(fts.init)) print('TRANS\n\t{}'.format(fts.trans)) print('PROP\n\t{}'.format(prop.prop)) # Create KInduction engine -- using same solver (in future can change the solver) kind = pono.KInduction(prop, fts, s) res = kind.check_until(20) print(res) assert res is True, "Expecting k-induction to prove the inductively strengthened property" print("KInduction returned true")
def test_history_modifier(create_solver): solver = create_solver(False) solver.set_opt("incremental", "true") solver.set_opt("produce-models", "true") bvsort8 = solver.make_sort(ss.sortkinds.BV, 8) ts = pono.FunctionalTransitionSystem(solver) counter = ts.make_statevar("counter", bvsort8) ts.constrain_init( ts.make_term(ss.primops.Equal, counter, ts.make_term(0, bvsort8))) ts.assign_next( counter, ts.make_term(ss.primops.BVAdd, counter, ts.make_term(1, bvsort8))) hm = pono.HistoryModifier(ts) counter_delay_2 = hm.get_hist(counter, 2) p = pono.Property( solver, ts.make_term(ss.primops.BVUlt, counter, ts.make_term(5, bvsort8))) bmc = pono.Bmc(p, ts, solver) res = bmc.check_until(10) assert not res, "should be false" witness = bmc.witness() checked_at_least_one = False for i, m in enumerate(witness): if i > 1: checked_at_least_one = True # checking semantics of history modifier delay assert witness[i][counter_delay_2] == witness[i - 2][counter] assert checked_at_least_one
def test_vcd_trace(create_solver): solver = create_solver(False) solver.set_opt("incremental", "true") solver.set_opt("produce-models", "true") bvsort8 = solver.make_sort(ss.sortkinds.BV, 8) ts = pono.FunctionalTransitionSystem(solver) x = ts.make_statevar('x', bvsort8) ts.constrain_init( solver.make_term(ss.primops.Equal, x, solver.make_term(0, x.get_sort()))) ts.assign_next( x, ts.make_term(ss.primops.BVAdd, x, solver.make_term(1, x.get_sort()))) prop_term = solver.make_term(ss.primops.BVUle, x, solver.make_term(9, x.get_sort())) prop = pono.Property(solver, prop_term) bmc = pono.Bmc(prop, ts, solver) res = bmc.check_until(10) assert res == False, "res should be false, not just unknown (i.e. None)" witness = bmc.witness() with tempfile.NamedTemporaryFile() as temp: assert os.stat(temp.name).st_size == 0, "Expect file to start empty" vcd_printer = pono.VCDWitnessPrinter(ts, witness) vcd_printer.dump_trace_to_file(temp.name) assert os.stat(temp.name).st_size, "Expect file to be non-empty"
def process_guarantees(self, solver, rts, at_end_state_flag, ports): for i, guarantee in enumerate(self.guarantees): prop = pono.Property( rts, solver.make_term( Implies, at_end_state_flag, guarantee.value(solver, ports) ) ) interp = pono.KInduction(prop, solver) assert interp.check_until(10), interp.witness()
def build_simple_alu_fts( s: ss.SmtSolver ) -> Tuple[pono.Property, pono.FunctionalTransitionSystem]: ''' Creates a simple alu transition system @param s - an SmtSolver from smt_switch @return a property ''' # Instantiate a functional transition system fts = pono.FunctionalTransitionSystem(s) # Create a bit-vector sorts bvsort1 = s.make_sort(BV, 1) bvsort8 = s.make_sort(BV, 8) # Create the states cfg = fts.make_statevar('cfg', bvsort1) spec_res = fts.make_statevar('spec_res', bvsort8) imp_res = fts.make_statevar('imp_res', bvsort8) # Create the inputs a = fts.make_inputvar('a', bvsort8) b = fts.make_inputvar('b', bvsort8) # Add logic for cfg ## Start at 0 fts.constrain_init(s.make_term(Equal, cfg, s.make_term(0, bvsort1))) ## Keeps the same value fts.assign_next(cfg, cfg) # Set logic for results ## they start equal fts.constrain_init(s.make_term(Equal, spec_res, imp_res)) ## spec_res is the sum: spec_res' = a + b fts.assign_next(spec_res, s.make_term(BVAdd, a, b)) ## depends on the configuration: imp_res' == (cfg == 0) ? a + b : a - b fts.assign_next( imp_res, s.make_term(Ite, s.make_term(Equal, cfg, s.make_term(0, bvsort1)), s.make_term(BVAdd, a, b), s.make_term(BVSub, a, b))) # Create a property: (spec_cnt == imp_cnt - 1) prop = pono.Property(s, s.make_term(Equal, spec_res, imp_res)) return prop, fts
def test_kind_inductive_prop(create_solver): s = create_solver(False) s.set_opt('produce-models', 'true') s.set_opt('incremental', 'true') prop = build_simple_alu_fts(s) states = {str(sv): sv for sv in prop.transition_system.statevars} prop = c.Property( prop.transition_system, s.make_term( And, s.make_term(Equal, states['cfg'], s.make_term(0, s.make_sort(BV, 1))), prop.prop)) kind = c.KInduction(prop, s) res = kind.check_until(10) assert res is True, "KInduction should be able to solve this manually strengthened property"