def testParseSet(self): ctxt = { "x": Ta, "A": set.setT(Ta), "B": set.setT(Ta), } test_data = [ ("({}::'a set)", "(∅::'a set)", "'a set"), ("x MEM A", "x ∈ A", "bool"), ("A SUB B", "A ⊆ B", "bool"), ("A INTER B", "A ∩ B", "'a set"), ("A UNION B", "A ∪ B", "'a set"), ] for s1, s2, Ts in test_data: T = parser.parse_type(thy, Ts) t1 = parser.parse_term(thy, ctxt, s1) self.assertIsInstance(t1, Term) self.assertEqual(t1.checked_get_type(), T) self.assertEqual(print_term(thy, t1), s1) t2 = parser.parse_term(thy, ctxt, s2) self.assertIsInstance(t2, Term) self.assertEqual(t2.checked_get_type(), T) self.assertEqual(print_term(thy, t2, unicode=True), s2)
def testCombineFractionConv(self): test_data = [ ('1 / (x + 1) + 1 / (x - 1)', 'x Mem real_open_interval (-1/2) (1/2)', '2 * x / ((x + 1) * (x - 1))'), ("2 + 1 / (x + 1)", 'x Mem real_open_interval 0 1', '(3 + 2 * x) / (x + 1)'), ("(x + 1) ^ -(1::real)", 'x Mem real_open_interval 0 1', '1 / (x + 1)'), ("2 * (x * (x + 1) ^ -(1::real))", 'x Mem real_open_interval 0 1', '2 * x / (x + 1)'), ("2 - 1 / (x + 1)", 'x Mem real_open_interval 0 1', '(1 + 2 * x) / (x + 1)'), ("x ^ (1/2)", "x Mem real_open_interval 0 1", "x ^ (1/2) / 1"), ("x ^ -(1/2)", "x Mem real_open_interval 0 1", "1 / (x ^ (1/2))"), ("x ^ -(2::real)", "x Mem real_open_interval 0 1", "1 / (x ^ (2::nat))"), ] vars = {'x': 'real'} context.set_context('interval_arith', vars=vars) for s, cond, res in test_data: s = parser.parse_term(s) res = parser.parse_term(res) cond_t = parser.parse_term(cond) cv = proof.combine_fraction([ProofTerm.assume(cond_t)]) test_conv(self, 'interval_arith', cv, vars=vars, t=s, t_res=res, assms=[cond])
def testRewriteIntWithAsserstion(self): test_data = [( "¬(¬(¬(¬P8 ∨ ¬(F20 + -1 * F18 ≤ 0)) ∨ ¬(P8 ∨ ¬(F4 + -1 * F2 ≤ 0))) ∨ ¬(¬(P8 ∨ ¬(F6 + -1 * F4 ≤ 0)) ∨ \ ¬(¬P8 ∨ ¬(F22 + -1 * F20 ≤ 0))) ∨ ¬(¬(P8 ∨ ¬(F2 + -1 * F0 ≤ 0)) ∨ ¬(¬P8 ∨ ¬(F18 + -1 * F16 ≤ 0))))\ ⟷ ¬(¬(F2 + -1 * F0 ≤ 0) ∨ ¬(F6 + -1 * F4 ≤ 0) ∨ ¬(F4 + -1 * F2 ≤ 0))", ("P8", "P8 ⟷ false"))] context.set_context('smt', vars={ "P8": "bool", "F20": "int", "F18": "int", "P8": "bool", "F4": "int", "F2": "int", "F6": "int", "F22": "int", "F20": "int", "F2": "int", "F16": "int", "F0": "int" }) for tm, ast in test_data: tm = parse_term(tm) var, prop = [parse_term(i) for i in ast] proofrec.atoms.clear() proofrec.atoms[var] = ProofTerm.assume(prop) proofrec._rewrite(tm)
def testNormFull(self): test_data = [ ("(x * y) * (z * y)", "x * y * y * z"), ("(x + y) + (z + y)", "x + y * 2 + z"), ("(x + y) * (y + z)", "x * y + x * z + y * y + y * z"), ("(x + y) * (x + y)", "x * x + x * y * 2 + y * y"), ("0 + 1 * x + 0 * y", "x"), ("x + 2 + y + 3", "x + y + 5"), ("3 * x * 5 * x", "x * x * 15"), ("(x + 2 * y) * (y + 2 * x)", "x * x * 2 + x * y * 5 + y * y * 2"), ("3 + 5 * 2", "13"), ("x + Suc y", "x + y + 1"), ("Suc (x + Suc y)", "x + y + 2"), ("x * Suc y", "x + x * y"), ("x * 1 * 1 * 1", "x"), ] cv = nat.norm_full() ctxt = {"x": nat.natT, "y": nat.natT, "z": nat.natT} for expr, res in test_data: t = parser.parse_term(thy, ctxt, expr) t2 = parser.parse_term(thy, ctxt, res) res_th = Thm.mk_equals(t, t2) prf = cv.get_proof_term(thy, t).export() self.assertEqual(thy.check_proof(prf), res_th)
def testSymPySolve2(self): test_data = [ # Interval condition ("1 - x ^ (2::nat) >= 0", "x Mem real_closed_interval 0 1", True), ("1 - x ^ (2::nat) >= 0", "x Mem real_closed_interval 0 (sqrt 2)", False), ("1 - x ^ (2::nat) > 0", "x Mem real_open_interval 0 1", True), ("2 - x ^ (2::nat) >= 0", "x Mem real_closed_interval 0 (sqrt 2)", True), ("2 - x ^ (2::nat) >= 0", "x Mem real_closed_interval 0 2", False), ("sqrt 2 * cos x >= 0", "x Mem real_closed_interval 0 (pi / 2)", True), ("sqrt 2 * cos x >= 0", "x Mem real_closed_interval 0 pi", False), ("log x >= 0", "x Mem real_closed_interval 1 (exp 1)", True), ("log x <= 0", "x Mem real_closed_interval (exp (-1)) 1", True), ("log x >= 0", "x Mem real_closed_interval (exp (-1)) (exp 1)", False), ("~(sin x = 0)", "x Mem real_closed_interval 1 2", True), ("~(sin x = 0)", "x Mem real_closed_interval (-1) 1", False), ("~(sin x = 0)", "x Mem real_closed_interval 0 1", False), ("~(x ^ (2::nat) = 0)", "x Mem real_closed_interval (-1) 1", False), ("~(x ^ (2::nat) + 1 = 0)", "x Mem real_closed_interval (-1) 1", True), ] context.set_context('transcendentals', vars={'x': 'real'}) for goal, cond, res in test_data: goal = parser.parse_term(goal) cond = parser.parse_term(cond) self.assertEqual(sympywrapper.solve_with_interval(goal, cond), res)
def testVCGIf(self): context.set_context(None, vars={'A': 'nat'}) c = parser.parse_term("Cond (%s. s (0::nat) = A) Skip (Assign 0 (%s. A))") P = parser.parse_term("%s::nat=>nat. true") Q = parser.parse_term("%s. s (0::nat) = A") goal = Valid(P, c, Q) prf = imp.vcg_solve(goal).export() self.assertEqual(theory.check_proof(prf), Thm([], goal))
def testVCGWhile(self): context.set_context(None, vars={"A": 'nat', "B": 'nat'}) c = parser.parse_term( "While (%s. ~s (0::nat) = A) (%s. s 1 = s 0 * B) (Seq (Assign 1 (%s. s 1 + B)) (Assign 0 (%s. s 0 + 1)))") P = parser.parse_term("%s. s (0::nat) = (0::nat) & s 1 = 0") Q = parser.parse_term("%s. s (1::nat) = A * B") goal = Valid(P, c, Q) prf = imp.vcg_solve(goal).export() self.assertEqual(theory.check_proof(prf), Thm([], goal))
def testVCGWhile(self): A = Var("A", natT) B = Var("B", natT) ctxt = {"A": natT, "B": natT} c = parser.parse_term(thy, ctxt, \ "While (%s. ~s 0 = A) (%s. s 1 = s 0 * B) (Seq (Assign 1 (%s. s 1 + B)) (Assign 0 (%s. s 0 + 1)))") P = parser.parse_term(thy, ctxt, "%s. s 0 = 0 & s 1 = 0") Q = parser.parse_term(thy, ctxt, "%s. s 1 = A * B") goal = Valid(P, c, Q) prf = hoare.vcg_solve(thy, goal).export() self.assertEqual(thy.check_proof(prf), Thm([], goal))
def testSwapDisjRConv(self): test_data = [ ('A | B', 'B | A'), ('A | B | C', 'B | A | C'), ] vars = {'A': 'bool', 'B': 'bool', 'C': 'bool'} context.set_context('logic', vars=vars) for t, res in test_data: t, res = parser.parse_term(t), parser.parse_term(res) test_conv(self, 'logic', proplogic.swap_disj_r(), vars=vars, t=t, t_res=res)
def testNormConjConjunction(self): test_data = [ ('(A & B) & (C & D)', 'A & B & C & D'), ('(C & D) & (A & B)', 'A & B & C & D') ] vars = {'A': 'bool', 'B': 'bool', 'C': 'bool'} context.set_context('logic', vars=vars) for t, res in test_data: t, res = parser.parse_term(t), parser.parse_term(res) test_conv(self, 'logic', proplogic.norm_conj_conjunction(), vars=vars, t=t, t_res=res)
def testNormDisjDisjunction(self): test_data = [ ('(A | B) | (C | D)', 'A | B | C | D'), ('(C | D) | (A | B)', 'A | B | C | D') ] vars = {'A': 'bool', 'B': 'bool', 'C': 'bool'} context.set_context('logic', vars=vars) for t, res in test_data: t, res = parser.parse_term(t), parser.parse_term(res) test_conv(self, 'logic', proplogic.norm_disj_disjunction(), vars=vars, t=t, t_res=res)
def testThLemmaIntMulti(self): test_data = [(('¬(x ≤ 3)', 'x ≤ 4'), '0 = -4 + x'), (('x ≥ 0', 'x ≤ 0'), '1 = 1 + x'), (('x ≥ 0', '¬(x ≥ 1)'), '1 = 1 + x')] context.set_context('smt', vars={'x': 'int'}) for assms, res in test_data: assms = [ProofTerm.assume(parse_term(assm)) for assm in assms] res = parse_term(res) self.assertEqual(proofrec.th_lemma([*assms, res]).prop, res)
def testNNF(self): test_data = [ # Test case from Section 3.5 of HPLAR. ("(!x. P x) --> ((?y. Q y) <--> ?z. P z & Q z)", "(?x. ~P x) | (?y. Q y) & (?z. P z & Q z) | (!y. ~Q y) & (!z. ~P z | ~Q z)") ] context.set_context('logic', vars={'P': "'a => bool", 'Q': "'a => bool"}) for fm, res in test_data: fm = parser.parse_term(fm) res = parser.parse_term(res) self.assertEqual(fologic.nnf(fm), res)
def testSimplify(self): test_data = [ # Three test cases Section 3.5 of HPLAR. ("true --> (p <--> (p <--> false))", "p <--> ~p"), ("?x. ?y::'a. ?z. P x --> Q z --> false", "?x. ?z. P x --> ~Q z"), ("(!x. !y. P x | (P y & false)) --> ?z::'a. q", "(!x. P x) --> q") ] context.set_context('logic', vars={'p': 'bool', 'q': 'bool', 'P': "'a => bool", 'Q': "'a => bool"}) for fm, res in test_data: fm = parser.parse_term(fm) res = parser.parse_term(res) self.assertEqual(fologic.simplify(fm), res)
def testIntNormMacro(self): test_data = (("x * z * y", "x * y * z"), ("x - y", "x + (-1) * y"), ("x - -y", "x + y"), ("x - --x", "(0::int)")) vars = {"x": "int", "y": "int", "z": "int"} context.set_context('int', vars=vars) for t, t_res in test_data: t, t_res = parser.parse_term(t), parser.parse_term(t_res) test_conv(self, 'int', integer.int_norm_conv(), vars=vars, t=t, t_res=t_res)
def testASKolem(self): test_data = [ # Test case from Section 3.6 of HPLAR. ("?y::nat. x < y --> !u. ?v. x * u < y * v", "~x < f_y x | (!u::nat. x * u < f_y x * f_v u x)"), ("!x. P x --> (?y. ?z::'a. Q y | ~(?z. P z & Q z))", "!x. ~P x | Q c_y | (!z. ~P z | ~Q z)") ] context.set_context('nat', vars={'P': "'a => bool", 'Q': "'a => bool"}) for fm, res in test_data: fm = parser.parse_term(fm) res = parser.parse_term(res) self.assertEqual(fologic.askolemize(fm), res)
def testSimplifyRewrConv(self): test_data = [ ("(sin x) ^ (3::nat)", "sin x * (sin x) ^ (2::nat)"), ] context.set_context('interval_arith', vars={'x': 'real'}) for s, t in test_data: s = parser.parse_term(s) t = parser.parse_term(t) test_conv(self, 'interval_arith', proof.simplify_rewr_conv(t), t=s, t_res=t)
def run_test(self, data, verbose=False): Ta = TVar('a') context.set_context('nat', vars={ 'a': Ta, 'b': Ta, 'c': Ta, 'd': Ta, 'f': TFun(Ta, Ta), 'g': TFun(Ta, Ta), 'R': TFun(Ta, Ta, Ta), 'm': NatType, 'n': NatType, 'p': NatType, 'q': NatType, 'x': NatType, 'y': NatType, 'z': NatType }) closure = congc.CongClosureHOL() for item in data: if item[0] == MERGE: _, s, t = item s = parser.parse_term(s) t = parser.parse_term(t) closure.merge(s, t) if verbose: print("Merge %s, %s\nAfter\n%s" % (s, t, closure)) elif item[0] == CHECK: _, s, t, b = item s = parser.parse_term(s) t = parser.parse_term(t) self.assertEqual(closure.test(s, t), b) elif item[0] == EXPLAIN: _, s, t = item s = parser.parse_term(s) t = parser.parse_term(t) prf = closure.explain(s, t).export() self.assertEqual(theory.check_proof(prf), Thm([], Eq(s, t))) if verbose: print("Proof of %s" % Eq(s, t)) print(prf) elif item[0] == MATCH: _, pat, t, res = item pat = parser.parse_term(pat) t = parser.parse_term(t) for res_inst in res: for k in res_inst: res_inst[k] = parser.parse_term(res_inst[k]) inst = closure.ematch(pat, t) self.assertEqual(inst, res) else: raise NotImplementedError
def testSolve(self): if not z3wrapper.z3_loaded: return context.set_context('nat', vars={ "s": 'nat => nat', "A": 'nat', "B": 'nat' }) test_data = [ ("s 0 = 0 & s 1 = 0 --> s 1 = s 0 * B", True), ("s 1 = s 0 * B & ~~s 0 = A --> s 1 = A * B", True), ("s 1 = s 0 * B & ~s 0 = A --> s 1 + B = (s 0 + 1) * B", True), ("A * B + 1 = 1 + B * A", True), ("s 0 = s 1", False), ("s 0 + s 1 = A --> A + s 2 = B --> s 0 + s 2 + s 1 = B", True), ("s 0 + s 1 = A --> A + s 2 = B --> s 0 + s 2 = B", False), ("(!n. s n = 0) --> s 2 = 0", True), ("(!n. s n = 0) --> s 0 = 1", False), ] for s, res in test_data: t = parser.parse_term(s) self.assertEqual(z3wrapper.solve(t), res)
def testRec1(self): test_data = [ # ('s 0 = 0 & s 1 = 0 --> s 1 = s 0 * B', # '~(s 1 = s 0 * B), s 0 = 0 & s 1 = 0 |- false'), ('s 1 = s 0 * B & ~~s 0 = A --> s 1 = A * B', '~(s 1 = A * B), s 1 = s 0 * B & s 0 = A |- false'), ('s 1 = s 0 * B & ~s 0 = A --> s 1 + B = (s 0 + 1) * B', '~(s 1 + B = (s 0 + 1) * B), s 1 = s 0 * B & ~(s 0 = A) |- false' ), ('A * B + 1 = 1 + B * A', '~(A * B + 1 = 1 + B * A) |- false'), ('s 0 + s 1 = A --> A + s 2 = B --> s 0 + s 2 + s 1 = B', 's 0 + s 1 = A, A + s 2 = B, ~(s 0 + s 2 + s 1 = B) |- false'), ('(!n. s n = 0) --> s 2 = 0', '!n. s n = 0, ~(s 2 = 0) |- false') ] for t, p in test_data: context.set_context('smt', vars={ "s": 'nat => nat', "A": 'nat', "B": 'nat' }) t = parse_term(t) proof, assertions = z3wrapper.solve_and_proof(t) r = proofrec.proofrec(proof, assertions=assertions, trace=True) self.assertNotEqual(r.rule, 'sorry')
def testNormAbsoluteValue(self): test_data = [ ("abs x", ["x >= 0"], "x"), ("abs x", ["x Mem real_closed_interval 0 1"], "x"), ("abs x", ["x Mem real_closed_interval (-1) 0"], "-1 * x"), ("abs (sin x)", ["x Mem real_closed_interval 0 (pi / 2)"], "sin x"), ("abs (sin x)", ["x Mem real_closed_interval (-pi / 2) 0"], "-1 * sin x"), ("abs (log x)", ["x Mem real_open_interval (exp (-1)) 1"], "-1 * log x"), ] vars = {'x': 'real'} context.set_context('interval_arith', vars=vars) for t, conds, res in test_data: conds_pt = [ ProofTerm.assume(parser.parse_term(cond)) for cond in conds ] cv = auto.auto_conv(conds_pt) test_conv(self, 'interval_arith', cv, vars=vars, t=t, t_res=res, assms=conds)
def testRecSolveSet(self): test_data = [ ('x Mem S --> S Sub T --> x Mem T', 'S x, ~(T x), !x1. S x1 --> T x1 |- false'), ('m Mem univ', '~true |- false'), ('x Mem (diff S T) --> x Mem S', '~(S x), S x & ~(T x) |- false'), ('(?x1. x = x1 & x1 Mem S) --> x Mem S', '~(S x), ?x1. x = x1 & S x1 |- false'), ('(?a1. a = a1 & a1 Mem A) --> a Mem A', '~(A a), ?a1. a = a1 & A a1 |- false'), ] for t, p in test_data: context.set_context('smt', vars={ 'm': 'nat', 'S': 'nat set', 'T': 'nat set', 'x': 'nat', 'a': "'a", 'A': "'a set" }) t = parse_term(t) proof, assertions = z3wrapper.solve_and_proof(t) r = proofrec.proofrec(proof, assertions=assertions, trace=True) self.assertNotEqual(r.rule, 'sorry')
def testSortDisjunction(self): test_data = [ ('A | ~A', 'true'), ('A | B | ~A', 'true'), ('A | B | (true | false) | C', 'true'), ('A | false', 'A'), ('B | (A | C) | (E | A) | D', 'A | B | C | D | E') ] vars = {"A": "bool", "B" : "bool", "C": "bool", "D": "bool", "E": "bool", "F" : "bool", "G": "bool", "H": "bool"} context.set_context('logic', vars=vars) for t, t_res in test_data: t, t_res = parser.parse_term(t), parser.parse_term(t_res) test_conv(self, 'logic', proplogic.sort_disj(), vars=vars, t=t, t_res=t_res)
def parse_init_state(prop): """Given data for a theorem statement, construct the initial partial proof. data['vars']: list of variables. data['prop']: proposition to be proved. In the form A1 --> ... --> An --> C. Construct initial partial proof for the given assumptions and conclusion. assums - assumptions A1, ... An. concl - conclusion C. Constructs: 0: assume A1 ... n-1: assume An n: C by sorry n+1: A1 --> ... --> An --> C by intros from 0, 1, ..., n. """ typecheck.checkinstance('parse_init_state', prop, (str, list, Term)) if isinstance(prop, (str, list)): prop = parser.parse_term(prop) assums, concl = prop.strip_implies() state = ProofState() for nm, T in context.ctxt.vars.items(): state.vars.append(Var(nm, T)) state.prf = Proof(*assums) n = len(assums) state.prf.add_item(n, "sorry", th=Thm(assums, concl)) state.prf.add_item(n + 1, "intros", prevs=range(n + 1)) state.check_proof(compute_only=True) return state
def run_test(self, thy_name, s, expected_res, **kwargs): context.set_context(thy_name) t = parser.parse_term(s) with global_setting(**kwargs): ast = pprint.get_ast_term(t) res = pprint.print_ast(ast) self.assertEqual(res, expected_res)
def parse(self, data): self.name = data['name'] try: with context.fresh_context(vars=data['vars']): self.vars = context.ctxt.vars self.prop = parser.parse_term(data['prop']) # theorem does not already exist if theory.thy.has_theorem(self.name): raise ItemException("Theorem %s: theorem already exists") # prop should not contain extra variables self_vars = set(self.vars.keys()) prop_vars = set(v.name for v in self.prop.get_vars()) if not prop_vars.issubset(self_vars): raise ItemException( "Theorem %s: extra variables in prop: %s" % (self.name, ", ".join(v for v in prop_vars - self_vars))) except Exception as error: self.vars = data['vars'] self.prop = data['prop'] self.error = error self.trace = traceback2.format_exc() if 'attributes' in data: self.attributes = data['attributes']
def parse(self, data): self.name = data['name'] try: self.type = parser.parse_type(data['type']) self.cname = theory.thy.get_overload_const_name( self.name, self.type) for rule in data['rules']: with context.fresh_context(defs={self.name: self.type}): prop = parser.parse_term(rule['prop']) # prop should be an equality if not prop.is_equals(): raise ItemException("Fun %s: rule is not an equality" % self.name) f, args = prop.lhs.strip_comb() if f != Const(self.name, self.type): raise ItemException("Fun %s: wrong head of lhs" % self.name) lhs_vars = set(v.name for v in prop.lhs.get_vars()) rhs_vars = set(v.name for v in prop.rhs.get_vars()) if not rhs_vars.issubset(lhs_vars): raise ItemException( "Fun %s: extra variables in rhs: %s" % (self.name, ", ".join(v for v in rhs_vars - lhs_vars))) self.rules.append({'prop': prop}) except Exception as error: self.type = data['type'] self.rules = data['rules'] self.error = error self.trace = traceback2.format_exc()
def parse(self, data): self.name = data['name'] try: self.type = parser.parse_type(data['type']) self.cname = theory.thy.get_overload_const_name( self.name, self.type) for rule in data['rules']: with context.fresh_context(defs={self.name: self.type}): prop = parser.parse_term(rule['prop']) # Test conclusion of the prop _, concl = prop.strip_implies() f, _ = concl.strip_comb() if f != Const(self.name, self.type): raise ItemException( "Inductive %s: wrong head of conclusion" % self.name) self.rules.append({'name': rule['name'], 'prop': prop}) except Exception as error: self.type = data['type'] self.rules = data['rules'] self.error = error self.trace = traceback2.format_exc()
def testParseUnicode(self): test_data = [ ("A ∧ B", "A & B"), ("A ∨ B", "A | B"), ("A ⟶ B ⟶ C", "A --> B --> C"), ("A ∧ B | C", "A & B | C"), ("¬A", "~A"), ("λx::'a. x", "%x::'a. x"), ("∀x::'a. P x", "!x. P x"), ("∃x::'a. P x", "?x. P x"), ("∀x::'a. P x ∧ Q x", "!x. P x & Q x"), ("(∀x::'a. P x) & Q y", "(!x. P x) & Q y"), ] context.set_context('logic_base', vars={ 'A': 'bool', 'B': 'bool', 'C': 'bool', 'P': "'a => bool", 'Q': "'a => bool" }) for s, ascii_s in test_data: t = parser.parse_term(s) self.assertIsInstance(t, Term) with global_setting(unicode=False): self.assertEqual(print_term(t), ascii_s)
def testThLemmaIntSingle(self): test_data = [ # ¬(y ≤ 3), y ≤ 4 ⊢ 0 = -4 + y, # y ≥ 0, y ≤ 0 ⊢ 1 = 1 + y, # y ≥ 0, ¬(y ≥ 1) ⊢ 1 = 1 + y, "x ≥ 1 ∨ x ≤ 0", "¬(x ≥ 2) ∨ ¬(x ≤ 0)", "¬(x ≥ 1) ∨ ¬(x ≤ 0)", "¬(x ≤ 2) ∨ x ≤ 3", "¬(x ≤ 3) ∨ ¬(x ≥ 4)", "¬(x = 4) ∨ x ≤ 4", "¬(1 = x) ∨ x ≥ 1", "¬(x ≤ 0) ∨ 4 + x = (if x ≤ 0 then 4 + x else -1 + x)", "1 = x ∨ ¬(x ≤ 1) ∨ ¬(x ≥ 1)", "3 = -1 + x ∨ ¬(-1 + x ≤ 3) ∨ ¬(-1 + x ≥ 3)", "x = 3 ∨ ¬(x ≤ 3) ∨ ¬(x ≥ 3)", # "x ≥ 4 ∨ 1 + x = (if x ≥ 4 then -4 + x else 1 + x)", # "¬(4 + x = (if x ≤ 0 then 4 + x else -1 + x)) ∨ 4 + x + -1 * (if x ≤ 0 then 4 + x else -1 + x) ≥ 0)", # "¬(-1 + x = (if x ≤ 0 then 4 + x else -1 + x)) ∨ -1 + x + -1 * (if x ≤ 0 then 4 + x else -1 + x) ≥ 0)", "¬(Succ x = 3) ∨ Succ x ≤ 3", "¬(Sum (Pred x) (Succ y) ≥ 2) ∨ ¬(Sum (Pred x) (Succ y) ≤ 1)", "¬(Sum (Pred x) (Succ y) = 2) ∨ Sum (Pred x) (Succ y) ≥ 2", ] context.set_context('smt', vars={ "x": "int", "Succ": "int => int", "Pred": "int => int", "Sum": "int => int => int" }) for tm in test_data: tm = parse_term(tm) self.assertNotEqual(proofrec.th_lemma([tm]).rule, 'sorry')