Ejemplo n.º 1
0
    def testAddLineBefore(self):
        state = ProofState.init_state(thy, [A, B], [conj(A, B)], conj(B, A))

        state.add_line_before(2, 1)
        self.assertEqual(len(state.prf.items), 4)
        self.assertEqual(state.check_proof(), Thm.mk_implies(conj(A, B), conj(B, A)))

        state.add_line_before(2, 3)
        self.assertEqual(len(state.prf.items), 7)
        self.assertEqual(state.check_proof(), Thm.mk_implies(conj(A, B), conj(B, A)))
Ejemplo n.º 2
0
    def testCheckProofGap(self):
        """Check proof with gap."""
        prf = Proof()
        prf.add_item(0, "sorry", th = Thm.mk_implies(A,B))
        prf.add_item(1, "sorry", th = Thm([], A))
        prf.add_item(2, "implies_elim", prevs=[0, 1])

        rpt = ProofReport()
        self.assertEqual(thy.check_proof(prf, rpt), Thm([], B))
        self.assertEqual(rpt.gaps, [Thm.mk_implies(A, B), Thm([], A)])
Ejemplo n.º 3
0
    def testCheckProof4(self):
        """Proof of |- x = y --> x = y by instantiating an existing theorem."""
        thy = Theory.EmptyTheory()
        thy.add_theorem("trivial", Thm.mk_implies(A,A))

        x_eq_y = Term.mk_equals(x,y)
        prf = Proof()
        prf.add_item(0, "theorem", args="trivial")
        prf.add_item(1, "substitution", args={"A" : x_eq_y}, prevs=[0])

        rpt = ProofReport()
        th = Thm.mk_implies(x_eq_y,x_eq_y)
        self.assertEqual(thy.check_proof(prf, rpt), th)
        self.assertEqual(rpt.steps, 2)
Ejemplo n.º 4
0
    def testCheckProof5(self):
        """Empty instantiation."""
        thy = Theory.EmptyTheory()
        thy.add_theorem("trivial", Thm.mk_implies(A,A))

        x_eq_y = Term.mk_equals(x,y)
        prf = Proof()
        prf.add_item(0, "theorem", args="trivial")
        prf.add_item(1, "substitution", args={}, prevs=[0])

        rpt = ProofReport()
        th = Thm.mk_implies(A,A)
        self.assertEqual(thy.check_proof(prf, rpt), th)
        self.assertEqual(rpt.steps_stat(), (1, 1, 0))
        self.assertEqual(rpt.th_names, {"trivial"})
Ejemplo n.º 5
0
    def testDoubleNegInv(self):
        """Proof of ~~A --> A, requires classical axiom."""
        thy = basic.load_theory('logic_base')
        A = Var("A", boolT)
        neg = logic.neg

        prf = Proof(neg(neg(A)))
        prf.add_item(1, "theorem", args="classical")
        prf.add_item(2, "assume", args=A)
        prf.add_item(3, "assume", args=neg(A))
        prf.add_item(4, "theorem", args="negE")
        prf.add_item(5, "substitution", args={"A": neg(A)}, prevs=[4])
        prf.add_item(6, "implies_elim", prevs=[5, 0])
        prf.add_item(7, "implies_elim", prevs=[6, 3])
        prf.add_item(8, "theorem", args="falseE")
        prf.add_item(9, "implies_elim", prevs=[8, 7])
        prf.add_item(10, "implies_intr", args=A, prevs=[2])
        prf.add_item(11, "implies_intr", args=neg(A), prevs=[9])
        prf.add_item(12, "theorem", args="disjE")
        prf.add_item(13,
                     "substitution",
                     args={
                         "B": neg(A),
                         "C": A
                     },
                     prevs=[12])
        prf.add_item(14, "implies_elim", prevs=[13, 1])
        prf.add_item(15, "implies_elim", prevs=[14, 10])
        prf.add_item(16, "implies_elim", prevs=[15, 11])
        prf.add_item(17, "implies_intr", args=neg(neg(A)), prevs=[16])
        th = Thm.mk_implies(neg(neg(A)), A)
        self.assertEqual(thy.check_proof(prf), th)
