Skip to content

Commit

Permalink
Added semigroup to machine transformation
Browse files Browse the repository at this point in the history
  • Loading branch information
Unaimend committed Nov 28, 2024
1 parent b20c3e8 commit aa5a44e
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 7 deletions.
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,33 @@ You can plot, layout and export the automata with the `--dot` flag.
python3 main.py --aut examples/lecture_1.csv -N 5 --dot test.png
```

## Running the program on a given semigroup
Currently you can only specify an semigroup in code.

```python
states = ["a", "b"]
semigroup = pd.DataFrame(
{"0":["0", "1"],
"1": ["1", "0"]}
)
semigroup.set_index(["0", "1"])

def action(s: State, sge: SemigroupElement) -> Optional[State]:
if str(sge) == "0":
return s
elif str(sge) == "1":
if s == "a":
return "b"
if s == "b":
return "a"
else:
print(f"SemigroupElement {sge} with State {s}")
raise Exception("Operation not defined")

res = semigroup_to_machine((states, semigroup, action))
plot(res, "test")
```


## Automate format
To sepcify an automate via csv use the following format
Expand Down
59 changes: 52 additions & 7 deletions src/automate.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import pandas as pd
from graphviz import Digraph
from itertools import product
from typing import Dict, Tuple, List
from typing import Callable, Dict, Tuple, List
from tabulate import tabulate

State = str
Letter = str
SemigroupElement = str
StateMachine = Dict[Tuple[State, Letter], State]

EqvTable = pd.DataFrame
Semigroup = pd.DataFrame
Action = Callable[[State, SemigroupElement], State]
TransformationSemigroup = (List[State], Semigroup, Action)


def get_states(transitions):
Expand Down Expand Up @@ -154,9 +157,51 @@ def format_semitable(s: Semigroup):
s.columns = [f"[{col}]" for col in s.columns]
return tabulate(s, headers="keys", tablefmt="grid")

#res2 = create_table(l1, ['a','b','c'], N = 5)
#u, class_, _ = add_representatives(l1, res2)
#
##print(u)
##
#r = eqv_class_to_semigroup(l1,['a','b','c'], u)


def compatability(states: List[State], sg: Semigroup, a: Action, filter_sames = True):
pass

def faithfullness(states: List[State], sg: Semigroup, a: Action, filter_sames = True):
# TODO Think about this some more
action_results = []
for s in states:
for g1 in sg.index:
for g2 in sg.index:
if g1 != g2:
#q*g1
res1 = a(s, g1)
#q*g2
res2 = a(s, g2)
action_results.append([s, g1, res1 == res2, s, g2])

action_results = pd.DataFrame(action_results)
action_results.columns = ['q', 'g1', 'is_same', 'q', 'q2']
return action_results[action_results['is_same'] == True]




def execute_semigroup(states: List[State], sg: Semigroup, a: Action, filter_sames = True):
# TODO Think about this some more
action_results = []
for s in states:
for g1 in sg.index:
res = a(s, g1)
action_results.append([s, g1, res])

action_results = pd.DataFrame(action_results)
action_results.columns = ['q', 'g1', 'action_result']
return action_results



def semigroup_to_machine(tsg: TransformationSemigroup):
action_table = execute_semigroup(tsg[0], tsg[1], tsg[2])
transformations = {}

for _, q1, l, q2 in action_table.itertuples():
transformations[(q1, str(l))] = q2

return transformations

32 changes: 32 additions & 0 deletions tests/test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import unittest
from src.automate import *
from typing import Optional

import unittest

Expand Down Expand Up @@ -62,3 +63,34 @@ def test_two_state_machine_representative(self):
r = create_table(TestAutomatonToState.one_state_two_trans, ['a', "b"], N = 3)
_, t, _ = add_representatives(TestAutomatonToState.one_state_two_trans, r)
self.assertEqual(list(t["eqv_class"]), ["a", "a", "b", "b", "ba", "ba"])



class TestSemigroupToAutomaton(unittest.TestCase):
def semigroup_to_machine(self):
states = ["a", "b"]
semigroup = pd.DataFrame(
{"0":["0", "1"],
"1": ["1", "0"]}
)
semigroup.set_index(["0", "1"])

def action(s: State, sge: SemigroupElement) -> Optional[State]:
if str(sge) == "0":
return s
elif str(sge) == "1":
if s == "a":
return "b"
if s == "b":
return "a"
else:
print(f"SemigroupElement {sge} with State {s}")
raise Exception("Operation not defined")

res = semigroup_to_machine((states, semigroup, action))
print(res)
plot(res, "test")




0 comments on commit aa5a44e

Please sign in to comment.