예제 #1
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)
예제 #2
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)
예제 #3
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)
예제 #4
0
    def testParseThm(self):
        test_data = [
            ("|- A", Thm([], A)),
            ("|- A & B", Thm([], logic.mk_conj(A, B))),
            ("A |- B", Thm([A], B)),
            ("A, B |- C", Thm([A, B], C)),
        ]

        for s, th in test_data:
            self.assertEqual(parser.parse_thm(thy, ctxt, s), th)
예제 #5
0
    def testApplyTheorem(self):
        thy = basic.load_theory('logic_base')
        A = Var("A", boolT)
        B = Var("B", boolT)

        th = Thm([logic.mk_conj(A, B)], A)

        prf = Proof(logic.mk_conj(A, B))
        prf.add_item(1, "apply_theorem", args="conjD1", prevs=[0])
        rpt = ProofReport()
        self.assertEqual(thy.check_proof(prf, rpt), th)
        self.assertEqual(rpt.prim_steps, 4)

        # Reset data for the next check
        prf = Proof(logic.mk_conj(A, B))
        prf.add_item(1, "apply_theorem", args="conjD1", prevs=[0])
        rpt = ProofReport()
        self.assertEqual(thy.check_proof(prf, rpt, check_level=1), th)
        self.assertEqual(rpt.prim_steps, 1)
        self.assertEqual(rpt.macro_steps, 1)
예제 #6
0
    def add_invariant(self):
        """Add the invariant for the system in GCL."""
        s = Var("s", gcl.stateT)
        invC = Const("inv", TFun(gcl.stateT, boolT))
        inv_rhs = logic.mk_conj(
            *[gcl.convert_term(self.var_map, s, t) for _, t in self.invs])
        prop = Term.mk_equals(invC(s), inv_rhs)

        exts = extension.TheoryExtension()
        exts.add_extension(extension.AxConstant("inv", TFun(gcl.stateT,
                                                            boolT)))
        exts.add_extension(extension.Theorem("inv_def", Thm([], prop)))
        self.thy.unchecked_extend(exts)
예제 #7
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)
예제 #8
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)
예제 #9
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)
예제 #10
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
예제 #11
0
파일: parser.py 프로젝트: zhouwenfan/temp
 def conj(self, s, t):
     return logic.mk_conj(s, t)
예제 #12
0
    def testParseProofRule(self):
        test_data = [
            ({
                'id': "0",
                'rule': "theorem",
                'args': "conjD1",
                'prevs': [],
                'th': ""
            }, ProofItem(0, "theorem", args="conjD1", prevs=[])),
            ({
                'id': "2",
                'rule': "implies_elim",
                'args': "",
                'prevs': ["1", "0"],
                'th': ""
            }, ProofItem(2, "implies_elim", prevs=[1, 0])),
            ({
                'id': "5",
                'rule': "substitution",
                'args': "{A: B, B: A}",
                'prevs': ["4"],
                'th': ""
            }, ProofItem(5, "substitution", args={
                'A': B,
                'B': A
            }, prevs=[4])),
            ({
                'id': "8",
                'rule': "implies_intr",
                'args': "conj A B",
                'prevs': ["7"],
                'th': ""
            }, ProofItem(8,
                         "implies_intr",
                         args=logic.mk_conj(A, B),
                         prevs=[7])),
            ({
                'id': "0",
                'rule': "sorry",
                'args': "",
                'prevs': [],
                'th': "conj A B |- conj B A"
            },
             ProofItem(0,
                       "sorry",
                       th=Thm([logic.mk_conj(A, B)], logic.mk_conj(B, A)))),
            ({
                'id': "1",
                'rule': "",
                'args': "",
                'prevs': [],
                'th': ""
            }, ProofItem(1, "")),
            ({
                'id': "5",
                'rule': "apply_theorem_for",
                'args': "disjI1, {}, {A: B, B: A}",
                'prevs': [4],
                'th': ""
            },
             ProofItem(5,
                       "apply_theorem_for",
                       args=("disjI1", {}, {
                           'A': B,
                           'B': A
                       }),
                       prevs=[4])),
        ]

        for s, res in test_data:
            self.assertEqual(parser.parse_proof_rule(thy, ctxt, s), res)
