Skip to content

Commit a67c489

Browse files
committed
Automata v.1.6.0
DFA, NFA, PDA, TM all corrected implemented as a Python library, with two examples of each, and a PROJECT that uses Automatons to simulate a Safebox, including an algorithm to design DFA's based on a Safebox password, all of them use cases :3
1 parent ef6bd0d commit a67c489

19 files changed

+519
-489
lines changed

Automata/__init__.py

Whitespace-only changes.

dfa.py renamed to Automata/dfa.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'''
2-
DETERMINISTIC FINITE ACCEPTORS AUTOMATONS
2+
DETERMINISTIC FINITE AUTOMATONS
33
'''
44

55
class DFA:
@@ -110,12 +110,12 @@ def show(self):
110110
'''Prints Automata data'''
111111
print()
112112
print("═"*40)
113-
print("\nAUTÓMATA FINITO DETERMINISTA\n")
113+
print("\nDETERMINISTIC FINITE AUTOMATON\n")
114114
print("═"*40)
115-
print(f"\nEstados: {set(self.States)}")
116-
print(f"Alfabeto: {set(self.Alphabet)}")
117-
print(f"Estado inicial: \"{self.Initial}\"")
118-
print(f"Estados finales: {set(self.Finals)}")
115+
print(f"\nStates: {set(self.States)}")
116+
print(f"Alphabet: {set(self.Alphabet)}")
117+
print(f"Initial state: \"{self.Initial}\"")
118+
print(f"Final states: {set(self.Finals)}")
119119
for t in self.Transitions:
120120
t1 = t[1] if t[1] != "" else "λ"
121121
print(f"* δ(\"{t[0]}\", \"{t1}\") = (\"{t[2]}\")")
@@ -140,13 +140,13 @@ def transite(self, symbol: str, printStep: bool = False):
140140

141141
# If Automata has 0 or more than 1 transitions;
142142
if len(validTransitions) != 1:
143-
print(f" * Transición δ(\"{self.actual}\", \"{symbol}\") inválida!")
143+
print(f" * Transition δ(\"{self.actual}\", \"{symbol}\") is invalid!")
144144
self.error = True
145145
return
146146
# Else; it generates a transition:
147147
else:
148148
if printStep:
149-
print(f" * \"{self.actual}\" lee \"{symbol}\" => \"{validTransitions[0][2]}\";")
149+
print(f" * \"{self.actual}\" reads \"{symbol}\" => \"{validTransitions[0][2]}\";")
150150
self.actual = validTransitions[0][2]
151151

152152
def accepts(self, string: str, stepByStep: bool = False):
@@ -162,7 +162,7 @@ def accepts(self, string: str, stepByStep: bool = False):
162162

163163
# It shows the step by step path for the string:
164164
if stepByStep:
165-
print(f"\nPara la cadena \"{string}\":\n")
165+
print(f"\nFor string \"{string}\":\n")
166166

167167
# Reads letter per letter:
168168
for character in string:

nfa.py renamed to Automata/nfa.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'''
2-
NO-DETERMINISTIC FINITE ACCEPTORS AUTOMATONS
2+
NON-DETERMINISTIC FINITE AUTOMATON
33
'''
44

55
class NFA:
@@ -114,12 +114,12 @@ def show(self):
114114
'''Prints Automata data'''
115115
print()
116116
print("═"*40)
117-
print("\nAUTÓMATA FINITO NO DETERMINISTA\n")
117+
print("\nNON-DETERMINISTIC FINITE AUTOMATON\n")
118118
print("═"*40)
119-
print(f"\nEstados: {set(self.States)}")
120-
print(f"Alfabeto: {set(self.Alphabet)}")
121-
print(f"Estado inicial: \"{self.Initial}\"")
122-
print(f"Estados finales: {set(self.Finals)}")
119+
print(f"\nStates: {set(self.States)}")
120+
print(f"Alphabet: {set(self.Alphabet)}")
121+
print(f"Initial state: \"{self.Initial}\"")
122+
print(f"Final states: {set(self.Finals)}")
123123
for t in self.Transitions:
124124
t1 = t[1] if t[1] != "" else "λ"
125125
print(f"* δ(\"{t[0]}\", \"{t1}\") = (\"{t[2]}\")")
@@ -145,12 +145,12 @@ def transite(self, symbol: str, printStep: bool = False):
145145

146146
# Prints the path:
147147
if printStep:
148-
print(" * Estados actuales:", self.currents)
149-
print(" * Símbolo a leer:", symbol)
148+
print(" * Current states:", self.currents)
149+
print(" * Reading symbol:", symbol)
150150
destinies = []
151151
for destiny in validTransitions:
152152
destinies.append(destiny[2])
153-
print(" * Destinos:", destinies)
153+
print(" * Destinations:", destinies)
154154
print()
155155

156156
# If Automata has 0 transitions, it will go to the "limbo"; means error;
@@ -203,7 +203,7 @@ def accepts(self, string: str, stepByStep: bool = False):
203203

