Skip to content

Commit

Permalink
readme extended
Browse files Browse the repository at this point in the history
tvml committed Nov 13, 2020
1 parent a32d4bf commit 81eaa6c
Showing 6 changed files with 93 additions and 66 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,13 @@
# python_fo
Theory of computing concepts in python3

Si consiglia di eseguire gli esempi nel folder examples all'interno di un
ambiente che consenta la selezione e l'esecuzione di righe di codice.

Ambienti di questo tipo sono l'IDE Spyder, l'editor Atom con plugin Hydrogen,
l'IDE VSCode (Visual Studio Code), tutti liberamente disponibili. Una
alternativa è rappresentata dall'utilizzo che Jupyterlab, che consente
l'apertura e l'esecuzione di file Python come notebook Jupyter.

Sia per Spyder, che per Atom, che per VSCode sono disponibili degli ambienti di
debugging.
4 changes: 2 additions & 2 deletions automata/fa/dfa.py
Original file line number Diff line number Diff line change
@@ -288,9 +288,9 @@ def rg(self):
for state, transitions in dfa.delta.items():
productions[('A'+state,)] = set()
for symbol, transition in transitions.items():
productions['A'+state].add((symbol, 'A'+transition.state))
productions[('A'+state,)].add((symbol, 'A'+transition.state))
if state in dfa.final_states:
productions['A'+state].add(symbol)
productions[('A'+state,)].add(symbol)
return rg.RG(terminals=terminals,
non_terminals=nonterminals,
axiom=axiom,
103 changes: 58 additions & 45 deletions examples/automata_ex.py
Original file line number Diff line number Diff line change
@@ -31,7 +31,8 @@
# - stati finali: un sottoinsieme dell'insieme degli stati
# - funzione di transizione: dizionario con
# - stati come chiavi
# - elementi rappresentati da dizionari con chiavi = simboli dell'alfabeto ed elementi = stati
# - elementi rappresentati da dizionari con chiavi = simboli dell'alfabeto
# ed elementi = stati

dfa = DFA(
states={'q0', 'q1'},
@@ -81,11 +82,16 @@
final_states={'q5'}
)

# Restituzione della computazione effettuata dall'automa sull'input specificato come tupla di simboli dell'alfabeto. Le righe rappresentano le configurazione attraversate: a sx lo stato, a dx la stringa da leggere. In fondo, esito della computazione.
# Restituzione della computazione effettuata dall'automa sull'input specificato
# come tupla di simboli dell'alfabeto. Le righe rappresentano le configurazione
# attraversate: a sx stato, a dx stringa da leggere. In fondo, esito della
# computazione.

dfa.report_computation(('expr', 'expr', 'id'))

# La funzione Tools.tokens() permette di specificare una tupla di simboli come stringa composta dalla concatenazione dei simboli stessi, separati dal simbolo specificato come separator
# La funzione Tools.tokens() permette di specificare una tupla di simboli come
# stringa composta da concatenazione dei simboli stessi, separati dal simbolo
# specificato come separator

dfa.report_computation(Tools.tokens('expr:expr:id', separator=':'))

@@ -131,7 +137,8 @@

# Configurazione di un DFA: stato attuale, lista di simboli da leggere, fornita come tupla. In aggiunta, riferimento all'automa relativo.

dfac = DFAConfiguration(state='q0', list_of_tokens=('id', 'expr'), automaton=dfa)
dfac = DFAConfiguration(
state='q0', list_of_tokens=('id', 'expr'), automaton=dfa)

dfac1 = DFAConfiguration(state='q0', list_of_tokens=('id'), automaton=dfa)

@@ -148,11 +155,13 @@
list_of_tokens=('digit', 'operator', 'operator'),
automaton=nfa)

nfac1 = NFAConfiguration(states={'q0'}, list_of_tokens=('0', '0', '1'), automaton=nfa1)
nfac1 = NFAConfiguration(
states={'q0'}, list_of_tokens=('0', '0', '1'), automaton=nfa1)

# Lista dei simboli fornita come stringa, nel caso in cui i simboli dell'alfabeto siano caratteri

nfac2 = NFAConfiguration.init(states={'q0'}, input_str='111001', automaton=nfa1)
nfac2 = NFAConfiguration.init(
states={'q0'}, input_str='111001', automaton=nfa1)

nfac0 = NFAConfiguration(states={'q0'}, list_of_tokens=(), automaton=nfa)

@@ -165,7 +174,8 @@

# Restituzione di una sequenza (casuale) di configurazioni deterministiche, derivate dalla computazione nondeterministica eseguita dal NFA sull'input dato.

nfa.report_random_deterministic_path(Tools.tokens('operator:operator:digit', separator=':'))
nfa.report_random_deterministic_path(
Tools.tokens('operator:operator:digit', separator=':'))