Ejemplo n.º 6
0
    def testAddLineAfter(self):
        state = ProofState.init_state(thy, [A, B], [conj(A, B)], conj(B, A))

        state.add_line_after(0)
        self.assertEqual(len(state.prf.items), 4)
        self.assertEqual(state.check_proof(), Thm.mk_implies(conj(A, B), conj(B, A)))
        self.assertEqual(state.prf.items[1].rule, "")
Ejemplo n.º 7
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)
Ejemplo n.º 8
0
    def testDisjCommWithMacro(self):
        """Proof of commutativity of disjunction, with macros."""
        thy = basic.load_theory('logic_base')
        A = Var("A", boolT)
        B = Var("B", boolT)
        disjAB = logic.mk_disj(A, B)
        disjBA = logic.mk_disj(B, A)

        prf = Proof(disjAB)
        prf.add_item(1, "assume", args=A)
        prf.add_item(2,
                     "apply_theorem_for",
                     args=("disjI2", {}, {
                         "A": B,
                         "B": A
                     }),
                     prevs=[1])
        prf.add_item(3, "implies_intr", args=A, prevs=[2])
        prf.add_item(4, "assume", args=B)
        prf.add_item(5,
                     "apply_theorem_for",
                     args=("disjI1", {}, {
                         "A": B,
                         "B": A
                     }),
                     prevs=[4])
        prf.add_item(6, "implies_intr", args=B, prevs=[5])
        prf.add_item(7, "apply_theorem", args="disjE", prevs=[0, 3, 6])
        prf.add_item(8, "implies_intr", args=disjAB, prevs=[7])
        th = Thm.mk_implies(disjAB, disjBA)
        self.assertEqual(thy.check_proof(prf), th)
Ejemplo n.º 9
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"))
Ejemplo n.º 10
0
 def testConjComm(self):
     """Proof of A & B --> B & A."""
     state = ProofState.init_state(thy, [A, B], [conj(A, B)], conj(B, A))
     state.apply_backward_step(1, "conjI")
     state.apply_backward_step(1, "conjD2", prevs=[0])
     state.apply_backward_step(2, "conjD1", prevs=[0])
     self.assertEqual(state.check_proof(no_gaps=True), Thm.mk_implies(conj(A, B), conj(B, A)))
Ejemplo n.º 11
0
 def testDoubleNegInv(self):
     """Proof of ~~A --> A."""
     state = ProofState.init_state(thy, [A], [neg(neg(A))], A)
     state.apply_cases(1, A)
     state.introduction(1)
     state.introduction(2)
     state.apply_backward_step((2, 1), "negE_gen", prevs=[0])
     self.assertEqual(state.check_proof(no_gaps=True), Thm.mk_implies(neg(neg(A)), A))
Ejemplo n.º 12
0
    def testCheckProof2(self):
        """Proof of |- A --> A."""
        prf = Proof(A)
        prf.add_item(1, "implies_intr", args=A, prevs=[0])

        rpt = ProofReport()
        self.assertEqual(thy.check_proof(prf, rpt), Thm.mk_implies(A,A))
        self.assertEqual(rpt.steps, 2)
Ejemplo n.º 13
0
 def testDisjComm(self):
     """Proof of A | B --> B | A."""
     state = ProofState.init_state(thy, [A, B], [disj(A, B)], disj(B, A))
     state.apply_backward_step(1, "disjE", prevs=[0])
     state.introduction(1)
     state.apply_backward_step((1, 1), "disjI2", prevs=[(1, 0)])
     state.introduction(2)
     state.apply_backward_step((2, 1), "disjI1", prevs=[(2, 0)])
     self.assertEqual(state.check_proof(no_gaps=True), Thm.mk_implies(disj(A, B), disj(B, A)))
Ejemplo n.º 14
0
    def testConjCommWithMacro(self):
        """Proof of commutativity of conjunction, with macros."""
        thy = basic.load_theory('logic_base')
        A = Var("A", boolT)
        B = Var("B", boolT)

        prf = Proof(logic.mk_conj(A, B))
        prf.add_item(1, "apply_theorem", args="conjD1", prevs=[0])
        prf.add_item(2, "apply_theorem", args="conjD2", prevs=[0])
        prf.add_item(3, "apply_theorem", args="conjI", prevs=[2, 1])
        prf.add_item(4, "implies_intr", args=logic.mk_conj(A, B), prevs=[3])
        th = Thm.mk_implies(logic.mk_conj(A, B), logic.mk_conj(B, A))
        self.assertEqual(thy.check_proof(prf), th)
