Beispiel #1
0
 def testRule4(self):
     n = Var('n', natT)
     goal = Thm([], Term.mk_equals(plus(n, zero), n))
     inst = {'P': Term.mk_abs(n, goal.prop), 'x': n}
     pt = tactic.rule().get_proof_term(thy, ProofTerm.sorry(goal), args=('nat_induct', ({}, inst)))
     prf = pt.export()
     self.assertEqual(thy.check_proof(prf), goal)
Beispiel #2
0
    def testAllConj(self):
        """Proof of (!x. A x & B x) --> (!x. A x) & (!x. B x)."""
        thy = basic.load_theory('logic_base')
        Ta = TVar("a")
        A = Var("A", TFun(Ta, boolT))
        B = Var("B", TFun(Ta, boolT))
        x = Var("x", Ta)
        all_conj = Term.mk_all(x, logic.mk_conj(A(x), B(x)))
        all_A = Term.mk_all(x, A(x))
        all_B = Term.mk_all(x, B(x))
        conj_all = logic.mk_conj(all_A, all_B)

        prf = Proof(all_conj)
        prf.add_item(1, "forall_elim", args=x, prevs=[0])
        prf.add_item(2, "theorem", args="conjD1")
        prf.add_item(3, "substitution", args={"A": A(x), "B": B(x)}, prevs=[2])
        prf.add_item(4, "implies_elim", prevs=[3, 1])
        prf.add_item(5, "forall_intr", args=x, prevs=[4])
        prf.add_item(6, "theorem", args="conjD2")
        prf.add_item(7, "substitution", args={"A": A(x), "B": B(x)}, prevs=[6])
        prf.add_item(8, "implies_elim", prevs=[7, 1])
        prf.add_item(9, "forall_intr", args=x, prevs=[8])
        prf.add_item(10, "theorem", args="conjI")
        prf.add_item(11,
                     "substitution",
                     args={
                         "A": all_A,
                         "B": all_B
                     },
                     prevs=[10])
        prf.add_item(12, "implies_elim", prevs=[11, 5])
        prf.add_item(13, "implies_elim", prevs=[12, 9])
        prf.add_item(14, "implies_intr", args=all_conj, prevs=[13])
        th = Thm.mk_implies(all_conj, conj_all)
        self.assertEqual(thy.check_proof(prf), th)
Beispiel #3
0
    def testInferType(self):
        test_data = [
            # A1 --> A2
            (Const("implies", None)(Var("A1", None), Var("A2", None)),
             Term.mk_implies(Var("A1", boolT), Var("A2", boolT))),
            # A1 = A2
            (Const("equals", None)(Var("A1", boolT), Var("A2", None)),
             Term.mk_equals(Var("A1", boolT), Var("A2", boolT))),
            # a = b
            (Const("equals", None)(Var("a", None), Var("b", None)),
             Const("equals", TFun(Ta, Ta, boolT))(Var("a", Ta), Var("b", Ta))),
            # %x. P x
            (Abs("x", None,
                 Var("P", None)(Bound(0))),
             Abs("x", Ta,
                 Var("P", TFun(Ta, boolT))(Bound(0)))),
            # %x y. x = y
            (Abs("x", Ta,
                 Abs("y", None,
                     Const("equals", None)(Bound(1), Bound(0)))),
             Abs(
                 "x", Ta,
                 Abs("y", Ta,
                     Const("equals", TFun(Ta, Ta, boolT))(Bound(1),
                                                          Bound(0))))),
            # [a]
            (Const("cons", None)(Var("a", None), Const("nil", None)),
             list.cons(Ta)(Var("a", Ta), Const("nil", listT(Ta)))),
        ]

        for t, res in test_data:
            self.assertEqual(type_infer(thy, ctxt, t), res)
