예제 #1
0
 def testAddZeroRight(self):
     """Proof of n + 0 = n by induction."""
     thy = basic.load_theory('nat')
     n = Var("n", nat.natT)
     eq = Term.mk_equals
     prf = Proof()
     prf.add_item(0, "theorem", args="nat_induct")
     prf.add_item(1,
                  "substitution",
                  args={
                      "P": Term.mk_abs(n, eq(nat.plus(n, nat.zero), n)),
                      "x": n
                  },
                  prevs=[0])
     prf.add_item(2, "beta_norm", prevs=[1])
     prf.add_item(3, "theorem", args="plus_def_1")
     prf.add_item(4, "substitution", args={"n": nat.zero}, prevs=[3])
     prf.add_item(5, "implies_elim", prevs=[2, 4])
     prf.add_item(6, "assume", args=eq(nat.plus(n, nat.zero), n))
     prf.add_item(7, "theorem", args="plus_def_2")
     prf.add_item(8,
                  "substitution",
                  args={
                      "m": n,
                      "n": nat.zero
                  },
                  prevs=[7])
     prf.add_item(9, "arg_combination", args=nat.Suc, prevs=[6])
     prf.add_item(10, "transitive", prevs=[8, 9])
     prf.add_item(11,
                  "implies_intr",
                  args=eq(nat.plus(n, nat.zero), n),
                  prevs=[10])
     prf.add_item(12, "forall_intr", args=n, prevs=[11])
     prf.add_item(13, "implies_elim", prevs=[5, 12])
     th = Thm.mk_equals(nat.plus(n, nat.zero), n)
     self.assertEqual(thy.check_proof(prf), th)
예제 #2
0
파일: real.py 프로젝트: bzhan/holpy
    def handle_leq_stage1(self, pts):
        if not pts:
            return None, None, None
        # ⊢ max(max(...(max(x_1, x_2), x_3)...), x_n-1), x_n) < 0
        max_pos_pt = functools.reduce(
            lambda pt1, pt2: logic.apply_theorem("max_less_0", pt1, pt2),
            pts[1:], pts[0])

        # ⊢ 0 < 2
        two_pos_pt = ProofTerm("real_compare", Real(2) > Real(0))

        # ⊢ max(...) / 2 < 0
        max_divides_two_pos = logic.apply_theorem("real_neg_div_pos",
                                                  max_pos_pt, two_pos_pt)

        # ⊢ 2 ≥ 1
        two_larger_one = ProofTerm("real_compare", Real(2) >= Real(1))

        # ⊢ max(...) ≤ max(...) / 2
        less_half_pt = logic.apply_theorem("real_neg_divides_larger_1",
                                           two_larger_one, max_pos_pt)

        # ⊢ max(...) / 2 = -δ
        delta_2 = Var("δ_2", RealType)
        pt_delta_eq = ProofTerm.assume(Eq(less_half_pt.prop.arg, -delta_2))

        # ⊢ δ > 0
        delta_pos_pt = max_divides_two_pos.on_prop(
            rewr_conv("real_le_gt"), top_conv(replace_conv(pt_delta_eq)),
            auto.auto_conv())

        # max(...) ≤ -δ
        less_half_pt_delta = less_half_pt.on_prop(
            arg_conv(replace_conv(pt_delta_eq)))

        return less_half_pt_delta, delta_pos_pt, pt_delta_eq
예제 #3
0
def strip_all_implies(t, names, svar=True):
    """Given a term of the form

    !x_1 ... x_k. A_1 --> ... --> A_n --> C.

    Return the triple ([v_1, ..., v_k], [A_1, ... A_n], C), where
    v_1, ..., v_k are new variables with the given names, and
    A_1, ..., A_n, C are the body of the input term, with bound variables
    substituted for v_1, ..., v_k.

    """
    if t.is_forall():
        assert len(names) > 0, "strip_all_implies: not enough names input."
        assert isinstance(names[0], str), "strip_all_implies: names must be strings."
        if svar:
            v = SVar(names[0], t.arg.var_T)
        else:
            v = Var(names[0], t.arg.var_T)
        vars, As, C = strip_all_implies(t.arg.subst_bound(v), names[1:], svar=svar)
        return ([v] + vars, As, C)
    else:
        assert len(names) == 0, "strip_all_implies: too many names input."
        As, C = t.strip_implies()
        return ([], As, C)
예제 #4
0
def compute_wp(T, c, Q):
    """Compute the weakest precondition for the given command
    and postcondition. Here c is the program and Q is the postcondition.
    The computation is by case analysis on the form of c. The function
    returns a proof term showing [...] |- Valid P c Q, where P is the
    computed precondition, and [...] contains the additional subgoals.

    """
    if c.is_const("Skip"):  # Skip
        return apply_theorem("skip_rule", concl=Valid(T)(Q, c, Q))
    elif c.is_comb("Assign", 2):  # Assign a b
        a, b = c.args
        s = Var("s", T)
        P2 = Lambda(s, Q(function.mk_fun_upd(s, a, b(s).beta_conv())))
        return apply_theorem("assign_rule",
                             inst=Inst(b=b),
                             concl=Valid(T)(P2, c, Q))
    elif c.is_comb("Seq", 2):  # Seq c1 c2
        c1, c2 = c.args
        wp1 = compute_wp(T, c2, Q)  # Valid Q' c2 Q
        wp2 = compute_wp(T, c1, wp1.prop.args[0])  # Valid Q'' c1 Q'
        return apply_theorem("seq_rule", wp2, wp1)
    elif c.is_comb("Cond", 3):  # Cond b c1 c2
        b, c1, c2 = c.args
        wp1 = compute_wp(T, c1, Q)
        wp2 = compute_wp(T, c2, Q)
        res = apply_theorem("if_rule", wp1, wp2, inst=Inst(b=b))
        return res
    elif c.is_comb("While", 3):  # While b I c
        _, I, _ = c.args
        pt = apply_theorem("while_rule", concl=Valid(T)(I, c, Q))
        pt0 = ProofTerm.assume(pt.assums[0])
        pt1 = vcg(T, pt.assums[1])
        return pt.implies_elim(pt0, pt1)
    else:
        raise NotImplementedError
예제 #5
0
    def testInductProd(self):
        Ta = TVar("a")
        Tb = TVar("b")
        Tab = Type("prod", Ta, Tb)
        prod_ext = induct.add_induct_type(
            "prod", ["a", "b"], [("Pair", TFun(Ta, Tb, Tab), ["a", "b"])])

        a = Var("a", Ta)
        b = Var("b", Tb)
        a2 = Var("a'", Ta)
        b2 = Var("b'", Tb)
        pair = Const("Pair", TFun(Ta, Tb, Tab))
        P = Var("P", TFun(Tab, boolT))
        x = Var("x", Tab)

        res = [
            AxType("prod", 2),
            AxConstant("Pair", TFun(Ta, Tb, Tab)),
            Theorem("prod_Pair_inject", Thm([], imp(eq(pair(a, b), pair(a2, b2)), conj(eq(a, a2), eq(b, b2))))),
            Theorem("prod_induct", Thm([], imp(all(a, all(b, P(pair(a, b)))), P(x)))),
            Attribute("prod_induct", "var_induct")
        ]
        self.assertEqual(prod_ext.data, res)
예제 #6
0
from kernel.thm import Thm
from logic import basic
from logic import logic
from data import nat
from data import real
from data import list
from data import set
from data import string
from data import function
from data import interval
from syntax import printer
from syntax.settings import settings, global_setting

basic.load_theory('list')

