Beispiel #1
0
    def get_proof_term(self, t):
        def strip_conj_all(t):
            if t.is_conj():
                return strip_conj_all(t.arg1) + strip_conj_all(t.arg)
            else:
                return [t]

        conj_terms = term_ord.sorted_terms(strip_conj_all(t))
        goal = Eq(t, And(*conj_terms))
        return imp_conj_iff(goal)
Beispiel #2
0
    def add_invariant(self):
        """Add the invariant for the system in GCL."""
        s = Var("s", gcl.stateT)
        invC = Const("inv", TFun(gcl.stateT, BoolType))
        inv_rhs = And(
            *[gcl.convert_term(self.var_map, s, t) for _, t in self.invs])
        prop = Eq(invC(s), inv_rhs)

        exts = [
            extension.Constant("inv", TFun(gcl.stateT, BoolType)),
            extension.Theorem("inv_def", Thm([], prop))
        ]
        theory.thy.unchecked_extend(exts)
Beispiel #3
0
def convert_cnf_to_HOL(cnf_file):
    disjs = read_cnf_file(cnf_file)
    tms = []
    for disj in disjs:
        lits = []
        for var, stat in disj:
            if stat:
                lits.append(Var(var, BoolType))
            else:
                lits.append(Not(Var(var, BoolType)))
        tms.append(Or(*lits))

    return And(*tms)
Beispiel #4
0
    def testPrintUnicode(self):
        test_data = [
            (And(A, B), "A ∧ B"),
            (Or(A, B), "A ∨ B"),
            (Implies(A, B), "A ⟶ B"),
            (Lambda(a, P(a)), "λa. P a"),
            (Forall(a, P(a)), "∀a. P a"),
            (Exists(a, P(a)), "∃a. P a"),
            (Not(A), "¬A"),
            (Lambda(m, m + 2), "λm::nat. m + 2"),
            (Lambda(m, m + n), "λm. m + n"),
        ]

        with global_setting(unicode=True):
            for t, s in test_data:
                self.assertEqual(printer.print_term(t), s)
Beispiel #5
0
    def testParseThm(self):
        A = Var('A', BoolType)
        B = Var('B', BoolType)
        C = Var('C', BoolType)
        test_data = [
            ("|- A", Thm([], A)),
            ("|- A & B", Thm([], And(A, B))),
            ("A |- B", Thm([A], B)),
            ("A, B |- C", Thm([A, B], C)),
        ]

        context.set_context('logic',
                            vars={
                                'A': 'bool',
                                'B': 'bool',
                                'C': 'bool'
                            })
        for s, th in test_data:
            self.assertEqual(parser.parse_thm(s), th)
Beispiel #6
0
def nnf(fm):
    """Negation normal form of a formula."""
    if fm.is_conj():
        return And(nnf(fm.arg1), nnf(fm.arg))
    elif fm.is_disj():
        return Or(nnf(fm.arg1), nnf(fm.arg))
    elif fm.is_implies():
        return Or(nnf(Not(fm.arg1)), nnf(fm.arg))
    elif fm.is_equals():
        return Or(And(nnf(fm.arg1), nnf(fm.arg)),
                  And(nnf(Not(fm.arg1)), nnf(Not(fm.arg))))
    elif fm.is_not():
        p = fm.arg
        if p.is_not():
            return nnf(p.arg)
        elif p.is_conj():
            return Or(nnf(Not(p.arg1)), nnf(Not(p.arg)))
        elif p.is_disj():
            return And(nnf(Not(p.arg1)), nnf(Not(p.arg)))
        elif p.is_implies():
            return And(nnf(p.arg1), nnf(Not(p.arg)))
        elif p.is_equals():
            return Or(And(nnf(p.arg1), nnf(Not(p.arg))),
                      And(nnf(Not(p.arg1)), nnf(p.arg)))
        elif p.is_forall():
            assert p.arg.is_abs()
            return term.exists(p.arg.var_T)(Abs(p.arg.var_name, p.arg.var_T,
                                                nnf(Not(p.arg.body))))
        elif p.is_exists():
            assert p.arg.is_abs()
            return term.forall(p.arg.var_T)(Abs(p.arg.var_name, p.arg.var_T,
                                                nnf(Not(p.arg.body))))
        else:
            return fm
    elif fm.is_forall() or fm.is_exists():
        assert fm.arg.is_abs()
        return fm.fun(Abs(fm.arg.var_name, fm.arg.var_T, nnf(fm.arg.body)))
    else:
        return fm
