コード例 #1
0
ファイル: hoare.py プロジェクト: zhouwenfan/temp
def compute_wp(thy, T, c, Q):
    """Compute the weakest precondition for the given command
    and postcondition. The computation is by case analysis on
    the form of c. Returns the validity theorem.

    """
    if c.head.is_const_name("Assign"):  # Assign a b
        a, b = c.args
        s = Var("s", T)
        P2 = Term.mk_abs(s, Q(function.mk_fun_upd(s, a, b(s).beta_conv())))
        return apply_theorem(thy,
                             "assign_rule",
                             inst={"b": b},
                             concl=Valid(T)(P2, c, Q))
    elif c.head.is_const_name("Seq"):  # Seq c1 c2
        c1, c2 = c.args
        wp1 = compute_wp(thy, T, c2, Q)  # Valid Q' c2 Q
        wp2 = compute_wp(thy, T, c1, wp1.prop.args[0])  # Valid Q'' c1 Q'
        return apply_theorem(thy, "seq_rule", wp2, wp1)
    elif c.head.is_const_name("While"):  # While b I c
        _, I, _ = c.args
        pt = apply_theorem(thy, "while_rule", concl=Valid(T)(I, c, Q))
        pt0 = ProofTerm.assume(pt.assums[0])
        pt1 = vcg(thy, T, pt.assums[1])
        return ProofTerm.implies_elim(pt, pt0, pt1)
    else:
        raise NotImplementedError