A = Var("A", BoolType)
B = Var("B", BoolType)
C = Var("C", BoolType)
Ta = TVar("a")
a = Var("a", Ta)
b = Var("b", Ta)
P = Var("P", TFun(Ta, BoolType))
Q = Var("Q", TFun(Ta, BoolType))
R = Var("R", TFun(Ta, Ta, BoolType))
nn = Var("n", TFun(BoolType, BoolType))
m = Var("m", NatType)
n = Var("n", NatType)
p = Var("p", NatType)
xs = Var("xs", TConst("list", Ta))
ys = Var("ys", TConst("list", Ta))
zs = Var("zs", TConst("list", Ta))
예제 #7
0
파일: matcher.py 프로젝트: zhouwenfan/temp
    def match(pat, t, instsp, bd_vars):
        tyinst, inst = instsp
        # print("Match", pat, "with", t)
        if pat.head.is_var() and pat.head.name.startswith('_'):
            # Case where the head of the function is a variable.
            if pat.head.name not in inst:
                # If the variable is not instantiated, check that the
                # arguments are distinct bound variables, and all bound
                # variables appearing in t also appear as an argument.
                # If all conditions hold, assign appropriately.
                t_vars = term.get_vars(t)
                if any(v not in bd_vars for v in pat.args):
                    raise MatchException
                if len(set(pat.args)) != len(pat.args):
                    raise MatchException
                if any(v in t_vars and v not in pat.args for v in bd_vars):
                    raise MatchException

                pat_T = TFun(*([v.T for v in pat.args] + [t.get_type()]))
                try:
                    pat.head.T.match_incr(pat_T, tyinst, internal_only=True)
                except TypeMatchException:
                    raise MatchException
                inst_t = t
                for v in reversed(pat.args):
                    if inst_t.is_comb(
                    ) and inst_t.arg == v and v not in term.get_vars(
                            inst_t.fun):
                        inst_t = inst_t.fun
                    else:
                        inst_t = Term.mk_abs(v, inst_t)
                inst[pat.head.name] = inst_t
            else:
                # If the variable is already instantiated, apply the
                # instantiation, simplify, and match again.
                pat2 = inst[pat.head.name](*pat.args).beta_norm()
                match(pat2, t.beta_norm(), instsp, bd_vars)
        elif pat.ty != t.ty:
            # In all other cases, top-level structure of the term
            # must agree.
            raise MatchException
        elif pat.is_var():
            # The case where pat come from a bound variable.
            if pat.name != t.name:
                raise MatchException
        elif pat.is_const():
            # When pat is a constant, t must also be a constant with
            # the same name and matching type.
            if pat.name != t.name:
                raise MatchException
            else:
                try:
                    pat.T.match_incr(t.T, tyinst, internal_only=True)
                except TypeMatchException:
                    raise MatchException
        elif pat.is_comb():
            # In the combination case (where the head is not a variable),
            # match fun and arg.
            if is_pattern(pat.fun, list(instsp[1].keys())):
                match(pat.fun, t.fun, instsp, bd_vars)
                match(pat.arg, t.arg, instsp, bd_vars)
            else:
                match(pat.arg, t.arg, instsp, bd_vars)
                match(pat.fun, t.fun, instsp, bd_vars)
        elif pat.is_abs():
            # When pat is a lambda term, t must also be a lambda term.
            # Replace bound variable by a variable, then match the body.
            try:
                pat.var_T.match_incr(t.var_T, tyinst, internal_only=True)
            except TypeMatchException:
                raise MatchException
            T = pat.var_T.subst(tyinst)
            v = Var(pat.var_name, T)
            pat_body = pat.subst_type(tyinst).subst_bound(v)
            t_body = t.subst_bound(v)
            match(pat_body, t_body, instsp, bd_vars + [v])
        elif pat.is_bound():
            raise MatchException
        else:
            raise TypeError
예제 #8
0
# Author: Bohua Zhan

import unittest

from kernel.type import TVar, TFun, NatType
from kernel.term import Var, Eq, Nat
from kernel.thm import Thm
from kernel import theory
from logic import basic
from data import nat
from data import function
from data.function import mk_fun_upd, strip_fun_upd

Ta = TVar("a")
Tb = TVar("b")
f = Var("f", TFun(Ta, Tb))
a1 = Var("a1", Ta)
a2 = Var("a2", Ta)
b1 = Var("b1", Ta)
b2 = Var("b2", Ta)

