def apply(self, r: RewriteRule): """Apply a rewrite rule to the current step.""" if not isinstance(r, RewriteRule): raise ValueError("apply must be given a RewriteRule") x_new = r.apply(self.premise) if x_new is None: return self.current_step = x_new self.steps.append(r) return x_new
def _process_subgoals(self): """ Go through all subgoals, if proven then remove subgoal and add to hypothesis list. """ for i, subgoal in reversed(list(enumerate(self.unproven_subgoals))): # Add proven subgoals to internal hypotheses list if subgoal.proven: new_rule = RewriteRule(subgoal.premise, subgoal.conclusion) self.hypotheses.append(new_rule) self.unproven_subgoals.pop(i) self.proven_subgoals.append(subgoal)
#!/usr/bin/env python3 from symcollab.algebra import Constant, Function, Variable from symcollab.rewrite import RewriteRule, RewriteSystem, narrow, is_finite, Variants f = Function("f", 2) x = Variable("x") a = Constant("a") b = Constant("b") r = RewriteRule(f(x, x), x) r2 = RewriteRule(f(a, x), b) print("Rewrite Rule 1:", r) print("Rewrite Rule 2:", r2) term = f(a, f(b, b)) rs = RewriteSystem({r, r2}) vt = Variants(term, rs) print("Variants of", term, ":", list(vt)) print("Variants Finite?", is_finite(vt, -1)) print("Rewrite rule from", term, "to", f(a, b), narrow(term, f(a,b), rs, -1))
from symcollab.algebra import Function, Variable from symcollab.rewrite import RewriteRule, RewriteSystem from .inductive import Inductive, TheorySystem @Inductive class Prop(TheorySystem): pass A = Variable("A", sort=Prop.sort) B = Variable("B", sort=Prop.sort) C = Variable("C", sort=Prop.sort) Not = Function("not", 1, domain_sort=Prop.sort, range_sort=Prop.sort) Prop.define(Not, RewriteSystem({RewriteRule(Not(Not(A)), A)})) And = Function("and", 2, domain_sort=Prop.sort, range_sort=Prop.sort) Prop.define(And, RewriteSystem({ RewriteRule(And(A, A), A), })) Or = Function("or", 2, domain_sort=Prop.sort, range_sort=Prop.sort) Prop.define(Or, RewriteSystem({ RewriteRule(Or(A, A), A), })) Implies = Function("implies", 2, domain_sort=Prop.sort, range_sort=Prop.sort) Prop.define(Implies, RewriteSystem({RewriteRule(Implies(A, B), Or(Not(A), B))}))
#!/usr/bin/env python3 from symcollab.algebra import Constant, Function, Variable from symcollab.rewrite import RewriteRule a = Constant("a") b = Constant("b") c = Constant("c") x = Variable("x") y = Variable("y") f = Function("f", 2) g = Function("g", 2) r = RewriteRule(f(y, g(x, a)), g(y, a)) term = f(b, g(c, a)) print("Applying " + str(r) + " to " + str(term)) print("Result:", r.apply(term)) print("Now to show what happens when you can't apply a term...") term = f(a, b) print("Applying " + str(r) + " to " + str(term)) print("Result:", r.apply(term)) print("Applying f(x, x) -> x to f(f(x, x), f(x, x))") term = f(f(x, x), f(x, x)) r = RewriteRule(f(x, x), x) print("Result:", r.apply(term)) print("Applying f(x, x) -> x to f(f(x, x), f(x,x)) at position 2") print("Result:", r.apply(term, '2'))
"""Definition and properties for two-arity tuple.""" from symcollab.algebra import Function, Variable from symcollab.rewrite import RewriteRule, RewriteSystem from .inductive import TheorySystem, Inductive @Inductive class Pair(TheorySystem): pair = Function("pair", 2) # Fix domain of pair to take anything Pair.pair.domain_sort = None # Variables for later rules _a = Variable("a", sort=Pair.sort) _b = Variable("b", sort=Pair.sort) fst = Function("fst", 1, domain_sort=Pair.sort) Pair.define(fst, RewriteSystem({ RewriteRule(fst(Pair.pair(_a, _b)), _a), })) lst = Function("lst", 1, domain_sort=Pair.sort) Pair.define(lst, RewriteSystem({ RewriteRule(lst(Pair.pair(_a, _b)), _b), }))
"""Converts a Boolean to an bool.""" if not isinstance(x, FuncTerm) or x != Boolean.trueb or x != Boolean.falseb: raise ValueError("to_bool function expects a simplified Boolean.") return x == Boolean.trueb # Variables for later rules _n = Variable("n", sort=Boolean.sort) _m = Variable("m", sort=Boolean.sort) # Negation neg = Function("neg", 1, domain_sort=Boolean.sort, range_sort=Boolean.sort) Boolean.define( neg, RewriteSystem({ RewriteRule(neg(Boolean.trueb), Boolean.falseb), RewriteRule(neg(Boolean.falseb), Boolean.trueb) }) ) # Boolean And andb = Function("andb", 2, domain_sort=Boolean.sort, range_sort=Boolean.sort) Boolean.define( andb, RewriteSystem({ RewriteRule(andb(Boolean.trueb, _n), _n), RewriteRule(andb(Boolean.falseb, _n), Boolean.falseb) }) ) # Boolean Or
class Ring(TheorySystem): """ A ring is an abelian group with another binary operation that is associative, distributive over the abelian operation, and has an ientity element. """ add = Function("add", 2) mul = Function("mul", 2) negate = Function("neg", 1) zero = Constant("0") _x = Variable("x", sort=Group.sort) _y = Variable("y", sort=Group.sort) _z = Variable("z", sort=Group.sort) # TODO: Make Group.rules.rules match what the function symbols are Ring.rules = RewriteSystem(Group.rules.rules | { ## Associativity Rules # (x * y) * z → x * (y * z) RewriteRule(Ring.mul(Ring.mul(_x, _y), _z), Ring.mul(_x, Ring.mul(_y, _z))), ## Zero rules # 0 * x → 0 RewriteRule(Ring.mul(Ring.zero, _x), Ring.zero), # x * 0 → 0 RewriteRule(Ring.mul(_x, Ring.zero), Ring.zero), ## Distributivity rules # x * (y + z) → (x * y) + (x * z) RewriteRule(Ring.mul(_x, Ring.add(_y, _z)), Ring.add(Ring.mul(_x, _y), Ring.mul(_x, _z))), # (y + z) * x → (y * x) + (z * x) RewriteRule(Ring.mul(Ring.add(_y, _z), _x), Ring.add(Ring.mul(_y, _x), Ring.mul(_z, _x))) })
#!/usr/bin/env python3 """ A thought experiment on how to define recursive MOOs. """ from symcollab.algebra import Constant, Function, Variable from symcollab.rewrite import RewriteRule, RewriteSystem, normal from symcollab.xor import xor from symcollab.theories.nat import Nat C = Function("C", 1, domain_sort=Nat.sort) P = Function("P", 1, domain_sort=Nat.sort) f = Function("f", 1) IV = Constant("IV") n = Variable("n", sort=Nat.sort) r0 = RewriteRule(C(Nat.zero), IV) rn = RewriteRule(C(Nat.S(n)), f(xor(P(Nat.S(n)), C(n)))) moo_system = RewriteSystem({r0, rn}) print("Cipher Block Chaining:", moo_system) three = Nat.from_int(3) print("Simplified form of the 3rd ciphertext:", normal(C(three), moo_system)[0])
return 0 if isinstance(x, FuncTerm) and x.function == Nat.S: return 1 + cls.to_int(x.arguments[0]) raise ValueError("to_int: Only accepts signature {0, S}") # Variables for later rules _n = Variable("n", sort=Nat.sort) _m = Variable("m", sort=Nat.sort) # Decrement dec = Function("dec", 1, domain_sort=Nat.sort, range_sort=Nat.sort) Nat.define( dec, RewriteSystem({ RewriteRule(dec(Nat.S(_n)), _n), RewriteRule(dec(Nat.zero), Nat.zero) })) ## Parity Test even = Function("even", 1, domain_sort=Nat.sort, range_sort=Boolean.sort) Nat.define( even, RewriteSystem({ RewriteRule(even(Nat.zero), Boolean.trueb), RewriteRule(even(Nat.S(Nat.zero)), Boolean.falseb), RewriteRule(even(Nat.S(Nat.S(_n))), even(_n)) })) odd = Function("odd", 1, domain_sort=Nat.sort, range_sort=Boolean.sort)
# Variables for later rules _element = Variable("element") _list = Variable("alist", sort=Listing.sort) _list2 = Variable("blist", sort=Listing.sort) # Repeat _count = Variable("n", sort=Nat.sort) repeat = Function("repeat", 2, domain_sort=[None, Nat.sort], range_sort=Listing.sort) Listing.define( repeat, RewriteSystem({ RewriteRule(repeat(_element, Nat.zero), Listing.nil), RewriteRule(repeat(_element, Nat.S(_count)), Listing.cons(_element, repeat(_element, _count))) })) # Length length = Function("length", 1, domain_sort=Listing.sort, range_sort=Nat.sort) Listing.define( length, RewriteSystem({ RewriteRule(length(Listing.nil), Nat.zero), RewriteRule(length(Listing.cons(_element, _list)), Nat.S(length(_list))) })) # Extends
A group is a set G with an operation op that contain the closure and associative properties, as well as contains an identity and inverse element. """ identity = Constant("e") op = Function("op", 2) inverse = Function("inv", 1) _x = Variable("x", sort=Group.sort) _y = Variable("y", sort=Group.sort) _z = Variable("z", sort=Group.sort) # From page 184 of Term Rewriting and All That Group.rules = RewriteSystem({ ## Associativity # (x * y) * z → x * (y * z) RewriteRule(Group.op(Group.op(_x, _y), _z), Group.op(_x, Group.op(_y, _z))), ## Identity Rules # 1 * x → x RewriteRule(Group.op(Group.identity, _x), _x), # x * 1 → x RewriteRule(Group.op(_x, Group.identity), _x), ## Inverse Rules # x * i(x) → 1 RewriteRule(Group.op(_x, Group.inverse(_x)), Group.identity), # i(x) * x → 1 RewriteRule(Group.op(Group.inverse(_x), _x), Group.identity), # i(1) → 1 RewriteRule(Group.inverse(Group.identity), Group.identity), # i(i(x)) → x RewriteRule(Group.inverse(Group.inverse(_x)), _x), # i(x * y) → i(y) * i(x)
add = Function("add", 2) mul = Function("mul", 2) negate = Function("neg", 1) inverse = Function("inv", 1) zero = Constant("0") unity = Constant("1") _x = Variable("x", sort=Field.sort) _y = Variable("y", sort=Field.sort) # TODO: Fix symbols of Ring and Field rules Field.rules = RewriteSystem( Ring.rules.rules | { ## One and Zero # 1 * 0 -> 0 RewriteRule(Field.mul(Field.unity, Field.zero), Field.zero), # 0 * 1 -> 0 RewriteRule(Field.mul(Field.zero, Field.unity), Field.zero), # 1 + 0 -> 1 RewriteRule(Field.add(Field.unity, Field.zero), Field.unity), # 0 + 1 -> 1 RewriteRule(Field.add(Field.zero, Field.unity), Field.unity), ## Unity Rules # 1 * x → x RewriteRule(Field.mul(Field.unity, _x), _x), # x * 1 → x RewriteRule(Field.mul(_x, Field.unity), _x), # -1 * x → -x RewriteRule(Field.mul(Field.negate(Field.unity), _x), Field.negate(_x) ), # x * -1 → -x