Ejemplo n.º 15
0
    def testInductPredicate(self):
        nat = Type("nat")
        even = Const("even", TFun(nat, boolT))
        zero = Const("zero", nat)
        Suc = Const("Suc", TFun(nat, nat))
        n = Var("n", nat)
        prop_zero = even(zero)
        prop_Suc = Term.mk_implies(even(n), even(Suc(Suc(n))))
        data = [("even_zero", prop_zero), ("even_Suc", prop_Suc)]
        even_ext = induct.add_induct_predicate("even", TFun(nat, boolT), data)
        a1 = Var("_a1", nat)
        P = Var("P", boolT)

        res = [
            AxConstant("even", TFun(nat, boolT)),
            Theorem("even_zero", Thm([], even(zero))),
            Attribute("even_zero", "hint_backward"),
            Theorem("even_Suc", Thm.mk_implies(even(n), even(Suc(Suc(n))))),
            Attribute("even_Suc", "hint_backward"),
            Theorem("even_cases", Thm.mk_implies(even(a1), imp(eq(a1,zero), P), all(n, imp(eq(a1,Suc(Suc(n))), even(n), P)), P))
        ]
        self.assertEqual(even_ext.data, res)
Ejemplo n.º 16
0
    def testCombination(self):
        """Test arg and fun combination together using proofs."""
        thy = basic.load_theory('logic_base')

        prf = Proof(Term.mk_equals(f, g), Term.mk_equals(x, y))
        prf.add_item(2, "arg_combination", args=f, prevs=[1])
        prf.add_item(3, "fun_combination", args=y, prevs=[0])
        prf.add_item(4, "transitive", prevs=[2, 3])
        prf.add_item(5, "implies_intr", args=Term.mk_equals(x, y), prevs=[4])
        prf.add_item(6, "implies_intr", args=Term.mk_equals(f, g), prevs=[5])
        th = Thm.mk_implies(Term.mk_equals(f, g), Term.mk_equals(x, y),
                            Term.mk_equals(f(x), g(y)))
        self.assertEqual(thy.check_proof(prf), th)
Ejemplo n.º 17
0
 def testIntersection(self):
     """Proof of x : A INTER B --> x : A."""
     thy = basic.load_theory('set')
     x = Var('x', Ta)
     A = Var('A', set.setT(Ta))
     B = Var('B', set.setT(Ta))
     x_in_AB = set.mk_mem(x, set.mk_inter(A, B))
     x_in_A = set.mk_mem(x, A)
     prf = Proof(x_in_AB)
     prf.add_item(1, "rewrite_fact", args="member_inter_iff", prevs=[0])
     prf.add_item(2, "apply_theorem", args="conjD1", prevs=[1])
     prf.add_item(3, "implies_intr", args=x_in_AB, prevs=[2])
     self.assertEqual(thy.check_proof(prf), Thm.mk_implies(x_in_AB, x_in_A))
Ejemplo n.º 18
0
 def testExistsConj(self):
     """Proof of (?x. A x & B x) --> (?x. A x) & (?x. B x)."""
     Ta = TVar("a")
     A = Var("A", TFun(Ta, boolT))
     B = Var("B", TFun(Ta, boolT))
     x = Var("x", Ta)
     ex_conj = exists(x, conj(A(x), B(x)))
     conj_ex = conj(exists(x, A(x)), exists(x, B(x)))
     state = ProofState.init_state(thy, [A, B], [ex_conj], conj_ex)
     state.apply_backward_step(1, "exE", prevs=[0])
     state.introduction(1, "x")
     state.apply_backward_step((1, 2), "conjI")
     state.apply_forward_step((1, 2), "conjD1", prevs=[(1, 1)])
     state.apply_backward_step((1, 3), "exI", prevs=[(1, 2)])
     state.apply_forward_step((1, 4), "conjD2", prevs=[(1, 1)])
     state.apply_backward_step((1, 5), "exI", prevs=[(1, 4)])
     self.assertEqual(state.check_proof(no_gaps=True), Thm.mk_implies(ex_conj, conj_ex))