zero = nat.zero
one = nat.one


def fun_upd_of_seq(*ns):
    return mk_fun_upd(function.mk_const_fun(NatType, zero),
                      *[Nat(n) for n in ns])


class FunctionTest(unittest.TestCase):
예제 #9
0
파일: theory_test.py 프로젝트: bzhan/holpy
    def testCheckProofFail7(self):
        """Typing error: type-checking failed."""
        prf = Proof(Comb(Var("P", TFun(Tb, BoolType)), x))

        self.assertRaisesRegex(CheckProofException, "typing error", theory.check_proof, prf)
예제 #10
0
파일: theory.py 프로젝트: bzhan/holpy
    def _check_proof_item(self, prf, seq, rpt, no_gaps, compute_only,
                          check_level):
        """Check a single proof item.

        prf -- proof to be checked.
        seq -- proof item to be checked.
        rpt -- report for proof-checking. Modified by the function.
        no_gaps -- disable gaps.
        compute_only -- only executes rule if theorem is not present.
        check_level -- trust level for proof checking. Trust all macros
            with macro.level <= self.check_level.
        
        """
        if seq.rule == "":
            # Empty line in the proof
            return None

        if seq.rule == "sorry":
            # Gap in the proof
            assert seq.th is not None, "sorry must have explicit statement."
            if no_gaps:
                raise CheckProofException("gaps are not allowed")
            if rpt is not None:
                rpt.add_gap(seq.th)
            return None

        if compute_only and seq.th is not None:
            # In compute_only mode, skip when a theorem exists. However,
            # subproofs still need to be checked.
            if seq.rule == "subproof":
                for s in seq.subproof.items:
                    self._check_proof_item(prf, s, rpt, no_gaps, compute_only,
                                           check_level)
            return None

        if seq.rule == "theorem":
            # Copies an existing theorem in the theory into the proof.
            try:
                res_th = self.get_theorem(seq.args)
                if rpt is not None:
                    rpt.apply_theorem(seq.args)
            except TheoryException:
                raise CheckProofException("theorem not found")
        elif seq.rule == "variable":
            # Declares a variable. Skip check.
            nm, T = seq.args
            res_th = Thm.mk_VAR(Var(nm, T))
        elif seq.rule == "subproof":
            for s in seq.subproof.items:
                self._check_proof_item(prf, s, rpt, no_gaps, compute_only,
                                       check_level)
            res_th = seq.subproof.items[-1].th
        else:
            # Otherwise, apply one of the proof methods. First, we
            # obtain list of previous sequents used by the proof method:
            prev_ths = []
            assert isinstance(seq.prevs, list), "prevs should be a list"
            for prev in seq.prevs:
                if not seq.id.can_depend_on(prev):
                    raise CheckProofException("id %s cannot depend on %s" %
                                              (seq.id, prev))
                try:
                    prev_ths.append(prf.find_item(prev).th)
                except ProofStateException:
                    raise CheckProofException("previous item not found")

            for prev, prev_th in zip(seq.prevs, prev_ths):
                if prev_th is None:
                    raise CheckProofException("previous theorem %s is None" %
                                              prev)

            if seq.rule in primitive_deriv:
                # If the method is one of the primitive derivations, obtain and
                # apply that primitive derivation.
                rule_fun, _ = primitive_deriv[seq.rule]
                try:
                    res_th = rule_fun(
                        *prev_ths) if seq.args is None else rule_fun(
                            seq.args, *prev_ths)
                    if rpt is not None:
                        rpt.apply_primitive_deriv()
                except InvalidDerivationException:
                    raise CheckProofException("invalid derivation")
                except TypeError:
                    raise CheckProofException("invalid input to derivation " +
                                              seq.rule)

            elif has_macro(seq.rule):
                # Otherwise, the proof method corresponds to a macro. If
                # the level of the macro is less than or equal to the current
                # trust level, simply evaluate the macro to check that results
                # match. Otherwise, expand the macro and check all of the steps.
                macro = get_macro(seq.rule)
                assert macro.level is None or (isinstance(macro.level, int) and macro.level >= 0), \
                    ("check_proof: invalid macro level " + str(macro.level))
                if macro.level is not None and macro.level <= check_level:
                    res_th = macro.eval(seq.args, prev_ths)
                    if rpt is not None:
                        rpt.eval_macro(seq.rule)
                else:
                    seq.subproof = macro.expand(seq.id, seq.args,
                                                list(zip(seq.prevs, prev_ths)))
                    if rpt is not None:
                        rpt.expand_macro(seq.rule)
                    for s in seq.subproof.items:
                        self._check_proof_item(prf, s, rpt, no_gaps,
                                               compute_only, check_level)
                    res_th = seq.subproof.items[-1].th
                    seq.subproof = None
            else:
                raise CheckProofException("proof method not found: " +
                                          seq.rule)

        if seq.th is None:
            # No expected theorem is provided
            seq.th = res_th
        elif not res_th.can_prove(seq.th):
            # Resulting res_th is OK as long as the conclusion is the same,
            # and the assumptions is a subset of that of seq.th.
            raise CheckProofException("output does not match\n" + str(seq.th) +
                                      "\n vs.\n" + str(res_th))

        # Check the current statement is correctly typed.
        try:
            seq.th.check_thm_type()
        except TypeCheckException:
            raise CheckProofException("typing error")

        return None
