def testGetForallName(self): test_data = [ (Forall(x, Forall(y, Eq(x, y))), ["x", "y"]), ] for t, res in test_data: self.assertEqual(logic.get_forall_names(t), res)
def rec(t): if t.is_exists(): # Obtain the list of variables that t depends on, not # counting functions (including skolem functions). xs = [v for v in t.arg.body.get_vars() if not v.T.is_fun()] # Obtain the new skolem variable. nm = "c_" + t.arg.var_name if len( xs) == 0 else "f_" + t.arg.var_name nm = name.get_variant_name(nm, var_names) var_names.append(nm) # Obtain the concrete instantiation of the skolem variable. T = TFun(*([x.T for x in xs] + [t.arg.var_T])) f = Var(nm, T)(*xs) return rec(t.arg.subst_bound(f)) elif t.is_forall(): nm = name.get_variant_name(t.arg.var_name, var_names) var_names.append(nm) v = Var(nm, t.arg.var_T) body = t.arg.subst_bound(v) return Forall(v, rec(body)) elif t.is_conj() or t.is_disj(): return t.head(rec(t.arg1), rec(t.arg)) else: return t
def get_extension(self): assert self.error is None, "get_extension" res = [] res.append( extension.Constant(self.name, self.type, ref_name=self.cname)) for rule in self.rules: res.append(extension.Theorem(rule['name'], Thm([], rule['prop']))) res.append(extension.Attribute(rule['name'], 'hint_backward')) # Case rule Targs, _ = self.type.strip_type() vars = [] for i, Targ in enumerate(Targs): vars.append(Var("_a" + str(i + 1), Targ)) P = Var("P", BoolType) pred = Const(self.name, self.type) assum0 = pred(*vars) assums = [] for rule in self.rules: prop = rule['prop'] As, C = prop.strip_implies() eq_assums = [Eq(var, arg) for var, arg in zip(vars, C.args)] assum = Implies(*(eq_assums + As), P) for var in reversed(prop.get_vars()): assum = Forall(var, assum) assums.append(assum) prop = Implies(*([assum0] + assums + [P])) res.append(extension.Theorem(self.cname + "_cases", Thm([], prop))) return res
def testPrintWithType(self): test_data = [ (list.nil(Ta), "([]::'a list)"), (Eq(list.nil(Ta), list.nil(Ta)), "([]::'a list) = []"), (Forall(a, Eq(a, a)), "!a::'a. a = a"), ] with global_setting(unicode=False): for t, s in test_data: self.assertEqual(printer.print_term(t), s)
def forall_intr(x, th): """Derivation rule FORALL_INTR: A |- t ------------ A |- !x. t where x does not occur in A. """ if any(hyp.occurs_var(x) for hyp in th.hyps): raise InvalidDerivationException("forall_intr") elif not (x.is_var() or x.is_svar()): raise InvalidDerivationException("forall_intr") else: return Thm(th.hyps, Forall(x, th.prop))
def testPrintUnicode(self): test_data = [ (And(A, B), "A ∧ B"), (Or(A, B), "A ∨ B"), (Implies(A, B), "A ⟶ B"), (Lambda(a, P(a)), "λa. P a"), (Forall(a, P(a)), "∀a. P a"), (Exists(a, P(a)), "∃a. P a"), (Not(A), "¬A"), (Lambda(m, m + 2), "λm::nat. m + 2"), (Lambda(m, m + n), "λm. m + n"), ] with global_setting(unicode=True): for t, s in test_data: self.assertEqual(printer.print_term(t), s)
def testPrintHighlight(self): """Test highlight""" t = Exists(a, Forall(b, R(a, b))) with global_setting(unicode=False, highlight=True): res = printer.print_term(t) self.assertEqual(res, [{ 'color': 0, 'text': '?' }, { 'color': 1, 'text': 'a' }, { 'color': 0, 'text': '. ' }, { 'color': 0, 'text': '!' }, { 'color': 1, 'text': 'b' }, { 'color': 0, 'text': '. ' }, { 'color': 2, 'text': 'R' }, { 'color': 0, 'text': ' ' }, { 'color': 1, 'text': 'a' }, { 'color': 0, 'text': ' ' }, { 'color': 1, 'text': 'b' }])
def testPrintLogical(self): test_data = [ # Variables (SVar("P", BoolType), "?P"), (a, "a"), # Equality and implies (Eq(a, b), "a = b"), (Implies(A, B), "A --> B"), (Implies(A, B, C), "A --> B --> C"), (Implies(Implies(A, B), C), "(A --> B) --> C"), (Implies(A, Eq(a, b)), "A --> a = b"), (Eq(Implies(A, B), Implies(B, C)), "(A --> B) <--> (B --> C)"), (Eq(A, Eq(B, C)), "A <--> B <--> C"), (Eq(Eq(A, B), C), "(A <--> B) <--> C"), # Conjunction and disjunction (And(A, B), "A & B"), (Or(A, B), "A | B"), (And(A, And(B, C)), "A & B & C"), (And(And(A, B), C), "(A & B) & C"), (Or(A, Or(B, C)), "A | B | C"), (Or(Or(A, B), C), "(A | B) | C"), (Or(And(A, B), C), "A & B | C"), (And(Or(A, B), C), "(A | B) & C"), (Or(A, And(B, C)), "A | B & C"), (And(A, Or(B, C)), "A & (B | C)"), (Or(And(A, B), And(B, C)), "A & B | B & C"), (And(Or(A, B), Or(B, C)), "(A | B) & (B | C)"), # Negation (Not(A), "~A"), (Not(Not(A)), "~~A"), # Constants (true, "true"), (false, "false"), # Mixed (Implies(And(A, B), C), "A & B --> C"), (Implies(A, Or(B, C)), "A --> B | C"), (And(A, Implies(B, C)), "A & (B --> C)"), (Or(Implies(A, B), C), "(A --> B) | C"), (Not(And(A, B)), "~(A & B)"), (Not(Implies(A, B)), "~(A --> B)"), (Not(Eq(A, B)), "~(A <--> B)"), (Eq(Not(A), B), "~A <--> B"), (Eq(Not(A), Not(B)), "~A <--> ~B"), (Implies(A, Eq(B, C)), "A --> B <--> C"), (Eq(Implies(A, B), C), "(A --> B) <--> C"), # Abstraction (Lambda(a, And(P(a), Q(a))), "%a. P a & Q a"), # Quantifiers (Forall(a, P(a)), "!a. P a"), (Forall(a, Forall(b, And(P(a), P(b)))), "!a. !b. P a & P b"), (Forall(a, And(P(a), Q(a))), "!a. P a & Q a"), (And(Forall(a, P(a)), Q(a)), "(!a1. P a1) & Q a"), (Forall(a, Implies(P(a), Q(a))), "!a. P a --> Q a"), (Implies(Forall(a, P(a)), Q(a)), "(!a1. P a1) --> Q a"), (Implies(Forall(a, P(a)), Forall(a, Q(a))), "(!a. P a) --> (!a. Q a)"), (Implies(Exists(a, P(a)), Exists(a, Q(a))), "(?a. P a) --> (?a. Q a)"), (Eq(A, Forall(a, P(a))), "A <--> (!a. P a)"), (Exists(a, P(a)), "?a. P a"), (Exists(a, Forall(b, R(a, b))), "?a. !b. R a b"), (logic.mk_exists1(a, P(a)), "?!a. P a"), (logic.mk_the(a, P(a)), "THE a. P a"), (logic.mk_some(a, P(a)), "SOME a. P a"), (Forall(a, Exists(b, R(a, b))), "!a. ?b. R a b"), # If (mk_if(A, a, b), "if A then a else b"), (Eq(mk_if(A, a, b), a), "(if A then a else b) = a"), (mk_if(A, P, Q), "if A then P else Q"), ] with global_setting(unicode=False): for t, s in test_data: self.assertEqual(printer.print_term(t), s)
def testForallElimFail2(self): P = Var("P", TFun(Ta, BoolType)) th = Thm([], Forall(x, P(x))) self.assertRaises(InvalidDerivationException, Thm.forall_elim, A, th)
def testForallElim(self): P = Var("P", TFun(Ta, BoolType)) th = Thm([], Forall(x, P(x))) self.assertEqual(Thm.forall_elim(y, th), Thm([], P(y)))
def testForallIntr2(self): """Also OK if the variable does not appear in theorem.""" th = Thm([], Eq(x,y)) t_res = Forall(z, Eq(x, y)) self.assertEqual(Thm.forall_intr(z, th), Thm([], t_res))
def testForallIntr(self): th = Thm([], Eq(x,y)) t_res = Forall(x, Eq(x, y)) self.assertEqual(Thm.forall_intr(x, th), Thm([], t_res))
def get_extension(self): assert self.error is None, "get_extension" res = [] # Add to type and term signature. res.append(extension.TConst(self.name, len(self.args))) for constr in self.constrs: res.append( extension.Constant(constr['name'], constr['type'], ref_name=constr['cname'])) # Add non-equality theorems. for constr1, constr2 in itertools.combinations(self.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, _ = constr1['type'].strip_type() argT2, _ = constr2['type'].strip_type() lhs_vars = [Var(nm, T) for nm, T in zip(constr1['args'], argT1)] rhs_vars = [Var(nm, T) for nm, T in zip(constr2['args'], argT2)] A = Const(constr1['name'], constr1['type']) B = Const(constr2['name'], constr2['type']) lhs = A(*lhs_vars) rhs = B(*rhs_vars) neq = Not(Eq(lhs, rhs)) th_name = "%s_%s_%s_neq" % (self.name, constr1['name'], constr2['name']) res.append(extension.Theorem(th_name, Thm([], neq))) # Add injectivity theorems. for constr in self.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 constr['args']: argT, _ = constr['type'].strip_type() lhs_vars = [Var(nm, T) for nm, T in zip(constr['args'], argT)] rhs_vars = [ Var(nm + "1", T) for nm, T in zip(constr['args'], argT) ] A = Const(constr['name'], constr['type']) assum = Eq(A(*lhs_vars), A(*rhs_vars)) concls = [ Eq(var1, var2) for var1, var2 in zip(lhs_vars, rhs_vars) ] concl = And(*concls) th_name = "%s_%s_inject" % (self.name, constr['name']) res.append( extension.Theorem(th_name, Thm([], Implies(assum, concl)))) # Add the inductive theorem. tvars = [TVar(targ) for targ in self.args] T = TConst(self.name, *tvars) var_P = Var("P", TFun(T, BoolType)) ind_assums = [] for constr in self.constrs: A = Const(constr['name'], constr['type']) argT, _ = constr['type'].strip_type() args = [Var(nm, T2) for nm, T2 in zip(constr['args'], argT)] C = var_P(A(*args)) As = [ var_P(Var(nm, T2)) for nm, T2 in zip(constr['args'], argT) if T2 == T ] ind_assum = Implies(*(As + [C])) for arg in reversed(args): ind_assum = Forall(arg, ind_assum) ind_assums.append(ind_assum) ind_concl = var_P(Var("x", T)) th_name = self.name + "_induct" res.append( extension.Theorem(th_name, Thm([], Implies(*(ind_assums + [ind_concl]))))) res.append(extension.Attribute(th_name, "var_induct")) return res