예제 #13
0
def encode(t):
    """Convert a holpy term into an equisatisfiable CNF. The result
    is a pair (cnf, prop), where cnf is the CNF form, and prop is
    a theorem stating that t, together with equality assumptions,
    imply the statement in CNF.

    """
    # Find the list of logical subterms, remove duplicates.
    subterms = logic_subterms(t)
    subterms = list(OrderedDict.fromkeys(subterms))
    subterms_dict = dict()
    for i, st in enumerate(subterms):
        subterms_dict[st] = i

    # The subterm at index i corresponds to variable x(i+1).
    def get_var(i):
        return Var("x" + str(i + 1), boolT)

    # Obtain the results:
    # eqs -- list of equality assumptions
    # clauses -- list of clauses
    eqs = []
    clauses = []
    for i, st in enumerate(subterms):
        l = get_var(i)
        if st.is_implies() or st.is_equals() or logic.is_conj(
                st) or logic.is_disj(st):
            r1 = get_var(subterms_dict[st.arg1])
            r2 = get_var(subterms_dict[st.arg])
            f = st.head
            eqs.append(Term.mk_equals(l, f(r1, r2)))
            if st.is_implies():
                clauses.extend(encode_eq_imp(l, r1, r2))
            elif st.is_equals():
                clauses.extend(encode_eq_eq(l, r1, r2))
            elif logic.is_conj(st):
                clauses.extend(encode_eq_conj(l, r1, r2))
            else:  # st.is_disj()
                clauses.extend(encode_eq_disj(l, r1, r2))
        elif logic.is_neg(st):
            r = get_var(subterms_dict[st.arg])
            eqs.append(Term.mk_equals(l, logic.neg(r)))
            clauses.extend(encode_eq_neg(l, r))
        else:
            eqs.append(Term.mk_equals(l, st))

    clauses.append(get_var(len(subterms) - 1))

    # Final proposition: under the equality assumptions and the original
    # term t, can derive the conjunction of the clauses.
    th = Thm(eqs + [t], logic.mk_conj(*clauses))

    # Final CNF: for each clause, get the list of disjuncts.
    cnf = []

    def literal(t):
        if logic.is_neg(t):
            return (t.arg.name, False)
        else:
            return (t.name, True)

    for clause in clauses:
        cnf.append(list(literal(t) for t in logic.strip_disj(clause)))

    return cnf, th
예제 #14
0
    def testStripConj(self):
        test_data = [(a, [a]), (logic.mk_conj(a, b, a), [a, b, a])]

        for t, res in test_data:
            self.assertEqual(logic.strip_conj(t), res)
예제 #15
0
    def testConj(self):
        test_data = [([], logic.true), ([a], a), ([a, b], logic.conj(a, b)),
                     ([a, b, a], logic.conj(a, logic.conj(b, a)))]

        for ts, res in test_data:
            self.assertEqual(logic.mk_conj(*ts), res)
예제 #16
0
    def testExistsConj(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)
        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, "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, "theorem", args="conjD2")
        prf.add_item(6, "substitution", args={"A": A(x), "B": B(x)}, prevs=[5])
        prf.add_item(7, "implies_elim", prevs=[6, 1])
        prf.add_item(8, "theorem", args="exI")
        prf.add_item(9, "substitution", args={"P": A, "a": x}, prevs=[8])
        prf.add_item(10, "implies_elim", prevs=[9, 4])
        prf.add_item(11, "substitution", args={"P": B, "a": x}, prevs=[8])
        prf.add_item(12, "implies_elim", prevs=[11, 7])
        prf.add_item(13, "implies_intr", args=conjAB, prevs=[10])
        prf.add_item(14, "implies_intr", args=conjAB, prevs=[12])
        prf.add_item(15, "forall_intr", args=x, prevs=[13])
        prf.add_item(16, "forall_intr", args=x, prevs=[14])
        prf.add_item(17, "theorem", args="exE")
        prf.add_item(18,
                     "substitution",
                     args={
                         "P": Term.mk_abs(x, conjAB),
                         "C": exists_A
                     },
                     prevs=[17])
        prf.add_item(19, "beta_norm", prevs=[18])
        prf.add_item(20, "implies_elim", prevs=[19, 0])
        prf.add_item(21, "implies_elim", prevs=[20, 15])
        prf.add_item(22,
                     "substitution",
                     args={
                         "P": Term.mk_abs(x, conjAB),
                         "C": exists_B
                     },
                     prevs=[17])
        prf.add_item(23, "beta_norm", prevs=[22])
        prf.add_item(24, "implies_elim", prevs=[23, 0])
        prf.add_item(25, "implies_elim", prevs=[24, 16])
        prf.add_item(26, "theorem", args="conjI")
        prf.add_item(27,
                     "substitution",
                     args={
                         "A": exists_A,
                         "B": exists_B
                     },
                     prevs=[26])
        prf.add_item(28, "implies_elim", prevs=[27, 21])
        prf.add_item(29, "implies_elim", prevs=[28, 25])
        prf.add_item(30, "implies_intr", args=exists_conj, prevs=[29])
        th = Thm.mk_implies(exists_conj, conj_exists)
        self.assertEqual(thy.check_proof(prf), th)