Ejemplo n.º 19
0
    def testDoubleNeg(self):
        """Proof of A --> ~~A."""
        thy = basic.load_theory('logic_base')
        A = Var("A", boolT)
        neg = logic.neg

        prf = Proof(A)
        prf.add_item(1, "assume", args=neg(A))
        prf.add_item(2, "theorem", args="negE")
        prf.add_item(3, "implies_elim", prevs=[2, 1])
        prf.add_item(4, "implies_elim", prevs=[3, 0])
        prf.add_item(5, "implies_intr", args=neg(A), prevs=[4])
        prf.add_item(6, "theorem", args="negI")
        prf.add_item(7, "substitution", args={"A": neg(A)}, prevs=[6])
        prf.add_item(8, "implies_elim", prevs=[7, 5])
        prf.add_item(9, "implies_intr", args=A, prevs=[8])
        th = Thm.mk_implies(A, neg(neg(A)))
        self.assertEqual(thy.check_proof(prf), th)
Ejemplo n.º 20
0
    def testDoubleNegInvWithMacro(self):
        """Proof of ~~A --> A, using macros."""
        thy = basic.load_theory('logic_base')
        A = Var("A", boolT)
        neg = logic.neg

        prf = Proof(neg(neg(A)))
        prf.add_item(1, "theorem", args="classical")
        prf.add_item(2, "assume", args=A)
        prf.add_item(3, "assume", args=neg(A))
        prf.add_item(4, "apply_theorem", args="negE", prevs=[0, 3])
        prf.add_item(5, "apply_theorem", args="falseE", prevs=[4])
        prf.add_item(6, "implies_intr", args=A, prevs=[2])
        prf.add_item(7, "implies_intr", args=neg(A), prevs=[5])
        prf.add_item(8, "apply_theorem", args="disjE", prevs=[1, 6, 7])
        prf.add_item(9, "implies_intr", args=neg(neg(A)), prevs=[8])
        th = Thm.mk_implies(neg(neg(A)), A)
        self.assertEqual(thy.check_proof(prf), th)
Ejemplo n.º 21
0
    def testConjComm(self):
        """Proof of commutativity of conjunction."""
        thy = basic.load_theory('logic_base')
        A = Var("A", boolT)
        B = Var("B", boolT)

        prf = Proof(logic.mk_conj(A, B))
        prf.add_item(1, "theorem", args="conjD1")
        prf.add_item(2, "implies_elim", prevs=[1, 0])
        prf.add_item(3, "theorem", args="conjD2")
        prf.add_item(4, "implies_elim", prevs=[3, 0])
        prf.add_item(5, "theorem", args="conjI")
        prf.add_item(6, "substitution", args={"A": B, "B": A}, prevs=[5])
        prf.add_item(7, "implies_elim", prevs=[6, 4])
        prf.add_item(8, "implies_elim", prevs=[7, 2])
        prf.add_item(9, "implies_intr", args=logic.mk_conj(A, B), prevs=[8])
        th = Thm.mk_implies(logic.mk_conj(A, B), logic.mk_conj(B, A))
        self.assertEqual(thy.check_proof(prf), th)
Ejemplo n.º 22
0
    def testTrueAbsorb(self):
        """Proof of A --> true & A."""
        thy = basic.load_theory('logic_base')
        A = Var("A", boolT)

        prf = Proof(A)
        prf.add_item(1, "theorem", args="trueI")
        prf.add_item(2, "theorem", args="conjI")
        prf.add_item(3,
                     "substitution",
                     args={
                         "A": logic.true,
                         "B": A
                     },
                     prevs=[2])
        prf.add_item(4, "implies_elim", prevs=[3, 1])
        prf.add_item(5, "implies_elim", prevs=[4, 0])
        prf.add_item(6, "implies_intr", args=A, prevs=[5])
        th = Thm.mk_implies(A, logic.mk_conj(logic.true, A))
        self.assertEqual(thy.check_proof(prf), th)
Ejemplo n.º 23
0
    def testBetaNorm(self):
        thy = basic.load_theory('logic_base')

        t = Term.mk_abs(x, f(x))
        prf = Proof(Term.mk_equals(t(x), y))
        prf.add_item(1, "beta_norm", prevs=[0])
        prf.add_item(2,
                     "implies_intr",
                     args=Term.mk_equals(t(x), y),
                     prevs=[1])

        th = Thm.mk_implies(Term.mk_equals(t(x), y), Term.mk_equals(f(x), y))
        rpt = ProofReport()
        self.assertEqual(thy.check_proof(prf, rpt), th)
        self.assertEqual(rpt.prim_steps, 8)

        rpt2 = ProofReport()
        self.assertEqual(thy.check_proof(prf, rpt2, check_level=1), th)
        self.assertEqual(rpt2.prim_steps, 2)
        self.assertEqual(rpt2.macro_steps, 1)