Beispiel #4
0
    def testInferPrintedType(self):
        t = Const("nil", listT(Ta))
        infer_printed_type(thy, t)
        self.assertTrue(hasattr(t, "print_type"))

        t = list.cons(Ta)(Var("a", Ta))
        infer_printed_type(thy, t)
        self.assertFalse(hasattr(t.fun, "print_type"))

        t = Term.mk_equals(Const("nil", listT(Ta)), Const("nil", listT(Ta)))
        infer_printed_type(thy, t)
        self.assertFalse(hasattr(t.fun.fun, "print_type"))
        self.assertTrue(hasattr(t.arg1, "print_type"))
        self.assertFalse(hasattr(t.arg, "print_type"))

        t = Term.mk_equals(list.mk_append(list.nil(Ta), list.nil(Ta)),
                           list.nil(Ta))
        infer_printed_type(thy, t)
        self.assertTrue(hasattr(t.arg1.arg1, "print_type"))
        self.assertFalse(hasattr(t.arg1.arg, "print_type"))
        self.assertFalse(hasattr(t.arg, "print_type"))

        t = Term.mk_abs(Var("x", Ta), Term.mk_equals(Var("x", Ta),
                                                     Var("x", Ta)))
        infer_printed_type(thy, t)
Beispiel #5
0
 def testApplyInduction(self):
     thy = basic.load_theory('nat')
     n = Var("n", nat.natT)
     state = ProofState.init_state(thy, [n], [], Term.mk_equals(nat.plus(n, nat.zero), n))
     state.apply_induction(0, "nat_induct", "n")
     self.assertEqual(state.check_proof(), Thm([], Term.mk_equals(nat.plus(n, nat.zero), n)))
     self.assertEqual(len(state.prf.items), 3)
Beispiel #6
0
 def testSubstitution(self):
     x_eq_y = Term.mk_equals(x, y)
     th = Thm([x_eq_y], x_eq_y)
     y_eq_x = Term.mk_equals(y, x)
     self.assertEqual(Thm.substitution({
         "x": y,
         "y": x
     }, th), Thm([y_eq_x], y_eq_x))
Beispiel #7
0
    def get_proof_term(self, thy, goal, *, args=None, prevs=None):
        assert isinstance(args, Term), "cases"

        As = goal.hyps
        C = goal.prop
        goal1 = ProofTerm.sorry(Thm(goal.hyps, Term.mk_implies(args, C)))
        goal2 = ProofTerm.sorry(
            Thm(goal.hyps, Term.mk_implies(logic.neg(args), C)))
        return apply_theorem(thy, 'classical_cases', goal1, goal2)
Beispiel #8
0
    def testExport(self):
        """Basic case."""
        pt1 = ProofTerm.assume(Term.mk_equals(x, y))
        pt2 = ProofTerm.assume(Term.mk_equals(y, z))
        pt3 = ProofTerm.transitive(pt1, pt2)

        prf = pt3.export()
        self.assertEqual(len(prf.items), 3)
        self.assertEqual(thy.check_proof(prf), pt3.th)
Beispiel #9
0
 def testIntros(self):
     Ta = TVar('a')
     x = Var('x', Ta)
     P = Var('P', TFun(Ta, boolT))
     Q = Var('Q', TFun(Ta, boolT))
     goal = Thm([], Term.mk_all(x, Term.mk_implies(P(x), Q(x))))
     intros_tac = tactic.intros()
     pt = intros_tac.get_proof_term(thy, ProofTerm.sorry(goal), args=['x'])
     prf = pt.export()
     self.assertEqual(thy.check_proof(prf), goal)
Beispiel #10
0
 def testRewriteGoalWithAssum(self):
     Ta = TVar("a")
     a = Var("a", Ta)
     b = Var("b", Ta)
     eq_a = Term.mk_equals(a, a)
     if_t = logic.mk_if(eq_a, b, a)
     state = ProofState.init_state(thy, [a, b], [], Term.mk_equals(if_t, b))
     state.rewrite_goal(0, "if_P")
     state.set_line(0, "reflexive", args=a)
     self.assertEqual(state.check_proof(no_gaps=True), Thm.mk_equals(if_t, b))
