def testSucConv(self): test_data = [ 0, 1, 2, 3, 4, 5, 6, 7, 19, 127, 1000, 1001, ] cv = nat.Suc_conv() for n in test_data: t = nat.Suc(nat.to_binary(n)) res_th = Thm.mk_equals(t, nat.to_binary(n + 1)) self.assertEqual(cv.eval(thy, t), res_th) prf = cv.get_proof_term(thy, t).export() self.assertEqual(thy.check_proof(prf), res_th)
def testComputeWP(self): Q = Var("Q", TFun(natFunT, boolT)) test_data = [ (Assign(zero, abs(s, one)), abs(s, Q(mk_fun_upd(s, zero, one)))), (Seq(Assign(zero, abs(s, one)), Assign(one, abs(s, nat.to_binary(2)))), abs(s, Q(mk_fun_upd(s, zero, one, one, nat.to_binary(2))))), ] for c, P in test_data: prf = hoare.compute_wp(thy, natFunT, c, Q).export() self.assertEqual(thy.check_proof(prf), Thm([], Valid(P, c, Q)))
def testNatIneqMacro(self): test_data = [ (0, 1), (1, 0), (0, 2), (2, 0), (1, 2), (2, 1), (1, 3), (3, 1), (2, 3), (3, 2), (10, 13), (17, 19), (22, 24), ] macro = nat.nat_const_ineq_macro() for m, n in test_data: goal = logic.neg(Term.mk_equals(nat.to_binary(m), nat.to_binary(n))) prf = macro.get_proof_term(thy, goal, []).export() self.assertEqual(thy.check_proof(prf), Thm([], goal))
def testBinaryLarge(self): test_data = [ 100, 10000, 100000, 111111, 999999, 10101010101, 12345678987654321, ] for n in test_data: self.assertEqual(nat.from_binary(nat.to_binary(n)), n)
def var_expr(self, s): if ord(s) >= ord('a') and ord(s) <= ord('z'): return st(nat.to_binary(str_to_nat(s))) elif ord(s) >= ord('A') and ord(s) <= ord('Z'): return Var(s, nat.natT) else: raise NotImplementedError
def testEvalSem(self): com = Seq(Assign(zero, abs(s, one)), Assign(one, abs(s, nat.to_binary(2)))) st = mk_const_fun(natT, zero) st2 = fun_upd_of_seq(0, 1, 1, 2) goal = Sem(com, st, st2) prf = hoare.eval_Sem_macro().get_proof_term(thy, goal, []).export() self.assertEqual(thy.check_proof(prf), Thm([], goal))
def testConvertTerm(self): a, b = Var("a", TFun(natT, natT)), Var("b", boolT) var_map = {a: 0, b: 1} s = Var("s", gcl.stateT) test_data = [ (a(one), s(Para(Ident(zero), one))), (b, s(Ident(one))), (to_binary(3), NatV(to_binary(3))), (eq(a(one), to_binary(3)), eq(s(Para(Ident(zero), one)), NatV(to_binary(3)))), (logic.true, BoolV(logic.true)), (eq(b, logic.false), eq(s(Ident(one)), BoolV(logic.false))), ] for t, res in test_data: self.assertEqual(gcl.convert_term(var_map, s, t), res)
def replace_states(self, t): """Replace states by their corresponding numbers.""" if t in self.states: return to_binary(self.state_map[t]) elif t.is_comb(): return self.replace_states(t.fun)(self.replace_states(t.arg)) else: return t
def testEvalSem5(self): com = While(abs(s, logic.neg(eq(s(zero), nat.to_binary(3)))), assn_true, incr_one) st = mk_const_fun(natT, zero) st2 = fun_upd_of_seq(0, 3) goal = Sem(com, st, st2) prf = hoare.eval_Sem_macro().get_proof_term(thy, goal, []).export() rpt = ProofReport() self.assertEqual(thy.check_proof(prf, rpt), Thm([], goal))
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()
def testAVal(self): thy = basic.load_theory('expr') th = thy.get_theorem('aval_test2') state = ProofState.init_state(thy, [], [], th.prop) state.rewrite_goal(0, "aval_def_3") state.rewrite_goal(0, "aval_def_2") state.rewrite_goal(0, "aval_def_1") state.rewrite_goal(0, "fun_upd_def") state.rewrite_goal(0, "if_not_P") state.set_line(0, "nat_norm", args=Term.mk_equals(nat.plus(nat.zero, nat.to_binary(5)), nat.to_binary(5))) state.apply_backward_step(1, "nat_zero_Suc_neq") self.assertEqual(state.check_proof(no_gaps=True), th)
def testMultConv(self): test_data = [ (0, 2), (2, 0), (1, 2), (2, 1), (2, 2), (2, 3), (3, 2), (3, 3), (5, 5), (10, 5), (123,987), ] cv = nat.mult_conv() for m, n in test_data: t = nat.mk_times(nat.to_binary(m), nat.to_binary(n)) res_th = Thm.mk_equals(t, nat.to_binary(m * n)) self.assertEqual(cv.eval(thy, t), res_th) prf = cv.get_proof_term(thy, t).export() self.assertEqual(thy.check_proof(prf), res_th)
def convert(t): if t.head in var_map: if len(t.args) == 0: return s(Ident(to_binary(var_map[t.head]))) elif len(t.args) == 1: return s(Para(Ident(to_binary(var_map[t.head])), t.arg)) else: raise NotImplementedError elif t.is_equals(): return Term.mk_equals(convert(t.arg1), convert(t.arg)) elif logic.is_neg(t): return logic.neg(convert(t.arg)) elif logic.is_conj(t): return logic.conj(convert(t.arg1), convert(t.arg)) elif logic.is_disj(t): return logic.disj(convert(t.arg1), convert(t.arg)) elif t.get_type() == boolT: return BoolV(t) elif t.get_type() == natT: return NatV(t) else: raise NotImplementedError
def testVCG(self): P = Var("P", TFun(natFunT, boolT)) Q = Var("Q", TFun(natFunT, boolT)) test_data = [ Assign(zero, abs(s, one)), Seq(Assign(zero, abs(s, one)), Assign(one, abs(s, nat.to_binary(2)))), ] for c in test_data: goal = Valid(P, c, Q) prf = hoare.vcg(thy, natFunT, goal).export() self.assertEqual(thy.check_proof(prf).prop, goal)
def testBinary(self): test_data = [ (0, zero), (1, one), (2, bit0(one)), (3, bit1(one)), (4, bit0(bit0(one))), (5, bit1(bit0(one))), (6, bit0(bit1(one))), (7, bit1(bit1(one))), (19, bit1(bit1(bit0(bit0(one))))), (127, bit1(bit1(bit1(bit1(bit1(bit1(one))))))), ] for n, binary in test_data: self.assertEqual(nat.to_binary(n), binary) self.assertEqual(nat.from_binary(binary), n)
def testNatConv(self): test_data = [ ("2 + 3", 5), ("Suc (2 + 3)", 6), ("Suc (Suc (Suc 0))", 3), ("5 + 2 * 3", 11), ("(5 + 2) * 3", 21), ("5 * Suc (2 + 5)", 40), ] cv = nat.nat_conv() for expr, n in test_data: t = parser.parse_term(thy, {}, expr) res_th = Thm.mk_equals(t, nat.to_binary(n)) self.assertEqual(cv.eval(thy, t), res_th) prf = cv.get_proof_term(thy, t).export() self.assertEqual(thy.check_proof(prf), res_th)
def load_system(filename): dn = os.path.dirname(os.path.realpath(__file__)) with open(os.path.join(dn, 'examples/' + filename + '.json'), encoding='utf-8') as a: data = json.load(a) thy = basic.load_theory('gcl') name = data['name'] vars = [] for nm, str_T in data['vars'].items(): T = parser.parse_type(thy, str_T) vars.append(Var(nm, T)) for i, nm in enumerate(data['states']): thy.add_term_sig(nm, natT) thy.add_theorem(nm + "_def", Thm.mk_equals(Const(nm, natT), to_binary(i))) states = [Const(nm, natT) for nm in data['states']] rules = [] for rule in data['rules']: if isinstance(rule['var'], str): rule_var = Var(rule['var'], natT) ctxt = dict((v.name, v.T) for v in vars + [rule_var]) else: assert isinstance(rule['var'], list) rule_var = [Var(nm, natT) for nm in rule['var']] ctxt = dict((v.name, v.T) for v in vars + rule_var) guard = parser.parse_term(thy, ctxt, rule['guard']) assign = dict() for k, v in rule['assign'].items(): assign[parser.parse_term(thy, ctxt, k)] = parser.parse_term(thy, ctxt, v) rules.append((rule_var, guard, assign)) invs = [] for inv in data['invs']: inv_vars = [Var(nm, natT) for nm in inv['vars']] ctxt = dict((v.name, v.T) for v in vars + inv_vars) prop = parser.parse_term(thy, ctxt, inv['prop']) invs.append((inv_vars, prop)) return ParaSystem(thy, name, vars, states, rules, invs)
def testProveEvalI(self): s = function.mk_fun_upd(function.mk_const_fun(natT, zero), one, nat.to_binary(7)) test_data = [ (expr.Plus(expr.V(one), expr.N(nat.to_binary(5))), nat.to_binary(12)), (expr.Plus(expr.V(zero), expr.N(nat.to_binary(5))), nat.to_binary(5)), (expr.Times(expr.V(one), expr.N(nat.to_binary(5))), nat.to_binary(35)), ] for t, n in test_data: goal = expr.avalI(s, t, n) prf = expr.prove_avalI_macro().get_proof_term(thy, goal, []).export() self.assertEqual(thy.check_proof(prf), Thm([], goal))
def number(self, n): return nat.to_binary(int(n))
def num_expr(self, n): return nat.to_binary(int(n))
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))
from syntax import printer 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) thy = basic.load_theory('function') natT = nat.natT zero = nat.zero one = nat.one five = nat.to_binary(5) def fun_upd_of_seq(*ns): return mk_fun_upd(mk_const_fun(natT, zero), *[nat.to_binary(n) for n in ns]) class FunctionTest(unittest.TestCase): def testMkFunUpd(self): self.assertEqual(mk_fun_upd(f, a1, b1, a2, b2), mk_fun_upd(mk_fun_upd(f, a1, b1), a2, b2)) def testStripFunUpd(self): self.assertEqual(strip_fun_upd(f), (f, [])) self.assertEqual(strip_fun_upd(mk_fun_upd(f, a1, b1)), (f, [(a1, b1)]))
def fun_upd_of_seq(*ns): return mk_fun_upd(mk_const_fun(natT, zero), *[nat.to_binary(n) for n in ns])