def theorem(s: Solver) -> None: utils.logger.always_print('checking theorems:') prog = syntax.the_program for th in prog.theorems(): if th.num_states == 2: num_states = 2 elif th.num_states == 1: num_states = 1 else: num_states = 0 t = s.get_translator(num_states) if th.name is not None: msg = ' ' + th.name elif th.span is not None: msg = ' on line %d' % th.span[0].lineno else: msg = '' utils.logger.always_print(' theorem%s... ' % msg, end='') sys.stdout.flush() with s.new_frame(): s.add(t.translate_expr(Not(th.expr))) logic.check_unsat([(th.span, 'theorem%s does not hold' % msg)], s, num_states)
def bmc_trace(prog: syntax.Program, trace: syntax.TraceDecl, s: Solver, sat_checker: Callable[[Solver, int], Optional[logic.Trace]], log: bool = False) -> Optional[logic.Trace]: n_states = len(list(trace.transitions())) + 1 if log: print('%s states' % (n_states, )) lator = s.get_translator(n_states) with s.new_frame(): if len(trace.components) > 0 and not isinstance( trace.components[0], syntax.AssertDecl): for init in prog.inits(): s.add(lator.translate_expr(init.expr)) i = 0 for c in trace.components: if isinstance(c, syntax.AssertDecl): if c.expr is None: if i != 0: utils.print_error_and_exit( c.span, 'assert init is only allowed in the first state') for init in prog.inits(): assert i == 0 s.add(lator.translate_expr(init.expr)) else: s.add(lator.translate_expr(New(c.expr, i))) else: te: syntax.TransitionExpr = c.transition if isinstance(te, syntax.AnyTransition): logic.assert_any_transition(s, lator, i, allow_stutter=True) else: l = [] for call in te.calls: tid = z3.Bool( logic.get_transition_indicator( str(i), call.target)) l.append(tid) s.add( z3.Implies( tid, translate_transition_call(s, lator, i, call))) s.add(z3.Or(*l)) i += 1 return sat_checker(s, n_states)