Ejemplo n.º 24
0
    def testDisjComm(self):
        """Proof of commutativity of disjunction."""
        thy = basic.load_theory('logic_base')
        A = Var("A", boolT)
        B = Var("B", boolT)
        disjAB = logic.mk_disj(A, B)
        disjBA = logic.mk_disj(B, A)

        prf = Proof(disjAB)
        prf.add_item(1, "theorem", args="disjI2")
        prf.add_item(2, "substitution", args={"A": B, "B": A}, prevs=[1])
        prf.add_item(3, "theorem", args="disjI1")
        prf.add_item(4, "substitution", args={"A": B, "B": A}, prevs=[3])
        prf.add_item(5, "theorem", args="disjE")
        prf.add_item(6, "substitution", args={"C": disjBA}, prevs=[5])
        prf.add_item(7, "implies_elim", prevs=[6, 0])
        prf.add_item(8, "implies_elim", prevs=[7, 2])
        prf.add_item(9, "implies_elim", prevs=[8, 4])
        prf.add_item(10, "implies_intr", args=disjAB, prevs=[9])
        th = Thm.mk_implies(disjAB, disjBA)
        self.assertEqual(thy.check_proof(prf), th)
Ejemplo n.º 25
0
    def testAllConjWithMacro(self):
        """Proof of (!x. A x & B x) --> (!x. A x) & (!x. B x), using macros."""
        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, "apply_theorem", args="conjD1", prevs=[1])
        prf.add_item(3, "forall_intr", args=x, prevs=[2])
        prf.add_item(4, "apply_theorem", args="conjD2", prevs=[1])
        prf.add_item(5, "forall_intr", args=x, prevs=[4])
        prf.add_item(6, "apply_theorem", args="conjI", prevs=[3, 5])
        prf.add_item(7, "implies_intr", args=all_conj, prevs=[6])
        th = Thm.mk_implies(all_conj, conj_all)
        self.assertEqual(thy.check_proof(prf), th)
Ejemplo n.º 26
0
    def testExistsConjWithMacro(self):
        """Proof of (?x. A x & B x) --> (?x. A x) & (?x. B x), using macros."""
        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)
        conjAB = logic.mk_conj(A(x), B(x))
        exists_conj = logic.mk_exists(x, conjAB)
        exists_A = logic.mk_exists(x, A(x))
        exists_B = logic.mk_exists(x, B(x))
        conj_exists = logic.mk_conj(exists_A, exists_B)

        prf = Proof(exists_conj)
        prf.add_item(1, "assume", args=conjAB)
        prf.add_item(2, "apply_theorem", args="conjD1", prevs=[1])
        prf.add_item(3, "apply_theorem", args="conjD2", prevs=[1])
        prf.add_item(4,
                     "apply_theorem_for",
                     args=("exI", {}, {
                         'P': A,
                         'a': x
                     }),
                     prevs=[2])
        prf.add_item(5,
                     "apply_theorem_for",
                     args=("exI", {}, {
                         'P': B,
                         'a': x
                     }),
                     prevs=[3])
        prf.add_item(6, "apply_theorem", args="conjI", prevs=[4, 5])
        prf.add_item(7, "implies_intr", args=conjAB, prevs=[6])
        prf.add_item(8, "forall_intr", args=x, prevs=[7])
        prf.add_item(9, "apply_theorem", args="exE", prevs=[0, 8])
        prf.add_item(10, "implies_intr", args=exists_conj, prevs=[9])
        th = Thm.mk_implies(exists_conj, conj_exists)
        self.assertEqual(thy.check_proof(prf), th)