Beispiel #7
0
    def testPrintLogical(self):
        test_data = [
            # Variables
            (SVar("P", BoolType), "?P"),
            (a, "a"),

            # Equality and implies
            (Eq(a, b), "a = b"),
            (Implies(A, B), "A --> B"),
            (Implies(A, B, C), "A --> B --> C"),
            (Implies(Implies(A, B), C), "(A --> B) --> C"),
            (Implies(A, Eq(a, b)), "A --> a = b"),
            (Eq(Implies(A, B), Implies(B, C)), "(A --> B) <--> (B --> C)"),
            (Eq(A, Eq(B, C)), "A <--> B <--> C"),
            (Eq(Eq(A, B), C), "(A <--> B) <--> C"),

            # Conjunction and disjunction
            (And(A, B), "A & B"),
            (Or(A, B), "A | B"),
            (And(A, And(B, C)), "A & B & C"),
            (And(And(A, B), C), "(A & B) & C"),
            (Or(A, Or(B, C)), "A | B | C"),
            (Or(Or(A, B), C), "(A | B) | C"),
            (Or(And(A, B), C), "A & B | C"),
            (And(Or(A, B), C), "(A | B) & C"),
            (Or(A, And(B, C)), "A | B & C"),
            (And(A, Or(B, C)), "A & (B | C)"),
            (Or(And(A, B), And(B, C)), "A & B | B & C"),
            (And(Or(A, B), Or(B, C)), "(A | B) & (B | C)"),

            # Negation
            (Not(A), "~A"),
            (Not(Not(A)), "~~A"),

            # Constants
            (true, "true"),
            (false, "false"),

            # Mixed
            (Implies(And(A, B), C), "A & B --> C"),
            (Implies(A, Or(B, C)), "A --> B | C"),
            (And(A, Implies(B, C)), "A & (B --> C)"),
            (Or(Implies(A, B), C), "(A --> B) | C"),
            (Not(And(A, B)), "~(A & B)"),
            (Not(Implies(A, B)), "~(A --> B)"),
            (Not(Eq(A, B)), "~(A <--> B)"),
            (Eq(Not(A), B), "~A <--> B"),
            (Eq(Not(A), Not(B)), "~A <--> ~B"),
            (Implies(A, Eq(B, C)), "A --> B <--> C"),
            (Eq(Implies(A, B), C), "(A --> B) <--> C"),

            # Abstraction
            (Lambda(a, And(P(a), Q(a))), "%a. P a & Q a"),

            # Quantifiers
            (Forall(a, P(a)), "!a. P a"),
            (Forall(a, Forall(b, And(P(a), P(b)))), "!a. !b. P a & P b"),
            (Forall(a, And(P(a), Q(a))), "!a. P a & Q a"),
            (And(Forall(a, P(a)), Q(a)), "(!a1. P a1) & Q a"),
            (Forall(a, Implies(P(a), Q(a))), "!a. P a --> Q a"),
            (Implies(Forall(a, P(a)), Q(a)), "(!a1. P a1) --> Q a"),
            (Implies(Forall(a, P(a)),
                     Forall(a, Q(a))), "(!a. P a) --> (!a. Q a)"),
            (Implies(Exists(a, P(a)),
                     Exists(a, Q(a))), "(?a. P a) --> (?a. Q a)"),
            (Eq(A, Forall(a, P(a))), "A <--> (!a. P a)"),
            (Exists(a, P(a)), "?a. P a"),
            (Exists(a, Forall(b, R(a, b))), "?a. !b. R a b"),
            (logic.mk_exists1(a, P(a)), "?!a. P a"),
            (logic.mk_the(a, P(a)), "THE a. P a"),
            (logic.mk_some(a, P(a)), "SOME a. P a"),
            (Forall(a, Exists(b, R(a, b))), "!a. ?b. R a b"),

            # If
            (mk_if(A, a, b), "if A then a else b"),
            (Eq(mk_if(A, a, b), a), "(if A then a else b) = a"),
            (mk_if(A, P, Q), "if A then P else Q"),
        ]

        with global_setting(unicode=False):
            for t, s in test_data:
                self.assertEqual(printer.print_term(t), s)
Beispiel #8
0
    def testStripConj(self):
        test_data = [(a, [a]), (And(a, b, a), [a, b, a])]

        for t, res in test_data:
            self.assertEqual(t.strip_conj(), res)