Beispiel #11
0
 def testIntroduction3(self):
     Ta = TVar("a")
     A = Var("A", TFun(Ta, boolT))
     B = Var("B", TFun(Ta, boolT))
     x = Var("x", Ta)
     state = ProofState.init_state(thy, [A, B], [], Term.mk_all(x, imp(A(x), B(x))))
     state.introduction(0, ["x"])
     self.assertEqual(state.check_proof(), Thm([], Term.mk_all(x, imp(A(x), B(x)))))
     self.assertEqual(len(state.prf.items), 1)
     self.assertEqual(len(state.prf.items[0].subproof.items), 4)
Beispiel #12
0
    def testCheckTerm(self):
        test_data = [
            x,
            Term.mk_equals(x, y),
            Term.mk_equals(f, f),
            Term.mk_implies(A, B),
            Abs("x", Ta, Term.mk_equals(x, y)),
        ]

        for t in test_data:
            self.assertEqual(thy.check_term(t), None)
Beispiel #13
0
    def run_test(self, thy_name, pat, t, *, vars=None, svars=None, tyinst=None, inst=None, failed=None):
        context.set_context(thy_name, vars=vars, svars=svars)

        pat, t = Term(pat), Term(t)
        inst = Inst((nm, Term(s)) for nm, s in inst.items()) if inst is not None else Inst()
        if tyinst is not None:
            inst.tyinst = TyInst((nm, Type(s)) for nm, s in tyinst.items())

        if failed is not None:
            self.assertRaises(failed, first_order_match, pat, t)
            return

        self.assertEqual(first_order_match(pat, t), inst)
Beispiel #14
0
 def testRewrConvWithAssum(self):
     x = Const("x", natT)
     y = Const("y", natT)
     x_eq_y = Term.mk_equals(x, y)
     th = Thm([], Term.mk_implies(x_eq_y, x_eq_y))
     cv = arg_conv(rewr_conv(ProofTerm.atom(0, th)))
     f = Const("f", TFun(natT, natT))
     res = Thm([x_eq_y], Term.mk_equals(f(x), f(y)))
     self.assertEqual(cv.eval(thy, f(x)), res)
     prf = Proof()
     prf.add_item(0, "sorry", th=th)
     cv.get_proof_term(thy, f(x)).export(prf=prf)
     self.assertEqual(thy.check_proof(prf), res)
Beispiel #15
0
    def testCheckProof3(self):
        """Proof of [x = y, y = z] |- f z = f x."""
        x_eq_y = Term.mk_equals(x,y)
        y_eq_z = Term.mk_equals(y,z)
        prf = Proof(x_eq_y, y_eq_z)
        prf.add_item(2, "transitive", prevs=[0, 1])
        prf.add_item(3, "symmetric", prevs=[2])
        prf.add_item(4, "reflexive", args=f)
        prf.add_item(5, "combination", prevs=[4, 3])

        rpt = ProofReport()
        th = Thm([x_eq_y, y_eq_z], Term.mk_equals(f(z),f(x)))
        self.assertEqual(thy.check_proof(prf, rpt), th)
        self.assertEqual(rpt.steps, 6)
Beispiel #16
0
    def testAbsConv(self):
        nat0 = Const("zero", natT)
        nat1 = Const("one", natT)
        f = Const("f", TFun(natT, natT))
        g = Const("g", TFun(natT, natT))
        x = Var("x", natT)

        thy.add_theorem("f_eq_g", eq(f(x), g(x)))
        t = Term.mk_abs(x, f(x))
        cv = abs_conv(rewr_conv("f_eq_g"))
        res_th = eq(t, Term.mk_abs(x, g(x)))
        self.assertEqual(cv.eval(thy, t), res_th)
        prf = cv.get_proof_term(thy, t).export()
        self.assertEqual(thy.check_proof(prf), res_th)
