Esempio n. 1
0
    def testAbsConv(self):
        nat0 = Const("zero", natT)
        nat1 = Const("one", natT)
        f = Const("f", TFun(natT, natT))
        g = Const("g", TFun(natT, natT))
        x = Var("x", natT)

        thy.add_theorem("f_eq_g", eq(f(x), g(x)))
        t = Term.mk_abs(x, f(x))
        cv = abs_conv(rewr_conv("f_eq_g"))
        res_th = eq(t, Term.mk_abs(x, g(x)))
        self.assertEqual(cv.eval(thy, t), res_th)
        prf = cv.get_proof_term(thy, t).export()
        self.assertEqual(thy.check_proof(prf), res_th)
Esempio n. 2
0
 def testRule4(self):
     n = Var('n', natT)
     goal = Thm([], Term.mk_equals(plus(n, zero), n))
     inst = {'P': Term.mk_abs(n, goal.prop), 'x': n}
     pt = tactic.rule().get_proof_term(thy, ProofTerm.sorry(goal), args=('nat_induct', ({}, inst)))
     prf = pt.export()
     self.assertEqual(thy.check_proof(prf), goal)
Esempio n. 3
0
    def testInferPrintedType(self):
        t = Const("nil", listT(Ta))
        infer_printed_type(thy, t)
        self.assertTrue(hasattr(t, "print_type"))

        t = list.cons(Ta)(Var("a", Ta))
        infer_printed_type(thy, t)
        self.assertFalse(hasattr(t.fun, "print_type"))

        t = Term.mk_equals(Const("nil", listT(Ta)), Const("nil", listT(Ta)))
        infer_printed_type(thy, t)
        self.assertFalse(hasattr(t.fun.fun, "print_type"))
        self.assertTrue(hasattr(t.arg1, "print_type"))
        self.assertFalse(hasattr(t.arg, "print_type"))

        t = Term.mk_equals(list.mk_append(list.nil(Ta), list.nil(Ta)),
                           list.nil(Ta))
        infer_printed_type(thy, t)
        self.assertTrue(hasattr(t.arg1.arg1, "print_type"))
        self.assertFalse(hasattr(t.arg1.arg, "print_type"))
        self.assertFalse(hasattr(t.arg, "print_type"))

        t = Term.mk_abs(Var("x", Ta), Term.mk_equals(Var("x", Ta),
                                                     Var("x", Ta)))
        infer_printed_type(thy, t)
Esempio n. 4
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))
Esempio n. 5
0
 def testAddZeroRightWithMacro(self):
     """Proof of n + 0 = n by induction, using macros."""
     thy = basic.load_theory('nat')
     n = Var("n", nat.natT)
     eq = Term.mk_equals
     plus = nat.plus
     zero = nat.zero
     S = nat.Suc
     prf = Proof()
     prf.add_item(0, "reflexive", args=zero)
     prf.add_item(1,
                  "rewrite_goal",
                  args=("plus_def_1", eq(plus(zero, zero), zero)),
                  prevs=[0])
     prf.add_item(2, "assume", args=eq(plus(n, zero), n))
     prf.add_item(3, "arg_combination", args=S, prevs=[2])
     prf.add_item(4,
                  "rewrite_goal",
                  args=("plus_def_2", eq(plus(S(n), zero), S(n))),
                  prevs=[3])
     prf.add_item(5, "implies_intr", args=eq(plus(n, zero), n), prevs=[4])
     prf.add_item(6, "forall_intr", args=n, prevs=[5])
     prf.add_item(7,
                  "apply_theorem_for",
                  args=("nat_induct", {}, {
                      "P": Term.mk_abs(n, eq(plus(n, zero), n)),
                      "x": n
                  }),
                  prevs=[1, 6])
     th = Thm.mk_equals(plus(n, zero), n)
     self.assertEqual(thy.check_proof(prf), th)
Esempio n. 6
0
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
Esempio n. 7
0
    def abstraction(x, th):
        """Derivation rule ABSTRACTION:

        A |- t1 = t2
        ------------------------
        A |- (%x. t1) = (%x. t2)  where x does not occur in A.
        """
        if any(hyp.occurs_var(x) for hyp in th.hyps):
            raise InvalidDerivationException("abstraction")
        elif th.prop.is_equals():
            t1, t2 = th.prop.args
            try:
                t1_new, t2_new = (Term.mk_abs(x, t1), Term.mk_abs(x, t2))
            except TermSubstitutionException:
                raise InvalidDerivationException("abstraction")
            return Thm(th.hyps, Term.mk_equals(t1_new, t2_new))
        else:
            raise InvalidDerivationException("abstraction")
Esempio n. 8
0
 def get_proof_term(self, thy, goal, *, args=None, prevs=None):
     th_name, var = args
     P = Term.mk_abs(var, goal.prop)
     th = thy.get_theorem(th_name)
     f, args = th.concl.strip_comb()
     if len(args) != 1:
         raise NotImplementedError
     inst = {f.name: P, args[0].name: var}
     return rule().get_proof_term(thy, goal, args=(th_name, ({}, inst)))
Esempio n. 9
0
def process_file(input, output):
    thy = basic.load_theory('hoare')

    dn = os.path.dirname(os.path.realpath(__file__))
    with open(os.path.join(dn, 'examples/' + input + '.json'), encoding='utf-8') as a:
        data = json.load(a)

    output = json_output.JSONTheory(output, ["hoare"], "Generated from " + input)
    content = data['content']
    eval_count = 0
    vcg_count = 0
    for run in content:
        if run['ty'] == 'eval':
            com = parse_hoare(run['com'])
            st1 = mk_const_fun(nat.natT, nat.zero)
            for k, v in sorted(run['init'].items()):
                st1 = mk_fun_upd(st1, nat.to_binary(str_to_nat(k)), nat.to_binary(v))
            st2 = mk_const_fun(nat.natT, nat.zero)
            for k, v in sorted(run['final'].items()):
                st2 = mk_fun_upd(st2, nat.to_binary(str_to_nat(k)), nat.to_binary(v))
            Sem = hoare.Sem(natFunT)
            goal = Sem(com, st1, st2)
            prf = ProofTermDeriv("eval_Sem", thy, goal, []).export()
            rpt = ProofReport()
            th = thy.check_proof(prf, rpt)
            output.add_theorem("eval" + str(eval_count), th, prf)
            eval_count += 1
        elif run['ty'] == 'vcg':
            com = parse_hoare(run['com'])
            pre = Term.mk_abs(st, parse_cond(run['pre']))
            post = Term.mk_abs(st, parse_cond(run['post']))
            Valid = hoare.Valid(natFunT)
            goal = Valid(pre, com, post)
            prf = hoare.vcg_solve(thy, goal).export()
            rpt = ProofReport()
            th = thy.check_proof(prf, rpt)
            output.add_theorem("vcg" + str(vcg_count), th, prf)
            vcg_count += 1
        else:
            raise TypeError()

    output.export_json()