Beispiel #9
0
    def testConj(self):
        test_data = [([], term.true), ([a], a), ([a, b], term.conj(a, b)),
                     ([a, b, a], term.conj(a, term.conj(b, a)))]

        for ts, res in test_data:
            self.assertEqual(And(*ts), res)
Beispiel #10
0
    def get_proof_term(self, t):

        if not t.is_conj():
            return refl(t)

        d_pos = dict()
        d_neg = dict()
        qu = deque([ProofTerm.assume(t)])
        # collect each conjunct's proof term in conjuntion
        while qu:
            pt = qu.popleft()
            if pt.prop.is_conj():
                conj1, conj2 = pt.prop.arg1, pt.prop.arg
                pt_conj1, pt_conj2 = apply_theorem('conjD1',
                                                   pt), apply_theorem(
                                                       'conjD2', pt)
                if conj1 == false:
                    th = ProofTerm.theorem("falseE")
                    inst = matcher.first_order_match(th.prop.arg, t)
                    pt_false_implies_conj = th.substitution(inst)
                    return ProofTerm.equal_intr(pt_conj1.implies_intr(t),
                                                pt_false_implies_conj)
                elif conj2 == false:
                    th = ProofTerm.theorem("falseE")
                    inst = matcher.first_order_match(th.prop.arg, t)
                    pt_false_implies_conj = th.substitution(inst)
                    return ProofTerm.equal_intr(pt_conj2.implies_intr(t),
                                                pt_false_implies_conj)
                if conj1.is_conj():
                    qu.appendleft(pt_conj1)
                else:
                    if conj1.is_not():
                        d_neg[conj1] = pt_conj1
                    else:
                        d_pos[conj1] = pt_conj1
                if conj2.is_conj():
                    qu.appendleft(pt_conj2)
                else:
                    if conj2.is_not():
                        d_neg[conj2] = pt_conj2
                    else:
                        d_pos[conj2] = pt_conj2
            else:
                if pt.prop.is_not():
                    d_neg[pt.prop] = pt
                else:
                    d_pos[pt.prop] = pt

        # first check if there are opposite terms in conjunctions, if there exists, return a false proof term
        for key in d_pos:
            if Not(key) in d_neg:
                pos_pt, neg_pt = d_pos[key], d_neg[Not(key)]
                pt_conj_pos_neg = apply_theorem("conjI", pos_pt, neg_pt)
                pt_conj_implies_false = pt_conj_pos_neg.on_prop(
                    rewr_conv("conj_pos_neg")).implies_intr(t)
                th = ProofTerm.theorem("falseE")
                inst = matcher.first_order_match(th.prop.arg, t)
                pt_false_implies_conj = th.substitution(inst)
                return ProofTerm.equal_intr(pt_conj_implies_false,
                                            pt_false_implies_conj)

        d_pos.update(d_neg)
        d = d_pos

        def right_assoc(ts):
            l = len(ts)
            if l == 1:
                return d[ts[0]]
            elif l == 2:
                return apply_theorem('conjI', d[ts[0]], d[ts[1]])
            else:
                return apply_theorem('conjI', d[ts[0]], right_assoc(ts[1:]))

        # pt_right = functools.reduce(lambda x, y: apply_theorem('conjI', x, d[y]), sorted(d.keys()), d[sorted(d.keys())[0]])
        if true not in d:
            sorted_keys = term_ord.sorted_terms(d.keys())
        else:
            d_keys_without_true = term_ord.sorted_terms(
                [k for k in d if k != true])
            sorted_keys = [true] + d_keys_without_true
        sorted_keys_num = len(sorted_keys)
        pt_right = functools.reduce(lambda x, y: apply_theorem('conjI', d[sorted_keys[sorted_keys_num - y - 2]], x), \
                        range(sorted_keys_num - 1), d[sorted_keys[-1]])
        # pt_right = right_assoc(sorted_keys)
        # order implies original
        dd = dict()
        norm_conj = And(*sorted_keys)
        norm_conj_pt = ProofTerm.assume(norm_conj)
        for k in sorted_keys:
            if k != sorted_keys[-1]:
                dd[k] = apply_theorem('conjD1', norm_conj_pt)
                norm_conj_pt = apply_theorem('conjD2', norm_conj_pt)
            else:
                dd[k] = norm_conj_pt

        def traverse(t):
            if not t.is_conj():
                return dd[t]
            else:
                return apply_theorem('conjI', traverse(t.arg1),
                                     traverse(t.arg))

        pt_left = traverse(t)

        pt_final = ProofTerm.equal_intr(pt_right.implies_intr(t),
                                        pt_left.implies_intr(norm_conj))
        if true in d:
            return pt_final.on_rhs(rewr_conv("conj_true_left"),
                                   top_sweep_conv(sort_disj()))
        else:
            return pt_final.on_rhs(top_sweep_conv(sort_disj()))