Beispiel #17
0
    def get_proof_term(self, thy, goal, *, args=None, prevs=None):
        assert isinstance(prevs,
                          list) and len(prevs) == 1, "rewrite_goal_with_prev"
        pt = prevs[0]

        init_As = goal.hyps
        C = goal.prop
        cv = then_conv(top_sweep_conv(rewr_conv(pt, match_vars=False)),
                       top_conv(beta_conv()))

        eq_th = cv.eval(thy, C)
        new_goal = eq_th.prop.rhs

        new_As = list(set(eq_th.hyps) - set(init_As))
        new_As_pts = [ProofTerm.sorry(Thm(init_As, A)) for A in new_As]
        if Term.is_equals(new_goal) and new_goal.lhs == new_goal.rhs:
            return ProofTermDeriv('rewrite_goal_with_prev',
                                  thy,
                                  args=C,
                                  prevs=[pt] + new_As_pts)
        else:
            new_goal_pts = ProofTerm.sorry(Thm(init_As, new_goal))
            return ProofTermDeriv('rewrite_goal_with_prev',
                                  thy,
                                  args=C,
                                  prevs=[pt, new_goal_pts] + new_As_pts)
Beispiel #18
0
    def testArgCombination(self):
        thy = basic.load_theory('logic_base')
        macro = logic_macro.arg_combination_macro()

        x_eq_y = Term.mk_equals(x, y)
        fx_eq_fy = Term.mk_equals(f(x), f(y))
        th = Thm.assume(x_eq_y)
        res = Thm([x_eq_y], fx_eq_fy)
        self.assertEqual(macro.eval(thy, f, [th]), res)

        prf = Proof(x_eq_y)
        prf.add_item(1, "arg_combination", args=f, prevs=[0])
        rpt = ProofReport()
        self.assertEqual(thy.check_proof(prf, rpt), res)
        self.assertEqual(rpt.macros_expand, {"arg_combination"})
        self.assertEqual(rpt.prim_steps, 3)
Beispiel #19
0
def compute_wp(thy, T, c, Q):
    """Compute the weakest precondition for the given command
    and postcondition. The computation is by case analysis on
    the form of c. Returns the validity theorem.

    """
    if c.head.is_const_name("Assign"):  # Assign a b
        a, b = c.args
        s = Var("s", T)
        P2 = Term.mk_abs(s, Q(function.mk_fun_upd(s, a, b(s).beta_conv())))
        return apply_theorem(thy,
                             "assign_rule",
                             inst={"b": b},
                             concl=Valid(T)(P2, c, Q))
    elif c.head.is_const_name("Seq"):  # Seq c1 c2
        c1, c2 = c.args
        wp1 = compute_wp(thy, T, c2, Q)  # Valid Q' c2 Q
        wp2 = compute_wp(thy, T, c1, wp1.prop.args[0])  # Valid Q'' c1 Q'
        return apply_theorem(thy, "seq_rule", wp2, wp1)
    elif c.head.is_const_name("While"):  # While b I c
        _, I, _ = c.args
        pt = apply_theorem(thy, "while_rule", concl=Valid(T)(I, c, Q))
        pt0 = ProofTerm.assume(pt.assums[0])
        pt1 = vcg(thy, T, pt.assums[1])
        return ProofTerm.implies_elim(pt, pt0, pt1)
    else:
        raise NotImplementedError
Beispiel #20
0
    def testFunCombination(self):
        thy = basic.load_theory('logic_base')
        macro = logic_macro.fun_combination_macro()

        f_eq_g = Term.mk_equals(f, g)
        fx_eq_gx = Term.mk_equals(f(x), g(x))
        th = Thm.assume(f_eq_g)
        res = Thm([f_eq_g], fx_eq_gx)
        self.assertEqual(macro.eval(thy, x, [th]), res)

        prf = Proof(f_eq_g)
        prf.add_item(1, "fun_combination", args=x, prevs=[0])
        rpt = ProofReport()
        self.assertEqual(thy.check_proof(prf, rpt), res)
        self.assertEqual(rpt.macros_expand, {"fun_combination"})
        self.assertEqual(rpt.prim_steps, 3)