# Descrizione di un automa a stati a pila deterministico:
# - tipo di automa: DPDA
@@ -192,21 +202,21 @@
stack_symbols={'SYM1', 'SYM2', 'SYM3'},
delta={
'q0': {
'id1': {'SYM1': ('q0', Tools.tokens('SYM1:SYM1', separator=':')),
'SYM2': ('q0', Tools.tokens('SYM2:SYM1', separator=':')),
'SYM3': ('q0', ('SYM1',))
},
'id2': {'SYM1': ('q0', Tools.tokens('SYM1:SYM2', separator=':')),
'SYM3': ('q0', ('SYM1',))
},
'id3': {'SYM1': ('q1', ('SYM1',)),
'SYM2': ('q1', ('SYM1',)),
'SYM3': ('q1', ())
}
},
'id1': {'SYM1': ('q0', Tools.tokens('SYM1:SYM1', separator=':')),
'SYM2': ('q0', Tools.tokens('SYM2:SYM1', separator=':')),
'SYM3': ('q0', ('SYM1',))
},
'id2': {'SYM1': ('q0', Tools.tokens('SYM1:SYM2', separator=':')),
'SYM3': ('q0', ('SYM1',))
},
'id3': {'SYM1': ('q1', ('SYM1',)),
'SYM2': ('q1', ('SYM1',)),
'SYM3': ('q1', ())
}
},
'q1': {'id1': {'SYM1': ('q1', ())},
'id2': {'SYM3': ('q1', ())}}
},
},
initial_state='q0',
initial_stack_symbol='SYM3',
final_states={},
@@ -220,21 +230,21 @@
stack_symbols={'X', 'Y', 'Z'},
delta={
'q0': {
'a': {'X': ('q0', Tools.tokens('X:X', separator=':')),
'Y': ('q0', Tools.tokens('Y:Y', separator=':')),
'Z': ('q0', ('X',))
},
'b': {'X': ('q0', Tools.tokens('X:Y', separator=':')),
'Z': ('q0', ('X',))
},
'c': {'X': ('q1', ('X',)),
'Y': ('q1', ('Y',)),
'Z': ('q1', ())
}
},
'a': {'X': ('q0', Tools.tokens('X:X', separator=':')),
'Y': ('q0', Tools.tokens('Y:Y', separator=':')),
'Z': ('q0', ('X',))
},
'b': {'X': ('q0', Tools.tokens('X:Y', separator=':')),
'Z': ('q0', ('X',))
},
'c': {'X': ('q1', ('X',)),
'Y': ('q1', ('Y',)),
'Z': ('q1', ())
}
},
'q1': {'a': {'X': ('q1', ())},
'b': {'Y': ('q1', ())}}
},
},
initial_state='q0',
initial_stack_symbol='X',
final_states={},
@@ -268,23 +278,23 @@
'q0': {
'': {
'#': {('q0', ())}
},
},
'aa': {
'#': {('q0', ('A',))},
'A': {
('q0', ('A', 'A')),
('q1', ()),
},
('q0', ('A', 'A')),
('q1', ()),
},
'BB': {('q0', ('BB', 'A'))}
},
},
'b': {
'#': {('q0', ('BB',))},
'A': {('q0', ('A', 'BB'))},
'BB': {
('q0', ('BB', 'BB')),
('q1', ()),
}
}
('q0', ('BB', 'BB')),
('q1', ()),
}
}
},
'q1': {
'': {'#': {('q2', ())}},
@@ -489,15 +499,17 @@
stp = StateTapePair(state='q0', tape=t)
print(stp)

stp1 = StateTapePair.init(state='q0', input_str='001', head=5, blank_symbol='.')
stp1 = StateTapePair.init(state='q0', input_str='001',
head=5, blank_symbol='.')
print(stp1)

# Definizione configurazione DTM, comprendente coppia stato+nastro e automa relativo

dtmc = DTMConfiguration(state_tape_pair=stp, automaton=dtm)
print(dtmc)

dtmc1 = DTMConfiguration.init(state='q0', input_str='011110', head=9, automaton=dtm)
dtmc1 = DTMConfiguration.init(
state='q0', input_str='011110', head=9, automaton=dtm)
print(dtmc1)

dtm.report_computation(Tools.tokens('0011'))
@@ -566,7 +578,8 @@


t1 = TMTape(list_of_tokens=('id1', 'id2', 'x', '.', 'y'), head=4)
t2 = TMTape(list_of_tokens=Tools.tokens('id2:id2:id2:x:id2', separator=':'), head=2)
t2 = TMTape(list_of_tokens=Tools.tokens(
'id2:id2:id2:x:id2', separator=':'), head=2)

stp1 = StateTapePair(state='q0', tape=t1)
stp2 = StateTapePair(state='q2', tape=t2)
5 changes: 2 additions & 3 deletions examples/dfa_quiz.py
Original file line number Diff line number Diff line change
@@ -7,8 +7,6 @@
from tools.tools import Tools
from automata.fa.dfa import DFA
from automata.fa.nfa import NFA
from automata.fa.dfa_configuration import DFAConfiguration
from automata.fa.nfa_configuration import NFAConfiguration


# Definire un ASFD che riconosce il linguaggio $L\subseteq\{0,1\}^*$ definito
@@ -110,7 +108,8 @@

dfa3.draw()

# Non specificare un valore per separator in Tools.tokens() corrisponde ad assumere nessun separatore, e quindi che i simboli siano singoli caratteri
# Non specificare un valore per separator in Tools.tokens() corrisponde ad
# assumere nessun separatore, e quindi che i simboli siano singoli caratteri

dfa3.report_computation(Tools.tokens('0010'))

Binary file modified grammar/base/__pycache__/derivation.cpython-37.pyc
Binary file not shown.
36 changes: 20 additions & 16 deletions grammar/base/derivation.py
Original file line number Diff line number Diff line change
@@ -56,7 +56,7 @@ def _left_part_occurrences(phrase, grammar):
else:
for i in range(len(phrase)):
for lp in grammar.productions.keys():
if phrase[i:i+len(lp)] == lp:
if phrase[i:i + len(lp)] == lp:
left_part_indices.append((i, len(lp)))
return left_part_indices

@@ -74,15 +74,16 @@ def __str__(self):
if self.grammar.all_chars:
s = '{} -> {}\t\t\t{} => {}'.format(
tools.Tools.print(self.left), tools.Tools.print(self.right),
tools.Tools.print(self.phrase), tools.Tools.print(self.next_phrase)
)
tools.Tools.print(self.phrase), tools.Tools.print(
self.next_phrase)
)
else:
s = '{} -> {}\t\t\t{} => {}'.format(
tools.Tools.print_tuple(self.left),
tools.Tools.print_tuple(self.right),
tools.Tools.print_tuple(self.phrase),
tools.Tools.print_tuple(self.next_phrase)
)
tools.Tools.print_tuple(self.left),
tools.Tools.print_tuple(self.right),
tools.Tools.print_tuple(self.phrase),
tools.Tools.print_tuple(self.next_phrase)
)
return s


