Beispiel #1
0
 def eval(self, goal, prevs=None):
     if len(goal.get_vars()) != 0:
         raise ConvException
     try:
         if goal.is_equals():
             if real_eval(goal.lhs) == real_eval(goal.rhs):
                 return Thm([], Eq(goal, true))
             else:
                 return Thm([], Eq(goal, false))
         else:  # inequations
             lhs, rhs = real_eval(goal.arg1), real_eval(goal.arg)
             if goal.is_less():
                 return Thm([], Eq(goal, true)) if lhs < rhs else Thm(
                     [], Eq(goal, false))
             elif goal.is_less_eq():
                 return Thm([], Eq(goal, true)) if lhs <= rhs else Thm(
                     [], Eq(goal, false))
             elif goal.is_greater():
                 return Thm([], Eq(goal, true)) if lhs > rhs else Thm(
                     [], Eq(goal, false))
             elif goal.is_greater_eq():
                 return Thm([], Eq(goal, true)) if lhs >= rhs else Thm(
                     [], Eq(goal, false))
             else:
                 raise NotImplementedError
     except:
         raise ConvException
Beispiel #2
0
 def testEvalFunUpd(self):
     f = fun_upd_of_seq(1, 5)
     cv = function.fun_upd_eval_conv()
     prf = cv.get_proof_term(f(one)).export()
     self.assertEqual(theory.check_proof(prf), Thm([], Eq(f(one), Nat(5))))
     prf = cv.get_proof_term(f(zero)).export()
     self.assertEqual(theory.check_proof(prf), Thm([], Eq(f(zero), zero)))
Beispiel #3
0
    def testExport(self):
        """Basic case."""
        pt1 = ProofTerm.assume(Eq(x, y))
        pt2 = ProofTerm.assume(Eq(y, z))
        pt3 = pt1.transitive(pt2)

        prf = pt3.export()
        self.assertEqual(len(prf.items), 3)
        self.assertEqual(theory.check_proof(prf), pt3.th)
Beispiel #4
0
    def testParseNamedThm(self):
        A = Var('A', BoolType)
        B = Var('B', BoolType)
        test_data = [("conjI: A = B", ('conjI', Eq(A, B))),
                     ("A = B", (None, Eq(A, B)))]

        context.set_context('logic_base', vars={'A': 'bool', 'B': 'bool'})
        for s, res in test_data:
            self.assertEqual(parser.parse_named_thm(s), res)
Beispiel #5
0
    def testPrintWithType(self):
        test_data = [
            (list.nil(Ta), "([]::'a list)"),
            (Eq(list.nil(Ta), list.nil(Ta)), "([]::'a list) = []"),
            (Forall(a, Eq(a, a)), "!a::'a. a = a"),
        ]

        with global_setting(unicode=False):
            for t, s in test_data:
                self.assertEqual(printer.print_term(t), s)
Beispiel #6
0
def encode(t):
    """Given a propositional formula t, compute its Tseitin encoding.

    The theorem is structured as follows:

    Each of the assumptions, except the last, is an equality, where
    the right side is either an atom or a logical operation between
    atoms. We call these assumptions As.

    The last assumption is the original formula. We call it F.

    The conclusion is in CNF. Each clause except the last is an
    expansion of one of As. The last clause is obtained by performing
    substitutions of As on F.

    """
    # Mapping from subterms to newly introduced variables
    subterm_dict = dict()
    for i, subt in enumerate(logic_subterms(t)):
        subterm_dict[subt] = Var('x' + str(i + 1), BoolType)

    # Collect list of equations
    eqs = []
    for subt in subterm_dict:
        r = subterm_dict[subt]
        if not is_logical(subt):
            eqs.append(Eq(r, subt))
        elif subt.is_not():
            r1 = subterm_dict[subt.arg]
            eqs.append(Eq(r, Not(r1)))
        else:
            r1 = subterm_dict[subt.arg1]
            r2 = subterm_dict[subt.arg]
            eqs.append(Eq(r, subt.head(r1, r2)))

    # Form the proof term
    eq_pts = [ProofTerm.assume(eq) for eq in eqs]
    encode_pt = ProofTerm.assume(t)
    for eq_pt in eq_pts:
        encode_pt = encode_pt.on_prop(top_conv(rewr_conv(eq_pt, sym=True)))
    for eq_pt in eq_pts:
        if is_logical(eq_pt.rhs):
            encode_pt = logic.apply_theorem('conjI', eq_pt, encode_pt)

    # Rewrite using Tseitin rules
    encode_thms = [
        'encode_conj', 'encode_disj', 'encode_imp', 'encode_eq', 'encode_not'
    ]

    for th in encode_thms:
        encode_pt = encode_pt.on_prop(top_conv(rewr_conv(th)))

    # Normalize the conjuncts
    return encode_pt.on_prop(logic.conj_norm())