Beispiel #11
0
 def conj(self, s, t):
     return And(s, t)
Beispiel #12
0
    def testParseProofRule(self):
        A = Var('A', BoolType)
        B = Var('B', BoolType)
        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=Inst(A=B, B=A), prevs=[4])),
            ({
                'id': "8",
                'rule': "implies_intr",
                'args': "conj A B",
                'prevs': ["7"],
                'th': ""
            }, ProofItem(8, "implies_intr", args=And(A, B), prevs=[7])),
            ({
                'id': "0",
                'rule': "sorry",
                'args': "",
                'prevs': [],
                'th': "conj A B |- conj B A"
            }, ProofItem(0, "sorry", th=Thm([And(A, B)], And(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", Inst(A=B, B=A)),
                       prevs=[4])),
        ]

        context.set_context('logic_base', vars={'A': 'bool', 'B': 'bool'})
        for s, res in test_data:
            self.assertEqual(parser.parse_proof_rule(s), res)
Beispiel #13
0
 def conj_cond(self, b1, b2):
     return And(b1, b2)
Beispiel #14
0
    def get_extension(self):
        assert self.error is None, "get_extension"
        res = []

        # Add to type and term signature.
        res.append(extension.TConst(self.name, len(self.args)))
        for constr in self.constrs:
            res.append(
                extension.Constant(constr['name'],
                                   constr['type'],
                                   ref_name=constr['cname']))

        # Add non-equality theorems.
        for constr1, constr2 in itertools.combinations(self.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, _ = constr1['type'].strip_type()
            argT2, _ = constr2['type'].strip_type()
            lhs_vars = [Var(nm, T) for nm, T in zip(constr1['args'], argT1)]
            rhs_vars = [Var(nm, T) for nm, T in zip(constr2['args'], argT2)]
            A = Const(constr1['name'], constr1['type'])
            B = Const(constr2['name'], constr2['type'])
            lhs = A(*lhs_vars)
            rhs = B(*rhs_vars)
            neq = Not(Eq(lhs, rhs))
            th_name = "%s_%s_%s_neq" % (self.name, constr1['name'],
                                        constr2['name'])
            res.append(extension.Theorem(th_name, Thm([], neq)))

        # Add injectivity theorems.
        for constr in self.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 constr['args']:
                argT, _ = constr['type'].strip_type()
                lhs_vars = [Var(nm, T) for nm, T in zip(constr['args'], argT)]
                rhs_vars = [
                    Var(nm + "1", T) for nm, T in zip(constr['args'], argT)
                ]
                A = Const(constr['name'], constr['type'])
                assum = Eq(A(*lhs_vars), A(*rhs_vars))
                concls = [
                    Eq(var1, var2) for var1, var2 in zip(lhs_vars, rhs_vars)
                ]
                concl = And(*concls)
                th_name = "%s_%s_inject" % (self.name, constr['name'])
                res.append(
                    extension.Theorem(th_name, Thm([], Implies(assum, concl))))

        # Add the inductive theorem.
        tvars = [TVar(targ) for targ in self.args]
        T = TConst(self.name, *tvars)
        var_P = Var("P", TFun(T, BoolType))
        ind_assums = []
        for constr in self.constrs:
            A = Const(constr['name'], constr['type'])
            argT, _ = constr['type'].strip_type()
            args = [Var(nm, T2) for nm, T2 in zip(constr['args'], argT)]
            C = var_P(A(*args))
            As = [
                var_P(Var(nm, T2)) for nm, T2 in zip(constr['args'], argT)
                if T2 == T
            ]
            ind_assum = Implies(*(As + [C]))
            for arg in reversed(args):
                ind_assum = Forall(arg, ind_assum)
            ind_assums.append(ind_assum)
        ind_concl = var_P(Var("x", T))
        th_name = self.name + "_induct"
        res.append(
            extension.Theorem(th_name,
                              Thm([], Implies(*(ind_assums + [ind_concl])))))
        res.append(extension.Attribute(th_name, "var_induct"))

        return res