예제 #11
0
파일: parser.py 프로젝트: zhouwenfan/temp
 def exists_notype(self, var_name, body):
     exists_t = Const("exists", None)
     return exists_t(
         Abs(var_name, None, body.abstract_over(Var(var_name, None))))
예제 #12
0
 def testForallElimFail2(self):
     P = Var("P", TFun(Ta, boolT))
     th = Thm([], Term.mk_all(x, P(x)))
     self.assertRaises(InvalidDerivationException, Thm.forall_elim, A, th)
예제 #13
0
 def testForallElim(self):
     P = Var("P", TFun(Ta, boolT))
     th = Thm([], Term.mk_all(x, P(x)))
     self.assertEqual(Thm.forall_elim(y, th), Thm([], P(y)))
예제 #14
0
 def testAbstractOverFail2(self):
     th = Thm.mk_equals(x, y)
     self.assertRaises(InvalidDerivationException, Thm.abstraction,
                       Var("x", Tb), th)
예제 #15
0
 def testSubstitutionFail(self):
     x_eq_y = Term.mk_equals(x, y)
     th = Thm([x_eq_y], x_eq_y)
     self.assertRaises(InvalidDerivationException, Thm.substitution,
                       {"x": Var("a", Tb)}, th)
예제 #16
0
파일: parser.py 프로젝트: zhouwenfan/temp
 def abs_notype(self, var_name, body):
     return Abs(var_name, None, body.abstract_over(Var(var_name, None)))
예제 #17
0
파일: parser.py 프로젝트: zhouwenfan/temp
 def all_notype(self, var_name, body):
     all_t = Const("all", None)
     return all_t(
         Abs(var_name, None, body.abstract_over(Var(var_name, None))))
예제 #18
0
import unittest

from kernel import type as hol_type
from kernel.type import STVar, TVar, TFun, TyInst
from kernel import term
from kernel.term import SVar, Var, Const, Comb, Abs, Bound, And, Or, Lambda, Binary, Inst
from kernel.term import TermException, TypeCheckException

Ta = TVar("a")
Tb = TVar("b")
STa = STVar("a")
STb = STVar("b")
Taa = TFun(Ta, Ta)  # 'a => 'a
Tab = TFun(Ta, Tb)  # 'a => 'b
Taab = TFun(Ta, Ta, Tb)  # 'a => 'a => 'b
a = Var("a", Ta)
b = Var("b", Tb)
c = Const("c", Ta)
f = Var("f", Tab)  # f: 'a => 'b
f2 = Var("f2", Taab)  # f2: 'a => 'a => 'b
g = Var("g", Taa)  # g: 'a => 'a
B0 = Bound(0)
B1 = Bound(1)