Beispiel #7
0
    def testCheckTerm(self):
        test_data = [
            x,
            Eq(x, y),
            Eq(f, f),
            Implies(A, B),
            Abs("x", Ta, Eq(x, y)),
        ]

        for t in test_data:
            self.assertEqual(theory.thy.check_term(t), None)
Beispiel #8
0
    def testExport3(self):
        """Case with atoms."""
        pt1 = ProofTerm.atom(0, Thm([], Eq(x, y)))
        pt2 = ProofTerm.atom(1, Thm([], Eq(y, z)))
        pt3 = pt1.transitive(pt2)

        prf = Proof()
        prf.add_item(0, rule="sorry", th=Thm([], Eq(x, y)))
        prf.add_item(1, rule="sorry", th=Thm([], Eq(y, z)))
        pt3.export(prf=prf)

        self.assertEqual(theory.check_proof(prf), Thm([], Eq(x, z)))
Beispiel #9
0
 def run_test(self, data, verbose=False):
     Ta = TVar('a')
     context.set_context('nat',
                         vars={
                             'a': Ta,
                             'b': Ta,
                             'c': Ta,
                             'd': Ta,
                             'f': TFun(Ta, Ta),
                             'g': TFun(Ta, Ta),
                             'R': TFun(Ta, Ta, Ta),
                             'm': NatType,
                             'n': NatType,
                             'p': NatType,
                             'q': NatType,
                             'x': NatType,
                             'y': NatType,
                             'z': NatType
                         })
     closure = congc.CongClosureHOL()
     for item in data:
         if item[0] == MERGE:
             _, s, t = item
             s = parser.parse_term(s)
             t = parser.parse_term(t)
             closure.merge(s, t)
             if verbose:
                 print("Merge %s, %s\nAfter\n%s" % (s, t, closure))
         elif item[0] == CHECK:
             _, s, t, b = item
             s = parser.parse_term(s)
             t = parser.parse_term(t)
             self.assertEqual(closure.test(s, t), b)
         elif item[0] == EXPLAIN:
             _, s, t = item
             s = parser.parse_term(s)
             t = parser.parse_term(t)
             prf = closure.explain(s, t).export()
             self.assertEqual(theory.check_proof(prf), Thm([], Eq(s, t)))
             if verbose:
                 print("Proof of %s" % Eq(s, t))
                 print(prf)
         elif item[0] == MATCH:
             _, pat, t, res = item
             pat = parser.parse_term(pat)
             t = parser.parse_term(t)
             for res_inst in res:
                 for k in res_inst:
                     res_inst[k] = parser.parse_term(res_inst[k])
             inst = closure.ematch(pat, t)
             self.assertEqual(inst, res)
         else:
             raise NotImplementedError
Beispiel #10
0
    def testCheckProof3(self):
        """Proof of [x = y, y = z] |- f z = f x."""
        x_eq_y = Eq(x,y)
        y_eq_z = Eq(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], Eq(f(z),f(x)))
        self.assertEqual(theory.check_proof(prf, rpt), th)
        self.assertEqual(rpt.steps, 6)
