Skip to content

Commit 8cee5d0

Browse files
committed
Added homomorphism calculation
1 parent af5eb9f commit 8cee5d0

File tree

2 files changed

+338
-23
lines changed

2 files changed

+338
-23
lines changed

src/automate.py

+91-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from itertools import product
44
from typing import Callable, Dict, Tuple, List
55
from tabulate import tabulate
6+
from typing import Optional
67

78
State = str
89
Letter = str
@@ -11,7 +12,7 @@
1112

1213
EqvTable = pd.DataFrame
1314
Semigroup = pd.DataFrame
14-
Action = Callable[[State, SemigroupElement], State]
15+
Action = Callable[[State, SemigroupElement], Optional[State]]
1516
TransformationSemigroup = (List[State], Semigroup, Action)
1617

1718

@@ -170,6 +171,8 @@ def compatability(states: List[State], sg: Semigroup, a: Action, filter_sames =
170171

171172
#(q*g1)*g2
172173
res11 = a(s, g1)
174+
if res11 is None:
175+
raise NotImplementedError
173176
res22 = a(res11, g2)
174177
if res != res22:
175178
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 =
197200

198201

199202
def execute_semigroup(states: List[State], sg: Semigroup, a: Action, filter_sames = True):
200-
# TODO Think about this some more
201203
action_results = []
202204
for s in states:
203205
for g1 in sg.index:
@@ -223,3 +225,90 @@ def semigroup_to_machine(tsg: TransformationSemigroup):
223225

224226
return transformations
225227

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\beta(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

Comments
 (0)