Skip to content

Commit 50958b6

Browse files
committed
Automata v.1.3.0
It has a precious implementation of Pushdown Automatas (PDA), deterministic and indeterministic. It also have an update of the rest of the classes, with a new method called [show], that prints on console the complete automata information. It also has a slight improvement on the examples printing, to be more fancy :3
1 parent 95b3642 commit 50958b6

File tree

9 files changed

+485
-47
lines changed

9 files changed

+485
-47
lines changed

dfa-example-1.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
Automata.addTransition(("q0", "b", "q0"))
1616
Automata.addTransition(("q1", "a", "q1"))
1717
Automata.addTransition(("q1", "b", "q1"))
18+
Automata.show()
1819

1920
#/ Executes the Automata:
2021
while True:
@@ -23,4 +24,6 @@
2324
if Automata.accepts(word, stepByStep=True):
2425
print(f"La cadena \"{word}\" SÍ es aceptada!")
2526
else:
26-
print(f"La cadena \"{word}\" NO es aceptada!")
27+
print(f"La cadena \"{word}\" NO es aceptada!")
28+
print()
29+
print("═"*40)

dfa-example-2.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545

4646
#? Automata:
4747
Automata = DFA(Q, A, T, S, F)
48+
Automata.show()
4849

4950
#/ Executes the Automata:
5051
while True:
@@ -53,4 +54,6 @@
5354
if Automata.accepts(word, stepByStep=True):
5455
print(f"La cadena \"{word}\" SÍ es aceptada!")
5556
else:
56-
print(f"La cadena \"{word}\" NO es aceptada!")
57+
print(f"La cadena \"{word}\" NO es aceptada!")
58+
print()
59+
print("═"*40)

dfa.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,22 @@ def setFinals(self, finals: set):
106106

107107

108108
#? Methods:
109+
def show(self):
110+
'''Prints Automata data'''
111+
print()
112+
print("═"*40)
113+
print("\nAUTÓMATA FINITO DETERMINISTA\n")
114+
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)}")
119+
for t in self.Transitions:
120+
t1 = t[1] if t[1] != "" else "λ"
121+
print(f"* δ(\"{t[0]}\", \"{t1}\") = (\"{t[2]}\")")
122+
print()
123+
print("═"*40)
124+
109125
def transite(self, symbol: str, printStep: bool = False):
110126
'''
111127
Recieves an actual reading symbol;
@@ -122,7 +138,7 @@ def transite(self, symbol: str, printStep: bool = False):
122138
if self.actual == transition[0] and symbol == transition[1]:
123139
validTransitions.append(transition)
124140

125-
# If Automata has 0 or more than 1 transitions:
141+
# If Automata has 0 or more than 1 transitions;
126142
if len(validTransitions) != 1:
127143
print(f" * Transición δ(\"{self.actual}\", \"{symbol}\") inválida!")
128144
self.error = True
@@ -132,7 +148,7 @@ def transite(self, symbol: str, printStep: bool = False):
132148
if printStep:
133149
print(f" * \"{self.actual}\" lee \"{symbol}\" => \"{validTransitions[0][2]}\";")
134150
self.actual = validTransitions[0][2]
135-
151+
136152
def accepts(self, string: str, stepByStep: bool = False):
137153
'''
138154
Recieves a string to read;
@@ -144,10 +160,16 @@ def accepts(self, string: str, stepByStep: bool = False):
144160
self.actual = self.Initial
145161
self.error = False
146162

163+
# It shows the step by step path for the string:
164+
if stepByStep:
165+
print(f"\nPara la cadena \"{string}\":\n")
166+
147167
# Reads letter per letter:
148168
for character in string:
149169
self.transite(character, stepByStep)
150170

171+
print()
172+
151173
# If the string was accepted or not:
152174
# Firstly checks if transitionsCount == word lenght,
153175
# If not, is because it has an invalid transition:

nfa-example-1.py

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,20 @@
22

33
if __name__ == "__main__":
44

