Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Marcus Apolinário #22

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 69 additions & 12 deletions src/automata.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
"""Implementação de autômatos finitos."""


class InvalidTransitionError(Exception):
"""Exceção lançada para indicar uma transição inválida no autômato."""


def load_automata(filename):
"""
Lê os dados de um autômato finito a partir de um arquivo.

A estsrutura do arquivo deve ser:
A estrutura do arquivo deve ser:

<lista de símbolos do alfabeto, separados por espaço (' ')>
<lista de nomes de estados>
Expand All @@ -15,7 +19,6 @@ def load_automata(filename):

Um exemplo de arquivo válido é:

```
a b
q0 q1 q2 q3
q0 q3
Expand All @@ -28,23 +31,77 @@ def load_automata(filename):
q2 b q0
q3 a q1
q3 b q2
```

Caso o arquivo seja inválido uma exceção Exception é gerada.

Caso o arquivo seja inválido uma exceção InvalidTransitionError é gerada.
"""
with open(filename, 'rt', encoding="utf-8") as file:
lines = file.read().splitlines()

alphabet = lines[0].split()
states = lines[1].split()
final_states = lines[2].split()
initial_state = lines[3]
transitions = [line.split() for line in lines[4:]]

delta = {}
for state in states:
delta[state] = {}
for symbol in alphabet:
delta[state][symbol] = None

for origin, symbol, destination in transitions:
if origin in states and symbol in alphabet and destination in states:
delta[origin][symbol] = destination
else:
raise InvalidTransitionError(f"Transição inválida: {origin} {symbol} {destination}")

# Verificar se todos os estados finais estão no conjunto de estados
for state in final_states:
if state not in states:
raise InvalidTransitionError(f"Estado final não encontrado no conjunto: {state}")

with open(filename, "rt") as arquivo:
# processa arquivo...
pass
# Verificar se o estado inicial está no conjunto de estados
if initial_state not in states:
raise InvalidTransitionError(f"Estado inicial não encontrado no conjunto: {initial_state}")

automata = (states, alphabet, delta, initial_state, final_states)
return automata


def process(automata, words):
"""
Processa a lista de palavras e retora o resultado.

Os resultados válidos são ACEITA, REJEITA, INVALIDA.
Processa uma lista de palavras através do autômato e retorna os resultados.

Args:
automata: A estrutura do autômato.
words: Lista de palavras a serem processadas.

Returns:
Um dicionário com palavras como chaves e
seus respectivos resultados ('ACEITA', 'REJEITA', 'INVALIDA').
"""
_, alphabet, delta, initial_state, final_states = automata
results = {}

for word in words:
# tenta reconhecer `word`
current_state = initial_state
valid = True

for symbol in word:
if symbol not in alphabet:
results[word] = 'INVALIDA'
valid = False
break
current_state = delta[current_state].get(symbol)
if current_state is None:
results[word] = 'REJEITA'
valid = False
break

if valid:
if current_state in final_states:
results[word] = 'ACEITA'
else:
results[word] = 'REJEITA'

return results
Loading