Beispiel #11
0
    def get_proof_term(self, args, pts):

        # First, find the pair i, j such that B_j = ~A_i or A_i = ~B_j, the
        # variable side records the side of the positive literal.
        pt1, pt2 = pts
        disj1 = strip_num(pt1.prop, args[0])
        disj2 = strip_num(pt2.prop, args[1])
        side = None
        for i, t1 in enumerate(disj1):
            for j, t2 in enumerate(disj2):
                if t2 == Not(t1):
                    side = 'left'
                    break
                elif t1 == Not(t2):
                    side = 'right'
                    break
            if side is not None:
                break

        assert side is not None, "resolution: literal not found"

        # If side is wrong, just swap:
        if side == 'right':
            return self.get_proof_term([args[1], args[0]], [pt2, pt1])

        # Move items i and j to the front
        disj1 = [disj1[i]] + disj1[:i] + disj1[i + 1:]
        disj2 = [disj2[j]] + disj2[:j] + disj2[j + 1:]
        eq_pt1 = logic.imp_disj_iff(Eq(pt1.prop, Or(*disj1)))
        eq_pt2 = logic.imp_disj_iff(Eq(pt2.prop, Or(*disj2)))
        pt1 = eq_pt1.equal_elim(pt1)
        pt2 = eq_pt2.equal_elim(pt2)

        if len(disj1) > 1 and len(disj2) > 1:
            pt = logic.apply_theorem('resolution', pt1, pt2)
        elif len(disj1) > 1 and len(disj2) == 1:
            pt = logic.apply_theorem('resolution_left', pt1, pt2)
        elif len(disj1) == 1 and len(disj2) > 1:
            pt = logic.apply_theorem('resolution_right', pt1, pt2)
        else:
            pt = logic.apply_theorem('negE', pt2, pt1)

        # return pt.on_prop(disj_norm())
        disj_new = set(disj1[1:] + disj2[1:])
        # eq_pt_norm = logic.imp_disj_iff(Eq(pt.prop, Or(*disj_new)))
        implies_pt_norm = ProofTerm("imp_disj",
                                    Implies(pt.prop, Or(*disj_new)))
        pt_final = implies_pt_norm.implies_elim(pt)
        self.arity = len(disj_new)
        return pt_final.on_prop(conv.top_conv(conv.rewr_conv("double_neg")))
Beispiel #12
0
    def testUncheckedExtend(self):
        """Unchecked extension."""
        id_const = Const("id", TFun(Ta,Ta))
        id_def = Abs("x", Ta, Bound(0))

        exts = [
            extension.Constant("id", TFun(Ta, Ta)),
            extension.Theorem("id_def", Thm([], Eq(id_const, id_def))),
            extension.Theorem("id.simps", Thm([], Eq(id_const, x)))
        ]

        self.assertEqual(theory.thy.unchecked_extend(exts), None)
        self.assertEqual(theory.thy.get_term_sig("id"), TFun(Ta, Ta))
        self.assertEqual(theory.get_theorem("id_def", svar=False), Thm([], Eq(id_const, id_def)))
        self.assertEqual(theory.get_theorem("id.simps", svar=False), Thm([], Eq(id_const, x)))
Beispiel #13
0
    def testConvertTerm(self):
        a, b = Var("a", TFun(NatType, NatType)), Var("b", BoolType)
        var_map = {a: 0, b: 1}
        s = Var("s", gcl.stateT)
        test_data = [
            (a(one), s(Para(Ident(zero), one))),
            (b, s(Ident(one))),
            (Binary(3), NatV(Binary(3))),
            (Eq(a(one),
                Binary(3)), Eq(s(Para(Ident(zero), one)), NatV(Binary(3)))),
            (true, BoolV(true)),
            (Eq(b, false), Eq(s(Ident(one)), BoolV(false))),
        ]

        for t, res in test_data:
            self.assertEqual(gcl.convert_term(var_map, s, t), res)