5-
# First example of NFA Automata instance:
5+
# Second example of NFA Automata instance:
66
# Language of the Automata:
7-
# L(Automata) = {aba(b^n): n>0} U
8-
# {ab(a^n): n>=0};
9-
#* States:
10-
Q = {"q0", "qa", "qab", "qf", "qabf"}
11-
12-
#* Alphabet:
13-
A = {"a", "b"}
14-
15-
#* Transitions:
16-
T = []
17-
18-
#* Starting state:
19-
S = "q0"
20-
21-
#* Finals states:
22-
F = {"qf", "qabf"}
23-
24-
#* Transitions definition:
25-
T.append( ("q0", "a", "qa") )
26-
T.append( ("qa", "b", "qab") )
27-
T.append( ("qab", "a", "qf") )
28-
T.append( ("qf", "b", "qf") )
29-
T.append( ("qab", "", "qabf") )
30-
T.append( ("qabf", "a", "qabf") )
31-
32-
#? Automata:
33-
Automata = NFA(Q, A, T, S, F)
7+
# L(Automata) = {(a^n): n>=0} U {(b^n)a: n>=1};
8+
Automata = NFA()
9+
Automata.setStates({"q0", "qb", "qa", "qba"})
10+
Automata.setAlphabet({"a", "b"})
11+
Automata.setInitial("q0")
12+
Automata.setFinals({"qa", "qba"})
13+
Automata.addTransition(("q0", "", "qa"))
14+
Automata.addTransition(("q0", "b", "qb"))
15+
Automata.addTransition(("qa", "a", "qa"))
16+
Automata.addTransition(("qb", "a", "qba"))
17+
Automata.addTransition(("qb", "b", "qb"))
18+
Automata.show()
3419

3520
#/ Executes the Automata:
3621
while True:
@@ -39,4 +24,6 @@
3924
if Automata.accepts(word, stepByStep=True):
4025
print(f"La cadena \"{word}\" SÍ es aceptada!")
4126
else:
42-
print(f"La cadena \"{word}\" NO es aceptada!")
27+
print(f"La cadena \"{word}\" NO es aceptada!")
28+
print()
29+
print("═"*40)

nfa-example-2.py

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,36 @@
22

33
if __name__ == "__main__":
44

5-
# Second example of NFA Automata instance:
5+
# First example of NFA Automata instance:
66
# Language of the Automata:
7-
# L(Automata) = {(a^n): n>=0} U {(b^n)a: n>=1};
8-
Automata = NFA()
9-
Automata.setStates({"q0", "qb", "qa", "qba"})
10-
Automata.setAlphabet({"a", "b"})
11-
Automata.setInitial("q0")
12-
Automata.setFinals({"qa", "qba"})
13-
Automata.addTransition(("q0", "", "qa"))
14-
Automata.addTransition(("q0", "b", "qb"))
15-
Automata.addTransition(("qa", "a", "qa"))
16-
Automata.addTransition(("qb", "a", "qba"))
17-
Automata.addTransition(("qb", "b", "qb"))
7+
# L(Automata) = {aba(b^n): n>0} U
8+
# {ab(a^n): n>=0};
9+
#* States:
10+
Q = {"q0", "qa", "qab", "qf", "qabf"}
11+
12+
#* Alphabet:
13+
A = {"a", "b"}
14+
15+
#* Transitions:
16+
T = []
17+
18+
#* Starting state:
19+
S = "q0"
20+
21+
#* Finals states:
22+
F = {"qf", "qabf"}
23+
24+
#* Transitions definition:
25+
T.append( ("q0", "a", "qa") )
26+
T.append( ("qa", "b", "qab") )
27+
T.append( ("qab", "a", "qf") )
28+
T.append( ("qf", "b", "qf") )
29+
T.append( ("qab", "", "qabf") )
30+
T.append( ("qabf", "a", "qabf") )
31+
32+
#? Automata:
33+
Automata = NFA(Q, A, T, S, F)
34+
Automata.show()
1835

1936
#/ Executes the Automata:
2037
while True:
@@ -23,4 +40,6 @@
2340
if Automata.accepts(word, stepByStep=True):
2441
print(f"La cadena \"{word}\" SÍ es aceptada!")
2542
else:
26-
print(f"La cadena \"{word}\" NO es aceptada!")
43+
print(f"La cadena \"{word}\" NO es aceptada!")
44+
print()
45+
print("═"*40)

nfa.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,22 @@ def setFinals(self, finals: set):
110110

111111

