amachine.am_generator
1import random 2import numpy as np 3import matplotlib.pyplot as plt 4from pathlib import Path 5from copy import deepcopy 6 7from .am_create import star, star_join, isomorphic_to 8import random 9 10class Generator : 11 12 def __init__(self, random_seed=None ) -> None : 13 14 if random_seed : 15 16 np.random.seed( random_seed ) 17 random.seed( random_seed ) 18 19 self.vocabulary = { 20 21 # 1. Printable ASCII: space (32) through tilde (126) → 95 chars 22 "ASCII" : [chr(i) for i in range(32, 127)], 23 24 # 2. Greek capitals Α–Τ (19), skipping U+03A2 (undefined slot) 25 "greek_upper" : [chr(i) for i in range(0x0391, 0x03A5) if i != 0x03A2][:19], 26 27 # 3. Greek smalls α–τ (19), skipping U+03C2 (ς, final-sigma variant) 28 "greek_lower" : [chr(i) for i in range(0x03B1, 0x03C5) if i != 0x03C2][:19], 29 30 # 4. Geometric Shapes block: U+25A0–U+25FF → 96 chars 31 "geometric" : [chr(i) for i in range(0x25A0, 0x2600)] 32 } 33 34 self.exit_symbol = self.vocabulary[ "geometric" ][ 0 ] 35 36 def generate( 37 self, n_states : int, 38 n_symbols, 39 n_modes : int, 40 mode_alphas : list[float], 41 residency_factor : float, 42 levels : int ) : 43 44 # 0-9 ASCII + lowercase letters + uppercase letters 45 normal_symbols = [ chr(i) for i in range( 48, 58 ) ] 46 normal_symbols += [ chr(i) for i in range( 97, 123 ) ] 47 normal_symbols += [ chr(i) for i in range( 65, 91 ) ] 48 enter_symbols = self.vocabulary[ "greek_lower" ] + self.vocabulary[ "greek_upper" ] 49 50 n_gen = n_modes*2 51 52 # n_gen^levels leaves 53 machines = [ 54 star( 55 exit_symbol=self.exit_symbol, 56 enter_symbols=enter_symbols[ 0:n_modes*2 ], 57 normal_symbols=normal_symbols, 58 n_modes=n_modes, 59 n_isomorphic=2, 60 randomness=0.3, 61 connectedness=0.5, 62 residency_factor=residency_factor, 63 n_normal_symbols=n_symbols, 64 t_states_per_machine=n_states 65 ) 66 for i in range( n_gen**levels ) 67 ] 68 69 es_per_lev = n_gen 70 es_offset = n_modes*2 71 72 # Reduce bottom-up, levels-1 times 73 for i in range( levels - 1 ) : 74 next_level = [] 75 x = 0 76 77 es = enter_symbols[ es_offset + es_per_lev*i : es_offset+es_per_lev*(i+1) ] 78 79 for k in range( len(machines) // n_gen ) : # shrinks each pass 80 m = star_join( 81 exit_symbol=self.exit_symbol, 82 enter_symbols=es, 83 machines=machines[ x:x+n_gen ], 84 mode_residency_factor=0.5 85 ) 86 next_level.append( m ) 87 x += n_gen 88 machines = deepcopy( next_level ) 89 90 # machines now has exactly n_gen elements — join into root 91 return star_join( 92 exit_symbol=self.exit_symbol, 93 enter_symbols=normal_symbols, 94 machines=machines, 95 mode_residency_factor=0.5 96 ) 97 98if __name__ == "__main__": 99 100 n_modes = 1 101 alpha = 0.3 102 residency_factor = 0.5 103 n_symbols = 4 104 n_states = 27 105 random_seed=42 106 107 generator = Generator( random_seed=random_seed ) 108 109 path = Path("../data/aM_7-mode-iso" ) 110 path.mkdir(parents=True, exist_ok=True) 111 112 aM = generator.generate( 113 n_states=n_states, 114 n_symbols=n_symbols, 115 n_modes=n_modes, 116 mode_alphas=[ alpha ]*n_modes, 117 residency_factor=residency_factor, 118 levels=3 ) 119 120 aM.minimize(retain_names=True) 121 print( aM.is_epsilon_HMM() ) 122 123 aM.draw_graph() 124 125 print( f"h_mu : {aM.h_mu()}" ) 126 print( f"C_mu : {aM.C_mu()}" )
class
Generator:
11class Generator : 12 13 def __init__(self, random_seed=None ) -> None : 14 15 if random_seed : 16 17 np.random.seed( random_seed ) 18 random.seed( random_seed ) 19 20 self.vocabulary = { 21 22 # 1. Printable ASCII: space (32) through tilde (126) → 95 chars 23 "ASCII" : [chr(i) for i in range(32, 127)], 24 25 # 2. Greek capitals Α–Τ (19), skipping U+03A2 (undefined slot) 26 "greek_upper" : [chr(i) for i in range(0x0391, 0x03A5) if i != 0x03A2][:19], 27 28 # 3. Greek smalls α–τ (19), skipping U+03C2 (ς, final-sigma variant) 29 "greek_lower" : [chr(i) for i in range(0x03B1, 0x03C5) if i != 0x03C2][:19], 30 31 # 4. Geometric Shapes block: U+25A0–U+25FF → 96 chars 32 "geometric" : [chr(i) for i in range(0x25A0, 0x2600)] 33 } 34 35 self.exit_symbol = self.vocabulary[ "geometric" ][ 0 ] 36 37 def generate( 38 self, n_states : int, 39 n_symbols, 40 n_modes : int, 41 mode_alphas : list[float], 42 residency_factor : float, 43 levels : int ) : 44 45 # 0-9 ASCII + lowercase letters + uppercase letters 46 normal_symbols = [ chr(i) for i in range( 48, 58 ) ] 47 normal_symbols += [ chr(i) for i in range( 97, 123 ) ] 48 normal_symbols += [ chr(i) for i in range( 65, 91 ) ] 49 enter_symbols = self.vocabulary[ "greek_lower" ] + self.vocabulary[ "greek_upper" ] 50 51 n_gen = n_modes*2 52 53 # n_gen^levels leaves 54 machines = [ 55 star( 56 exit_symbol=self.exit_symbol, 57 enter_symbols=enter_symbols[ 0:n_modes*2 ], 58 normal_symbols=normal_symbols, 59 n_modes=n_modes, 60 n_isomorphic=2, 61 randomness=0.3, 62 connectedness=0.5, 63 residency_factor=residency_factor, 64 n_normal_symbols=n_symbols, 65 t_states_per_machine=n_states 66 ) 67 for i in range( n_gen**levels ) 68 ] 69 70 es_per_lev = n_gen 71 es_offset = n_modes*2 72 73 # Reduce bottom-up, levels-1 times 74 for i in range( levels - 1 ) : 75 next_level = [] 76 x = 0 77 78 es = enter_symbols[ es_offset + es_per_lev*i : es_offset+es_per_lev*(i+1) ] 79 80 for k in range( len(machines) // n_gen ) : # shrinks each pass 81 m = star_join( 82 exit_symbol=self.exit_symbol, 83 enter_symbols=es, 84 machines=machines[ x:x+n_gen ], 85 mode_residency_factor=0.5 86 ) 87 next_level.append( m ) 88 x += n_gen 89 machines = deepcopy( next_level ) 90 91 # machines now has exactly n_gen elements — join into root 92 return star_join( 93 exit_symbol=self.exit_symbol, 94 enter_symbols=normal_symbols, 95 machines=machines, 96 mode_residency_factor=0.5 97 )
Generator(random_seed=None)
13 def __init__(self, random_seed=None ) -> None : 14 15 if random_seed : 16 17 np.random.seed( random_seed ) 18 random.seed( random_seed ) 19 20 self.vocabulary = { 21 22 # 1. Printable ASCII: space (32) through tilde (126) → 95 chars 23 "ASCII" : [chr(i) for i in range(32, 127)], 24 25 # 2. Greek capitals Α–Τ (19), skipping U+03A2 (undefined slot) 26 "greek_upper" : [chr(i) for i in range(0x0391, 0x03A5) if i != 0x03A2][:19], 27 28 # 3. Greek smalls α–τ (19), skipping U+03C2 (ς, final-sigma variant) 29 "greek_lower" : [chr(i) for i in range(0x03B1, 0x03C5) if i != 0x03C2][:19], 30 31 # 4. Geometric Shapes block: U+25A0–U+25FF → 96 chars 32 "geometric" : [chr(i) for i in range(0x25A0, 0x2600)] 33 } 34 35 self.exit_symbol = self.vocabulary[ "geometric" ][ 0 ]
def
generate( self, n_states: int, n_symbols, n_modes: int, mode_alphas: list[float], residency_factor: float, levels: int):
37 def generate( 38 self, n_states : int, 39 n_symbols, 40 n_modes : int, 41 mode_alphas : list[float], 42 residency_factor : float, 43 levels : int ) : 44 45 # 0-9 ASCII + lowercase letters + uppercase letters 46 normal_symbols = [ chr(i) for i in range( 48, 58 ) ] 47 normal_symbols += [ chr(i) for i in range( 97, 123 ) ] 48 normal_symbols += [ chr(i) for i in range( 65, 91 ) ] 49 enter_symbols = self.vocabulary[ "greek_lower" ] + self.vocabulary[ "greek_upper" ] 50 51 n_gen = n_modes*2 52 53 # n_gen^levels leaves 54 machines = [ 55 star( 56 exit_symbol=self.exit_symbol, 57 enter_symbols=enter_symbols[ 0:n_modes*2 ], 58 normal_symbols=normal_symbols, 59 n_modes=n_modes, 60 n_isomorphic=2, 61 randomness=0.3, 62 connectedness=0.5, 63 residency_factor=residency_factor, 64 n_normal_symbols=n_symbols, 65 t_states_per_machine=n_states 66 ) 67 for i in range( n_gen**levels ) 68 ] 69 70 es_per_lev = n_gen 71 es_offset = n_modes*2 72 73 # Reduce bottom-up, levels-1 times 74 for i in range( levels - 1 ) : 75 next_level = [] 76 x = 0 77 78 es = enter_symbols[ es_offset + es_per_lev*i : es_offset+es_per_lev*(i+1) ] 79 80 for k in range( len(machines) // n_gen ) : # shrinks each pass 81 m = star_join( 82 exit_symbol=self.exit_symbol, 83 enter_symbols=es, 84 machines=machines[ x:x+n_gen ], 85 mode_residency_factor=0.5 86 ) 87 next_level.append( m ) 88 x += n_gen 89 machines = deepcopy( next_level ) 90 91 # machines now has exactly n_gen elements — join into root 92 return star_join( 93 exit_symbol=self.exit_symbol, 94 enter_symbols=normal_symbols, 95 machines=machines, 96 mode_residency_factor=0.5 97 )