mirror of
https://git.cs.ou.nl/joshua.moerman/mealy-decompose.git
synced 2025-04-29 17:57:44 +02:00
56 lines
1.7 KiB
Python
56 lines
1.7 KiB
Python
import argparse
|
|
|
|
|
|
class RKMachine:
|
|
# Rick Koenders came up with this example in the case of N=3.
|
|
# FSM will have 2*N states, but can be decomposed into N + 2 states.
|
|
# For N <= 2, the machine is NOT minimal, i.e., there are equivalent states.
|
|
def __init__(self, N):
|
|
self.initial_state = (0, False)
|
|
self.inputs = ['a', 'b']
|
|
self.outputs = [n for n in range(N)]
|
|
self.states = [(n, b) for b in [False, True] for n in range(N)]
|
|
|
|
self.transition_map = {((n, 0), 'a'): ((n + 1) % N, 0) for n in range(N)}
|
|
self.transition_map |= {(((n + 1) % N, 1), 'a'): (n % N, 1) for n in range(N)}
|
|
self.transition_map |= {((n, b), 'b'): (n, not b) for b in [False, True] for n in range(N)}
|
|
|
|
self.output_map = {((n, b), 'a'): n for b in [False, True] for n in range(N)}
|
|
self.output_map |= {((n, b), 'b'): 0 for b in [False, True] for n in range(N)}
|
|
|
|
def state_to_string(self, s):
|
|
(n, b) = s
|
|
return f's{n}Dn' if b else f's{n}Up'
|
|
|
|
def transition(self, s, a):
|
|
return self.transition_map[(s, a)]
|
|
|
|
def output(self, s, a):
|
|
return self.output_map[(s, a)]
|
|
|
|
|
|
def fsm_to_dot(name, m):
|
|
def transition_string(s, i, o, t):
|
|
return f'{s} -> {t} [label="{i}/{o}"]'
|
|
|
|
ret = f'digraph {name} {{\n'
|
|
for s in m.states:
|
|
for a in m.inputs:
|
|
t = m.transition(s, a)
|
|
o = m.output(s, a)
|
|
ret += ' '
|
|
ret += transition_string(m.state_to_string(s), a, o, m.state_to_string(t))
|
|
ret += '\n'
|
|
|
|
ret += '}\n'
|
|
|
|
return ret
|
|
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('machine', nargs='?', default='rk', choices=['rk'])
|
|
parser.add_argument('-n', type=int, default=3, help='size parameter')
|
|
args = parser.parse_args()
|
|
|
|
if args.machine == 'rk':
|
|
print(fsm_to_dot(f'RKMachine_{args.n}', RKMachine(args.n)))
|