Example #1
0
    def testInductList(self):
        Ta = TVar("a")
        Tlista = Type("list", Ta)
        list_ext = induct.add_induct_type(
            "list", ["a"], [("nil", Tlista, []), ("cons", TFun(Ta, Tlista, Tlista), ["x", "xs"])])

        nil = Const("nil", Tlista)
        cons = Const("cons", TFun(Ta, Tlista, Tlista))
        x = Var("x", Ta)
        xs = Var("xs", Tlista)
        x2 = Var("x'", Ta)
        xs2 = Var("xs'", Tlista)
        P = Var("P", TFun(Tlista, boolT))
        xlist = Var("x", Tlista)

        res = [
            AxType("list", 1),
            AxConstant("nil", Tlista),
            AxConstant("cons", TFun(Ta, Tlista, Tlista)),
            Theorem("list_nil_cons_neq", Thm([], logic.neg(eq(nil, cons(x, xs))))),
            Theorem("list_cons_inject", Thm([], imp(eq(cons(x, xs), cons(x2, xs2)), conj(eq(x, x2), eq(xs, xs2))))),
            Theorem("list_induct", Thm([], imp(P(nil), all(x, all(xs, imp(P(xs), P(cons(x, xs))))), P(xlist)))),
            Attribute("list_induct", "var_induct")
        ]
        self.assertEqual(list_ext.data, res)
Example #2
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"))
Example #3
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))
Example #4
0
    def get_proof(self):
        invC = Const("inv", TFun(gcl.stateT, BoolType))
        transC = Const("trans", TFun(gcl.stateT, gcl.stateT, BoolType))
        s1 = Var("s1", gcl.stateT)
        s2 = Var("s2", gcl.stateT)
        prop = Thm([], Implies(invC(s1), transC(s1, s2), invC(s2)))
        # print(printer.print_thm(prop))

        trans_pt = ProofTerm.assume(transC(s1, s2))
        # print(printer.print_thm(trans_pt.th))
        P = Implies(invC(s1), invC(s2))
        ind_pt = apply_theorem("trans_cases", inst=Inst(a1=s1, a2=s2, P=P))
        # print(printer.print_thm(ind_pt.th))

        ind_As, ind_C = ind_pt.prop.strip_implies()
        for ind_A in ind_As[1:-1]:
            # print("ind_A: ", ind_A)
            vars, As, C = logic.strip_all_implies(ind_A, ["s", "k"])
            # for A in As:
            #     print("A: ", A)
            # print("C: ", C)
            eq1 = ProofTerm.assume(As[0])
            eq2 = ProofTerm.assume(As[1])
            guard = ProofTerm.assume(As[2])
            inv_pre = ProofTerm.assume(As[3]).on_arg(rewr_conv(eq1)).on_prop(
                rewr_conv("inv_def"))
            C_goal = ProofTerm.assume(C).on_arg(rewr_conv(eq2)).on_prop(
                rewr_conv("inv_def"))
Example #5
0
    def testFirstOrderMatchFun(self):
        """First-order matching of variables in function position."""
        P = Var("P", TFun(Ta, boolT))
        Q = Var("Q", TFun(Ta, boolT))
        C = Const("C", TFun(boolT, boolT, boolT))

        test_data = [
            (abs(x, P(x)), abs(x, C(P(x), Q(x))), {
                "P": abs(x, C(P(x), Q(x)))
            }),
            (abs(x, C(P(x), Q(x))), abs(x, C(Q(x), P(x))), {
                "P": Q,
                "Q": P
            }),
            (abs(x, C(P(x), P(x))), abs(x, C(C(P(x), Q(x)), C(P(x), Q(x)))), {
                "P": abs(x, C(P(x), Q(x)))
            }),
            (exists(x, P(x)), exists(x, conj(P(x), Q(x))), {
                "P": abs(x, conj(P(x), Q(x)))
            }),
        ]

        for pat, t, inst in test_data:
            if inst is not None:
                self.assertEqual(matcher.first_order_match(pat, t)[1], inst)
            else:
                self.assertRaises(matcher.MatchException,
                                  matcher.first_order_match, pat, t)
Example #6
0
    def testPrintType(self):
        test_data = [
            (Ta, "'a"),
            (TVar("ab"), "'ab"),
            (TConst("bool"), "bool"),
            (TConst("list", Ta), "'a list"),
            (TConst("list", TConst("list", Ta)), "'a list list"),
            (TConst("tree", Ta, Tb), "('a, 'b) tree"),
            (TFun(Ta, Tb), "'a => 'b"),
            (TFun(Ta, Tb, Tc), "'a => 'b => 'c"),
            (TFun(TFun(Ta, Tb), Tc), "('a => 'b) => 'c"),
            (TFun(TConst("list", Ta), Tb), "'a list => 'b"),
            (TFun(Ta, TConst("list", Tb)), "'a => 'b list"),
            (TConst("list", TFun(Ta, Tb)), "('a => 'b) list"),
            (TConst("list", TConst("list", TFun(Ta,
                                                Tb))), "('a => 'b) list list"),
            (TFun(TConst("list", Ta), TConst("list",
                                             Tb)), "'a list => 'b list"),
            (TConst("list", TFun(TConst("list", Ta),
                                 Tb)), "('a list => 'b) list"),
        ]

        for T, str_T in test_data:
            with global_setting(unicode=False):
                self.assertEqual(str(T), str_T)