Beispiel #21
0
    def get_proof(self):
        invC = Const("inv", TFun(gcl.stateT, boolT))
        transC = Const("trans", TFun(gcl.stateT, gcl.stateT, boolT))
        s1 = Var("s1", gcl.stateT)
        s2 = Var("s2", gcl.stateT)
        prop = Thm.mk_implies(invC(s1), transC(s1, s2), invC(s2))
        # print(printer.print_thm(self.thy, prop))

        trans_pt = ProofTerm.assume(transC(s1, s2))
        # print(printer.print_thm(self.thy, trans_pt.th))
        P = Term.mk_implies(invC(s1), invC(s2))
        ind_pt = apply_theorem(self.thy,
                               "trans_cases",
                               inst={
                                   "a1": s1,
                                   "a2": s2,
                                   "P": P
                               })
        # print(printer.print_thm(self.thy, ind_pt.th))

        ind_As, ind_C = ind_pt.prop.strip_implies()
        for ind_A in ind_As[1:-1]:
            # print("ind_A: ", printer.print_term(self.thy, ind_A))
            vars, As, C = logic.strip_all_implies(ind_A, ["s", "k"])
            # for A in As:
            #     print("A: ", printer.print_term(self.thy, A))
            # print("C: ", printer.print_term(self.thy, C))
            eq1 = ProofTerm.assume(As[0])
            eq2 = ProofTerm.assume(As[1])
            guard = ProofTerm.assume(As[2])
            inv_pre = ProofTerm.assume(As[3]).on_arg(self.thy, rewr_conv(eq1)) \
                                             .on_prop(self.thy, rewr_conv("inv_def"))
            C_goal = ProofTerm.assume(C).on_arg(self.thy, rewr_conv(eq2)) \
                                        .on_prop(self.thy, rewr_conv("inv_def"))
Beispiel #22
0
def mk_exists(x, body):
    """Given a variable x and a term t possibly depending on x, return
    the term ?x. t.

    """
    exists_t = Const("exists", TFun(TFun(x.T, boolT), boolT))
    return exists_t(Term.mk_abs(x, body))
Beispiel #23
0
 def testAddZeroRightWithMacro(self):
     """Proof of n + 0 = n by induction, using macros."""
     thy = basic.load_theory('nat')
     n = Var("n", nat.natT)
     eq = Term.mk_equals
     plus = nat.plus
     zero = nat.zero
     S = nat.Suc
     prf = Proof()
     prf.add_item(0, "reflexive", args=zero)
     prf.add_item(1,
                  "rewrite_goal",
                  args=("plus_def_1", eq(plus(zero, zero), zero)),
                  prevs=[0])
     prf.add_item(2, "assume", args=eq(plus(n, zero), n))
     prf.add_item(3, "arg_combination", args=S, prevs=[2])
     prf.add_item(4,
                  "rewrite_goal",
                  args=("plus_def_2", eq(plus(S(n), zero), S(n))),
                  prevs=[3])
     prf.add_item(5, "implies_intr", args=eq(plus(n, zero), n), prevs=[4])
     prf.add_item(6, "forall_intr", args=n, prevs=[5])
     prf.add_item(7,
                  "apply_theorem_for",
                  args=("nat_induct", {}, {
                      "P": Term.mk_abs(n, eq(plus(n, zero), n)),
                      "x": n
                  }),
                  prevs=[1, 6])
     th = Thm.mk_equals(plus(n, zero), n)
     self.assertEqual(thy.check_proof(prf), th)
Beispiel #24
0
 def testInduct(self):
     n = Var('n', natT)
     goal = Thm([], Term.mk_equals(plus(n, zero), n))
     induct_tac = tactic.var_induct()
     pt = induct_tac.get_proof_term(thy, ProofTerm.sorry(goal), args=('nat_induct', n))
     prf = pt.export()
     self.assertEqual(thy.check_proof(prf), goal)