204204
# It shows the step by step path for the string:
205205
if stepByStep:
206-
print(f"\nPara la cadena \"{string}\":\n")
206+
print(f"\nFor string \"{string}\":\n")
207207

208208
# If the string is empty:
209209
if len(string) == 0:

pda.py renamed to Automata/pda.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'''
2-
PUSHDOWN FINITE ACCEPTORS AUTOMATONS
2+
PUSHDOWN FINITE AUTOMATON
33
'''
44

55
class PDA:
@@ -140,16 +140,16 @@ def show(self):
140140
'''Prints Automata data'''
141141
print()
142142
print("═"*40)
143-
print("\nAUTÓMATA DE PILA\n")
143+
print("\nPUSHDOWN FINITE AUTOMATON\n")
144144
print("═"*40)
145-
print(f"\nEstados: {set(self.States)}")
146-
print(f"Alfabeto: {set(self.Alphabet)}")
147-
print(f"Estado inicial: \"{self.Initial}\"")
148-
print(f"Estados finales: {set(self.Finals)}")
149-
print(f"Alfabeto de la pila: {set(self.StackAlphabet)}")
145+
print(f"\nStates: {set(self.States)}")
146+
print(f"Alphabet: {set(self.Alphabet)}")
147+
print(f"Initial state: \"{self.Initial}\"")
148+
print(f"Final states: {set(self.Finals)}")
149+
print(f"Stack alphabet: {set(self.StackAlphabet)}")
150150
userShowStack = self.InitialStack[:]
151151
userShowStack.reverse()
152-
print(f"Pila inicial: {userShowStack}")
152+
print(f"Initial stack: {userShowStack}")
153153
for t in self.Transitions:
154154
t1 = t[1] if t[1] != "" else "λ"
155155
t2 = t[2] if t[2] != "" else "λ"
@@ -160,7 +160,7 @@ def show(self):
160160

161161
def transite(self, symbol: str, printStep: bool = False):
162162
'''
163-
Recieves an catual reading symbol;
163+
Recieves a reading symbol;
164164
Based on the currents states and the transitions,
165165
It changes the currents states to move;
166166
'''
@@ -186,7 +186,7 @@ def transite(self, symbol: str, printStep: bool = False):
186186
else:
187187
topSymbol = self.stack[len(self.stack)-1]
188188
if (current == transition[0]) and (symbol == transition[1] or transition[1] == "") and (topSymbol == transition[2]) and (not self.error):
189-
print(" * Transición a tomar:", transition)
189+
print(" * Transition to take:", transition)
190190
validTransitions.append(transition)
191191

192192
# If Automata has 0 transitions, it will go to the "limbo"; means error;
@@ -215,21 +215,21 @@ def transite(self, symbol: str, printStep: bool = False):
215215
for transition in validTransitions:
216216
# Prints the path:
217217
if printStep:
218-
print(" * Estados actuales:", self.currents)
219-
print(" * Símbolo a leer:", symbol)
218+
print(" * Current states:", self.currents)
219+
print(" * Reading symbol:", symbol)
220220
userShowStack = self.stack[:]
221221
userShowStack.reverse()
222-
print(" * Pila:", userShowStack)
222+
print(" * Stack:", userShowStack)
223223
if len(self.stack) == 0:
224224
topSymbol = ""
225225
else:
226226
topSymbol = self.stack[len(self.stack)-1]
227-
print(" * Símbolo top en la pila:", topSymbol)
228-
print(" * Símbolo en apilar:", transition[3])
227+
print(" * Top symbol on stack:", topSymbol)
228+
print(" * Symbol to stack", transition[3])
229229
destinies = []
230230
for destiny in validTransitions:
231231
destinies.append(destiny[4])
232-
print(" * Destinos:", destinies)
232+
print(" * Destinations: ", destinies)
233233

234234
print()
235235

@@ -274,7 +274,7 @@ def accepts(self, string: str, stepByStep: bool = False):
274274

275275
# It shows the step by step path for the string:
276276
if stepByStep:
277-
print(f"\nPara la cadena \"{string}\":\n")
277+
print(f"\nTo string \"{string}\":\n")
278278

279279
# If the string is empty:
280280
if len(string) == 0:

tm.py renamed to Automata/tm.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,19 +105,19 @@ def setFinals(self, finals: set):
105105
def show(self):
106106
'''Prints Turing Machine data'''
107107
print()
108-
print("═"*50)
108+
print("═"*40)
109109
print("\nTURING MACHINE\n")
110-
print("═"*50)
110+
print("═"*40)
111111
print(f"\nStates: {set(self.States)}")
112112
print(f"Alphabet: {set(self.Alphabet)}")
113113
print(f"Initial state: \"{self.Initial}\"")
114114
print(f"Final states: {set(self.Finals)}")
115115
for t in self.Transitions:
116-
t1 = t[1] if t[1] != "" else "λ"
117-
t2 = t[2] if t[2] != "" else "λ"
116+
t1 = t[1] if t[1] != "*" else ""
117+
t2 = t[2] if t[2] != "*" else ""
118118
print(f"* δ(\"{t[0]}\", \"{t1}\") = (\"{t[3]}\", \"{t2}\", \"{t[4]}\")")
119119
print()
120-
print("═"*50)
120+
print("═"*40)
121121

