3
3
from itertools import product
4
4
from typing import Callable , Dict , Tuple , List
5
5
from tabulate import tabulate
6
+ from typing import Optional
6
7
7
8
State = str
8
9
Letter = str
11
12
12
13
EqvTable = pd .DataFrame
13
14
Semigroup = pd .DataFrame
14
- Action = Callable [[State , SemigroupElement ], State ]
15
+ Action = Callable [[State , SemigroupElement ], Optional [ State ] ]
15
16
TransformationSemigroup = (List [State ], Semigroup , Action )
16
17
17
18
@@ -170,6 +171,8 @@ def compatability(states: List[State], sg: Semigroup, a: Action, filter_sames =
170
171
171
172
#(q*g1)*g2
172
173
res11 = a (s , g1 )
174
+ if res11 is None :
175
+ raise NotImplementedError
173
176
res22 = a (res11 , g2 )
174
177
if res != res22 :
175
178
print (f"q*(g1*g2) { res } != (q*g1)*g2 { res22 } " )
@@ -197,7 +200,6 @@ def faithfullness(states: List[State], sg: Semigroup, a: Action, filter_sames =
197
200
198
201
199
202
def execute_semigroup (states : List [State ], sg : Semigroup , a : Action , filter_sames = True ):
200
- # TODO Think about this some more
201
203
action_results = []
202
204
for s in states :
203
205
for g1 in sg .index :
@@ -223,3 +225,90 @@ def semigroup_to_machine(tsg: TransformationSemigroup):
223
225
224
226
return transformations
225
227
228
+ from itertools import product
229
+
230
+ def generate_combinations (keys , values ):
231
+ # Generate all possible combinations of values for each key
232
+ all_combinations = list (product (values , repeat = len (keys )))
233
+
234
+ # Create a dictionary for each combination
235
+ result = [dict (zip (keys , comb )) for comb in all_combinations ]
236
+ return result
237
+
238
+
239
+
240
+ def check_homom_multiple_state (tsm1 , tsm2 , alpha , beta ) -> bool :
241
+ """h
242
+ Checks if alpha(qDelta_a) \subset (alha(q))Delta'_a\b eta(a)
243
+ for all a for a mapping that throws each state q_i to a fixed q'
244
+ Returns true if it is a homo
245
+ """
246
+
247
+ def dict_or_func (f , v ):
248
+ if isinstance (f , dict ):
249
+ return f [v ]
250
+ else :
251
+ return f (v )
252
+ states = sorted (list (get_states (tsm1 )))
253
+ alphabet = sorted (get_alphabet (tsm1 ))
254
+ for state in states :
255
+ for letter in alphabet :
256
+ # Caclulate alpha(qD_a)
257
+ try :
258
+ nextStateLeft = tsm1 [(state , letter )]
259
+ res = dict_or_func (alpha , nextStateLeft )
260
+ #print("left", state, nextStateLeft, letter, res)
261
+ except KeyError :
262
+ res = ""
263
+ try :
264
+ t = (dict_or_func (alpha , state ), dict_or_func (beta , letter ))
265
+ res2 = tsm2 [t ]
266
+ #print("right", t, res2)
267
+ except KeyError :
268
+ res2 = ""
269
+ #print("S", {res}, {res2})
270
+ #print({res} in {res2})
271
+ if ([res ] <= [res2 ]) == False :
272
+ return False
273
+
274
+ return True
275
+
276
+ def try_full_homoms_beta_alpha (tsm1 : StateMachine , tsm2 : StateMachine ):
277
+ """
278
+ Defines homo that throws all states to a single state and keep beta as the identity
279
+ Returns true if it is a homo
280
+ """
281
+ # TODO Those are quite specific requieremnets to the states aka each the states must be named the same except the '
282
+ homoms = []
283
+ # TODO USE dicts instead of functions:
284
+ s1 = sorted (get_states (tsm1 ))
285
+ s2 = sorted (get_states (tsm2 ))
286
+ l1 = sorted (get_alphabet (tsm1 ))
287
+ l2 = sorted (get_alphabet (tsm2 ))
288
+ betas = generate_combinations (l1 ,l2 )
289
+ alphas = generate_combinations (s1 ,s2 )
290
+ for a in alphas :
291
+ for b in betas :
292
+ res = check_homom_multiple_state (tsm1 , tsm2 , a , b )
293
+ homoms .append ((str (a ), str (b ), res ))
294
+
295
+
296
+
297
+ homoms_df = pd .DataFrame (homoms )
298
+ homoms_df .columns = ["alpha" , "beta" , "is_homom" ]
299
+ homoms_df .sort_values (by = ["alpha" , "beta" , "is_homom" ], inplace = True , ignore_index = True )
300
+ return (homoms_df )
301
+
302
+
303
+ #return homoms_df
304
+
305
+
306
+
307
+
308
+ def generate_homom (tsm1 : StateMachine , tsm2 : StateMachine ):
309
+ states1 = get_states (tsm1 )
310
+ states2 = get_states (tsm2 )
311
+ alphabet1 = get_alphabet (tsm1 )
312
+ alphabet2 = get_alphabet (tsm2 )
313
+
314
+
0 commit comments