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 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 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::nat) + 5 * 2", "(13::nat)"), ("x + Suc y", "x + y + 1"), ("Suc (x + Suc y)", "x + y + 2"), ("x * Suc y", "x + x * y"), ("x * 1 * 1 * 1", "x"), ] vars = {"x": 'nat', "y": 'nat', "z": 'nat'} for expr, res in test_data: test_conv(self, 'nat', nat.norm_full(), vars=vars, t=expr, t_res=res)
def testNormPoly(self): test_data = [ ("x + x", "2 * x"), ("x + 2 * x", "3 * x"), ("(1 / 2) * x + (1 / 3) * x", "5 / 6 * x"), ("x + y + x", "2 * x + y"), ("x + (-1) * x", "(0::real)"), ("x + (-1) * y + y", "x"), ("x + y + (-1) * x", "y"), ("(x + y) * (x + y)", "2 * (x * y) + x ^ (2::nat) + y ^ (2::nat)"), ("(x + y) * (x - y)", "x ^ (2::nat) + -1 * y ^ (2::nat)"), ("x ^ (3::real)", "x ^ (3::nat)"), ("(2::real) ^ (3::nat)", "(8::real)"), ("(2::real) ^ (-(1::real))", "1 / 2"), ("(9::real) ^ (1 / 2)", "(3::real)"), ("(9::real) ^ (1 / 3)", "(3::real) ^ (2 / 3)"), ("(3::real) ^ (4 / 3)", "3 * (3::real) ^ (1 / 3)"), ("(2::real) ^ -(1 / 2)", "1 / 2 * 2 ^ (1 / 2)"), ("(1 / 4) ^ (1 / 2)", "1 / 2"), ("((3::real) ^ (1 / 2) * 3 ^ (1 / 2))", "(3::real)"), ("(2::real) * (-((1/2) * -(3 ^ (1/2))) + 1)", "2 + (3::real) ^ (1 / 2)"), ("(0::real) ^ (6::nat)", "(0::real)"), ] vars = {'x': 'real', 'y': 'real'} for expr, res in test_data: test_conv(self, 'transcendentals', auto.auto_conv(), vars=vars, t=expr, t_res=res)
def testRealEvalConv(self): test_data = [ ("3 + (2::real) * 5", "(13::real)"), ("(2 + 3) / (3::real)", "5 / (3::real)"), ] for expr, res in test_data: test_conv(self, 'real', real.real_eval_conv(), t=expr, t_res=res)
def testNormRealDerivative(self): test_data = [ # Differentiable everywhere ("real_derivative (%x. x) x", [], "(1::real)"), ("real_derivative (%x. 3) x", [], "(0::real)"), ("real_derivative (%x. 3 * x) x", [], "(3::real)"), ("real_derivative (%x. x ^ (2::nat)) x", [], "2 * x"), ("real_derivative (%x. x ^ (3::nat)) x", [], "3 * x ^ (2::nat)"), ("real_derivative (%x. (x + 1) ^ (3::nat)) x", [], "3 + 6 * x + 3 * x ^ (2::nat)"), ("real_derivative (%x. exp x) x", [], "exp x"), ("real_derivative (%x. exp (x ^ (2::nat))) x", [], "2 * (exp (x ^ (2::nat)) * x)"), # ("real_derivative (%x. exp (exp x)) x", [], "exp (x + exp x)"), ("real_derivative (%x. sin x) x", [], "cos x"), ("real_derivative (%x. cos x) x", [], "-1 * sin x"), ("real_derivative (%x. sin x * cos x) x", [], "(cos x) ^ (2::nat) + -1 * (sin x) ^ (2::nat)"), # Differentiable with conditions ("real_derivative (%x. 1 / x) x", ["x Mem real_open_interval 0 1"], "-1 * x ^ -(2::real)"), ("real_derivative (%x. 1 / (x ^ (2::nat) + 1)) x", ["x Mem real_open_interval (-1) 1"], "-2 * (x * (1 + 2 * x ^ (2::nat) + x ^ (4::nat)) ^ -(1::real))"), ("real_derivative (%x. log x) x", ["x Mem real_open_interval 0 1"], "x ^ -(1::real)"), ("real_derivative (%x. log (sin x)) x", ["x Mem real_open_interval 0 1"], "cos x * (sin x) ^ -(1::real)"), ("real_derivative (%x. sqrt x) x", ["x Mem real_open_interval 0 1"], "1 / 2 * x ^ -(1 / 2)"), ("real_derivative (%x. sqrt (x ^ (2::nat) + 1)) x", ["x Mem real_open_interval (-1) 1" ], "x * (1 + x ^ (2::nat)) ^ -(1 / 2)"), # Real power ("real_derivative (%x. x ^ (1 / 3)) x", ["x Mem real_open_interval 0 1"], "1 / 3 * x ^ -(2 / 3)"), ("real_derivative (%x. 2 ^ x) x", ["x Mem real_open_interval (-1) 1"], "log 2 * 2 ^ 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 testNatEqConv(self): test_data = [ ((0, 0), true), ((1, 1), true), ((0, 1), false), ] for (a, b), res in test_data: expr = "(%d::nat) = %d" % (a, b) test_conv(self, 'nat', nat.nat_eq_conv(), t=expr, t_res=res)
def testNormBoolExpr(self): test_data = [ ("true", "true"), ("false", "false"), ("~true", "false"), ("~false", "true"), ] for t, t_res in test_data: test_conv(self, 'logic', logic.norm_bool_expr(), t=t, t_res=t_res)
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 testNormInequation(self): test_data = [ ("a - b > c", "a - b - c > 0"), ("a + b < c", "a + b - c < 0"), ("-b * 5 <= 2 * a + -4 * c", "-b * 5 - (2 * a + -4 * c) <= 0"), ("a - a >= b - c", "a - a - (b - c) >= 0") ] for expr, res in test_data: vars = {'a' : 'real', 'b' : 'real', 'c' : 'real'} test_conv(self, 'transcendentals', real.norm_real_ineq_conv(), vars=vars, t=expr, t_res=res)
def testNegInequation(self): test_data = [ ("~(x > y)", "x <= y"), ("~(x >= y)", "x < y"), ("~(x < y)", "x >= y"), ("~(x <= y)", "x > y") ] vars = {'x' : 'real', 'y' : 'real'} for expr, res in test_data: test_conv(self, 'transcendentals', real.norm_neg_real_ineq_conv(), vars=vars, t=expr, t_res=res)
def testNatConv(self): test_data = [ ("(2::nat) + 3", 5), ("Suc (2 + 3)", 6), ("Suc (Suc (Suc 0))", 3), ("(5::nat) + 2 * 3", 11), ("((5::nat) + 2) * 3", 21), ("5 * Suc (2 + 5)", 40), ] for t, n in test_data: test_conv(self, 'nat', nat.nat_conv(), t=t, t_res=Nat(n))
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 testConjNorm(self): test_data = [ ('A & (D & B) & C', 'A & B & C & D'), ('A & A & B & B & C & C', 'A & B & C'), ] vars = {'A': 'bool', 'B': 'bool', 'C': 'bool', 'D': 'bool'} for t, t_res in test_data: test_conv(self, 'logic', logic.conj_norm(), vars=vars, t=t, t_res=t_res)
def testDisjNorm(self): test_data = [ ('A | (D | B) | C', 'A | B | C | D'), ('A | A | B | B | C | C', 'A | B | C'), ] vars = {'A': 'bool', 'B': 'bool', 'C': 'bool', 'D': 'bool'} for t, t_res in test_data: test_conv(self, 'logic', logic.disj_norm(), vars=vars, t=t, t_res=t_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 testNormConjAssoc(self): test_data = [ ("A", "A"), ("A & B", "A & B"), ("(A & B) & (C & D)", "A & B & C & D"), ("((A & B) & C) & D", "A & B & C & D"), ] vars = {'A': 'bool', 'B': 'bool'} for t, t_res in test_data: test_conv(self, 'logic', logic.norm_conj_assoc(), vars=vars, t=t, t_res=t_res)
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 testSubstitution(self): test_data = [ ("real_integral (real_closed_interval 0 1) (%x. exp (6 * x))", "%x::real. (1/6) * exp x", "%x::real. 6 * x", "real_integral (real_closed_interval 0 6) (%x. 1 / 6 * exp x)"), ] context.set_context('interval_arith') for expr, f, g, res in test_data: f = parser.parse_term(f) g = parser.parse_term(g) res = parser.parse_term(res) test_conv(self, 'interval_arith', proof.substitution(f, g, res), t=expr, t_res=res)
def testNormFullLevel2(self): test_data = [ ("(x + y) * (y + x)", "x * x + x * y + x * y + y * y"), ("(Suc x) * y", "y + x * y"), ] cv = nat.norm_full() limit = ('thm', 'add_cancel_left') vars = {"x": 'nat', "y": 'nat', "z": 'nat'} for expr, res in test_data: test_conv(self, 'nat', nat.norm_full(), limit=limit, vars=vars, t=expr, t_res=res)
def testRealNormConv(self): test_data = [ ("x + 0", "x"), ("x * (y + z)", "x * y + x * z"), ("of_nat 2 + x", "2 + x"), ("of_nat (m + n) + x", "of_nat m + of_nat n + x"), ("of_nat (m * n) + x", "x + of_nat m * of_nat n"), ("x ^ (1::nat)", "x"), ("(x + y) ^ (2::nat)", "x ^ (2::nat) + y ^ (2::nat) + 2 * x * y"), ("x ^ ((2::nat) - 1)", "x"), ("x ^ (0::nat) + y", "1 + y"), ("(3 + x) ^ (3::nat)", "27 + 27 * x + 9 * x ^ (2::nat) + x ^ (3::nat)"), ] vars = {'x': 'real', 'y': 'real', 'z': 'real', 'm': 'nat', 'n': 'nat'} for expr, res in test_data: test_conv(self, 'real', real.real_norm_conv(), vars=vars, t=expr, t_res=res)
def testSortConjuntion(self): test_data = [ ('A & ~A', 'false'), ('A & B & ~A', 'false'), ('A & C & B', 'A & B & C'), ('A & (A & C) & B', 'A & B & C'), ('~A & C & (B & false)', 'false'), ('A & true', 'A'), ('false & A', 'false') ] 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_conj(), vars=vars, t=t, t_res=t_res)
def testIntegrateByParts(self): test_data = [ ("real_integral (real_closed_interval (-1) 2) (%x. x * exp x)", "%x::real. x", "%x::real. exp x", "evalat (%x. x * exp x) (-1) 2 - real_integral (real_closed_interval (-1) 2) (%x. exp x)" ), ] context.set_context('interval_arith') for expr, u, v, res in test_data: u = parser.parse_term(u) v = parser.parse_term(v) res = parser.parse_term(res) test_conv(self, 'interval_arith', proof.integrate_by_parts(u, v, res), t=expr, t_res=res)
def testNormFullLevel1(self): test_data = [ ("y + (x + x * y)", "x + y + x * y"), ("z + y + x", "x + y + z"), ("1 + y", "y + 1"), ("Suc (x + y)", "x + y + 1"), ] cv = nat.norm_full() limit = ('thm', 'mult_0_right') vars = {"x": 'nat', "y": 'nat', "z": 'nat'} for expr, res in test_data: test_conv(self, 'nat', nat.norm_full(), limit=limit, vars=vars, t=expr, t_res=res)
def testNormConjAtomConv(self): test_data = [ ('B & A & C', 'A & B & C'), ('true & A', 'A'), ('A & true', 'A'), ('true & A & C', 'A & C'), ('false & A & C', 'false'), ('A & false', 'false'), ('C & A & B', 'A & B & C'), ('B & ~B & A', 'false'), ('~B & B & A', 'false'), ('~C & A & C', 'false') ] 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_atom(), vars=vars, t=t, t_res=res)
def testCombineAtomConv(self): test_data = [ ("x ^ (2::nat) * x ^ (3::nat)", [], "x ^ (5::nat)"), ("x ^ (2::nat) * x ^ (1 / 2)", ["x > 0"], "x ^ (5 / 2)"), ("x * x", [], "x ^ (2::nat)"), ("x * (x ^ (2::nat))", [], "x ^ (3::nat)"), ("x * (x ^ (1 / 2))", ["x > 0"], "x ^ (3 / 2)"), ("x ^ (1 / 2) * x ^ (1 / 2)", ["x > 0"], "x"), ("x ^ (1 / 2) * x ^ (3 / 2)", ["x > 0"], "x ^ (2::nat)"), ("x * x ^ (-(1::real))", ["x > 0"], "(1::real)"), ("x ^ (1 / 2) * x ^ -(1 / 2)", ["x > 0"], "(1::real)"), ] vars = {'x': 'real'} context.set_context('realintegral', vars=vars) for t, conds, res in test_data: conds_pt = [ProofTerm.assume(parser.parse_term(cond)) for cond in conds] cv = real.combine_atom(conds_pt) test_conv(self, 'realintegral', cv, vars=vars, t=t, t_res=res, assms=conds)
def testTrigRewrConv(self): test_data = [ ("sin x ^ (2::nat)", "", "TR5", "1 - cos x ^ (2::nat)"), ("1 - cos x ^ (2::nat)", "", "TR6", "1 - (1 - sin x ^ (2::nat))"), ("real_integral (real_closed_interval 0 pi) (%x. sin x ^ (2::nat) * sin x)", "0.0", "TR5", "real_integral (real_closed_interval 0 pi) (%x. (1 - cos x ^ (2::nat)) * sin x)" ), ] context.set_context('interval_arith', vars={'x': 'real'}) for s, loc, code, res in test_data: s = parser.parse_term(s) res = parser.parse_term(res) loc = proof.Location(loc) cv = proof.location_conv( loc, proof.trig_rewr_conv(code, target=proof.get_at_location(loc, res))) test_conv(self, 'interval_arith', cv, t=s, t_res=res)
def testSimplexFormConv(self): test_data = (("x + 3 * y > 4", "1 * x + 3 * y >= 5"), ("x + 3 * y > -x + 3 * y", "2 * x >= 1"), ("x - 2 * y + 4 * z - 3 < x + 5 * z - 4", "-2 * y + -1 * z <= -2"), ("x - y + z >= 6 * y", "1 * x + -7 * y + 1 * z >= 0"), ("x + y <= x + y", "(0::int) <= 0"), ("x + 6 * z >= x + 6 * z", "(0::int) >= 0"), ("x + -2 * y >= x + -2 * y - 4", "(4::int) >= 0")) 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_simplex_form(), vars=vars, t=t, t_res=t_res)