122122
def transite(self, symbol: str, printStep: bool = False):
123123
'''
@@ -141,17 +141,17 @@ def transite(self, symbol: str, printStep: bool = False):
141141
# Perform the transition:
142142
else:
143143
if printStep:
144-
print(f" * \"{self.actual}\" reads \"{symbol}\", writes \"{validTransitions[0][2]}\", moves {validTransitions[0][3]}, goes to \"{validTransitions[0][4]}\";")
144+
print(f" * \"{self.actual}\" reads \"{symbol}\", writes \"{validTransitions[0][2]}\", moves {str(validTransitions[0][3]).upper()}, goes to \"{validTransitions[0][4]}\";")
145145

146146
self.actual = validTransitions[0][4]
147147
self.tape[self.head] = validTransitions[0][2]
148148

149149
# Move the head and extend the tape if necessary:
150-
if validTransitions[0][3] == "R":
150+
if str(validTransitions[0][3]).upper() == "R":
151151
self.head += 1
152152
if self.head == len(self.tape):
153153
self.tape.append("*")
154-
elif validTransitions[0][3] == "L":
154+
elif str(validTransitions[0][3]).upper() == "L":
155155
self.head -= 1
156156
if self.head < 0:
157157
self.tape.insert(0, "*")

dfa-example-1.py renamed to Examples/dfa-example-1.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from dfa import DFA
1+
from Automata.dfa import DFA
22

33
if __name__ == "__main__":
44

@@ -15,15 +15,16 @@
1515
Automata.addTransition(("q0", "b", "q0"))
1616
Automata.addTransition(("q1", "a", "q1"))
1717
Automata.addTransition(("q1", "b", "q1"))
18+
1819
Automata.show()
1920

2021
#/ Executes the Automata:
2122
while True:
2223
print()
23-
word = input("Cadena: ")
24+
word = input("String: ")
2425
if Automata.accepts(word, stepByStep=True):
25-
print(f"La cadena \"{word}\" SÍ es aceptada!")
26+
print(f"The string \"{word}\" IS accepted!")
2627
else:
27-
print(f"La cadena \"{word}\" NO es aceptada!")
28+
print(f"The string \"{word}\" IS NOT accepted!")
2829
print()
2930
print("═"*40)

Examples/dfa-example-2.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from Automata.dfa import DFA
2+
3+
if __name__ == "__main__":
4+
5+
# Second example of DFA Automata instance:
6+
# Language of the Automata:
7+
# L(Automata) = All strings with at least one "a",
8+
# and exactly two b's:
9+
#* States:
10+
Q = {"q0", "qa", "q1", "qb", "q2", "qf", "qx"}
11+
12+
#* Alphabet:
13+
A = {"a", "b"}
14+
15+
#* Starting state:
16+
S = "q0"
17+
18+
#* Finals states:
19+
F = {"qf"}
20+
21+
#* Transitions:
22+
T = [
23+
("q0", "a", "qa"),
24+
("q0", "b", "q1"),
25+
26+
("qa", "a", "qa"),
27+
("qa", "b", "qb"),
28+
29+
("q1", "a", "qb"),
30+
("q1", "b", "q2"),
31+
32+
("qb", "a", "qb"),
33+
("qb", "b", "qf"),
34+
35+
("q2", "a", "qf"),
36+
("q2", "b", "qx"),
37+
38+
("qf", "a", "qf"),
39+
("qf", "b", "qx"),
40+
41+
("qx", "a", "qx"),
42+
("qx", "b", "qx")
43+
]
44+
45+
#? Automata:
46+
Automata = DFA(Q, A, T, S, F)
47+
Automata.show()
48+
49+
#/ Executes the Automata:
50+
while True:
51+
print()
52+
word = input("String: ")
53+
if Automata.accepts(word, stepByStep=True):
54+
print(f"The string \"{word}\" IS accepted!")
55+
else:
56+
print(f"The string \"{word}\" IS NOT accepted!")
57+
print()
58+
print("═"*40)

nfa-example-1.py renamed to Examples/nfa-example-1.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from nfa import NFA
1+
from Automata.nfa import NFA
22

33
if __name__ == "__main__":
44

@@ -15,15 +15,16 @@
1515
Automata.addTransition(("qa", "a", "qa"))
1616
Automata.addTransition(("qb", "a", "qba"))
1717
Automata.addTransition(("qb", "b", "qb"))
18+
1819
Automata.show()
1920

2021
#/ Executes the Automata:
2122
while True:
2223
print()
23-
word = input("Cadena: ")
24+
word = input("String: ")
2425
if Automata.accepts(word, stepByStep=True):
25-
print(f"La cadena \"{word}\" SÍ es aceptada!")
26+
print(f"The string \"{word}\" IS accepted!")
2627
else:
27-
print(f"La cadena \"{word}\" NO es aceptada!")
28+
print(f"The string \"{word}\" IS NOT accepted!")
2829
print()
2930
print("═"*40)

0 commit comments

Comments
 (0)