Beispiel #14
0
    def get_extension(self):
        assert self.error is None, "get_extension"
        res = []
        res.append(
            extension.Constant(self.name, self.type, ref_name=self.cname))

        for rule in self.rules:
            res.append(extension.Theorem(rule['name'], Thm([], rule['prop'])))
            res.append(extension.Attribute(rule['name'], 'hint_backward'))

        # Case rule
        Targs, _ = self.type.strip_type()
        vars = []
        for i, Targ in enumerate(Targs):
            vars.append(Var("_a" + str(i + 1), Targ))

        P = Var("P", BoolType)
        pred = Const(self.name, self.type)
        assum0 = pred(*vars)
        assums = []
        for rule in self.rules:
            prop = rule['prop']
            As, C = prop.strip_implies()
            eq_assums = [Eq(var, arg) for var, arg in zip(vars, C.args)]
            assum = Implies(*(eq_assums + As), P)
            for var in reversed(prop.get_vars()):
                assum = Forall(var, assum)
            assums.append(assum)

        prop = Implies(*([assum0] + assums + [P]))
        res.append(extension.Theorem(self.cname + "_cases", Thm([], prop)))

        return res
Beispiel #15
0
    def testGetForallName(self):
        test_data = [
            (Forall(x, Forall(y, Eq(x, y))), ["x", "y"]),
        ]

        for t, res in test_data:
            self.assertEqual(logic.get_forall_names(t), res)
Beispiel #16
0
 def get_proof_term(self, t):
     if t.get_type() != RealType:
         return refl(t)
     simp_t = Real(real_eval(t))
     if simp_t == t:
         return refl(t)
     return ProofTerm('real_eval', Eq(t, simp_t))
Beispiel #17
0
    def handle_leq_stage2(self, pt_upper_bound, pts, delta):
        # get ⊢ x_i ≤ -δ, for i = 1...n
        leq_pt = []
        pt_b = pt_upper_bound

        for i in range(len(pts)):
            if i != len(pts) - 1:
                pt = logic.apply_theorem("both_leq_max", pt_b)
                pt_1, pt_2 = logic.apply_theorem("conjD1",
                                                 pt), logic.apply_theorem(
                                                     "conjD2", pt)
            else:
                pt_2 = pt_b

            ineq = pt_2.prop

            if ineq.arg1.is_minus() and ineq.arg1.arg.is_number():
                num = ineq.arg1.arg
                expr = less_eq(ineq.arg1.arg1, num - delta)

            else:
                expr = less_eq(ineq.arg1, Real(0) - delta)

            pt_eq_comp = ProofTerm("real_eq_comparison", Eq(ineq, expr))
            leq_pt.insert(0, pt_2.on_prop(replace_conv(pt_eq_comp)))
            if i != len(pts) - 1:
                pt_b = pt_1

        return leq_pt
Beispiel #18
0
    def handle_geq_stage2(self, pt_lower_bound, pts, delta):
        # get ⊢ x_i ≥ δ, i = 1...n
        geq_pt = []
        pt_a = pt_lower_bound
        d = set()

        for i in range(len(pts)):
            if i != len(pts) - 1:
                pt = logic.apply_theorem("both_geq_min", pt_a)
                pt_1, pt_2 = logic.apply_theorem("conjD1",
                                                 pt), logic.apply_theorem(
                                                     "conjD2", pt)
            else:
                pt_2 = pt_a

            ineq = pt_2.prop

            if ineq.arg1.is_minus() and ineq.arg1.arg.is_number():
                # move all constant term from left to right in pt_2's prop
                num = ineq.arg1.arg
                expr = greater_eq(ineq.arg1.arg1, num + delta)

            else:
                expr = greater_eq(ineq.arg1, Real(0) + delta)

            pt_eq_comp = ProofTerm("real_eq_comparison", Eq(ineq, expr))
            geq_pt.insert(0, pt_2.on_prop(replace_conv(pt_eq_comp)))

            if i != len(pts) - 1:
                pt_a = pt_1

        return geq_pt
Beispiel #19
0
 def get_proof_term(self, t):
     if t.get_type() != IntType:
         return refl(t)
     simp_t = Int(int_eval(t))
     if simp_t == t:
         return refl(t)
     else:
         return ProofTerm('int_eval', Eq(t, int_eval(t)))