class TermTest(unittest.TestCase):
    def setUp(self):
        self.type_printer, self.term_printer = hol_type.type_printer, term.term_printer
        hol_type.type_printer, term.term_printer = None, None

    def tearDown(self):
예제 #19
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
예제 #20
0
 def testAbstractOverFail2(self):
     self.assertRaises(TermException, a.abstract_over, Var("a", Tb))
예제 #21
0
파일: theory_test.py 프로젝트: bzhan/holpy
import unittest

from kernel.type import TConst, TVar, STVar, TFun, BoolType
from kernel.term import Term, SVar, Var, Const, Comb, Abs, Bound, Implies, Eq, Inst, TyInst
from kernel.thm import Thm
from kernel.proof import Proof, ItemID
from kernel import theory
from kernel.theory import Theory, TheoryException, CheckProofException
from kernel import extension
from kernel.report import ProofReport, ExtensionReport


Ta = TVar("a")
Tb = TVar("b")
Tab = TFun(Ta, Tb)
x = Var("x", Ta)
y = Var("y", Ta)
z = Var("z", Ta)
f = Var("f", Tab)
A = Var("A", BoolType)
B = Var("B", BoolType)
C = Var("C", BoolType)


class TheoryTest(unittest.TestCase):
    def setUp(self):
        theory.thy = theory.EmptyTheory()

    def testEmptyTheory(self):
        self.assertEqual(theory.thy.get_type_sig("bool"), 0)
        self.assertEqual(theory.thy.get_type_sig("fun"), 2)
예제 #22
0
    "Q": TFun(Ta, boolT),
    "R": TFun(Ta, Ta, boolT),
    "a": Ta,
    "b": Ta,
    "c": Ta,
    "f": TFun(Ta, Ta),
    "nn": TFun(boolT, boolT),
    "m": nat.natT,
    "n": nat.natT,
    "p": nat.natT,
    "xs": Type("list", Ta),
    "ys": Type("list", Ta),
    "zs": Type("list", Ta),
}

A = Var("A", boolT)
B = Var("B", boolT)
C = Var("C", boolT)


class ParserTest(unittest.TestCase):
    def testParseType(self):
        test_data = [
            "'b",
            "nat",
            "'a list",
            "nat list",
            "('a, 'b) prod",
            "nat list list",
            "(nat, 'a) prod",
            "'a => 'b",
예제 #23
0
 def term(self):
     return Var(self.name)
예제 #24
0
import unittest

from kernel.type import TVar, Type, TFun, boolT
from kernel.term import Var, Const, Comb, Abs, Bound, Term
from kernel.thm import Thm
from logic import logic
from logic import nat
from logic import list
from logic import set
from logic import basic
from logic import function
from syntax import printer

thy = basic.load_theory('list')

A = Var("A", boolT)
B = Var("B", boolT)
C = Var("C", boolT)
Ta = TVar("a")
a = Var("a", Ta)
b = Var("b", Ta)
P = Var("P", TFun(Ta, boolT))
Q = Var("Q", TFun(Ta, boolT))
R = Var("R", TFun(Ta, Ta, boolT))
f = Var("f", TFun(Ta, Ta))
nn = Var("n", TFun(boolT, boolT))
m = Var("m", nat.natT)
n = Var("n", nat.natT)
p = Var("p", nat.natT)
xs = Var("xs", Type("list", Ta))
ys = Var("ys", Type("list", Ta))
예제 #25
0
# Author: Bohua Zhan

import unittest

from kernel.type import TVar, TFun
from kernel.term import Var, Term, Eq
from kernel.thm import Thm
from kernel.proof import Proof
from kernel import theory
from logic import basic
from kernel.proofterm import ProofTerm

basic.load_theory('logic_base')

Ta = TVar("a")
x = Var("x", Ta)
y = Var("y", Ta)
z = Var("z", Ta)
f = Var("f", TFun(Ta, Ta, Ta))


class ProofTermTest(unittest.TestCase):
    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)