Esempio n. 10
0
 def testMultZeroRight(self):
     """Proof of n * 0 = 0 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.times(n, nat.zero),
                                          nat.zero)),
                      "x": n
                  },
                  prevs=[0])
     prf.add_item(2, "beta_norm", prevs=[1])
     prf.add_item(3, "theorem", args="times_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.times(n, nat.zero), nat.zero))
     prf.add_item(7, "theorem", args="times_def_2")
     prf.add_item(8,
                  "substitution",
                  args={
                      "m": n,
                      "n": nat.zero
                  },
                  prevs=[7])
     prf.add_item(9, "theorem", args="plus_def_1")
     prf.add_item(10,
                  "substitution",
                  args={"n": nat.times(n, nat.zero)},
                  prevs=[9])
     prf.add_item(11, "transitive", prevs=[8, 10])
     prf.add_item(12, "transitive", prevs=[11, 6])
     prf.add_item(13,
                  "implies_intr",
                  args=eq(nat.times(n, nat.zero), nat.zero),
                  prevs=[12])
     prf.add_item(14, "forall_intr", args=n, prevs=[13])
     prf.add_item(15, "implies_elim", prevs=[5, 14])
     th = Thm.mk_equals(nat.times(n, nat.zero), nat.zero)
     self.assertEqual(thy.check_proof(prf), th)
Esempio n. 11
0
    def testBetaNorm(self):
        thy = basic.load_theory('logic_base')

        t = Term.mk_abs(x, f(x))
        prf = Proof(Term.mk_equals(t(x), y))
        prf.add_item(1, "beta_norm", prevs=[0])
        prf.add_item(2,
                     "implies_intr",
                     args=Term.mk_equals(t(x), y),
                     prevs=[1])

        th = Thm.mk_implies(Term.mk_equals(t(x), y), Term.mk_equals(f(x), y))
        rpt = ProofReport()
        self.assertEqual(thy.check_proof(prf, rpt), th)
        self.assertEqual(rpt.prim_steps, 8)

        rpt2 = ProofReport()
        self.assertEqual(thy.check_proof(prf, rpt2, check_level=1), th)
        self.assertEqual(rpt2.prim_steps, 2)
        self.assertEqual(rpt2.macro_steps, 1)
Esempio n. 12
0
 def testMultZeroRightWithMacro(self):
     """Proof of n * 0 = 0 by induction, using macros."""
     thy = basic.load_theory('nat')
     n = Var("n", nat.natT)
     eq = Term.mk_equals
     zero = nat.zero
     plus = nat.mk_plus
     times = nat.mk_times
     S = nat.Suc
     prf = Proof()
     prf.add_item(0, "reflexive", args=zero)
     prf.add_item(1,
                  "rewrite_goal",
                  args=("times_def_1", eq(times(zero, zero), zero)),
                  prevs=[0])
     prf.add_item(2, "assume", args=eq(times(n, zero), zero))
     prf.add_item(3, "reflexive", args=times(n, zero))
     prf.add_item(4,
                  "rewrite_goal",
                  args=("plus_def_1",
                        eq(plus(zero, times(n, zero)), times(n, zero))),
                  prevs=[3])
     prf.add_item(5, "transitive", prevs=[4, 2])
     prf.add_item(6,
                  "rewrite_goal",
                  args=("times_def_2", eq(times(S(n), zero), zero)),
                  prevs=[5])
     prf.add_item(7,
                  "implies_intr",
                  args=eq(times(n, zero), zero),
                  prevs=[6])
     prf.add_item(8, "forall_intr", args=n, prevs=[7])
     prf.add_item(9,
                  "apply_theorem_for",
                  args=("nat_induct", {}, {
                      "P": Term.mk_abs(n, eq(times(n, zero), zero)),
                      "x": n
                  }),
                  prevs=[1, 8])
     th = Thm.mk_equals(times(n, zero), zero)
     self.assertEqual(thy.check_proof(prf), th)
Esempio n. 13
0
 def while_cmd(self, b, c):
     While = hoare.While(natFunT)
     return While(Term.mk_abs(st, b), Term.mk_abs(st, logic.true), c)
Esempio n. 14
0
 def if_cmd(self, b, c1, c2):
     Cond = hoare.Cond(natFunT)
     return Cond(Term.mk_abs(st, b), c1, c2)
Esempio n. 15
0
 def assign_cmd(self, v, e):
     Assign = hoare.Assign(nat.natT, nat.natT)
     return Assign(nat.to_binary(str_to_nat(v)), Term.mk_abs(st, e))
Esempio n. 16
0
 def while_cmd_inv(self, b, inv, c):
     While = hoare.While(natFunT)
     return While(Term.mk_abs(st, b), Term.mk_abs(st, inv), c)
Esempio n. 17
0
    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
Esempio n. 18
0
    def testExistsConj(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)
        conjAB = logic.mk_conj(A(x), B(x))
        exists_conj = logic.mk_exists(x, conjAB)
        exists_A = logic.mk_exists(x, A(x))
        exists_B = logic.mk_exists(x, B(x))
        conj_exists = logic.mk_conj(exists_A, exists_B)

        prf = Proof(exists_conj)
        prf.add_item(1, "assume", args=conjAB)
        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, "theorem", args="conjD2")
        prf.add_item(6, "substitution", args={"A": A(x), "B": B(x)}, prevs=[5])
        prf.add_item(7, "implies_elim", prevs=[6, 1])
        prf.add_item(8, "theorem", args="exI")
        prf.add_item(9, "substitution", args={"P": A, "a": x}, prevs=[8])
        prf.add_item(10, "implies_elim", prevs=[9, 4])
        prf.add_item(11, "substitution", args={"P": B, "a": x}, prevs=[8])
        prf.add_item(12, "implies_elim", prevs=[11, 7])
        prf.add_item(13, "implies_intr", args=conjAB, prevs=[10])
        prf.add_item(14, "implies_intr", args=conjAB, prevs=[12])
        prf.add_item(15, "forall_intr", args=x, prevs=[13])
        prf.add_item(16, "forall_intr", args=x, prevs=[14])
        prf.add_item(17, "theorem", args="exE")
        prf.add_item(18,
                     "substitution",
                     args={
                         "P": Term.mk_abs(x, conjAB),
                         "C": exists_A
                     },
                     prevs=[17])
        prf.add_item(19, "beta_norm", prevs=[18])
        prf.add_item(20, "implies_elim", prevs=[19, 0])
        prf.add_item(21, "implies_elim", prevs=[20, 15])
        prf.add_item(22,
                     "substitution",
                     args={
                         "P": Term.mk_abs(x, conjAB),
                         "C": exists_B
                     },
                     prevs=[17])
        prf.add_item(23, "beta_norm", prevs=[22])
        prf.add_item(24, "implies_elim", prevs=[23, 0])
        prf.add_item(25, "implies_elim", prevs=[24, 16])
        prf.add_item(26, "theorem", args="conjI")
        prf.add_item(27,
                     "substitution",
                     args={
                         "A": exists_A,
                         "B": exists_B
                     },
                     prevs=[26])
        prf.add_item(28, "implies_elim", prevs=[27, 21])
        prf.add_item(29, "implies_elim", prevs=[28, 25])
        prf.add_item(30, "implies_intr", args=exists_conj, prevs=[29])
        th = Thm.mk_implies(exists_conj, conj_exists)
        self.assertEqual(thy.check_proof(prf), th)