Example #7
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)
Example #8
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)
Example #9
0
    def testMatchFail(self):
        test_data = [
            (TFun(Ta, Ta), TFun(Ta, Tb)),
            (boolT, Ta),
        ]

        for pat, T in test_data:
            self.assertRaises(TypeMatchException, pat.match, T)
Example #10
0
def mk_some(x, body):
    """Given a variable x and a term P possibly depending on x, return
    the term SOME x. P.

    """
    assert x.is_var(), "mk_some"
    some_t = Const("Some", TFun(TFun(x.T, BoolType), x.T))
    return some_t(Lambda(x, body))
Example #11
0
def mk_exists1(x, body):
    """Given a variable x and a term P possibly depending on x, return
    the term ?!x. P.

    """
    assert x.is_var(), "mk_exists1"
    exists1_t = Const("exists1", TFun(TFun(x.T, BoolType), BoolType))
    return exists1_t(Lambda(x, body))
Example #12
0
    def mk_all(x, body):
        """Given a variable x and a term t possibly depending on x, return
        the term !x. t. Optional arguments var_name and T specify the
        suggested name and type of the bound variable.

        """
        all_t = Const("all", TFun(TFun(x.T, boolT), boolT))
        return all_t(Term.mk_abs(x, body))
Example #13
0
    def testStripType(self):
        test_data = [
            (Ta, ([], Ta)),
            (TFun(Ta, Tb), ([Ta], Tb)),
            (TFun(Ta, Ta, Tb), ([Ta, Ta], Tb)),
        ]

        for T, res in test_data:
            self.assertEqual(T.strip_type(), res)
Example #14
0
    def testGetTSubs(self):
        test_data = [
            (boolT, [boolT]),
            (TFun(Ta, Ta), [TFun(Ta, Ta), Ta]),
            (TFun(Ta, Tb), [TFun(Ta, Tb), Ta, Tb]),
        ]

        for T, res in test_data:
            self.assertEqual(T.get_tsubs(), res)
Example #15
0
    def testGetTVars(self):
        test_data = [
            (boolT, []),
            (TFun(Ta, Ta), [Ta]),
            (TFun(Ta, Tb), [Ta, Tb]),
        ]

        for T, res in test_data:
            self.assertEqual(T.get_tvars(), res)
Example #16
0
    def testGetTSubs(self):
        test_data = [
            (BoolType, [BoolType]),
            (TFun(Ta, Ta), [Ta, TFun(Ta, Ta)]),
            (TFun(Ta, Tb), [Ta, Tb, TFun(Ta, Tb)]),
        ]

        for T, res in test_data:
            self.assertEqual(T.get_tsubs(), res)
Example #17
0
    def testIsPattern(self):
        test_data = [
            (Var('a', Ta), True),
            (Var('f', TFun(Ta, Tb))(Var('a', Ta)), False),
            (Const('f', TFun(Ta, Tb))(Var('a', Ta)), True),
        ]

        for t, res in test_data:
            self.assertEqual(matcher.is_pattern(t, []), res)
Example #18
0
 def testCheckedExtend3(self):
     """Axiomatized constant."""
     exts = [
         extension.TConst("nat", 0),
         extension.Constant("id", TFun(Ta,Ta))
     ]
     ext_report = theory.thy.checked_extend(exts)
     self.assertEqual(theory.thy.get_type_sig("nat"), 0)
     self.assertEqual(theory.thy.get_term_sig("id"), TFun(Ta,Ta))
Example #19
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)
Example #20
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)
Example #21
0
    def testSubst(self):
        test_data = [
            (STa, Tb),
            (STb, Ta),
            (TFun(STa, Tb), TFun(Tb, Tb)),
            (TFun(STa, STb), TFun(Tb, Ta)),
            (TConst("list", STa), TConst("list", Tb)),
        ]

        for T, res in test_data:
            self.assertEqual(T.subst(TyInst(a=Tb, b=Ta)), res)
Example #22
0
    def testCheckedExtend3(self):
        """Axiomatized constant."""
        thy = Theory.EmptyTheory()
        thy_ext = TheoryExtension()

        thy_ext.add_extension(AxType("nat", 0))
        thy_ext.add_extension(AxConstant("id", TFun(Ta,Ta)))
        ext_report = thy.checked_extend(thy_ext)
        self.assertEqual(thy.get_type_sig("nat"), 0)
        self.assertEqual(thy.get_term_sig("id"), TFun(Ta,Ta))
        self.assertEqual(ext_report.get_axioms(), [("nat", 0), ("id", TFun(Ta,Ta))])