예제 #26
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)
예제 #27
0
파일: paraverifier.py 프로젝트: bzhan/holpy
    def get_subgoal(self, inv_id, rule_id, case_id, hint):
        """Obtain the subgoal for the given case and hint.

        inv_id: index of the invariant to be shown at the end of the
                transition.
        rule_id: index of the transition rule.
        case_id: index of the case. The cases are as follows:
            - 0 to n-1: parameter in rule equals i'th parameter in inv.
            - n: parameter in rule does not equal any parameter in inv.
        hint: either:
            - GUARD: invariant is implied by the guard.
            - PRE: invariant is implied by the same invariant in the
                   previous state.
            - INV, i, inst:
                Invariant is implied by the guard and a different
                invariant i in the previous state. inst is a list specifying
                how to instantiate the invariant.

        """
        rule_var, guard, assigns = self.rules[rule_id]
        inv_vars, inv = self.invs[inv_id]
        assert case_id >= 0 and case_id <= len(inv_vars), \
               "get_subgoal: unexpected case_id."

        # Obtain invariant on the updated state.
        def subst(t):
            if t.is_comb() and t.fun in self.vars and t.arg in inv_vars:
                # Substitution for a parameterized variable
                if case_id < len(inv_vars) and inv_vars[case_id] == t.arg and \
                   t.fun(rule_var) in assigns:
                    return assigns[t.fun(rule_var)]
                elif t.fun in assigns:
                    return assigns[t.fun](t.arg)
                else:
                    return t
            elif t.is_var():
                # Substitution for a non-parameterized variable
                if t in assigns:
                    return assigns[t]
                else:
                    return t
            elif t.is_const():
                return t
            elif t.is_comb():
                return subst(t.fun)(subst(t.arg))
            else:
                raise NotImplementedError

        inv_after = subst(inv)
        if hint == GUARD:
            return Implies(guard, inv_after)
        elif hint == PRE:
            return Implies(inv, inv_after)
        else:
            hint_ty, hint_inv_id, subst_vars = hint
            if hint_ty == INV:
                inv_vars, inv = self.invs[hint_inv_id]
                inv_var_nms = [v.name for v in inv_vars]
                subst = Inst((nm, Var(subst_var, NatType))
                             for nm, subst_var in zip(inv_var_nms, subst_vars))
                inv_subst = inv.subst(subst)
                return Implies(inv_subst, guard, inv_after)
예제 #28
0
from kernel.thm import Thm
from kernel.proof import Proof
from kernel.report import ProofReport
from logic import logic
from logic import basic
from logic import nat
from logic import list
from logic import function
from syntax import printer
from server import server
from server import method
from server.server import ProofState

thy = basic.load_theory('logic_base')

A = Var("A", boolT)
B = Var("B", boolT)
conj = logic.mk_conj
disj = logic.mk_disj
imp = Term.mk_implies
neg = logic.neg
exists = logic.mk_exists


