示例#1
0
def nedeterministička_konkatenacija(N1, N2):
    if not N1.stanja.isdisjoint(N2.stanja):
        N1 = označi(N1, '3')
        N2 = označi(N2, '4')
    Q1, Σ1, Δ1, q1, F1 = petorka(N1)
    Q2, Σ2, Δ2, q2, F2 = petorka(N2)
    assert Σ1 == Σ2
    Q = disjunktna_unija(Q1, Q2)
    Δ = Δ1 | Δ2 | {(p1, ε, q2) for p1 in F1}
    return NedeterminističkiKonačniAutomat.definicija(Q, Σ1, Δ, q1, F2)
示例#2
0
def nedeterministička_unija(N1, N2):
    if not N1.stanja.isdisjoint(N2.stanja):
        N1 = označi(N1, '1')
        N2 = označi(N2, '2')
    q0 = novo('q0', N1.stanja | N2.stanja)
    Q1, Σ1, Δ1, q1, F1 = petorka(N1)
    Q2, Σ2, Δ2, q2, F2 = petorka(N2)
    assert Σ1 == Σ2
    Q = disjunktna_unija(Q1, Q2, {q0})
    F = disjunktna_unija(F1, F2)
    Δ = Δ1 | Δ2 | {(q0, ε, q1), (q0, ε, q2)}
    return NedeterminističkiKonačniAutomat.definicija(Q, Σ1, Δ, q0, F)
示例#3
0
class NedeterminističkiKonačniAutomat(types.SimpleNamespace):
    @classmethod
    def definicija(klasa, stanja, abeceda, prijelaz, početno, završna):
        assert abeceda and početno in stanja and završna <= stanja
        assert relacija(prijelaz, stanja, ε_proširenje(abeceda), stanja)
        return klasa(**locals())

    @classmethod
    def funkcijska_definicija(klasa, stanja, abeceda, funkcija_prijelaza,
                              početno, završna):
        prijelaz = set(relacija_iz_funkcije(funkcija_prijelaza))
        return klasa.definicija(stanja, abeceda, prijelaz, početno, završna)

    @classmethod
    def iz_tablice(klasa, tablica):
        prva, *ostale = tablica.strip().splitlines()
        znakovi = prva.split()
        assert all(len(znak) == 1 for znak in znakovi)
        abeceda = set(znakovi)
        stanja, završna = set(), set()
        prijelaz, početno = set(), None
        for linija in ostale:
            stanje, *dolazna = linija.split()
            if početno is None: početno = stanje
            extra = len(dolazna) - len(znakovi)
            assert extra >= 0
            if extra > 0 and dolazna[~0] == '#':
                del dolazna[~0]
                završna.add(stanje)
            for znak, dolazno in zip(znakovi, dolazna):
                for dolazno1 in filter(None, dolazno.split('/')):
                    prijelaz.add((stanje, znak, dolazno1))
            for dolazno in dolazna[len(znakovi):]:
                for dolazno2 in dolazno.split('/'):
                    prijelaz.add((stanje, ε, dolazno2))
            stanja.add(stanje)
        return klasa.definicija(stanja, abeceda, prijelaz, početno, završna)

    @classmethod
    def iz_konačnog_automata(klasa, konačni_automat):
        Q, Σ, δ, q0, F = petorka(konačni_automat)
        Δ = {(q, α, δ[q, α]) for q in Q for α in Σ}
        return klasa.definicija(Q, Σ, Δ, q0, F)

    @property
    def abeceda_ε(automat):
        return ε_proširenje(automat.abeceda)

    @property
    def funkcija_prijelaza(automat):
        return funkcija_iz_relacije(
            automat.prijelaz, automat.stanja, automat.abeceda_ε)

    ispiši = lambda automat: pprint.pprint(petorka(automat))

    def prihvaća(automat, ulaz):
        δ = automat.funkcija_prijelaza
        moguća = ε_zatvorenje(δ, {automat.početno})
        for znak in ulaz: moguća = ε_zatvorenje(δ, dolazna(δ, moguća, znak))
        return not moguća.isdisjoint(automat.završna)
示例#4
0
def označi(nka, l):
    Q, Σ, Δ, q0, F = petorka(nka)
    Ql = {označi1(q, l) for q in Q}
    Δl = {(označi1(p, l), α, označi1(q, l)) for p, α, q in Δ}
    q0l = označi1(q0, l)
    Fl = {označi1(q, l) for q in F}
    return NedeterminističkiKonačniAutomat.definicija(Ql, Σ, Δl, q0l, Fl)
示例#5
0
def partitivna_konstrukcija(nka):
    Q, Σ, Δ, q0, F = petorka(nka)
    δ = nka.funkcija_prijelaza
    PQ = partitivni_skup(Q)
    δ_KA = {}
    F_KA = set()
    for stanje in PQ:
        for α in Σ:
            δ_KA[stanje, α] = ε_zatvorenje(δ, dolazna(δ, stanje, α))
        if not stanje.isdisjoint(F): F_KA.add(stanje)
    q0_KA = ε_zatvorenje(δ, fset({q0}))
    return KonačniAutomat.definicija(PQ, Σ, δ_KA, q0_KA, F_KA)
示例#6
0
def optimizirana_partitivna_konstrukcija(nka):
    Q, Σ, Δ, q0, F = petorka(nka)
    δ = nka.funkcija_prijelaza
    Q_KA = set()
    δ_KA = {}
    F_KA = set()
    q0_KA = ε_zatvorenje(δ, fset({q0}))
    red = collections.deque([q0_KA])
    while red:
        stanje = red.popleft()
        if stanje not in Q_KA:
            for α in Σ:
                novo_stanje = ε_zatvorenje(δ, dolazna(δ, stanje, α))
                δ_KA[stanje, α] = novo_stanje
                red.append(novo_stanje)
            Q_KA.add(stanje)
            if not stanje.isdisjoint(F): F_KA.add(stanje)
    return KonačniAutomat.definicija(Q_KA, Σ, δ_KA, q0_KA, F_KA)
示例#7
0
 def iz_konačnog_automata(klasa, konačni_automat):
     Q, Σ, δ, q0, F = petorka(konačni_automat)
     Δ = {(q, α, δ[q, α]) for q in Q for α in Σ}
     return klasa.definicija(Q, Σ, Δ, q0, F)
示例#8
0
def nedeterministički_reverz(N):
    Q, Σ, Δ, q0, F = petorka(N)
    kraj = novo('qz', Q)
    Δ_ᴙ = {(q, α, p) for p, α, q in Δ} | {(kraj, ε, z) for z in F}
    return NedeterminističkiKonačniAutomat.definicija(
        Q | {kraj}, Σ, Δ_ᴙ, kraj, {q0})
示例#9
0
def nedeterministička_zvijezda(N):
    Q, Σ, Δ, q0, F = petorka(nedeterministički_plus(N))
    poč = novo('q0', Q)
    return NedeterminističkiKonačniAutomat.definicija(
        Q | {poč}, Σ, Δ | {(poč, ε, q0)}, poč, F | {poč})
示例#10
0
def nedeterministički_plus(N):
    Q, Σ, Δ, q0, F = petorka(N)
    Δ_plus = Δ | {(p, ε, q0) for p in F}
    return NedeterminističkiKonačniAutomat.definicija(Q, Σ, Δ_plus, q0, F)