コード例 #2
0
def ineq_zero_proof_term(thy, n):
    """Returns the inequality n ~= 0."""
    assert n != 0, "ineq_zero_proof_term: n = 0"
    if n == 1:
        return ProofTerm.theorem(thy, "one_nonzero")
    elif n % 2 == 0:
        return apply_theorem(thy, "bit0_nonzero",
                             ineq_zero_proof_term(thy, n // 2))
    else:
        return apply_theorem(thy,
                             "bit1_nonzero",
                             inst={"m": to_binary(n // 2)})
コード例 #3
0
def ineq_one_proof_term(thy, n):
    """Returns the inequality n ~= 1."""
    assert n != 1, "ineq_one_proof_term: n = 1"
    if n == 0:
        return apply_theorem(thy, "ineq_symmetric",
                             ProofTerm.theorem(thy, "one_nonzero"))
    elif n % 2 == 0:
        return apply_theorem(thy,
                             "bit0_neq_one",
                             inst={"m": to_binary(n // 2)})
    else:
        return apply_theorem(thy, "bit1_neq_one",
                             ineq_zero_proof_term(thy, n // 2))
コード例 #4
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"))
コード例 #5
0
ファイル: tactic.py プロジェクト: zhouwenfan/temp
    def get_proof_term(self, thy, goal, *, args=None, prevs=None):
        assert isinstance(args, Term), "cases"

        As = goal.hyps
        C = goal.prop
        goal1 = ProofTerm.sorry(Thm(goal.hyps, Term.mk_implies(args, C)))
        goal2 = ProofTerm.sorry(
            Thm(goal.hyps, Term.mk_implies(logic.neg(args), C)))
        return apply_theorem(thy, 'classical_cases', goal1, goal2)
コード例 #6
0
ファイル: expr.py プロジェクト: zhouwenfan/temp
 def helper(t):
     if t.head == N:
         n, = t.args
         return apply_theorem(thy,
                              "avalI_const",
                              concl=avalI(s, N(n), n))
     elif t.head == V:
         x, = t.args
         pt = apply_theorem(thy,
                            "avalI_var",
                            concl=avalI(s, V(x), s(x)))
         return pt.on_arg(thy, function.fun_upd_eval_conv())
     elif t.head == Plus:
         a1, a2 = t.args
         pt = apply_theorem(thy, "avalI_plus", helper(a1), helper(a2))
         return pt.on_arg(thy, nat.nat_conv())
     elif t.head == Times:
         a1, a2 = t.args
         pt = apply_theorem(thy, "avalI_times", helper(a1), helper(a2))
         return pt.on_arg(thy, nat.nat_conv())
コード例 #7
0
def ineq_proof_term(thy, m, n):
    """Returns the inequality m ~= n."""
    assert m != n, "ineq_proof_term: m = n"
    if n == 0:
        return ineq_zero_proof_term(thy, m)
    elif n == 1:
        return ineq_one_proof_term(thy, m)
    elif m == 0:
        return apply_theorem(thy, "ineq_symmetric",
                             ineq_zero_proof_term(thy, n))
    elif m == 1:
        return apply_theorem(thy, "ineq_symmetric",
                             ineq_one_proof_term(thy, n))
    elif m % 2 == 0 and n % 2 == 0:
        return apply_theorem(thy, "bit0_neq",
                             ineq_proof_term(thy, m // 2, n // 2))
    elif m % 2 == 1 and n % 2 == 1:
        return apply_theorem(thy, "bit1_neq",
                             ineq_proof_term(thy, m // 2, n // 2))
    elif m % 2 == 0 and n % 2 == 1:
        return apply_theorem(thy,
                             "bit0_bit1_neq",
                             inst={
                                 "m": to_binary(m // 2),
                                 "n": to_binary(n // 2)
                             })
    else:
        return apply_theorem(thy, "ineq_symmetric", ineq_proof_term(thy, n, m))
コード例 #8
0
def get_encode_proof(th):
    """Given resulting theorem for an encoding, obtain the proof
    of the theorem.

    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.

    """
    As, F = th.hyps[:-1], th.hyps[-1]

    # Obtain the assumptions
    ptAs = [ProofTerm.assume(A) for A in As]
    ptF = ProofTerm.assume(F)

    # Obtain the expansion of each As to a non-atomic term.
    pts = []
    for ptA in ptAs:
        rhs = ptA.prop.rhs
        if logic.is_conj(rhs):
            pts.append(ptA.on_prop(thy, rewr_conv("encode_conj")))
        elif logic.is_disj(rhs):
            pts.append(ptA.on_prop(thy, rewr_conv("encode_disj")))
        elif rhs.is_implies():
            pts.append(ptA.on_prop(thy, rewr_conv("encode_imp")))
        elif rhs.is_equals():
            pts.append(ptA.on_prop(thy, rewr_conv("encode_eq")))
        elif logic.is_neg(rhs):
            pts.append(ptA.on_prop(thy, rewr_conv("encode_not")))

    # Obtain the rewrite of the original formula.
    cvs = [
        top_conv(rewr_conv(ProofTerm.symmetric(ptA), match_vars=False))
        for ptA in ptAs
    ]
    cv = every_conv(*cvs)

    pts.append(ptF.on_prop(thy, cv))

    pt = pts[0]
    for pt2 in pts[1:]:
        pt = logic_macro.apply_theorem(thy, 'conjI', pt, pt2)

    return pt.on_prop(thy, logic.norm_conj_assoc())
コード例 #9
0
ファイル: tactic.py プロジェクト: zhouwenfan/temp
    def get_proof_term(self, thy, goal, *, args=None, prevs=None):
        if isinstance(args, tuple):
            th_name, instsp = args
        else:
            th_name = args
            instsp = None
        assert isinstance(th_name, str), "rule: theorem name must be a string"

        if prevs is None:
            prevs = []

        th = thy.get_theorem(th_name)
        As, C = th.assums, th.concl

        if instsp is None:
            instsp = (dict(), dict())
            if matcher.is_pattern(C, []):
                matcher.first_order_match_incr(C, goal.prop, instsp)
                for pat, prev in zip(As, prevs):
                    matcher.first_order_match_incr(pat, prev.prop, instsp)
            else:
                for pat, prev in zip(As, prevs):
                    matcher.first_order_match_incr(pat, prev.prop, instsp)
                matcher.first_order_match_incr(C, goal.prop, instsp)

        As, _ = logic.subst_norm(th.prop, instsp).strip_implies()
        pts = prevs + [
            ProofTerm.sorry(Thm(goal.hyps, A)) for A in As[len(prevs):]
        ]

        if set(term.get_vars(th.assums)) != set(term.get_vars(th.prop)) or \
           not matcher.is_pattern_list(th.assums, []):
            tyinst, inst = instsp
            return apply_theorem(thy, th_name, *pts, tyinst=tyinst, inst=inst)
        else:
            return apply_theorem(thy, th_name, *pts)
コード例 #10
0
ファイル: hoare.py プロジェクト: zhouwenfan/temp
def eval_Sem(thy, com, st):
    """Evaluates the effect of program com on state st."""
    f, args = com.strip_comb()
    T = st.get_type()
    if f.is_const_name("Skip"):
        return apply_theorem(thy, "Sem_Skip", tyinst={"a": T}, inst={"s": st})
    elif f.is_const_name("Assign"):
        a, b = args
        Ta = a.get_type()
        Tb = b.get_type().range_type()
        pt = apply_theorem(thy,
                           "Sem_Assign",
                           tyinst={
                               "a": Ta,
                               "b": Tb
                           },
                           inst={
                               "a": a,
                               "b": b,
                               "s": st
                           })
        return pt.on_arg(thy, arg_conv(norm_cv))
    elif f.is_const_name("Seq"):
        c1, c2 = args
        pt1 = eval_Sem(thy, c1, st)
        pt2 = eval_Sem(thy, c2, pt1.prop.arg)
        pt = apply_theorem(thy, "Sem_seq", pt1, pt2)
        return pt.on_arg(thy, function.fun_upd_norm_one_conv())
    elif f.is_const_name("Cond"):
        b, c1, c2 = args
        b_st = beta_norm(thy, b(st))
        b_eval = norm_cond_cv.get_proof_term(thy, b_st)
        if b_eval.prop.arg == logic.true:
            b_res = rewr_conv("eq_true", sym=True).apply_to_pt(thy, b_eval)
            pt1 = eval_Sem(thy, c1, st)
            return apply_theorem(thy,
                                 "Sem_if1",
                                 b_res,
                                 pt1,
                                 concl=Sem(T)(com, st, pt1.prop.arg))
        else:
            b_res = rewr_conv("eq_false", sym=True).apply_to_pt(thy, b_eval)
            pt2 = eval_Sem(thy, c2, st)
            return apply_theorem(thy,
                                 "Sem_if2",
                                 b_res,
                                 pt2,
                                 concl=Sem(T)(com, st, pt2.prop.arg))
    elif f.is_const_name("While"):
        b, inv, c = args
        b_st = beta_norm(thy, b(st))
        b_eval = norm_cond_cv.get_proof_term(thy, b_st)
        if b_eval.prop.arg == logic.true:
            b_res = rewr_conv("eq_true", sym=True).apply_to_pt(thy, b_eval)
            pt1 = eval_Sem(thy, c, st)
            pt2 = eval_Sem(thy, com, pt1.prop.arg)
            pt = apply_theorem(thy,
                               "Sem_while_loop",
                               b_res,
                               pt1,
                               pt2,
                               concl=Sem(T)(com, st, pt2.prop.arg),
                               inst={"s3": pt1.prop.arg})
            return pt.on_arg(thy, function.fun_upd_norm_one_conv())
        else:
            b_res = rewr_conv("eq_false", sym=True).apply_to_pt(thy, b_eval)
            return apply_theorem(thy,
                                 "Sem_while_skip",
                                 b_res,
                                 concl=Sem(T)(com, st, st))
    else:
        raise NotImplementedError
コード例 #11
0
ファイル: hoare.py プロジェクト: zhouwenfan/temp
def vcg(thy, T, goal):
    """Compute the verification conditions for the goal."""
    P, c, Q = goal.args
    pt = compute_wp(thy, T, c, Q)
    entail_P = ProofTerm.assume(Entail(T)(P, pt.prop.args[0]))
    return apply_theorem(thy, "pre_rule", entail_P, pt)