class ServerTest(unittest.TestCase):
    def testIncrIdAfter(self):
        test_data = [
            (((0,), (0,), 1), (1,),),
            (((0, 1), (0,), 1), (1, 1)),
            (((1,), (2, 2), 1), (1,)),
            (((2, 1), (2, 2), 1), (2, 1)),
예제 #29
0
파일: inequality.py 프로젝트: bzhan/holpy
def get_nat_power_bounds(pt, n):
    """Given theorem of the form t Mem I, obtain a theorem of
    the form t ^ n Mem J.

    """
    a, b = get_mem_bounds(pt)
    if not n.is_number():
        raise NotImplementedError
    if eval_hol_expr(a) >= 0 and is_mem_closed(pt):
        pt = apply_theorem('nat_power_interval_pos_closed',
                           auto.auto_solve(real_nonneg(a)),
                           pt,
                           inst=Inst(n=n))
    elif eval_hol_expr(a) >= 0 and is_mem_open(pt):
        pt = apply_theorem('nat_power_interval_pos_open',
                           auto.auto_solve(real_nonneg(a)),
                           pt,
                           inst=Inst(n=n))
    elif eval_hol_expr(a) >= 0 and is_mem_lopen(pt):
        pt = apply_theorem('nat_power_interval_pos_lopen',
                           auto.auto_solve(real_nonneg(a)),
                           pt,
                           inst=Inst(n=n))
    elif eval_hol_expr(a) >= 0 and is_mem_ropen(pt):
        pt = apply_theorem('nat_power_interval_pos_ropen',
                           auto.auto_solve(real_nonneg(a)),
                           pt,
                           inst=Inst(n=n))
    elif eval_hol_expr(b) <= 0 and is_mem_closed(pt):
        int_n = n.dest_number()
        if int_n % 2 == 0:
            even_pt = nat_as_even(int_n)
            pt = apply_theorem('nat_power_interval_neg_even_closed',
                               auto.auto_solve(real_nonpos(b)), even_pt, pt)
        else:
            odd_pt = nat_as_odd(int_n)
            pt = apply_theorem('nat_power_interval_neg_odd_closed',
                               auto.auto_solve(real_nonpos(b)), odd_pt, pt)
    elif eval_hol_expr(b) <= 0 and is_mem_open(pt):
        int_n = n.dest_number()
        if int_n % 2 == 0:
            even_pt = nat_as_even(int_n)
            pt = apply_theorem('nat_power_interval_neg_even_open',
                               auto.auto_solve(real_nonpos(b)), even_pt, pt)
        else:
            odd_pt = nat_as_odd(int_n)
            pt = apply_theorem('nat_power_interval_neg_odd_open',
                               auto.auto_solve(real_nonpos(b)), odd_pt, pt)
    elif is_mem_closed(pt):
        # Closed interval containing 0
        t = pt.prop.arg1
        assm1 = hol_set.mk_mem(t, real.closed_interval(a, Real(0)))
        assm2 = hol_set.mk_mem(t, real.closed_interval(Real(0), b))
        pt1 = get_nat_power_bounds(ProofTerm.assume(assm1),
                                   n).implies_intr(assm1)
        pt2 = get_nat_power_bounds(ProofTerm.assume(assm2),
                                   n).implies_intr(assm2)
        x = Var('x', RealType)
        pt = apply_theorem('split_interval_closed',
                           auto.auto_solve(real.less_eq(a, Real(0))),
                           auto.auto_solve(real.less_eq(Real(0), b)),
                           pt1,
                           pt2,
                           pt,
                           inst=Inst(x=t, f=Lambda(x, x**n)))
        subset_pt = interval_union_subset(pt.prop.arg)
        pt = apply_theorem('subsetE', subset_pt, pt)
    elif is_mem_open(pt):
        # Open interval containing 0
        t = pt.prop.arg1
        assm1 = hol_set.mk_mem(t, real.open_interval(a, Real(0)))
        assm2 = hol_set.mk_mem(t, real.ropen_interval(Real(0), b))
        pt1 = get_nat_power_bounds(ProofTerm.assume(assm1),
                                   n).implies_intr(assm1)
        pt2 = get_nat_power_bounds(ProofTerm.assume(assm2),
                                   n).implies_intr(assm2)
        x = Var('x', RealType)
        pt = apply_theorem('split_interval_open',
                           auto.auto_solve(real.less_eq(a, Real(0))),
                           auto.auto_solve(real.less_eq(Real(0), b)),
                           pt1,
                           pt2,
                           pt,
                           inst=Inst(x=t, f=Lambda(x, x**n)))
        subset_pt = interval_union_subset(pt.prop.arg)
        pt = apply_theorem('subsetE', subset_pt, pt)
    else:
        raise NotImplementedError
    return norm_mem_interval(pt)
예제 #30
0
 def testRewriteGoalThms(self):
     thy = basic.load_theory('nat')
     n = Var("n", nat.natT)
     state = ProofState.init_state(thy, [n], [], Term.mk_equals(nat.plus(nat.zero, n), n))
     search_res = state.apply_search(0, method.rewrite_goal())
     self.assertEqual([res['theorem'] for res in search_res], ["plus_def_1"])