@@ -126,14 +127,14 @@ def next_step(self):
return None
left_choices = self._select_choices(left_part_indices)
start_index, length = random.choice(left_choices)
lpart_tokens = phrase_tokens[start_index:start_index+length]
lpart_tokens = phrase_tokens[start_index:start_index + length]
choices = self.grammar.get_right_parts(lpart_tokens)
if choices is None or len(choices) == 0:
return None
rpart_tokens = random.choice(list(choices))
sub_phrases = [phrase_tokens[:start_index],
rpart_tokens,
phrase_tokens[start_index+length:]]
phrase_tokens[start_index + length:]]
next_phrase_tokens = tuple(itertools.chain.from_iterable(sub_phrases))
return Step(left=lpart_tokens,
right=rpart_tokens,
@@ -184,7 +185,7 @@ def _syntax_tree(self, f):
node.father = father
father.add_child(node)
new_leaves.append(node)
new_leaves.extend(leaves[ind+1:])
new_leaves.extend(leaves[ind + 1:])
leaves = new_leaves
return st

@@ -200,22 +201,25 @@ def __str__(self):
if self.steps:
for step in self.steps:
lst = [tools.Tools.print(step.phrase),
tools.Tools.print(step.left)+' -> ' +
tools.Tools.print(step.left) + ' -> ' +
tools.Tools.print(step.right)]
lstlst.append(lst)
lstlst.append([tools.Tools.print(self.steps[-1].next_phrase), ''])
lstlst.append(
[tools.Tools.print(self.steps[-1].next_phrase), ''])
else:
lstlst.append([tools.Tools.print(self.grammar.axiom), ''])
else:
if self.steps:
for step in self.steps:
lst = [tools.Tools.print_tuple(step.phrase),
tools.Tools.print_tuple(step.left)+' -> ' +
tools.Tools.print_tuple(step.left) + ' -> ' +
tools.Tools.print_tuple(step.right)]
lstlst.append(lst)
lstlst.append([tools.Tools.print_tuple(self.steps[-1].next_phrase), ''])
lstlst.append([tools.Tools.print_tuple(
self.steps[-1].next_phrase), ''])
else:
lstlst.append([tools.Tools.print_tuple(self.grammar.axiom), ''])
lstlst.append(
[tools.Tools.print_tuple(self.grammar.axiom), ''])
return tabulate(lstlst, tablefmt='plain')


0 comments on commit 81eaa6c

Please sign in to comment.