Beispiel #20
0
    def testCheckedExtend(self):
        """Checked extension: adding an axiom."""
        id_simps = Eq(Comb(Const("id", TFun(Ta,Ta)), x), x)
        exts = [extension.Theorem("id.simps", Thm([], id_simps))]

        ext_report = theory.thy.checked_extend(exts)
        self.assertEqual(theory.get_theorem("id.simps", svar=False), Thm([], id_simps))
        self.assertEqual(ext_report.get_axioms(), [("id.simps", Thm([], id_simps))])
Beispiel #21
0
 def get_proof_term(self, goal, pts):
     assert isinstance(goal, Term)
     assert len(pts) == 0, "nat_const_less_macro"
     m, n = goal.args
     assert m.dest_number() < n.dest_number()
     less_eq_pt = nat_const_less_eq_macro().get_proof_term(m <= n, [])
     ineq_pt = nat_const_ineq_macro().get_proof_term(Not(Eq(m, n)), [])
     return apply_theorem("less_lesseqI", less_eq_pt, ineq_pt)
Beispiel #22
0
    def get_proof_term(self, arg, pts):
        """Input proof terms are A_1 | ... | A_m and B_1 | ... | B_n, where
        there is some i, j such that B_j = ~A_i or A_i = ~B_j."""
        
        # First, find the pair i, j such that B_j = ~A_i or A_i = ~B_j, the
        # variable side records the side of the positive literal.
        pt1, pt2 = pts
        disj1 = strip_disj(pt1.prop)
        disj2 = strip_disj(pt2.prop)
        
        side = None
        for i, t1 in enumerate(disj1):
            for j, t2 in enumerate(disj2):
                if t2 == Not(t1):
                    side = 'left'
                    break
                elif t1 == Not(t2):
                    side = 'right'
                    break
            if side is not None:
                break
                
        assert side is not None, "resolution: literal not found"
        
        # If side is wrong, just swap:
        if side == 'right':
            return self.get_proof_term(arg, [pt2, pt1])
        
        # Move items i and j to the front
        disj1 = [disj1[i]] + disj1[:i] + disj1[i+1:]
        disj2 = [disj2[j]] + disj2[:j] + disj2[j+1:]
        eq_pt1 = imp_disj_iff(Eq(pt1.prop, Or(*disj1)))
        eq_pt2 = imp_disj_iff(Eq(pt2.prop, Or(*disj2)))
        pt1 = eq_pt1.equal_elim(pt1)
        pt2 = eq_pt2.equal_elim(pt2)
        
        if len(disj1) > 1 and len(disj2) > 1:
            pt = apply_theorem('resolution', pt1, pt2)
        elif len(disj1) > 1 and len(disj2) == 1:
            pt = apply_theorem('resolution_left', pt1, pt2)
        elif len(disj1) == 1 and len(disj2) > 1:
            pt = apply_theorem('resolution_right', pt1, pt2)
        else:
            pt = apply_theorem('negE', pt2, pt1)

        return pt.on_prop(disj_norm())
Beispiel #23
0
 def testEvalSem5(self):
     com = While(Lambda(s, Not(Eq(s(zero), Nat(3)))), assn_true, incr_one)
     st = mk_const_fun(NatType, zero)
     st2 = fun_upd_of_seq(0, 3)
     goal = Sem(com, st, st2)
     prf = imp.eval_Sem_macro().get_proof_term(goal, []).export()
     rpt = ProofReport()
     self.assertEqual(theory.check_proof(prf, rpt), Thm([], goal))
Beispiel #24
0
    def testExport2(self):
        """Repeated theorems."""
        pt1 = ProofTerm.assume(Eq(x, y))
        pt2 = ProofTerm.reflexive(f)
        pt3 = pt2.combination(pt1)  # f x = f y
        pt4 = pt3.combination(pt1)  # f x x = f y y

        prf = pt4.export()
        self.assertEqual(len(prf.items), 4)
        self.assertEqual(theory.check_proof(prf), pt4.th)
Beispiel #25
0
    def beta_conv(t):
        """Derivation rule BETA_CONV:

        |- (%x. t1) t2 = t1[t2/x]
        """
        try:
            t_new = t.beta_conv()
        except term.TermException:
            raise InvalidDerivationException("beta_conv")
        return Thm([], Eq(t, t_new))