Example #23
0
    def infer(t, bd_vars):
        # Var case: if type is not known, try to obtain it from context,
        # otherwise, make a new type.
        if t.is_var():
            if t.T is None:
                if t.name in ctxt:
                    t.T = ctxt[t.name]
                else:
                    t.T = new_type()
            add_type(t.T)
            return t.T

        # Const case: if type is not known, obtain it from theory,
        # replacing arbitrary variables by new types.
        elif t.is_const():
            if t.T is None:
                T = thy.get_term_sig(t.name)
                Tvars = T.get_tvars()
                tyinst = dict()
                for Tv in Tvars:
                    tyinst[Tv.name] = new_type()
                t.T = T.subst(tyinst)
            add_type(t.T)
            return t.T

        # Comb case: recursively infer type of fun and arg, then
        # unify funT with argT => resT, where resT is a new type.
        elif t.is_comb():
            funT = infer(t.fun, bd_vars)
            argT = infer(t.arg, bd_vars)
            resT = new_type()
            add_type(TFun(argT, resT))
            unify(uf, funT, TFun(argT, resT))
            return resT

        # Abs case: if var_T is not known, make a new type. Recursively
        # call infer on the body under the context where var_name has
        # type var_T. The resulting type is var_T => body_T.
        elif t.is_abs():
            if t.var_T is None:
                t.var_T = new_type()
                add_type(t.var_T)
            bodyT = infer(t.body, [t.var_T] + bd_vars)
            resT = TFun(t.var_T, bodyT)
            add_type(resT)
            return resT

        # Bound variables should not appear during inference.
        elif t.is_bound():
            return bd_vars[t.n]

        else:
            raise TypeError()
Example #24
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
Example #25
0
    def testCheckTermFail(self):
        test_data = [
            Const("random", Ta),
            Const("equals", TFun(Ta, Tb, BoolType)),
            Const("equals", TFun(Ta, Ta, Tb)),
            Const("implies", TFun(Ta, Ta, BoolType)),
            Comb(Const("random", Tab), x),
            f(Const("random", Ta)),
            Abs("x", Ta, Const("random", Ta)),
        ]

        for t in test_data:
            self.assertRaises(TheoryException, theory.thy.check_term, t)
Example #26
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)
Example #27
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)
Example #28
0
def convert(t):
    """Convert term t to Z3 input."""
    if t.is_var():
        T = t.get_type()
        if T == nat.natT:
            return z3.Int(t.name)
        elif T == TFun(nat.natT, nat.natT):
            return z3.Function(t.name, z3.IntSort(), z3.IntSort())
        elif T == TFun(nat.natT, boolT):
            return z3.Function(t.name, z3.IntSort(), z3.BoolSort())
        elif T == boolT:
            return z3.Bool(t.name)
        else:
            print("convert: unsupported type " + repr(T))
            raise NotImplementedError
    elif t.is_all():
        if t.arg.var_T == nat.natT:
            v = Var(t.arg.var_name, nat.natT)
            z3_v = z3.Int(t.arg.var_name)
            return z3.ForAll([z3_v], convert(t.arg.subst_bound(v)))
        else:
            raise NotImplementedError
    elif t.is_implies():
        return z3.Implies(convert(t.arg1), convert(t.arg))
    elif t.is_equals():
        return convert(t.arg1) == convert(t.arg)
    elif logic.is_conj(t):
        return z3.And(convert(t.arg1), convert(t.arg))
    elif logic.is_disj(t):
        return z3.Or(convert(t.arg1), convert(t.arg))
    elif logic.is_neg(t):
        return z3.Not(convert(t.arg))
    elif nat.is_plus(t):
        return convert(t.arg1) + convert(t.arg)
    elif nat.is_times(t):
        return convert(t.arg1) * convert(t.arg)
    elif nat.is_binary(t):
        return nat.from_binary(t)
    elif t.is_comb():
        return convert(t.fun)(convert(t.arg))
    elif t.is_const():
        if t == logic.true:
            return z3.BoolVal(True)
        elif t == logic.false:
            return z3.BoolVal(False)
        else:
            print("convert: unsupported constant " + repr(t))
            raise NotImplementedError
    else:
        print("convert: unsupported operation " + repr(t))
        raise NotImplementedError
Example #29
0
    def testPrintRename(self):
        test_data = [
            (Const("exists",
                   TFun(TFun(NatType, BoolType),
                        BoolType))(Abs("x", NatType,
                                       nat.less(Bound(0), Var("x", NatType)))),
             "?x1. x1 < x"),
            (Abs("x", NatType, nat.less(Bound(0),
                                        Var("x", NatType))), "%x1. x1 < x"),
        ]

        with global_setting(unicode=False):
            for t, s in test_data:
                self.assertEqual(printer.print_term(t), s)
Example #30
0
    def testCheckTypeFail(self):
        test_data = [
            TConst("bool", Ta),
            TConst("bool", Ta, Ta),
            TConst("fun"),
            TConst("fun", Ta),
            TConst("fun", Ta, Ta, Ta),
            TFun(TConst("bool", Ta), TConst("bool")),
            TFun(TConst("bool"), TConst("bool", Ta)),
            TConst("random")
        ]

        for T in test_data:
            self.assertRaises(TheoryException, theory.thy.check_type, T)