Ejemplo n.º 27
0
def add_induct_type(name, targs, constrs):
    """Add the given inductive type to the theory.
    
    The inductive type is specified by name, arity (as list of default
    names of type arguments), and a list of constructors (triple
    consisting of name of the constant, type of the constant, and a
    list of suggested names of the arguments).

    For example, the natural numbers is specified by:
    (nat, [], [(0, nat, []), (Suc, nat => nat, ["n"])]).

    List type is specified by:
    (list, ["a"], [(nil, 'a list, []), (cons, 'a => 'a list => 'a list, ["x", "xs"])]).

    """
    exts = TheoryExtension()

    # Add to type and term signature.
    exts.add_extension(AxType(name, len(targs)))
    for cname, cT, _ in constrs:
        exts.add_extension(AxConstant(cname, cT))

    # Add non-equality theorems.
    for (cname1, cT1, vars1), (cname2, cT2,
                               vars2) in itertools.combinations(constrs, 2):
        # For each A x_1 ... x_m and B y_1 ... y_n, get the theorem
        # ~ A x_1 ... x_m = B y_1 ... y_n.
        argT1, _ = cT1.strip_type()
        argT2, _ = cT2.strip_type()
        lhs_vars = [Var(nm, T) for nm, T in zip(vars1, argT1)]
        rhs_vars = [Var(nm, T) for nm, T in zip(vars2, argT2)]
        A = Const(cname1, cT1)
        B = Const(cname2, cT2)
        lhs = A(*lhs_vars)
        rhs = B(*rhs_vars)
        neq = logic.neg(Term.mk_equals(lhs, rhs))
        th_name = name + "_" + cname1 + "_" + cname2 + "_neq"
        exts.add_extension(Theorem(th_name, Thm([], neq)))

    # Add injectivity theorems.
    for cname, cT, vars in constrs:
        # For each A x_1 ... x_m with m > 0, get the theorem
        # A x_1 ... x_m = A x_1' ... x_m' --> x_1 = x_1' & ... & x_m = x_m'
        if vars:
            argT, _ = cT.strip_type()
            lhs_vars = [Var(nm, T) for nm, T in zip(vars, argT)]
            rhs_vars = [Var(nm + "'", T) for nm, T in zip(vars, argT)]
            A = Const(cname, cT)
            assum = Term.mk_equals(A(*lhs_vars), A(*rhs_vars))
            concls = [
                Term.mk_equals(var1, var2)
                for var1, var2 in zip(lhs_vars, rhs_vars)
            ]
            concl = logic.mk_conj(*concls) if len(concls) > 1 else concls[0]
            th_name = name + "_" + cname + "_inject"
            exts.add_extension(Theorem(th_name, Thm.mk_implies(assum, concl)))

    # Add the inductive theorem.
    tvars = [TVar(targ) for targ in targs]
    T = Type(name, *tvars)
    var_P = Var("P", TFun(T, boolT))
    ind_assums = []
    for cname, cT, vars in constrs:
        A = Const(cname, cT)
        argT, _ = cT.strip_type()
        args = [Var(nm, T2) for nm, T2 in zip(vars, argT)]
        C = var_P(A(*args))
        As = [var_P(Var(nm, T2)) for nm, T2 in zip(vars, argT) if T2 == T]
        ind_assum = Term.mk_implies(*(As + [C]))
        for arg in reversed(args):
            ind_assum = Term.mk_all(arg, ind_assum)
        ind_assums.append(ind_assum)
    ind_concl = var_P(Var("x", T))
    th_name = name + "_induct"
    exts.add_extension(
        Theorem(th_name, Thm.mk_implies(*(ind_assums + [ind_concl]))))
    exts.add_extension(Attribute(th_name, "var_induct"))

    return exts
Ejemplo n.º 28
0
 def testParseInitState(self):
     state = ProofState.parse_init_state(
         thy, {'vars': {'A': 'bool', 'B': 'bool'}, 'prop': "A & B --> B & A"})
     self.assertEqual(len(state.prf.items), 3)
     self.assertEqual(state.check_proof(), Thm.mk_implies(conj(A, B), conj(B, A)))
Ejemplo n.º 29
0
 def testInitProof2(self):
     state = ProofState.init_state(thy, [A, B], [A, B], conj(A, B))
     self.assertEqual(len(state.prf.items), 4)
     self.assertEqual(state.check_proof(), Thm.mk_implies(A, B, conj(A, B)))
Ejemplo n.º 30
0
 def testIntroduction2(self):
     state = ProofState.init_state(thy, [A, B], [], imp(A, B, conj(A, B)))
     state.introduction(0)
     self.assertEqual(state.check_proof(), Thm.mk_implies(A, B, conj(A, B)))