Beispiel #26
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 #27
0
    def get_proof_term(self, goal, prevs=None):
        elems = goal.strip_disj()
        preds, concl = elems[:-1], elems[-1]
        args_pair = [(i, j) for i, j in zip(concl.lhs.strip_comb()[1],
                                            concl.rhs.strip_comb()[1])]
        preds_pair = [(i.arg.lhs, i.arg.rhs) for i in preds]
        fun = concl.lhs.head
        pt0 = ProofTerm.reflexive(fun)
        pt_args_assms = []
        for pair in args_pair:
            r_pair = pair[::-1]
            if pair in args_pair:
                pt_args_assms.append(ProofTerm.assume(Eq(*pair)))
            elif r_pair in args_pair:
                pt_args_assms.append(ProofTerm.assume(Eq(*r_pair)))

        pt1 = functools.reduce(lambda x, y: x.combination(y), pt_args_assms,
                               pt0)
        return ProofTerm("imp_to_or", elems[:-1] + [goal], prevs=[pt1])
Beispiel #28
0
    def get_proof_term(self, goal, pts):
        assert len(pts) == 1 and hol_set.is_mem(pts[0].prop) and pts[0].prop.arg1.is_var(), \
            "interval_inequality"
        var_name = pts[0].prop.arg1.name
        var_range = {var_name: pts[0]}

        if goal.is_not() and goal.arg.is_equals():
            if expr.is_polynomial(expr.holpy_to_expr(goal.arg.arg1)):
                factored = expr.expr_to_holpy(
                    expr.factor_polynomial(expr.holpy_to_expr(goal.arg.arg1)))
                if factored.is_times() and factored != goal.arg.arg1:
                    eq_pt = auto.auto_solve(Eq(factored, goal.arg.arg1))
                    pt1 = get_bounds_proof(factored, var_range).on_prop(
                        arg1_conv(rewr_conv(eq_pt)))
                else:
                    pt1 = get_bounds_proof(goal.arg.arg1, var_range)
            else:
                pt1 = get_bounds_proof(goal.arg.arg1, var_range)
            pt2 = get_bounds_proof(goal.arg.arg, var_range)
            try:
                pt = combine_interval_bounds(pt1, pt2)
                if pt.prop.is_less_eq():
                    raise TacticException
                pt = apply_theorem('real_lt_neq', pt)
            except TacticException:
                pt = combine_interval_bounds(pt2, pt1)
                if pt.prop.is_less_eq():
                    raise TacticException
                pt = apply_theorem('real_gt_neq', reverse_inequality(pt))
            return pt
        else:
            pt1 = get_bounds_proof(goal.arg1, var_range)
            pt2 = get_bounds_proof(goal.arg, var_range)
            if goal.is_less_eq():
                pt = combine_interval_bounds(pt1, pt2)
                if pt.prop.is_less():
                    pt = apply_theorem('real_lt_imp_le', pt)
                return pt
            elif goal.is_less():
                pt = combine_interval_bounds(pt1, pt2)
                if pt.prop.is_less_eq():
                    raise TacticException
                return pt
            elif goal.is_greater_eq():
                pt = combine_interval_bounds(pt2, pt1)
                if pt.prop.is_less():
                    pt = apply_theorem('real_lt_imp_le', pt)
                return reverse_inequality(pt)
            elif goal.is_greater():
                pt = combine_interval_bounds(pt2, pt1)
                if pt.prop.is_less_eq():
                    raise TacticException
                return reverse_inequality(pt)
            else:
                raise AssertionError('interval_inequality')
