Newer
Older
from collections import deque
from functools import reduce
from graphviz import Digraph

Jan Maximilian Michal
committed
import re
def gap(content, points):
return "[gap({points}P)]{gap}[/gap]".format(points=points, gap=content)
def p(content):
return '<p>{}</p>\n'.format(content)
def tex(content):
return ('<span class="latex">' + content + '</span>').replace('\\', '\\\\')
class NEA:
"""docstring for NEA"""
__slots__ = ['states', 'sigma', 'delta', 'q0', 'F']
def __init__(self, states, sigma, delta, q0, F):
self.states = states
self.sigma = sigma
self.delta = delta
self.q0 = q0
self.F = set(F)
def to_dea(self):
done = []
new_steps = deque([{self.q0}])
table = []
while new_steps:
cur = new_steps.popleft()
table.append([cur])
for a in self.sigma:

Jan Maximilian Michal
committed
next = reduce(lambda a, b: a | b, (self.delta(s, a) for s in cur))
table[-1].append(next)
if next not in done:
new_steps.append(next)
done.append(next)
return table
def graph_output(self, file_format='svg'):

Jan Maximilian Michal
committed
f = Digraph('finite_state_machine', format=file_format, engine='dot')
f.body.extend(['rankdir=LR', 'size="8,5"'])
f.attr('node', shape='doublecircle')
for node in self.F:
f.node(node)
f.attr('node', shape='circle')
f.node('', style='invis')
f.edge('', self.q0)
for state in self.states:
for a in self.sigma:
for next in self.delta(state, a):
f.edge(str(state), next, label=a)

Jan Maximilian Michal
committed
return str(f.pipe(), encoding='utf-8')

Jan Maximilian Michal
committed
def generate_form(self):
table = self.to_dea()
tr = '<tr>\n{}</tr>\n'
td = '\t<td>{}</td>\n'

Jan Maximilian Michal
committed
aufgabe = '<table border-collapse: collapse; border-style: hidden; rules=\"all\">\n'
aufgabe += tr.format(''.join(td.format(s)
for s in [tex(r'\delta'), "a", "b"]))

Jan Maximilian Michal
committed
first, second, third = map(', '.join, (sorted(s) for s in row))
aufgabe += tr.format(td.format(first) +
td.format(gap(second, 1)) +
td.format(gap(third, 1)))

Jan Maximilian Michal
committed
return aufgabe

Jan Maximilian Michal
committed
aufgabe = '''Wandeln Sie M in einen DEA M' um, indem Sie die
Potenzmenge der Zustände aus M in M' als neue Zustände einfügen
(Eine Anleitung befindet sich im Skript von Dr. Müller S. 25).\n\n'''
aufgabe += p(self.graph_output())
aufgabe += p('''Füllen Sie diese Tabelle nach dem Vorbild im Müller
Skript aus. Achten Sie dabei darauf alle Zustände in lexikographischer
Reihenfolge aufzulisten (Zum Beispiel: s1, s2, s4) und alle Zustände
müssen mit Komma und Leerzeichen getrennt werden.''')
aufgabe += p(self.generate_form())
return aufgabe.replace('"', r'\"')
def generate_solution(self):
solution = "<h3>Musterloesung</h3><br>"
solution += re.sub(r'\[gap\(\d+P\)\](.+)\[\/gap\]',
r'\1', self.generate_form())
return solution.replace(r'"', r'\"')
def delta(state, char):
return {
('s0', 'a'): {'s0', 's1'},
('s0', 'b'): {'s0', 's2'},
('s1', 'a'): {'s1', 's3'},
('s1', 'b'): {'s1'},
('s2', 'a'): {'s2'},
('s2', 'b'): {'s2', 's3'},
('s3', 'a'): set(),
('s3', 'b'): set(),
}[(state, char)]
states = ["s{}".format(i) for i in range(4)]
F = ["s3"]

Jan Maximilian Michal
committed
### END OF SCRIPT ########################################################

Jan Maximilian Michal
committed
"type": "GAP",
"title": "NEA in DEA umwandeln",
"author": "Jan Maximilian Michal",
"gapLength": 10,
"question": N.generate_ilias(),
"solution": N.generate_solution(),