Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # There is a simple connection between natural numbers and DFAs on a singleton
- # alphabet. The importance of this connection is easily illustrated in modular
- # arithmetic.
- # Def: A roll is a pair of natural numbers, the second one of which is nonzero.
- # (Thus a roll is a fraction, but we won't make this connection.)
- # To every roll [p, q] we associate a DFA which goes through p states and then
- # goes into a loop of length q. Addition and multiplication of rolls, as well
- # as of their states, is easily defined. The states of this DFA are
- # conventionally taken to be the natural range [0, p+q).
- # Good picture: https://pixabay.com/p-147631/?no_redirect
- # (Actually, the theory of rolls should require no prior theory of natural
- # numbers if a roll is defined more like a DFA directly, but that's a more
- # beautiful story.)
- # Here's some arithmetic aided by rolls.
- """ Compute what state the DFA of b will be in after natural input a. """
- def nat_mod_roll(a, b):
- flat, loop = b
- return a if a < flat else (a - flat) % loop + flat
- """
- Compute the smallest roll whose DFA states can index the states that the DFA
- of b ends up in after any input a^i.
- """
- def roll_of_powers(a, b):
- powers = [1]
- while True:
- c = nat_mod_roll(a*powers[-1], b)
- if c in powers:
- return powers.index(c), len(powers) - powers.index(c)
- powers.append(c)
- """ Compute what state the DFA of b will be in after tower input a. """
- def tower_mod_roll(a, b):
- if len(a) == 0:
- return nat_mod_roll(1, b)
- return nat_mod_roll(a[0]**tower_mod_roll(a[1:], roll_of_powers(a[0], b)), b)
- def mod(a, b):
- if isinstance(a, int): a = a,
- if isinstance(b, int): b = 0, b
- return tower_mod_roll(a, b)
- def test():
- arg_a = [2, 10], [100, 1000, 10000], [104, 2], [2, 3]
- arg_b = 100, 100000, 5, 112
- expect = 24, 0, 1, 8
- for a, b, good in zip(arg_a, arg_b, expect):
- c = mod(a, b)
- print("mod({}, {}) = {} -- ".format(a, b, c), end="")
- print("OK" if c == good else "FAIL (expected {})".format(good))
- if __name__ == "__main__":
- test()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement