def test_prenex_basic(self): a, b, c = (Symbol(x) for x in "abc") f = Not(And(a, Exists([b], And(a, b)), ForAll([c], Or(a, c)))) prenex = prenex_normal_form(f) # Two prenex normal forms are possible my_prenex_1 = Exists([c], ForAll([b], Not(And(a, And(a, b), Or(a, c))))) my_prenex_2 = ForAll([b], Exists([c], Not(And(a, And(a, b), Or(a, c))))) self.assertTrue(prenex == my_prenex_1 or prenex == my_prenex_2)
def test_quantifiers(self): x = Symbol("x") fa = ForAll([x], And(x, Not(x))) fe = Exists([x], And(x, Not(x))) self.assertEqual(fa.to_smtlib(daggify=False), "(forall ((x Bool)) (and x (not x)))") self.assertEqual(fe.to_smtlib(daggify=False), "(exists ((x Bool)) (and x (not x)))") self.assertEqual(fa.to_smtlib(daggify=True), "(let ((.def_0 (forall ((x Bool)) (let ((.def_0 (not x))) (let ((.def_1 (and x .def_0))) .def_1))))).def_0)") self.assertEqual(fe.to_smtlib(daggify=True), "(let ((.def_0 (exists ((x Bool)) (let ((.def_0 (not x))) (let ((.def_1 (and x .def_0))) .def_1))))).def_0)")
def smart_walk_not(self, formula): if formula in self.subs: # Smarties contains a string. # In the future, we could allow for arbitrary function calls self.write(self.subs[formula]) else: arg = formula.arg(0) if arg.is_iff(): arg = self.get_iff(arg) if arg.is_exists(): argn = ForAll(arg.quantifier_vars(), Not(arg.arg(0))) return self.walk(argn) elif arg.is_forall(): argn = Exists(arg.quantifier_vars(), Not(arg.arg(0))) return self.walk(argn) elif arg.is_and(): args = [Not(a) for a in arg.args()] argn = Or(args) return self.walk(argn) elif arg.is_or(): args = [Not(a) for a in arg.args()] argn = And(args) return self.walk(argn) elif arg.is_not(): return self.walk(arg.arg(0)) else: if (arg.is_not()): assert (0) return HRPrinter.super(self, formula)
def _alternation_real_example(self, qe): # Alternation of quantifiers r, s = Symbol("r", REAL), Symbol("s", REAL) f = ForAll([r], Exists([s], Equals(r, Plus(s, Real(1))))) qf = qe.eliminate_quantifiers(f).simplify() self.assertEqual(qf, TRUE())
def _alternation_int_example(self, qe): # Alternation of quantifiers p, q = Symbol("p", INT), Symbol("q", INT) f = ForAll([p], Exists([q], Equals(p, Plus(q, Int(1))))) qf = qe.eliminate_quantifiers(f).simplify() self.assertEqual(qf, TRUE())
def test_quantifiers(self): x = Symbol("x") fa = ForAll([x], And(x, Not(x))) fe = Exists([x], And(x, Not(x))) self.assertEqual(fa.to_smtlib(daggify=False), "(forall ((x Bool)) (and x (not x)))") self.assertEqual(fe.to_smtlib(daggify=False), "(exists ((x Bool)) (and x (not x)))") self.assertEqual( fa.to_smtlib(daggify=True), "(let ((.def_0 (forall ((x Bool)) (let ((.def_0 (not x))) (let ((.def_1 (and x .def_0))) .def_1))))).def_0)" ) self.assertEqual( fe.to_smtlib(daggify=True), "(let ((.def_0 (exists ((x Bool)) (let ((.def_0 (not x))) (let ((.def_1 (and x .def_0))) .def_1))))).def_0)" )
def _alternation_bool_example(self, qe): # Alternation of quantifiers x, y = Symbol("x"), Symbol("y") f = ForAll([x], Exists([y], Iff(x, Not(y)))) qf = qe.eliminate_quantifiers(f).simplify() self.assertEqual(qf, TRUE())
def test_quantifiers(self): x = Symbol("x") fa = ForAll([x], And(x, Not(x))) fe = Exists([x], And(x, Not(x))) fa_string = self.print_to_string(fa) fe_string = self.print_to_string(fe) self.assertEqual(fa_string, "(forall ((x Bool)) (and x (not x)))") self.assertEqual(fe_string, "(exists ((x Bool)) (and x (not x)))")
def test_lia_qe_requiring_modulus(self): x = Symbol("x", INT) y = Symbol("y", INT) f = Exists([x], Equals(y, Times(x, Int(2)))) with self.assertRaises(ConvertExpressionError): qelim(f) try: qelim(f) except ConvertExpressionError as ex: # The modulus operator must be there self.assertIn("%2", str(ex.expression))
def test_qe_z3(self): qe = QuantifierEliminator(name='z3') self._bool_example(qe) self._real_example(qe) self._int_example(qe) self._alternation_bool_example(qe) self._alternation_real_example(qe) self._alternation_int_example(qe) self._std_examples(qe, LRA) self._std_examples(qe, LIA) # Additional test for raising error on back conversion of # quantified formulae p, q = Symbol("p", INT), Symbol("q", INT) f = ForAll([p], Exists([q], Equals(ToReal(p), Plus(ToReal(q), ToReal(Int(1)))))) with self.assertRaises(NotImplementedError): qe.eliminate_quantifiers(f).simplify()
def test_examples_solving(self): for example in get_example_formulae(): if example.logic != pysmt.logics.BOOL: continue fv = example.expr.get_free_variables() f = Exists(fv, example.expr) g = qelim(f, solver_name="shannon").simplify() if example.is_sat: self.assertTrue(g.is_true()) else: self.assertTrue(g.is_false()) f = ForAll(fv, example.expr) g = qelim(f, solver_name="shannon").simplify() if example.is_valid: self.assertTrue(g.is_true()) else: self.assertTrue(g.is_false())
def test_qe_eq(self): qe = QuantifierEliminator(logic=LRA) varA = Symbol("A", BOOL) varB = Symbol("B", BOOL) varAt = Symbol("At", REAL) varBt = Symbol("Bt", REAL) f = And(Iff(varA, GE(Minus(varAt, varBt), Real(0))), Iff(varB, LT(Minus(varAt, varBt), Real(1)))) qf = Exists([varBt, varA], f) r1 = qe.eliminate_quantifiers(qf) try: self.assertValid(Iff(r1, qf), logic=LRA, msg="The two formulas should be equivalent.") except SolverReturnedUnknownResultError: pass
def test_exists(self): f = Exists([self.x], And(self.x, self.y)) g = qelim(f, solver_name="shannon") g = g.simplify() self.assertEqual(g, self.y)
def symmetry_cube(self, cube, fIdx, reducePremise, dest=None): # cube_str = pretty_serialize(Not(cube), mode=0) cube_str = pretty_serialize(Not(cube), mode=0) print("(clause)") print("\t%s" % cube_str) cvars = cube.get_enum_constants() crels = cube.get_free_variables() print("(relations)") for r in crels: print("\t%s" % pretty_serialize(r)) # assert(0) subs = dict() # print(cvars) enum2qvar = dict() # for v in cvars: for v in sorted(cvars, key=str): enumsort = v.constant_type() if self.ordered == "partial" and enumsort in self.system._ordered_sorts: continue if self.ordered == "zero" and str(enumsort).startswith("epoch"): # continue assert(enumsort in self.system._enumsorts) domain = self.system._enumsorts[enumsort] zero = self.system.zero[1] firste = self.system.firste[1] le = self.system.le if v == domain[0]: subs[v] = zero continue elif v == domain[1]: subs[v] = firste continue else: rhs = firste end = 2 try: end = domain.index(v) except ValueError: assert(0) for idx in range(end-1, 1, -2): v2 = domain[idx] if v2 in cvars: rhs = v2 break gt = Not(Function(le, [v, rhs])) print("\tadding condition: %s" % pretty_print_str(gt)) cube = And(cube, gt) # neq = And(Not(EqualsOrIff(v, zero)), Not(EqualsOrIff(v, firste))) # cube = And(cube, neq) # if (self.quorums != "none" and # (str(enumsort).startswith("node") or str(enumsort).startswith("acceptor"))): # continue if (self.quorums != "none" and (str(enumsort).startswith("quorum"))): continue if enumsort in self.system._enum2qvar: qvar = [] if enumsort in enum2qvar: qvar = enum2qvar[enumsort] idx = len(qvar) qv = self.system._enum2qvar[enumsort][idx] qvar.append(qv) enum2qvar[enumsort] = qvar subs[v] = qv antecedent = dict() qvars = set() fullsorts = [] # print(enum2qvar) # print(self.system._enum2qvar) minSz = 3 if experimentGeneralize: minSz = 2 for enumsort, qvar in enum2qvar.items(): if ( # False and # (str(enumsort).startswith("acceptor") # or str(enumsort).startswith("node") # or str(enumsort).startswith("quorum") # ) and # (str(enumsort).startswith("quorum")) and (len(qvar) >= minSz) and (len(qvar) == len(self.system._enum2qvar[enumsort]))): fullsorts.append([enumsort, qvar]) antecedent[enumsort] = [] for i in range(len(qvar) - 1): qvi = qvar[i] qvars.add(qvi) for j in range(i+1, len(qvar)): if i != j: deq = Not(EqualsOrIff(qvi, qvar[j])) antecedent[enumsort].append(deq) # print("adding: %s" % deq) qvars.add(qvar[-1]) self.print_fullsorts(fullsorts) cubeSym = cube isorts = dict() ivars = set() if cubeSym.is_exists(): for v in cubeSym.quantifier_vars(): if v not in subs: vs = v.symbol_type() if vs not in isorts: isorts[vs] = list() idx = len(isorts[vs]) name = str(vs) + ":i" + str(idx) isymbol = Symbol(name, vs) isorts[vs].append(isymbol) subs[v] = isymbol ivars.add(isymbol) qvars.add(isymbol) cubeSym = cubeSym.args()[0] cubeSym = cubeSym.simple_substitute(subs) cubeSet = flatten_cube(cubeSym) # self.reduce_antecedent(cubeSet, qvars, antecedent, fIdx) print("(cube: std)") for c in cubeSet: print("\t%s" % pretty_serialize(c, mode=0)) if common.gopts.opt > 0 and reducePremise: push_time() antecedent, reduceSz, varSet = self.reduce_antecedent2(cubeSym, qvars, enum2qvar, fIdx) self.update_time_stat("time-antecedent", pop_time()) print() if self.ordered == "partial": cubeSet = self.boost_ordered(cubeSet, antecedent, qvars, fIdx) eqMap = dict() if common.gopts.const > 0: eqMap, cubeSet, antecedent, fullsorts = self.propagate_eq(cubeSet, antecedent, ivars, qvars, fullsorts) if True: cubeSetSimple = cubeSet.copy() for v in antecedent.values(): for c in v: cubeSetSimple.add(c) cubeSimple = And(cubeSetSimple) if len(qvars) != 0: cubeSimple = Exists(qvars, cubeSimple) cubesOut = list() if (self.system.gen == "univ") or (len(fullsorts) == 0) or (len(crels) <= 1) or (len(cubeSet) < minSz): cubesOut.append((cubeSimple, "univ")) else: uqvars = set() cubeSet2 = cubeSet.copy() for fs in fullsorts: enumsort = fs[0] qvar = fs[1] qvarSet = set() for q in qvar: qvarSet.add(q) qvart = fs[0] uSymbol = Symbol("V:"+str(qvart), qvart) qv2cubes = {} qv2ucubes = {} for q in qvar: qv2cubes[q] = set() qv2ucubes[q] = set() ucubes = set() for c in cubeSet: cvars = c.get_free_variables() cqvars = cvars.intersection(qvarSet) # cqvars = c.get_filtered_nodes(qvarSet) for q in cqvars: tmp_subs = {} tmp_subs[q] = uSymbol uc = c.substitute(tmp_subs) ucubes.add(uc) qv2cubes[q].add(c) qv2ucubes[q].add(uc) print("qv2cubes #%d" % len(qv2cubes)) for k, v in qv2cubes.items(): print("\t%s -> %s" % (pretty_serialize(k), pretty_print_set(v, mode=0))) print("qv2ucubes #%d" % len(qv2ucubes)) for k, v in qv2ucubes.items(): print("\t%s -> %s" % (pretty_serialize(k), pretty_print_set(v, mode=0))) ucubes2qv = {} emptyIdx = 1 for qv, ucubes in qv2ucubes.items(): uIdx = emptyIdx uc = TRUE() if len(ucubes) == 0: emptyIdx += 1 elif qv in self.system.curr._states: emptyIdx += 1 print("\t(creating separate cell for %s)" % pretty_serialize(qv)) else: uIdx = 0 ucubes_sorted = sorted(ucubes, key=str) uc = And(ucubes_sorted) k = (uIdx, uc) if k not in ucubes2qv: ucubes2qv[k] = set() ucubes2qv[k].add(qv) print("ucubes2qv #%d" % len(ucubes2qv)) singles = [] multiples = [] for k, v in ucubes2qv.items(): if len(v) == 1: singles.append(k) elif len(v) >= minSz: multiples.append(k) print("\t%s -> %s" % (pretty_serialize(k[1]), pretty_print_set(v, mode=0))) print("(partition) #%d %s -> { " % (len(ucubes2qv), enumsort), end="") for v in ucubes2qv.values(): for d in v: print("%s, " % pretty_serialize(d), end="") print("| ", end="") print("}") nsingles = len(singles) nmultiples = len(multiples) ncells = len(ucubes2qv) print("\t#%d singles, #%d multiples (out of #%d cells)" % (nsingles, nmultiples, ncells)) if len(ucubes2qv) == 1: for rhs in ucubes2qv.values(): if len(rhs) != len(qvar): print("found single part with incomplete instances") assert(0) if qvar[0].is_symbol(): uqvars.add(qvar[0]) antecedent.pop(enumsort, None) for cubes in qv2cubes.values(): for cube in cubes: cubeSet2.discard(cube) for _, uc in ucubes2qv.keys(): tmp_subs = {} tmp_subs[uSymbol] = qvar[0] uc = uc.simple_substitute(tmp_subs) ucList = flatten_cube(uc) for v in ucList: cubeSet2.add(v) for q in qvar: qvars.discard(q) cubeSet = cubeSet2 elif (ncells == (nsingles + nmultiples) and nmultiples == 1 and nsingles == 1 ): # elif (len(ucubes2qv) == 2 # and (len(qvar) > minSz) # # and (not self.system.is_epr()) # ): # elif len(ucubes2qv) == 2 and (len(qvar) > minSz) and (not self.system.is_epr()): qsingle = [] qmulti = None for k in singles: assert(k in ucubes2qv) qg = ucubes2qv[k] assert(len(qg) == 1) for q in qg: qsingle.append(q) for k in multiples: assert(k in ucubes2qv) qg = ucubes2qv[k] assert(len(qg) >= minSz) if len(qg) == (len(qvar) - len(qsingle)): qmulti = qg if len(qsingle) != 0 and qmulti != None: ucsingle = {} ucmulti = set() for qs in qsingle: ucsingle[qs] = set() tmp_subs = {} tmp_subs[uSymbol] = qs for uc in qv2ucubes[qs]: uc = uc.simple_substitute(tmp_subs) ucsingle[qs].add(uc) qm = sorted(qmulti, key=str)[0] tmp_subs = {} tmp_subs[uSymbol] = qm for uc in qv2ucubes[qm]: uc = uc.simple_substitute(tmp_subs) ucmulti.add(uc) print("ucsingle:") for k, rhs in ucsingle.items(): print("\t%s:" % pretty_serialize(k)) for v in rhs: print("\t\t%s" % pretty_serialize(v)) print("ucmulti:") for v in ucmulti: print("\t%s" % pretty_serialize(v)) if qm.is_symbol(): uqvars.add(qm) if enumsort in antecedent: newAnt = [] for v in antecedent[enumsort]: vvars = v.get_free_variables() vmvars = vvars.intersection(qmulti) if len(vmvars) == 0: newAnt.append(v) antecedent.pop(enumsort, None) if len(newAnt) != 0: antecedent[enumsort] = newAnt for q in qmulti: for cube in qv2cubes[q]: cubeSet2.discard(cube) # for v in ucsingle: # cubeSet2.add(v) for q in qmulti: qvars.discard(q) eqM = [] for qs in qsingle: eqM.append(EqualsOrIff(qs, qm)) sEqm = Or(eqM) for v in ucmulti: vNew = Or(sEqm, v) cubeSet2.add(vNew) cubeSet = cubeSet2 eqvars2 = set() forwardArcs = 0 reverseArcs = 0 if len(uqvars) != 0: if (self.system.gen != "fe"): for u in qvars: ut = u.symbol_type() for e in uqvars: et = e.symbol_type() if (self.system.gen == "fef"): if ut != et or True: eqvars2.add(u) else: print("\t(epr check: forward)", end="") if not self.system.allowed_arc(ut, et): forwardArcs += 1 print("\t(epr check: reverse)", end="") if not self.system.allowed_arc(et, ut): reverseArcs += 1 eqvars2.add(u) for u in eqvars2: if u in qvars: qvars.remove(u) cubeSet = cubeSet2 for v in antecedent.values(): for c in v: cubeSet.add(c) cubesOut = list() if (self.system.gen == "fef") and (len(uqvars) != 0) and (len(eqvars2) != 0): fancy = "fef" cubeSym = None count = 0 innerVars = list(eqvars2) while True or (len(innerVars) != 0): count += 1 preCube = set() postCube = set() postVars = set() for q in uqvars: postVars.add(q) for q in innerVars: postVars.add(q) for c in cubeSet: argvars = c.get_free_variables() argvars = argvars.intersection(postVars) if len(argvars) == 0: preCube.add(c) else: postCube.add(c) postCube = sorted(postCube, key=str) preCube = sorted(preCube, key=str) cubeSym = And(postCube) if len(innerVars) != 0: cubeSym = Exists(innerVars, cubeSym) if len(uqvars) != 0: cubeSym = ForAll(uqvars, cubeSym) if len(preCube) != 0: cubeSym = And(And(preCube), cubeSym) if len(qvars) != 0: cubeSym = Exists(qvars, cubeSym) print("(#%d: quantifier-reduced) " % count) print("\t%s" % pretty_serialize(Not(cubeSym), mode=0)) # notCubeSym_formula = self.get_formula_qf(Not(cubeSym)) # print("\t(quantifier-free version)") # notCubeSym_formulaList = flatten_and(notCubeSym_formula) # for v in notCubeSym_formulaList: # print("\t\t%s" % pretty_serialize(v)) solver = self.get_framesolver(fIdx) cubeSym_formula = self.get_formula_qf(cubeSym) print("\t(#%d: quantifier-rearrangement) " % count, end="") result = self.solve_formula(solver, cubeSym_formula) if not result: cubesOut.append((cubeSym, fancy)) break if len(innerVars) != 0: u = innerVars.pop(0) qvars.add(u) else: break assert(len(cubesOut) != 0) cubesOut.reverse() # if len(cubesOut) == 0: # preCube = set() # postCube = set() # postVars = set() # for q in uqvars: # postVars.add(q) # for q in innerVars: # postVars.add(q) # for c in cubeSet: # argvars = c.get_free_variables() # argvars = argvars.intersection(postVars) # if False and len(argvars) == 0: # preCube.add(c) # else: # postCube.add(c) # postCube = sorted(postCube, key=str) # preCube = sorted(preCube, key=str) # cubeSym2 = And(postCube) # if len(uqvars) != 0: # cubeSym2 = ForAll(uqvars, cubeSym2) # if len(innerVars) != 0: # cubeSym2 = Exists(innerVars, cubeSym2) # if len(preCube) != 0: # cubeSym2 = And(And(preCube), cubeSym2) # if len(qvars) != 0: # cubeSym2 = Exists(qvars, cubeSym2) # cubesOut.append((cubeSym2, fancy)) else: preCube = set() postCube = set() if len(uqvars) == 0: postCube = cubeSet else: postVars = set() for q in uqvars: postVars.add(q) for q in eqvars2: postVars.add(q) for c in cubeSet: argvars = c.get_free_variables() argvars = argvars.intersection(postVars) if len(argvars) == 0: preCube.add(c) else: postCube.add(c) postCube = sorted(postCube, key=str) preCube = sorted(preCube, key=str) cubeSym = And(postCube) if len(eqvars2) != 0: cubeSym = Exists(eqvars2, cubeSym) if len(uqvars) != 0: cubeSym = ForAll(uqvars, cubeSym) if len(preCube) != 0: cubeSym = And(And(preCube), cubeSym) if len(qvars) != 0: cubeSym = Exists(qvars, cubeSym) fancy = "univ" if (len(uqvars) != 0): fancy = "epr" cubesOut.append((cubeSym, fancy)) if fancy: if len(eqvars2) != 0: cubeSym2 = And(postCube) if len(uqvars) != 0: cubeSym2 = ForAll(uqvars, cubeSym2) if len(eqvars2) != 0: cubeSym2 = Exists(eqvars2, cubeSym2) if len(preCube) != 0: cubeSym2 = And(And(preCube), cubeSym2) if len(qvars) != 0: cubeSym2 = Exists(qvars, cubeSym2) print("(epr reduced)") print("\t%s" % pretty_serialize(Not(cubeSym), mode=0)) print("(non-epr version)") print("\t%s" % pretty_serialize(Not(cubeSym2), mode=0)) result = False if (reverseArcs != 0): print("\tBoth verions not allowed!") if (self.system.gen == "epr_strict"): result = True if not result: solver = self.get_framesolver(fIdx) print("(epr-reduction) ", end="") cubeSym_formula = self.get_formula_qf(cubeSym) result = self.solve_formula(solver, cubeSym_formula) if result: print("\tEPR-reduction is not allowed!") cubesOut.pop() if (self.system.gen == "epr_strict") or (self.system.gen == "epr_loose"): print("\tLearning universal version instead.") cubesOut.append((cubeSimple, "univ")) else: print("\tLearning non-epr version instead.") cubesOut.append((cubeSym2, "non-epr")) # assert(0) if common.gopts.const > 0: for i in range(len(cubesOut)): cubeTop = cubesOut[i] cubeEq = self.propagate_eq_post(cubeTop[0]) cubesOut[i] = (cubeEq, cubeTop[1]) print("(boosted clause)") print("\t%s" % pretty_serialize(Not(cubesOut[0][0]), mode=0)) print("---------------------------") print("(original clause)") print("\t%s" % cube_str) print("(learnt sym-boosted clause)") print("\t%s" % pretty_serialize(Not(cubesOut[0][0]), mode=0)) print("---------------------------") else: cubesOut = get_uniform(self, fullsorts, cubeSet, qvars, antecedent) return cubesOut
def get_uniform(self, fullsorts, cubeSet, eqvars, antecedent): # print("fullsorts: %s" % (fullsorts)) uqvars = [] eqvars2 = [] subs = dict() if len(fullsorts) != 0: for fs in fullsorts: # continue efs = fs[0] qvar = fs[1] # qvar = fullsorts[0][1] qvarSet = set() for q in qvar: qvarSet.add(q) subs[q] = qvar[0] isUniform = True uniformSet = dict() otherPresent = False for c in cubeSet: cvars = c.get_free_variables() cqvars = cvars.intersection(qvarSet) # print(c) # print(cvars) # print(qvarSet) # print(cqvars) if len(cqvars) == 1: uniformc = c.simple_substitute(subs) if uniformc not in uniformSet: uniformSet[uniformc] = list() uniformSet[uniformc].append(c) # print("uniformc %s" % uniformc) elif len(cqvars) > 1: print("cube %s has multiple cqvars: %s" % (c, cqvars)) isUniform = False elif len(cqvars) == 0: otherPresent = True ucList = [] if isUniform: for uc, clist in uniformSet.items(): if len(clist) != len(qvar): isUniform = False print("not symmetric due to:") for c in clist: print("\t%s" % pretty_serialize(c)) break # for c in clist: # print("\t%s" % c.serialize()) ucList.append(uc) if experimentGeneralize: if isUniform and not otherPresent: isUniform = False if len(qvar) > 2: eprint("Warning: experimental") print("Warning: experimental") if not isUniform: for q in qvar: subs.pop(q) if (isUniform and len(ucList) != 0): for k, clist in uniformSet.items(): for c in clist: cubeSet.remove(c) uqvars.append(qvar[0]) for uc in ucList: cubeSet.add(uc) antecedent.pop(efs) for q in qvar: eqvars.remove(q) if len(uqvars) != 0: for u in eqvars: ut = u.symbol_type() for e in uqvars: et = e.symbol_type() if not self.system.allowed_arc(ut, et): eqvars2.append(u) for u in eqvars2: if u in eqvars: eqvars.remove(u) for k, v in antecedent.items(): for i in v: cubeSet.add(i) preCube = set() postCube = set() if len(uqvars) == 0: postCube = cubeSet else: postVars = set() for q in uqvars: postVars.add(q) for q in eqvars2: postVars.add(q) for c in cubeSet: argvars = c.get_free_variables() argvars = argvars.intersection(postVars) if len(argvars) == 0: preCube.add(c) else: postCube.add(c) # print("pre : %s" % preCube) # print("post: %s" % postCube) cubeSym = And(postCube) if len(eqvars2) != 0: cubeSym = Exists(eqvars2, cubeSym) if len(uqvars) != 0: cubeSym = ForAll(uqvars, cubeSym) print("uniform: %s\t%s" % (uqvars, cubeSym)) # if len(uqvars) > 1: # assert(0) if len(preCube) != 0: cubeSym = And(And(preCube), cubeSym) if len(eqvars) != 0: cubeSym = Exists(eqvars, cubeSym) cubesOut = list() fancy = (len(uqvars) != 0) cubesOut.append((cubeSym, fancy)) # if complex: # pretty_print(cubeSym) # assert(0) return cubesOut
# (x,y) is a point in a 2d space. x = Symbol("x", REAL) y = Symbol("y", REAL) # phi(x,y) is true if (x,y) is within a given area. In particular, we # pick a rectangular area of size 5x10: the bottom-left corner has # coordinate (0,0), the top-right has coordinate (5, 10). # rect = (x >= 0.0) & (x <= 5.0) & \ (y >= 0.0) & (y <= 10.0) # The first expression that we build asks if for any value of x we can # define a value of y that would satisfy the expression above. f1 = ForAll([x], Exists([y], rect)) # This is false, because we know that if we pick x=11, the formula # above cannot be satisfied. Eliminating all the symbols in an # expression is the same as solving the expression. # # The function to perform quantifier elimination is called qelim: qf_f1 = qelim(f1) print(qf_f1) # We can restrict the values that x can adopt by imposing them as # precondition. # # If we perform quantifier elimination on this expression we obtain an # unsurprising result: #
def get_uniform2(self, fullsorts, cubeSet, eqvars, antecedent, varSet, enum2qvar): allow_nonepr = False uqvars = [] eqvars2 = [] subs = dict() uniformed = False if len(fullsorts) != 0: cubeSetSym = set() for cube in cubeSet: cubeSetSym.add(cube) # for k in antecedent.keys(): # if k in varSet: # continue # kt = k.symbol_type() # assert(kt in enum2qvar) # for qv in enum2qvar[kt]: # subs[qv] = k # for cube in cubeSet: # cubeSym = cube.simple_substitute(subs) # cubeSetSym.add(cubeSym) # if cubeSym != cube: # uniformed = True # subs.clear() for k, v in antecedent.items(): for i in v: cubeSet.add(i) cubeSym = And(cubeSet) if len(eqvars) != 0: cubeSym = Exists(eqvars, cubeSym) cubesOut = list() cubesOut.append((cubeSym, False)) for fs in fullsorts: qvart = fs[0] qvar = fs[1] qvarSet = set() for q in qvar: qvarSet.add(q) uSymbol = Symbol("V:"+str(qvart), qvart) qv2cubes = {} qv2ucubes = {} for q in qvar: qv2cubes[q] = set() qv2ucubes[q] = set() for c in cubeSetSym: cvars = c.get_free_variables() cqvars = cvars.intersection(qvarSet) if len(cqvars) > 1: print("Found multiple fullsorts in atom %s" % c) print("Enabling nonepr mode") allow_nonepr = True for q in cqvars: tmp_subs = {} tmp_subs[q] = uSymbol uc = c.simple_substitute(tmp_subs) qv2cubes[q].add(c) qv2ucubes[q].add(uc) # print("qv2cubes #%d" % len(qv2cubes)) # for k, v in qv2cubes.items(): # print("\t%s -> %s" % (k, v)) # print("qv2ucubes #%d" % len(qv2ucubes)) # for k, v in qv2ucubes.items(): # print("\t%s -> %s" % (k, v)) ucubes2qv = {} for qv, ucubes in qv2ucubes.items(): uc = And(ucubes) if uc not in ucubes2qv: ucubes2qv[uc] = set() ucubes2qv[uc].add(qv) print("ucubes2qv #%d" % len(ucubes2qv)) for k, v in ucubes2qv.items(): print("\t%s -> %s" % (k, v)) nump = len(ucubes2qv) assert(nump != 0) if nump == 1: # just 1 uniform structure for rhs in ucubes2qv.values(): if len(rhs) != len(qvar): print("found single part with incomplete instances") assert(0) uq = qvar[0] # print("uq: %s" % uq) for qv, cubes in qv2cubes.items(): eqvars.discard(qv) # print("cubes: %s" % cubes ) if qv != uq: for cube in cubes: cubeSetSym.discard(cube) # print("discarding: %s" % cube) uqvars.append(uq) antecedent.pop(qvar[0]) # print("cubeSetSym: %s" % cubeSetSym) elif nump == 2 and allow_nonepr: pass # uc = None # for ucubes, qv in ucubes2qv.items(): # if len(qv) == (len(qvar)-1): # uc = ucubes # break # if uc != None: # print("found 1,N-1 parts") # cubeRem = set() # for qv, cubes in qv2cubes.items(): # for cube in cubes: # cubeSetSym.discard(cube) # cubeRem.add(cube) # # uqs = ucubes2qv[uc] # uq = sorted(uqs, key=str)[0] # qvars_new = set() # tmp_subs = {} # cubeL = set() # for qv, cubes in qv2cubes.items(): # if qv not in uqs: # qvars_new.add(qv) # continue # eqvars.discard(qv) # if qv != uq: # tmp_subs[qv] = uq # for cube in cubes: # cubeRem.discard(cube) # else: # for cube in cubes: # cubeL.add(cube) # cubeRem.discard(cube) # assert(len(qvars_new) == 1) # assert(len(cubeL) != 0) # for qv in qvars_new: # eq = EqualsOrIff(qv, uq) # cubeNew = Or(eq, And(cubeL)) # cubeSetSym.add(cubeNew) # for cube in cubeRem: # cubeSetSym.add(cube) # uqvars.append(uq) # antecedent.pop(qvar[0]) # qvars_new.add(uq) if len(uqvars) == 0: return cubesOut for k, v in antecedent.items(): for i in v: cubeSetSym.add(i) for u in eqvars: ut = u.symbol_type() for e in uqvars: et = e.symbol_type() if not allow_nonepr and (not self.system.allowed_arc(ut, et)): eqvars2.append(u) for u in eqvars2: if u in eqvars: eqvars.remove(u) preCube = set() postCube = set() postVars = set() for q in uqvars: postVars.add(q) for q in eqvars2: postVars.add(q) for c in cubeSetSym: argvars = c.get_free_variables() argvars = argvars.intersection(postVars) if len(argvars) == 0: preCube.add(c) else: postCube.add(c) cubeSym = And(postCube) if len(eqvars2) != 0: cubeSym = Exists(eqvars2, cubeSym) cubeSym = ForAll(uqvars, cubeSym) if len(preCube) != 0: cubeSym = And(And(preCube), cubeSym) if len(eqvars) != 0: cubeSym = Exists(eqvars, cubeSym) print("uniform: %s\n\t" % uqvars, end="") pretty_print(cubeSym) if not uniformed: cubesOut.pop() fancy = (len(uqvars) != 0) cubesOut.insert(0, (cubeSym, fancy)) return cubesOut
def get_example_formulae(environment=None): if environment is None: environment = get_env() with environment: x = Symbol("x", BOOL) y = Symbol("y", BOOL) p = Symbol("p", INT) q = Symbol("q", INT) r = Symbol("r", REAL) s = Symbol("s", REAL) rf = Symbol("rf", FunctionType(REAL, [REAL, REAL])) rg = Symbol("rg", FunctionType(REAL, [REAL])) ih = Symbol("ih", FunctionType(INT, [REAL, INT])) ig = Symbol("ig", FunctionType(INT, [INT])) bv8 = Symbol("bv1", BV8) bv16 = Symbol("bv2", BV16) result = [ # Formula, is_valid, is_sat, is_qf # x /\ y Example(expr=And(x, y), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BOOL), # x <-> y Example(expr=Iff(x, y), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BOOL), # (x \/ y ) /\ ! ( x \/ y ) Example(expr=And(Or(x, y), Not(Or(x, y))), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BOOL), # (x /\ !y) Example(expr=And(x, Not(y)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BOOL), # False -> True Example(expr=Implies(FALSE(), TRUE()), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BOOL), # # LIA # # (p > q) /\ x -> y Example(expr=And(GT(p, q), Implies(x, y)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_IDL), # (p + q) = 5 /\ (p > q) Example(expr=And(Equals(Plus(p, q), Int(5)), GT(p, q)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LIA), # (p >= q) \/ ( p <= q) Example(expr=Or(GE(p, q), LE(p, q)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_IDL), # !( p < q * 2 ) Example(expr=Not(LT(p, Times(q, Int(2)))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LIA), # p - (5 - 2) > p Example(expr=GT(Minus(p, Minus(Int(5), Int(2))), p), is_valid=False, is_sat=False, logic=pysmt.logics.QF_IDL), # x ? 7: (p + -1) * 3 = q Example(expr=Equals( Ite(x, Int(7), Times(Plus(p, Int(-1)), Int(3))), q), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LIA), Example(expr=LT(p, Plus(q, Int(1))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LIA), # # LRA # # (r > s) /\ x -> y Example(expr=And(GT(r, s), Implies(x, y)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_RDL), # (r + s) = 5.6 /\ (r > s) Example(expr=And(Equals(Plus(r, s), Real(Fraction("5.6"))), GT(r, s)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LRA), # (r >= s) \/ ( r <= s) Example(expr=Or(GE(r, s), LE(r, s)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_RDL), # !( (r / (1/2)) < s * 2 ) Example(expr=Not(LT(Div(r, Real((1, 2))), Times(s, Real(2)))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LRA), # ! ( r - (5 - 2) > r ) Example(expr=Not(GT(Minus(r, Minus(Real(5), Real(2))), r)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_RDL), # x ? 7: (s + -1) * 3 = r Example(expr=Equals( Ite(x, Real(7), Times(Plus(s, Real(-1)), Real(3))), r), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LRA), # # EUF # # rf(5, rg(2)) = 0 Example(expr=Equals(Function(rf, (Real(5), Function(rg, (r, )))), Real(0)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_UFLRA), # (rg(r) = 5 + 2) <-> (rg(r) = 7) Example(expr=Iff(Equals(Function(rg, [r]), Plus(Real(5), Real(2))), Equals(Function(rg, [r]), Real(7))), is_valid=True, is_sat=True, logic=pysmt.logics.QF_UFLRA), # (r = s + 1) & (rg(s) = 5) & (rg(r - 1) = 7) Example(expr=And([ Equals(r, Plus(s, Real(1))), Equals(Function(rg, [s]), Real(5)), Equals(Function(rg, [Minus(r, Real(1))]), Real(7)) ]), is_valid=False, is_sat=False, logic=pysmt.logics.QF_UFLRA), # # BV # # bv_one & bv_zero == bv_zero Example(expr=Equals(BVAnd(BVOne(32), BVZero(32)), BVZero(32)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # ~(010) == 101 Example(expr=Equals(BVNot(BV("010")), BV("101")), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # "111" xor "000" == "000" Example(expr=Equals(BVXor(BV("111"), BV("000")), BV("000")), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), # bv8 :: bv8 < bv_zero Example(expr=BVULT(BVConcat(bv8, bv8), BVZero(16)), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), # bv_one[:7] == bv_one Example(expr=Equals(BVExtract(BVOne(32), end=7), BVOne(8)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # (((bv8 + bv_one) * bv(5)) / bv(5)) > bv(0) Example(expr=BVUGT( BVUDiv(BVMul(BVAdd(bv8, BVOne(8)), BV(5, width=8)), BV(5, width=8)), BVZero(8)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), # bv16 >=u bv(0) Example(expr=BVUGE(bv16, BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # bv16 >=s bv(0) Example(expr=BVSGE(bv16, BVZero(16)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), # (BV(5) rem BV(2) > bv_zero) /\ (BV(5) rem BV(2) < bv_one) Example(expr=And( BVUGT(BVURem(BV(5, width=32), BV(2, width=32)), BVZero(32)), BVULE(BVURem(BV(5, width=32), BV(2, width=32)), BVOne(32))), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # ((bv_one + (- bv_one)) << 1) >> 1 == bv_one Example(expr=Equals( BVLShr(BVLShl(BVAdd(BVOne(32), BVNeg(BVOne(32))), 1), 1), BVOne(32)), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), # bv_one - bv_one == bv_zero Example(expr=Equals(BVSub(BVOne(32), BVOne(32)), BVZero(32)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # Rotations Example(expr=Equals(BVRor(BVRol(BVOne(32), 1), 1), BVOne(32)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # Extensions Example(expr=Equals(BVZExt(BVZero(5), 11), BVSExt(BVZero(1), 15)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # bv16 - bv16 = 0_16 Example(expr=Equals(BVSub(bv16, bv16), BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # (bv16 - bv16)[0:7] = bv8 Example(expr=Equals(BVExtract(BVSub(bv16, bv16), 0, 7), bv8), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), # (bv16[0,7] comp bv8) = bv1 Example(expr=Equals(BVComp(BVExtract(bv16, 0, 7), bv8), BVOne(1)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), # (bv16 comp bv16) = bv0 Example(expr=Equals(BVComp(bv16, bv16), BVZero(1)), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), # (bv16 s< bv16) Example(expr=BVSLT(bv16, bv16), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), # (bv16 s< 0_16) Example(expr=BVSLT(bv16, BVZero(16)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), # (bv16 u< bv16) Example(expr=BVULT(bv16, bv16), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), # (bv16 s< 0_16) Example(expr=BVULT(bv16, BVZero(16)), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), # (bv16 | 0_16) = bv16 Example(expr=Equals(BVOr(bv16, BVZero(16)), bv16), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # (bv16 & 0_16) = 0_16 Example(expr=Equals(BVAnd(bv16, BVZero(16)), BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # 0_16 s< bv16 & ((bv16 s/ -1) s< 0) Example(expr=And(BVSLT(BVZero(16), bv16), BVSLT(BVSDiv(bv16, SBV(-1, 16)), BVZero(16))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), # 0_16 s< bv16 & ((bv16 s% -1) s< 0) Example(expr=And(BVSLT(BVZero(16), bv16), BVSLT(BVSRem(bv16, BVOne(16)), BVZero(16))), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), # bv16 u% 1 = 0_16 Example(expr=Equals(BVURem(bv16, BVOne(16)), BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # bv16 s% 1 = 0_16 Example(expr=Equals(BVSRem(bv16, BVOne(16)), BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # bv16 s% -1 = 0_16 Example(expr=Equals(BVSRem(bv16, BVNeg(BVOne(16))), BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # bv16 a>> 0 = bv16 Example(expr=Equals(BVAShr(bv16, BVZero(16)), bv16), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # 0 s<= bv16 & bv16 a>> 1 = bv16 >> 1 Example(expr=And( BVSLE(BVZero(16), bv16), Equals(BVAShr(bv16, BVOne(16)), BVLShr(bv16, BVOne(16)))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), # # Quantification # # forall y . x -> y Example(expr=ForAll([y], Implies(x, y)), is_valid=False, is_sat=True, logic=pysmt.logics.BOOL), # forall p,q . p + q = 0 Example(expr=ForAll([p, q], Equals(Plus(p, q), Int(0))), is_valid=False, is_sat=False, logic=pysmt.logics.LIA), # forall r,s . ((r > 0) & (s > 0)) -> (r - s < r) Example(expr=ForAll([r, s], Implies(And(GT(r, Real(0)), GT(s, Real(0))), (LT(Minus(r, s), r)))), is_valid=True, is_sat=True, logic=pysmt.logics.LRA), # exists x,y . x -> y Example(expr=Exists([x, y], Implies(x, y)), is_valid=True, is_sat=True, logic=pysmt.logics.BOOL), # exists p,q . p + q = 0 Example(expr=Exists([p, q], Equals(Plus(p, q), Int(0))), is_valid=True, is_sat=True, logic=pysmt.logics.LIA), # exists r . forall s . (r - s > r) Example(expr=Exists([r], ForAll([s], GT(Minus(r, s), r))), is_valid=False, is_sat=False, logic=pysmt.logics.LRA), # forall r . exists s . (r - s > r) Example(expr=ForAll([r], Exists([s], GT(Minus(r, s), r))), is_valid=True, is_sat=True, logic=pysmt.logics.LRA), # x /\ forall r. (r + s = 5) Example(expr=And(x, ForAll([r], Equals(Plus(r, s), Real(5)))), is_valid=False, is_sat=False, logic=pysmt.logics.LRA), # # UFLIRA # # ih(r,q) > p /\ (x -> y) Example(expr=And(GT(Function(ih, (r, q)), p), Implies(x, y)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_UFLIRA), # ( (p - 3) = q ) -> ( ih(r, q + 3) > p \/ ih(r, p) <= p ) Example(expr=Implies( Equals(Minus(p, Int(3)), q), Or(GT(Function(ih, (r, Plus(q, Int(3)))), p), LE(Function(ih, (r, p)), p))), is_valid=True, is_sat=True, logic=pysmt.logics.QF_UFLIRA), # ( (ToReal(p - 3) = r) /\ (ToReal(q) = r) ) -> # ( ( ih(ToReal(p - 3), q + 3) > p ) \/ (ih(r, p) <= p) ) Example(expr=Implies( And(Equals(ToReal(Minus(p, Int(3))), r), Equals(ToReal(q), r)), Or( GT( Function(ih, (ToReal(Minus(p, Int(3))), Plus(q, Int(3)))), p), LE(Function(ih, (r, p)), p))), is_valid=True, is_sat=True, logic=pysmt.logics.QF_UFLIRA), # ! ( (ToReal(p - 3) = r /\ ToReal(q) = r) -> # ( ih(ToReal(p - 3), q + 3) > p \/ # ih(r,p) <= p ) ) Example(expr=Not( Implies( And(Equals(ToReal(Minus(p, Int(3))), r), Equals(ToReal(q), r)), Or( GT( Function( ih, (ToReal(Minus(p, Int(3))), Plus(q, Int(3)))), p), LE(Function(ih, (r, p)), p)))), is_valid=False, is_sat=False, logic=pysmt.logics.QF_UFLIRA), # Test complex names Example(expr=And( Symbol("Did you know that any string works? #yolo"), Symbol("10"), Symbol("|#somesolverskeepthe||"), Symbol(" ")), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BOOL), ] return result
def test_exists(self): f = Exists([self.x], And(self.x, self.y)) for qe in self.qe: g = qelim(f, solver_name=qe) g = g.simplify() self.assertEqual(g, self.y, qe)
def test_quantifier_eliminator(self): f = Exists([self.x], And(self.x, self.y)) g = qelim(f, solver_name="bdd") self.assertEqual(g, self.y)
def test_quantifier_elimination(self): convert = self.bdd_converter.convert f = Exists([self.x], And(self.x, self.y)) bdd_g = convert(f) g = self.bdd_converter.back(bdd_g) self.assertEqual(g, self.y)
def add_trel_new(self): eprint("\t(found #%d actions)" % len(self._actions)) print("\t(found #%d actions)" % len(self._actions)) if len(self._actions) == 0: eprint("\t(error: no action found)") print("\t(error: no action found)") assert (0) if len(self._axiom) != 0: ax = And(self._axiom) axvar = ax.get_free_variables() for v in axvar: self._axiomvars.add(v) tcond = [] enVar = [] enOr = [] noop = self.add_action_noop() for idx, f in enumerate(self._actions): action = f[0] action_name = f[1] action_vars = action.get_free_variables() en = Symbol("en_" + action_name, BOOL) self._action_en2idx[en] = idx enVar.append(en) qvars = None if action.is_exists(): qvars = action.quantifier_vars() action = action.arg(0) action_all = [action] missing_nex = [] for n in self._nex2pre.keys(): if n not in action_vars: if str(n) not in self._definitions: if True or (str(n) != "choosable"): action_all.append(noop[n]) missing_nex.append(n) if len(missing_nex) != 0: print("adding #%d noops to action %s" % (len(missing_nex), f[1])) for n in missing_nex: print("\tnoop(%s)" % n) action = And(action_all) if qvars != None: action = Exists(qvars, action) self._actions[idx][0] = action self._actions[idx][2] = en cond = Implies(en, action) tcond.append(cond) enOr.append(en) cond = Or(enOr) tcond.append(cond) for i in range(len(enVar) - 1): ei = enVar[i] for j in range(i + 1, len(enVar)): assert (i != j) ej = enVar[j] cond = Or(Not(ei), Not(ej)) tcond.append(cond) self._trel = And(tcond)
def test_prenex_negated_exists(self): a, b = (Symbol(x) for x in "ab") f = Implies(Exists([b], Implies(a, b)), b) prenex = prenex_normal_form(f) self.assertTrue(prenex.is_forall()) self.assertValid(Iff(f, prenex), logic=BOOL)
def construct_vaccination_formula_from_graph(spread_graph, limit, target, n_vaccinations): initial_infection_ints = [ Symbol('init_int_' + str(i), INT) for i in spread_graph.nodes ] final_infection_ints = [ Symbol('final_int_' + str(i), INT) for i in spread_graph.nodes ] vaccination_ints = [ Symbol('vax_' + str(i), INT) for i in spread_graph.nodes ] spreading_clauses = [] origin_clauses = [] all_bounds = [] vaccination_clauses = [] # Here, we ensure that, if node i is selected as an initial infector, all of its neighbors are also infected: for starting_node in spread_graph.nodes: initial_infection_bounds = And( LE(initial_infection_ints[int(starting_node)], Int(1)), GE(initial_infection_ints[int(starting_node)], Int(0))) infected_neighbors = And([ Equals(final_infection_ints[int(i)], Int(1)) for i in spread_graph.successors(starting_node) ]) infected_nodes = And( infected_neighbors, Equals(final_infection_ints[int(starting_node)], Int(1))) spreading_forumla = Implies( Equals(initial_infection_ints[int(starting_node)], Int(1)), infected_nodes) spreading_clauses.append(spreading_forumla) all_bounds.append(initial_infection_bounds) # Here, we ensure that, if node i becomes infected, either it was infected by an initial infectors with an edge to node i # of node i itself was an initial infector. for infected_node in spread_graph.nodes: final_infection_bounds = And( LE(final_infection_ints[int(infected_node)], Int(1)), GE(final_infection_ints[int(infected_node)], Int(0))) origin_neighbors = Or([ Equals(initial_infection_ints[int(i)], Int(1)) for i in spread_graph.predecessors(infected_node) ]) origin_nodes = Or( origin_neighbors, Equals(initial_infection_ints[int(infected_node)], Int(1))) origin_formula = Implies( Equals(final_infection_ints[int(infected_node)], Int(1)), origin_nodes) origin_clauses.append(origin_formula) all_bounds.append(final_infection_bounds) initial_infection_limit = LE(Plus(initial_infection_ints), Int(limit)) final_infection_target = LE(Plus(final_infection_ints), Int(target - 1)) # Here, we ensure that, if node i is selected as a vaccine recipiant, it won't be infected: for vaccinatable_node in spread_graph.nodes: vaccination_bounds = And( LE(vaccination_ints[int(vaccinatable_node)], Int(1)), GE(vaccination_ints[int(vaccinatable_node)], Int(0))) vaccine_works_start = Not( And(Equals(vaccination_ints[int(vaccinatable_node)], Int(1)), Equals(initial_infection_ints[int(vaccinatable_node)], Int(1)))) vaccine_works_future = Not( And(Equals(vaccination_ints[int(vaccinatable_node)], Int(1)), Equals(final_infection_ints[int(vaccinatable_node)], Int(1)))) vaccination_clauses.append(vaccine_works_start) vaccination_clauses.append(vaccine_works_future) all_bounds.append(vaccination_bounds) vaccination_limit = LE(Plus(vaccination_ints), Int(n_vaccinations)) infection_formula = And(And(spreading_clauses), And(origin_clauses), And(vaccination_clauses), And(all_bounds), initial_infection_limit, final_infection_target, vaccination_limit) quantified_infection_formula = Exists( vaccination_ints, ForAll(initial_infection_ints, infection_formula)) return quantified_infection_formula, infection_formula, vaccination_ints
def test_nested(self): f = Exists([self.x], ForAll([self.y], Or(self.x, self.y))) g = qelim(f, solver_name="shannon") g = g.simplify() self.assertEqual(g, TRUE())
og_design_scans_results.append("scan_const9") scan_const9 = BV(0, 16) with Solver("cvc4", logic=logicBV, incremental=True) as s: per_step_constraints = [] for step in range(2): print("handling step " + str(step)) for i in range(len(op_design_scans)): globals()[op_design_scans_results[i]] = op_design_scans[i]( globals()[op_design_scans_results[i]]) for i in range(len(og_design_scans)): globals()[og_design_scans_results[i]] = og_design_scans[i]( globals()[og_design_scans_results[i]]) per_step_constraints.append( Equals( globals()[op_design_scans_results[len(op_design_scans_results) - 1]], globals()[og_design_scans_results[len(og_design_scans_results) - 1]])) final_constraint = per_step_constraints[0] for c in per_step_constraints[1:]: final_constraint = And(final_constraint, c) s.add_assertion( ForAll(op_design_free_vars.values(), Exists(og_design_free_vars.values(), final_constraint))) start = time.time() res = s.solve() assert res end = time.time() print("time: " + str(end - start))
def test_nested(self): f = Exists([self.x], ForAll([self.y], Or(self.x, self.y))) for qe in self.qe: g = qelim(f, solver_name=qe) g = g.simplify() self.assertEqual(g, TRUE(), qe)
def test_prenex_simple_exists(self): a, b = (Symbol(x) for x in "ab") f = And(b, Exists([b], Implies(a, b))) prenex = prenex_normal_form(f) self.assertTrue(prenex.is_exists()) self.assertValid(Iff(f, prenex), logic=BOOL)
def process_prospectives(self): print("\nProcessing prospectives") for nv, (action, cond) in self.nexinfer.items(): print("\tprocessing %s in %s" % (nv, action)) action_suffix = self.action2suffix[action] action_nvars = And(action_suffix).get_free_variables() action_nvars = action_nvars.intersection( self.system._nex2pre.keys()) action_pvars = set() for n in action_nvars: action_pvars.add(self.system._nex2pre[n]) action_prefix = self.action2prefix[action] concs_global = [] concs = [] for c in action_prefix: cvars = c.get_free_variables() common = cvars.intersection(action_pvars) if len(common) == 0: statevars = cvars.intersection(self.system._states) statevars = statevars.difference(self.system._globals) if len(statevars) == 0: concs_global.append(c) else: concs.append(c) if (len(concs) + len(concs_global)) == 0: print("\t\tskipping %s since no static precondition found" % nv) continue qvars = set() if cond.is_forall(): cqvars = cond.quantifier_vars() for v in cqvars: qvars.add(v) cond = cond.arg(0) if not (cond.is_iff() or cond.is_equals()): continue lhs = cond.arg(0) rhs = cond.arg(1) lvars = lhs.get_free_variables() rvars = rhs.get_free_variables() if nv in rvars: lhs, rhs = rhs, lhs lvars, rvars = rvars, lvars if nv in rvars: continue ldvars = lvars.difference(qvars) if len(ldvars) != 1: continue ldvar = next(iter(ldvars)) if nv != ldvar: continue if len(qvars) != 0: if not lhs.is_function_application(): continue nsym = lhs.function_name() if nv != nsym: continue if len(self.action2def) != 0: rhs = rhs.substitute(self.action2def[action]) rconds = [] rval = self.process_assign(rhs, rconds) premise = [] qsubs = {} for c in rconds: if c.is_iff() or c.is_equals(): lc = c.arg(0) rc = c.arg(1) if rc.is_symbol(): if rc in qvars: lc, rc = rc, lc if lc.is_symbol(): if lc in qvars: if rc in self.system._others: qsubs[rc] = lc continue premise.append(c) eq = EqualsOrIff(lhs, rval) premise.insert(0, eq) prem = And(premise) qsubs[nv] = self.system._nex2pre[nv] prem = prem.substitute(qsubs) ivars = prem.get_free_variables() ivars = ivars.intersection(self.system._others) if len(ivars) != 0: for v in ivars: vname = "Q" + str(v) vname = vname.replace(":", "") vnew = Symbol(vname, v.symbol_type()) qsubs[v] = vnew qvars.add(vnew) prem = prem.substitute(qsubs) if len(concs_global) != 0: concs.append(None) for conc in concs: if conc == None: conc = And(concs_global) else: if len(concs_global) != 0: conc = And(conc, And(concs_global)) conc = conc.substitute(qsubs) ivars = conc.get_free_variables() ivars = ivars.intersection(self.system._others) evars = [] if len(ivars) != 0: esubs = {} for v in ivars: vname = "Q" + str(v) vname = vname.replace(":", "") vnew = Symbol(vname, v.symbol_type()) esubs[v] = vnew evars.append(vnew) conc = conc.substitute(esubs) # conc = Exists(evars, conc) # evars = [] # print("evars ", evars) # print("conc ", conc) inference = Implies(prem, conc) qvars2 = [] # if len(qvars) != 0: # for u in qvars: # ut = u.symbol_type() # for e in evars: # et = e.symbol_type() # if not self.strat.allowed_arc(ut, et): # qvars2.append(u) uqvars = qvars.difference(qvars2) # for u in qvars2: # if u in qvars: # qvars.remove(u) # print("qvars2 ", qvars2) # print("uqvars ", uqvars) if len(qvars2) != 0: inference = ForAll(qvars2, inference) if len(evars) != 0: inference = Exists(evars, inference) if len(uqvars) != 0: inference = ForAll(uqvars, inference) iname = "syntax" + str(len(self.system._infers) + 1) self.system._infers[inference] = iname print("\t\tinferred %s: %s" % (iname, inference))
def get_full_example_formulae(environment=None): """Return a list of Examples using the given environment.""" if environment is None: environment = get_env() with environment: x = Symbol("x", BOOL) y = Symbol("y", BOOL) p = Symbol("p", INT) q = Symbol("q", INT) r = Symbol("r", REAL) s = Symbol("s", REAL) aii = Symbol("aii", ARRAY_INT_INT) ari = Symbol("ari", ArrayType(REAL, INT)) arb = Symbol("arb", ArrayType(REAL, BV8)) abb = Symbol("abb", ArrayType(BV8, BV8)) nested_a = Symbol("a_arb_aii", ArrayType(ArrayType(REAL, BV8), ARRAY_INT_INT)) rf = Symbol("rf", FunctionType(REAL, [REAL, REAL])) rg = Symbol("rg", FunctionType(REAL, [REAL])) ih = Symbol("ih", FunctionType(INT, [REAL, INT])) ig = Symbol("ig", FunctionType(INT, [INT])) bf = Symbol("bf", FunctionType(BOOL, [BOOL])) bg = Symbol("bg", FunctionType(BOOL, [BOOL])) bv8 = Symbol("bv1", BV8) bv16 = Symbol("bv2", BV16) result = [ # Formula, is_valid, is_sat, is_qf Example(hr="(x & y)", expr=And(x, y), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BOOL), Example(hr="(x <-> y)", expr=Iff(x, y), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BOOL), Example(hr="((x | y) & (! (x | y)))", expr=And(Or(x, y), Not(Or(x, y))), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BOOL), Example(hr="(x & (! y))", expr=And(x, Not(y)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BOOL), Example(hr="(False -> True)", expr=Implies(FALSE(), TRUE()), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BOOL), # # LIA # Example(hr="((q < p) & (x -> y))", expr=And(GT(p, q), Implies(x, y)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_IDL), Example(hr="(((p + q) = 5) & (q < p))", expr=And(Equals(Plus(p, q), Int(5)), GT(p, q)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LIA), Example(hr="((q <= p) | (p <= q))", expr=Or(GE(p, q), LE(p, q)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_IDL), Example(hr="(! (p < (q * 2)))", expr=Not(LT(p, Times(q, Int(2)))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LIA), Example(hr="(p < (p - (5 - 2)))", expr=GT(Minus(p, Minus(Int(5), Int(2))), p), is_valid=False, is_sat=False, logic=pysmt.logics.QF_IDL), Example(hr="((x ? 7 : ((p + -1) * 3)) = q)", expr=Equals( Ite(x, Int(7), Times(Plus(p, Int(-1)), Int(3))), q), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LIA), Example(hr="(p < (q + 1))", expr=LT(p, Plus(q, Int(1))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LIA), # # LRA # Example(hr="((s < r) & (x -> y))", expr=And(GT(r, s), Implies(x, y)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_RDL), Example(hr="(((r + s) = 28/5) & (s < r))", expr=And(Equals(Plus(r, s), Real(Fraction("5.6"))), GT(r, s)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LRA), Example(hr="((s <= r) | (r <= s))", expr=Or(GE(r, s), LE(r, s)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_RDL), Example(hr="(! ((r * 2.0) < (s * 2.0)))", expr=Not(LT(Div(r, Real((1, 2))), Times(s, Real(2)))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LRA), Example(hr="(! (r < (r - (5.0 - 2.0))))", expr=Not(GT(Minus(r, Minus(Real(5), Real(2))), r)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_RDL), Example(hr="((x ? 7.0 : ((s + -1.0) * 3.0)) = r)", expr=Equals( Ite(x, Real(7), Times(Plus(s, Real(-1)), Real(3))), r), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LRA), # # EUF # Example(hr="(bf(x) <-> bg(x))", expr=Iff(Function(bf, (x, )), Function(bg, (x, ))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_UF), Example(hr="(rf(5.0, rg(r)) = 0.0)", expr=Equals(Function(rf, (Real(5), Function(rg, (r, )))), Real(0)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_UFLRA), Example(hr="((rg(r) = (5.0 + 2.0)) <-> (rg(r) = 7.0))", expr=Iff(Equals(Function(rg, [r]), Plus(Real(5), Real(2))), Equals(Function(rg, [r]), Real(7))), is_valid=True, is_sat=True, logic=pysmt.logics.QF_UFLRA), Example( hr="((r = (s + 1.0)) & (rg(s) = 5.0) & (rg((r - 1.0)) = 7.0))", expr=And([ Equals(r, Plus(s, Real(1))), Equals(Function(rg, [s]), Real(5)), Equals(Function(rg, [Minus(r, Real(1))]), Real(7)) ]), is_valid=False, is_sat=False, logic=pysmt.logics.QF_UFLRA), # # BV # Example(hr="((1_32 & 0_32) = 0_32)", expr=Equals(BVAnd(BVOne(32), BVZero(32)), BVZero(32)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((! 2_3) = 5_3)", expr=Equals(BVNot(BV("010")), BV("101")), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((7_3 xor 0_3) = 0_3)", expr=Equals(BVXor(BV("111"), BV("000")), BV("000")), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), Example(hr="((bv1::bv1) u< 0_16)", expr=BVULT(BVConcat(bv8, bv8), BVZero(16)), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), Example(hr="(1_32[0:7] = 1_8)", expr=Equals(BVExtract(BVOne(32), end=7), BVOne(8)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="(0_8 u< (((bv1 + 1_8) * 5_8) u/ 5_8))", expr=BVUGT( BVUDiv(BVMul(BVAdd(bv8, BVOne(8)), BV(5, width=8)), BV(5, width=8)), BVZero(8)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="(0_16 u<= bv2)", expr=BVUGE(bv16, BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="(0_16 s<= bv2)", expr=BVSGE(bv16, BVZero(16)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), Example( hr="((0_32 u< (5_32 u% 2_32)) & ((5_32 u% 2_32) u<= 1_32))", expr=And( BVUGT(BVURem(BV(5, width=32), BV(2, width=32)), BVZero(32)), BVULE(BVURem(BV(5, width=32), BV(2, width=32)), BVOne(32))), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((((1_32 + (- 1_32)) << 1_32) >> 1_32) = 1_32)", expr=Equals( BVLShr(BVLShl(BVAdd(BVOne(32), BVNeg(BVOne(32))), 1), 1), BVOne(32)), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), Example(hr="((1_32 - 1_32) = 0_32)", expr=Equals(BVSub(BVOne(32), BVOne(32)), BVZero(32)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # Rotations Example(hr="(((1_32 ROL 1) ROR 1) = 1_32)", expr=Equals(BVRor(BVRol(BVOne(32), 1), 1), BVOne(32)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), # Extensions Example(hr="((0_5 ZEXT 11) = (0_1 SEXT 15))", expr=Equals(BVZExt(BVZero(5), 11), BVSExt(BVZero(1), 15)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((bv2 - bv2) = 0_16)", expr=Equals(BVSub(bv16, bv16), BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((bv2 - bv2)[0:7] = bv1)", expr=Equals(BVExtract(BVSub(bv16, bv16), 0, 7), bv8), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((bv2[0:7] bvcomp bv1) = 1_1)", expr=Equals(BVComp(BVExtract(bv16, 0, 7), bv8), BVOne(1)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((bv2 bvcomp bv2) = 0_1)", expr=Equals(BVComp(bv16, bv16), BVZero(1)), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), Example(hr="(bv2 s< bv2)", expr=BVSLT(bv16, bv16), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), Example(hr="(bv2 s< 0_16)", expr=BVSLT(bv16, BVZero(16)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((bv2 s< 0_16) | (0_16 s<= bv2))", expr=Or(BVSGT(BVZero(16), bv16), BVSGE(bv16, BVZero(16))), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="(bv2 u< bv2)", expr=BVULT(bv16, bv16), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), Example(hr="(bv2 u< 0_16)", expr=BVULT(bv16, BVZero(16)), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), Example(hr="((bv2 | 0_16) = bv2)", expr=Equals(BVOr(bv16, BVZero(16)), bv16), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((bv2 & 0_16) = 0_16)", expr=Equals(BVAnd(bv16, BVZero(16)), BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((0_16 s< bv2) & ((bv2 s/ 65535_16) s< 0_16))", expr=And(BVSLT(BVZero(16), bv16), BVSLT(BVSDiv(bv16, SBV(-1, 16)), BVZero(16))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((0_16 s< bv2) & ((bv2 s% 1_16) s< 0_16))", expr=And(BVSLT(BVZero(16), bv16), BVSLT(BVSRem(bv16, BVOne(16)), BVZero(16))), is_valid=False, is_sat=False, logic=pysmt.logics.QF_BV), Example(hr="((bv2 u% 1_16) = 0_16)", expr=Equals(BVURem(bv16, BVOne(16)), BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((bv2 s% 1_16) = 0_16)", expr=Equals(BVSRem(bv16, BVOne(16)), BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((bv2 s% (- 1_16)) = 0_16)", expr=Equals(BVSRem(bv16, BVNeg(BVOne(16))), BVZero(16)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((bv2 a>> 0_16) = bv2)", expr=Equals(BVAShr(bv16, BVZero(16)), bv16), is_valid=True, is_sat=True, logic=pysmt.logics.QF_BV), Example(hr="((0_16 s<= bv2) & ((bv2 a>> 1_16) = (bv2 >> 1_16)))", expr=And( BVSLE(BVZero(16), bv16), Equals(BVAShr(bv16, BVOne(16)), BVLShr(bv16, BVOne(16)))), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BV), # # Quantification # Example(hr="(forall y . (x -> y))", expr=ForAll([y], Implies(x, y)), is_valid=False, is_sat=True, logic=pysmt.logics.BOOL), Example(hr="(forall p, q . ((p + q) = 0))", expr=ForAll([p, q], Equals(Plus(p, q), Int(0))), is_valid=False, is_sat=False, logic=pysmt.logics.LIA), Example( hr="(forall r, s . (((0.0 < r) & (0.0 < s)) -> ((r - s) < r)))", expr=ForAll([r, s], Implies(And(GT(r, Real(0)), GT(s, Real(0))), (LT(Minus(r, s), r)))), is_valid=True, is_sat=True, logic=pysmt.logics.LRA), Example(hr="(exists x, y . (x -> y))", expr=Exists([x, y], Implies(x, y)), is_valid=True, is_sat=True, logic=pysmt.logics.BOOL), Example(hr="(exists p, q . ((p + q) = 0))", expr=Exists([p, q], Equals(Plus(p, q), Int(0))), is_valid=True, is_sat=True, logic=pysmt.logics.LIA), Example(hr="(exists r . (forall s . (r < (r - s))))", expr=Exists([r], ForAll([s], GT(Minus(r, s), r))), is_valid=False, is_sat=False, logic=pysmt.logics.LRA), Example(hr="(forall r . (exists s . (r < (r - s))))", expr=ForAll([r], Exists([s], GT(Minus(r, s), r))), is_valid=True, is_sat=True, logic=pysmt.logics.LRA), Example(hr="(x & (forall r . ((r + s) = 5.0)))", expr=And(x, ForAll([r], Equals(Plus(r, s), Real(5)))), is_valid=False, is_sat=False, logic=pysmt.logics.LRA), Example(hr="(exists x . ((x <-> (5.0 < s)) & (s < 3.0)))", expr=Exists([x], (And(Iff(x, GT(s, Real(5))), LT(s, Real(3))))), is_valid=False, is_sat=True, logic=pysmt.logics.LRA), # # UFLIRA # Example(hr="((p < ih(r, q)) & (x -> y))", expr=And(GT(Function(ih, (r, q)), p), Implies(x, y)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_UFLIRA), Example( hr= "(((p - 3) = q) -> ((p < ih(r, (q + 3))) | (ih(r, p) <= p)))", expr=Implies( Equals(Minus(p, Int(3)), q), Or(GT(Function(ih, (r, Plus(q, Int(3)))), p), LE(Function(ih, (r, p)), p))), is_valid=True, is_sat=True, logic=pysmt.logics.QF_UFLIRA), Example( hr= "(((ToReal((p - 3)) = r) & (ToReal(q) = r)) -> ((p < ih(ToReal((p - 3)), (q + 3))) | (ih(r, p) <= p)))", expr=Implies( And(Equals(ToReal(Minus(p, Int(3))), r), Equals(ToReal(q), r)), Or( GT( Function( ih, (ToReal(Minus(p, Int(3))), Plus(q, Int(3)))), p), LE(Function(ih, (r, p)), p))), is_valid=True, is_sat=True, logic=pysmt.logics.QF_UFLIRA), Example( hr= "(! (((ToReal((p - 3)) = r) & (ToReal(q) = r)) -> ((p < ih(ToReal((p - 3)), (q + 3))) | (ih(r, p) <= p))))", expr=Not( Implies( And(Equals(ToReal(Minus(p, Int(3))), r), Equals(ToReal(q), r)), Or( GT( Function(ih, (ToReal(Minus( p, Int(3))), Plus(q, Int(3)))), p), LE(Function(ih, (r, p)), p)))), is_valid=False, is_sat=False, logic=pysmt.logics.QF_UFLIRA), Example( hr= """("Did you know that any string works? #yolo" & "10" & "|#somesolverskeepthe||" & " ")""", expr=And(Symbol("Did you know that any string works? #yolo"), Symbol("10"), Symbol("|#somesolverskeepthe||"), Symbol(" ")), is_valid=False, is_sat=True, logic=pysmt.logics.QF_BOOL), # # Arrays # Example(hr="((q = 0) -> (aii[0 := 0] = aii[0 := q]))", expr=Implies( Equals(q, Int(0)), Equals(Store(aii, Int(0), Int(0)), Store(aii, Int(0), q))), is_valid=True, is_sat=True, logic=pysmt.logics.QF_ALIA), Example(hr="(aii[0 := 0][0] = 0)", expr=Equals(Select(Store(aii, Int(0), Int(0)), Int(0)), Int(0)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_ALIA), Example(hr="((Array{Int, Int}(0)[1 := 1] = aii) & (aii[1] = 0))", expr=And(Equals(Array(INT, Int(0), {Int(1): Int(1)}), aii), Equals(Select(aii, Int(1)), Int(0))), is_valid=False, is_sat=False, logic=pysmt.logics.get_logic_by_name("QF_ALIA*")), Example(hr="((Array{Int, Int}(0)[1 := 3] = aii) & (aii[1] = 3))", expr=And(Equals(Array(INT, Int(0), {Int(1): Int(3)}), aii), Equals(Select(aii, Int(1)), Int(3))), is_valid=False, is_sat=True, logic=pysmt.logics.get_logic_by_name("QF_ALIA*")), Example(hr="((Array{Real, Int}(10) = ari) & (ari[6/5] = 0))", expr=And(Equals(Array(REAL, Int(10)), ari), Equals(Select(ari, Real((6, 5))), Int(0))), is_valid=False, is_sat=False, logic=pysmt.logics.get_logic_by_name("QF_AUFBVLIRA*")), Example( hr= "((Array{Real, Int}(0)[1.0 := 10][2.0 := 20][3.0 := 30][4.0 := 40] = ari) & (! ((ari[0.0] = 0) & (ari[1.0] = 10) & (ari[2.0] = 20) & (ari[3.0] = 30) & (ari[4.0] = 40))))", expr=And( Equals( Array( REAL, Int(0), { Real(1): Int(10), Real(2): Int(20), Real(3): Int(30), Real(4): Int(40) }), ari), Not( And(Equals(Select(ari, Real(0)), Int(0)), Equals(Select(ari, Real(1)), Int(10)), Equals(Select(ari, Real(2)), Int(20)), Equals(Select(ari, Real(3)), Int(30)), Equals(Select(ari, Real(4)), Int(40))))), is_valid=False, is_sat=False, logic=pysmt.logics.get_logic_by_name("QF_AUFBVLIRA*")), Example( hr= "((Array{Real, Int}(0)[1.0 := 10][2.0 := 20][3.0 := 30][4.0 := 40][5.0 := 50] = ari) & (! ((ari[0.0] = 0) & (ari[1.0] = 10) & (ari[2.0] = 20) & (ari[3.0] = 30) & (ari[4.0] = 40) & (ari[5.0] = 50))))", expr=And( Equals( Array( REAL, Int(0), { Real(1): Int(10), Real(2): Int(20), Real(3): Int(30), Real(4): Int(40), Real(5): Int(50) }), ari), Not( And(Equals(Select(ari, Real(0)), Int(0)), Equals(Select(ari, Real(1)), Int(10)), Equals(Select(ari, Real(2)), Int(20)), Equals(Select(ari, Real(3)), Int(30)), Equals(Select(ari, Real(4)), Int(40)), Equals(Select(ari, Real(5)), Int(50))))), is_valid=False, is_sat=False, logic=pysmt.logics.get_logic_by_name("QF_AUFBVLIRA*")), Example( hr= "((a_arb_aii = Array{Array{Real, BV{8}}, Array{Int, Int}}(Array{Int, Int}(7))) -> (a_arb_aii[arb][42] = 7))", expr=Implies( Equals(nested_a, Array(ArrayType(REAL, BV8), Array(INT, Int(7)))), Equals(Select(Select(nested_a, arb), Int(42)), Int(7))), is_valid=True, is_sat=True, logic=pysmt.logics.get_logic_by_name("QF_AUFBVLIRA*")), Example(hr="(abb[bv1 := y_][bv1 := z_] = abb[bv1 := z_])", expr=Equals( Store(Store(abb, bv8, Symbol("y_", BV8)), bv8, Symbol("z_", BV8)), Store(abb, bv8, Symbol("z_", BV8))), is_valid=True, is_sat=True, logic=pysmt.logics.QF_ABV), Example(hr="((r / s) = (r * s))", expr=Equals(Div(r, s), Times(r, s)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_NRA), Example(hr="(2.0 = (r * r))", expr=Equals(Real(2), Times(r, r)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_NRA), Example(hr="((p ^ 2) = 0)", expr=Equals(Pow(p, Int(2)), Int(0)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_NIA), Example(hr="((r ^ 2.0) = 0.0)", expr=Equals(Pow(r, Real(2)), Real(0)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_NRA), Example(hr="((r * r * r) = 25.0)", expr=Equals(Times(r, r, r), Real(25)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_NRA), Example(hr="((5.0 * r * 5.0) = 25.0)", expr=Equals(Times(Real(5), r, Real(5)), Real(25)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LRA), Example(hr="((p * p * p) = 25)", expr=Equals(Times(p, p, p), Int(25)), is_valid=False, is_sat=False, logic=pysmt.logics.QF_NIA), Example(hr="((5 * p * 5) = 25)", expr=Equals(Times(Int(5), p, Int(5)), Int(25)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LIA), Example(hr="(((1 - 1) * p * 1) = 0)", expr=Equals(Times(Minus(Int(1), Int(1)), p, Int(1)), Int(0)), is_valid=True, is_sat=True, logic=pysmt.logics.QF_LIA), # Huge Fractions: Example( hr= "((r * 1606938044258990275541962092341162602522202993782792835301376/7) = -20480000000000000000000000.0)", expr=Equals(Times(r, Real(Fraction(2**200, 7))), Real(-200**11)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_LRA), Example(hr="(((r + 5.0 + s) * (s + 2.0 + r)) = 0.0)", expr=Equals( Times(Plus(r, Real(5), s), Plus(s, Real(2), r)), Real(0)), is_valid=False, is_sat=True, logic=pysmt.logics.QF_NRA), Example( hr= "(((p + 5 + q) * (p - (q - 5))) = ((p * p) + (10 * p) + 25 + (-1 * q * q)))", expr=Equals( Times(Plus(p, Int(5), q), Minus(p, Minus(q, Int(5)))), Plus(Times(p, p), Times(Int(10), p), Int(25), Times(Int(-1), q, q))), is_valid=True, is_sat=True, logic=pysmt.logics.QF_NIA), ] return result
def add_trel(self): eprint("\t(found #%d actions)" % len(self._actions)) print("\t(found #%d actions)" % len(self._actions)) if len(self._actions) == 0: eprint("\t(error: no action found)") print("\t(error: no action found)") assert (0) if len(self._axiom) != 0: ax = And(self._axiom) axvar = ax.get_free_variables() for v in axvar: self._axiomvars.add(v) noop_name, noop = self.get_action_noop() noop_all = And([i for i in noop.values()]) self._trel = noop_all self._input_action = Symbol(self.input_action_name(), INT) self.add_var(self._input_action) # axiom_vars = self.get_axiom_vars() # action_en = [] # self.add_action(noop_all, noop_name) for idx, f in enumerate(self._actions): action = f[0] action_name = f[1] # action_vars = axiom_vars.copy() # for v in action.get_free_variables(): # action_vars.add(v) action_vars = action.get_free_variables() qvars = None if action.is_exists(): qvars = action.quantifier_vars() action = action.arg(0) action_all = [action] missing_nex = [] for n in self._nex2pre.keys(): if n not in action_vars: if str(n) not in self._definitions: if True or (str(n) != "choosable"): action_all.append(noop[n]) missing_nex.append(n) if len(missing_nex) != 0: print("adding #%d noops to action %s" % (len(missing_nex), f[1])) for n in missing_nex: print("\tnoop(%s)" % n) action = And(action_all) if qvars != None: action = Exists(qvars, action) self._actions[idx][0] = action # self._trel = Or(action, self._trel) action_symbol = Int(idx) self._actions[idx][-1] = action_symbol cond = EqualsOrIff(self._input_action, action_symbol) self._trel = Ite(cond, action, self._trel) # action_symbol = Symbol("en_"+action_name) # action_en.append(action_symbol) # self._trel = Ite(action_symbol, action, self._trel) # action_cond = [] # action_cond.append(self._trel) # for i in range(len(action_en)-1): # fi = Not(action_en[i]) # for j in range(i+1, len(action_en)): # fj = Not(action_en[j]) # cond = Or(fi, fj) # action_cond.insert(0, cond) # self._trel = And(action_cond) # if len(self._axiom) != 0: # q = [] # q.extend(self._axiom) # # self.add_init(And(q)) # q.append(self._trel) # self._trel = And(q) self.add_action(noop_all, noop_name)