Beispiel #25
0
    def get_proof_term(self, thy, t):
        if isinstance(self.pt, str):
            self.pt = ProofTerm.theorem(thy, self.pt)
            if self.sym:
                self.pt = ProofTerm.symmetric(self.pt)

        # Deconstruct th into assumptions and conclusion
        As, C = self.pt.assums, self.pt.concl
        assert Term.is_equals(C), "rewr_conv: theorem is not an equality."

        tyinst, inst = dict(), dict()

        if self.match_vars:
            try:
                matcher.first_order_match_incr(C.lhs, t, (tyinst, inst))
            except matcher.MatchException:
                raise ConvException()
        elif C.lhs != t:
            raise ConvException()

        pt = ProofTerm.substitution(inst,
                                    ProofTerm.subst_type(tyinst, self.pt))
        if self.conds is not None:
            pt = ProofTerm.implies_elim(pt, *self.conds)

        As = pt.assums
        for A in As:
            pt = ProofTerm.implies_elim(pt, ProofTerm.assume(A))
        return pt
Beispiel #26
0
    def search(self, state, id, prevs):
        cur_th = state.get_proof_item(id).th
        if cur_th.prop.is_all():
            return []

        thy = state.thy
        results = []
        for th_name, th in thy.get_data("theorems").items():
            if 'hint_rewrite' not in thy.get_attributes(th_name):
                continue

            cv = top_conv(rewr_conv(th_name))
            th = cv.eval(thy, cur_th.prop)
            new_goal = th.prop.rhs
            new_As = list(th.hyps)
            if cur_th.prop != new_goal:
                if Term.is_equals(new_goal) and new_goal.lhs == new_goal.rhs:
                    results.append({"theorem": th_name, "_goal": new_As})
                else:
                    results.append({
                        "theorem": th_name,
                        "_goal": [new_goal] + new_As
                    })

        return sorted(results, key=lambda d: d['theorem'])
Beispiel #27
0
        def from_json(cls, json_item):
            context = list(map(Binding.from_json, json_item['context']))

            # FIXME that is weird!
            if json_item['arity']['type'] == "template":
                arity = Term.from_json(json_item['arity']['arity'])
            else:
                arity = Term.from_json(json_item['arity']['arity'])

            ind = cls(
                json_item['name'], context, arity,
                list(
                    map(MutInductive.Constructor.from_json,
                        json_item['constructors'])))

            ind.raw_arity = Term.from_json(json_item['arity']['arity'])
            return ind
Beispiel #28
0
 def testPrintThmHighlight(self):
     """Test printing of theorems with highlight."""
     # 0, 1, 2, 3 = NORMAL, BOUND, VAR, TVAR
     A = Var('A', boolT)
     B = Var('B', boolT)
     A_to_B = Term.mk_implies(A, B)
     th = Thm([A, A_to_B], B)
     res = printer.print_thm(thy, th, highlight=True)
     self.assertEqual(res, [('A',2),(', ',0),('A',2),(' --> ',0),('B',2),(' ',0),('|-',0),(' ',0),('B',2)])
Beispiel #29
0
 def get_proof_term(self, thy, goal, *, args=None, prevs=None):
     th_name, var = args
     P = Term.mk_abs(var, goal.prop)
     th = thy.get_theorem(th_name)
     f, args = th.concl.strip_comb()
     if len(args) != 1:
         raise NotImplementedError
     inst = {f.name: P, args[0].name: var}
     return rule().get_proof_term(thy, goal, args=(th_name, ({}, inst)))
Beispiel #30
0
def solve(t):
    """Solve the given goal using Z3."""
    s = z3.Solver()

    # First strip foralls from t.
    while Term.is_all(t):
        t = t.arg.subst_bound(Var(t.arg.var_name, t.arg.var_T))
    s.add(z3.Not(convert(t)))
    return str(s.check()) == 'unsat'