112112
#? Methods:
113+
def show(self):
114+
'''Prints Automata data'''
115+
print()
116+
print("═"*40)
117+
print("\nAUTÓMATA FINITO NO DETERMINISTA\n")
118+
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)}")
123+
for t in self.Transitions:
124+
t1 = t[1] if t[1] != "" else "λ"
125+
print(f"* δ(\"{t[0]}\", \"{t1}\") = (\"{t[2]}\")")
126+
print()
127+
print("═"*40)
128+
113129
def transite(self, symbol: str, printStep: bool = False):
114130
'''
115131
Recieves an catual reading symbol;
@@ -184,7 +200,10 @@ def accepts(self, string: str, stepByStep: bool = False):
184200
self.currents = [self.Initial]
185201
self.error = False
186202
self.correct = False
187-
print()
203+
204+
# It shows the step by step path for the string:
205+
if stepByStep:
206+
print(f"\nPara la cadena \"{string}\":\n")
188207

189208
# If the string is empty:
190209
if len(string) == 0:

pda-example-1.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from pda import PDA
2+
3+
if __name__ == "__main__":
4+
5+
# First example of PDA Automata instance:
6+
# Language of the Automata:
7+
# L(Automata) = { (a^n)(b^2n): n >= 0 };
8+
# "ab" structure with the double of b's respect to a's.
9+
# It includes the empty string.
10+
Automata = PDA()
11+
Automata.setStates({"q0", "qa", "qb", "qf"})
12+
Automata.setAlphabet({"a", "b"})
13+
Automata.setInitial("q0")
14+
Automata.setFinals({"qf"})
15+
Automata.addTransition(("q0", "a", "Z", "aaZ", "qa"))
16+
Automata.addTransition(("qa", "a", "a", "aaa", "qa"))
17+
Automata.addTransition(("qa", "b", "a", "", "qb"))
18+
Automata.addTransition(("qb", "b", "a", "", "qb"))
19+
Automata.addTransition(("qb", "", "Z", "", "qf"))
20+
Automata.setStackAlphabet({"a", "Z"})
21+
Automata.setInitialStack(["Z"])
22+
Automata.show()
23+
24+
#/ Executes the Automata:
25+
while True:
26+
print()
27+
word = input("Cadena: ")
28+
if Automata.accepts(word, stepByStep=True):
29+
print(f"La cadena \"{word}\" SÍ es aceptada!")
30+
else:
31+
print(f"La cadena \"{word}\" NO es aceptada!")
32+
print()
33+
print("═"*80)

pda-example-2.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
from pda import PDA
2+
3+
if __name__ == "__main__":
4+
5+
# Second example of PDA Automata instance:
6+
# Language of the Automata:
7+
# L(Automata) = { w c (w)^R: w in {a, b}* };
8+
# Any "a" and "b" combination string (also empty),
9+
# with then a "c", and then his reverse:
10+
11+
#* States:
12+
Q = {"qw", "qc", "qf"}
13+
14+
#* Alphabet:
15+
A = {"a", "b", "c"}
16+
17+
#* Transitions:
18+
T = []
19+
20+
#* Starting state:
21+
S = "qw"
22+
23+
#* Finals states:
24+
F = {"qf"}
25+
26+
#* Stack alphabet:
27+
X = {"Z", "1", "2"}
28+
29+
#* Initial stack:
30+
I = ["Z"]
31+
32+
#* Transitions definition:
33+
T.append( ("qw", "a", "Z", "1Z", "qw") )
34+
T.append( ("qw", "b", "Z", "2Z", "qw") )
35+
T.append( ("qw", "a", "1", "11", "qw") )
36+
T.append( ("qw", "a", "2", "12", "qw") )
37+
T.append( ("qw", "b", "1", "21", "qw") )
38+
T.append( ("qw", "b", "2", "22", "qw") )
39+
40+
T.append( ("qw", "c", "1", "1", "qc") )
41+
T.append( ("qw", "c", "2", "2", "qc") )
42+
T.append( ("qw", "c", "Z", "Z", "qc") )
43+
44+
T.append( ("qc", "a", "1", "", "qc") )
45+
T.append( ("qc", "b", "2", "", "qc") )
46+
47+
T.append( ("qc", "", "Z", "", "qf") )
48+
49+
#? Automata:
50+
Automata = PDA(Q, A, T, S, F, X, I)
51+
Automata.show()
52+
53+
#/ Executes the Automata:
54+
while True:
55+
print()
56+
word = input("Cadena: ")
57+
if Automata.accepts(word, stepByStep=True):
58+
print(f"La cadena \"{word}\" SÍ es aceptada!")
59+
else:
60+
print(f"La cadena \"{word}\" NO es aceptada!")
61+
print()
62+
print("═"*40)

0 commit comments

Comments
 (0)