def _match_fn(self, fname, fn, crash): self._debug('Running', fname, fn) for args in fn(self): self._debug('Iteration', args) disk.native = False self.enable_symbolic_execution() disk.assertion.assertions = [] disk.debug.debugs = [] spec_mach = Machine() impl_mach = Machine() spec = self.create_spec(spec_mach) self.assertIsNotNone(spec) impl = self.create_impl(impl_mach) self.assertIsNotNone(impl) pp = self.pre_post(spec=spec, impl=impl, spec_mach=spec_mach, impl_mach=impl_mach, fnargs=args, crash=crash, fname=fname, pre=False) pre = pp.next() self._debug('Pre', pre) if hasattr(self, 'call_%s' % fname): rets = getattr(self, 'call_%s' % fname)(spec, impl, args) if rets is None: rets = (None, None) else: if hasattr(self, 'call_%s_spec' % fname): rets_spec = getattr(self, 'call_%s_spec' % fname)(spec, args) else: # Guess something sensible.. if hasattr(spec, 'begin_tx'): spec.begin_tx() rets_spec = getattr(spec, fname)(*args) if hasattr(spec, 'commit_tx'): spec.commit_tx() if hasattr(self, 'call_%s_impl' % fname): rets_impl = getattr(self, 'call_%s_impl' % fname)(impl, args) else: # Guess something sensible.. if hasattr(impl, 'begin_tx'): impl.begin_tx() rets_impl = getattr(impl, fname)(*args) if hasattr(impl, 'commit_tx'): impl.commit_tx() rets = (rets_spec, rets_impl) if crash: if hasattr(self, 'crash_impl'): impl = self.crash_impl(impl) else: impl = impl.crash(Machine()) if hasattr(self, 'crash_spec'): spec = self.crash_spec(spec) else: spec = spec.crash(Machine()) post = pp.send((spec, impl, args, rets)) assumption = self.assumption(fname, spec_mach, impl_mach) self._debug('Post', post) self._debug('Assumption', assumption) if self.DEBUG or getattr(fn, 'debug', False): self._debug('Precondition sat', self.show(pre)) if crash: opt = { 'AUTO_CONFIG': False, # 'MBQI': True } opt.update(getattr(fn, '_z3_options', {})) if spec_mach.control: model = self._solve( assumption, ForAll(spec_mach.control, Not(Implies(pre, post))), **opt) else: model = self._solve(assumption, Not(Implies(pre, post)), **opt) if model: print "" for msg, vs in disk.debug.debugs: print msg, for v in vs: print model.evaluate(v), print "" print "" spec_mach.explain(model) impl_mach.explain(model) self.assertIsNone(model) else: opt = {} opt.update(getattr(fn, '_z3_options', {})) self.psolve(And(*spec_mach.control), And(*impl_mach.control), Not(Implies(pre, post)), **opt)
#!/usr/bin/env python # from TU Graz presentation by Vedad Hadzic from z3 import Solver, Int, IntSort, BoolSort, Function from z3 import ForAll, And, Or, Not, Implies, sat as SAT # create an integer and a function x = Int("x") f = Function("f", IntSort(), IntSort(), BoolSort()) solver = Solver() solver.add(ForAll([x], Implies(And(x > 0, x < 4), f(x, x)))) solver.add(ForAll([x], Implies(Or(x <= 0, x >= 4), Not(f(x, x))))) if solver.check() != SAT: exit(1) m = solver.model() print(f'f(0,0)={m.eval(f(0,0))}') print(f'f(1,2)={m.eval(f(1,2))}') print(f'f(2,3)={m.eval(f(2,3))}') print(f'f(3,3)={m.eval(f(3,3))}') for i in range(0, 5): # assert ∀ x in (0,4). f(x,x) = 1 # check if satisfiable # get the solution # print the relation table vs = [int(bool(m.eval(f(i, j)))) for j in range(0, 5)]
Mansion = MansionDT.create() # constants for ease of reference a, b, c = Mansion.Agatha, Mansion.Butler, Mansion.Charles # declare predicates killed = Function("killed", Mansion, Mansion, BoolSort()) hates = Function("hates", Mansion, Mansion, BoolSort()) richer = Function("richer", Mansion, Mansion, BoolSort()) # quantified variables x = Const("x", Mansion) y = Const("y", Mansion) e1 = Exists([x], killed(x, a)) e2a = ForAll([x, y], Implies(killed(x, y), hates(x, y))) e2b = ForAll([x, y], Implies(killed(x, y), Not(richer(x, y)))) e3 = ForAll([x], Implies(hates(a, x), Not(hates(c, x)))) e4a = hates(a, a) e4b = hates(a, c) e5 = ForAll([x], Implies(Not(richer(x, a)), hates(b, x))) e6 = ForAll([x], Implies(hates(a, x), hates(b, x))) e7 = ForAll([x], Exists([y], Not(hates(x, y)))) s = Solver() s.add(e1) s.add(e2a) s.add(e2b) s.add(e3) s.add(e4a) s.add(e4b)