Beispiel #29
0
 def get_proof_term(self, goal, prevs=None):
     """{(not (= x_1 y_1)) ... (not (= x_n y_n)) (not (p x_1 ... x_n)) (p y_1 ... y_n)}
     Special case: (not (= x y)) (not (p x y)) (p y x)
     """
     elems = goal.strip_disj()
     preds, pred_fun, concl = elems[:-2], elems[-2], elems[-1]
     if pred_fun.is_not():
         args_pair = [(i, j) for i, j in zip(pred_fun.arg.strip_comb()[1],
                                             concl.strip_comb()[1])]
     else:
         args_pair = [(i, j) for i, j in zip(pred_fun.strip_comb()[1],
                                             concl.arg.strip_comb()[1])]
     if len(preds) > 1:
         preds_pair = [(i.arg.lhs, i.arg.rhs) for i in preds]
     else:
         preds_pair = [(preds[0].arg.lhs, preds[0].arg.rhs),
                       (preds[0].arg.lhs, preds[0].arg.rhs)]
     if pred_fun.is_not():
         fun = concl.head
     else:
         fun = pred_fun.head
     pt0 = ProofTerm.reflexive(fun)
     pt_args_assms = []
     for arg, pred in zip(args_pair, preds_pair):
         if arg == pred:
             pt_args_assms.append(ProofTerm.assume(Eq(pred[0], pred[1])))
         elif arg[0] == pred[1] and pred[0] == arg[1]:
             pt_args_assms.append(
                 ProofTerm.assume(Eq(pred[0], pred[1])).symmetric())
         else:
             raise NotImplementedError
     pt1 = functools.reduce(lambda x, y: x.combination(y), pt_args_assms,
                            pt0)
     if pred_fun.is_not():
         pt2 = logic.apply_theorem("eq_implies1", pt1).implies_elim(
             ProofTerm.assume(pred_fun.arg))
         return ProofTerm("imp_to_or", elems[:-1] + [goal], prevs=[pt2])
     else:
         pt2 = pt1.on_prop(conv.rewr_conv("neg_iff_both_sides"))
         pt3 = logic.apply_theorem("eq_implies1", pt2).implies_elim(
             ProofTerm.assume(Not(pred_fun)))
         return ProofTerm("imp_to_or", elems[:-1] + [goal], prevs=[pt3])
Beispiel #30
0
    def get_proof_term(self, prevs, goal_lit):
        disj, *lit_pts = prevs
        pt_conj = lit_pts[0]

        for i in range(len(lit_pts)):
            pt = lit_pts[i]
            if not pt.prop.is_not():
                lit_pts[i] = pt.on_prop(rewr_conv('double_neg', sym=True))

        def conj_right_assoc(pts):
            """
            Give a sequence of proof terms: ⊢ A, ⊢ B, ⊢ C,
            return ⊢ A ∧ (B ∧ C)
            """
            if len(pts) == 1:
                return pts[0]
            else:
                return apply_theorem('conjI', pts[0],
                                     conj_right_assoc(pts[1:]))

        # get a /\ b /\ c
        pt_conj = conj_right_assoc(lit_pts)

        other_lits = [
            l.prop.arg if l.prop.is_not() else Not(l.prop) for l in lit_pts
        ]

        # use de Morgan
        pt_conj1 = pt_conj.on_prop(
            bottom_conv(rewr_conv('de_morgan_thm2', sym=True)))

        # if len(other_lits) == 1 and other_lits[0].is_not():
        #     pt_conj1 = pt_conj.on_prop(rewr_conv('double_neg', sym=True))

        # Equality for two disjunctions which literals are the same, but order is different.
        eq_pt = imp_disj_iff(Eq(disj.prop, Or(goal_lit, *other_lits)))
        new_disj_pt = disj.on_prop(top_conv(replace_conv(eq_pt)))

        # A \/ B --> ~B --> A
        pt = ProofTerm.theorem('force_disj_true1')
        A, B = pt.prop.strip_implies()[0]
        C = pt.prop.strip_implies()[1]

        inst1 = matcher.first_order_match(C, goal_lit)
        inst2 = matcher.first_order_match(A,
                                          Or(goal_lit, *other_lits),
                                          inst=inst1)
        inst3 = matcher.first_order_match(B, pt_conj1.prop, inst=inst2)
        pt_implies = apply_theorem('force_disj_true1',
                                   new_disj_pt,
                                   pt_conj1,
                                   inst=inst3)

        return pt_implies.on_prop(try_conv(rewr_conv('double_neg')))