Języki

by Jerry Sky

2020-10-26



1. Słowa, języki

Mamy A=({a1,a2,…,am},∣⋅∣)\mathcal{A} = (\left\{ a_1, a_2, \dots, a_m \right\}, |\cdot|), gdzie ∀i∣ai∣=1\forall i \enspace |a_i| = 1.

Wówczas W=SEQ⁡(A)\mathcal{W} = \operatorname{SEQ}(\mathcal{A})
oraz W(z)=11−mzW(z) = \frac{1}{1 - mz}, bo A(z)=m⋅zA(z) = m\cdot z.


1.1. Przykład

Ile jest słów długości nn takich, że nie ma* kk liter aa z rzędu?*
n=4, k=2bbbbabbbababbaba…n=4,~ k=2 \qquad bbbb \quad abbb \quad abab \quad baba \quad \dots


1.2. Przykład

Co, gdy chcemy policzyć, ile jest słów takich, że jest co najwyżej kk liter aa oraz bb z rzędu.


1.3. Przykład

Ile jest słów nad {a,b}\{a,b\} długości nn takich, że jest dokładnie kk wystąpień litery (symbolu) «bb»?

Standardowo, oczywiście (nk)\binom{n}{k} jako, że wybieramy z nn miejsc kk miejsc, na których stawiamy litery (symbole) «bb».

Ale popatrzmy na to zadanie w nieco inny sposób.

Mamy a…a⏟0–∞ b1 a…a⏟0–∞ b2 a…a⏟0–∞ b3 …bk a…a⏟0–∞ \underbrace{a\dots a}_{0–\infty}\, \overset{1}{b}\, \underbrace{a\dots a}_{0–\infty}\, \overset{2}{b}\, \underbrace{a\dots a}_{0–\infty}\, \overset{3}{b}\, \dots \overset{k}{b}\, \underbrace{a\dots a}_{0–\infty}

Czyli mamy SEQ⁡({a}){b}SEQ⁡({a}){b}SEQ⁡({a}){b}…{b}SEQ⁡({a}) \operatorname{SEQ}(\{a\}) \enspace \{b\} \enspace \operatorname{SEQ}(\{a\}) \enspace \{b\} \enspace \operatorname{SEQ}(\{a\}) \{b\} \dots \{b\} \operatorname{SEQ}(\{a\})

Ostatecznie mamy język określony przez klasę kombinatoryczną: L≅(SEQ⁡({a}))k+1({b})k,L(z)=(11−z)k+1⋅zk. \mathcal{L} \cong (\operatorname{SEQ}(\{a\}))^{k+1} (\{b\})^k,\\ L(z) = \left( \frac{1}{1-z} \right)^{k+1} \cdot z^k.


1.4. Przykład

Ile jest ciągów nad alfabetem {a,b}\{a,b\} takich, że jest kk liter «bb» oraz odległość każdego «bb» od swojego poprzednika to co najwyżej dd?

Popatrzmy na przykład słowa należącego do takiego języka. Weźmy k=3,d=3k=3, d=3: aaaaaaaaaaaaa b a b aaa b aaaaaaaa aaaaaaaaaaaaa\, b\, a\, b\, aaa\, b\, aaaaaaaa

Jesteśmy w stanie określić klasę kombinatoryczną: L≅SEQ⁡({a}) {b} SEQ⁡≤d({a}) {b} SEQ⁡≤d({a}) … {b} SEQ⁡({a}) \mathcal{L} \cong \operatorname{SEQ}(\{a\})\, \{b\}\, \operatorname{SEQ}_{\le d}(\{a\})\, \{b\}\, \operatorname{SEQ}_{\le d}(\{a\})\, \dots\, \{b\}\, \operatorname{SEQ}(\{a\})

Wówczas OGF: L(z)=(11−z)2⋅zk⋅(1+z+z2+⋯+zd)k−1==(11−z)2⋅zk⋅(1−zd−11−z)k−1==zk(1−zd−1)k−1(1−z)k−1 L(z) = \left( \frac{1}{1-z} \right)^2 \cdot z^k \cdot \left( 1 + z + z^2 + \dots + z^d \right)^{k-1} =\\ = \left( \frac{1}{1-z} \right)^2 \cdot z^k \cdot \left( \frac{1 - z^{d-1}}{1-z} \right)^{k-1} =\\ = \frac{z^k\left( 1 - z^{d-1} \right)^{k-1}}{(1-z)^{k-1}}

Podzielmy na części OGF: A1(z)=zk(1−z)k+1=∑n≥0an(1)znA2(z)=(1−zd+1)k−1=∑n≥0an(2)zn A_1(z) = \frac{z^k}{(1-z)^{k+1}} = \sum_{n\ge0} a^{(1)}_n z^n\\ A_2(z) = \left( 1-z^{d+1} \right)^{k-1} = \sum_{n\ge0} a^{(2)}_n z^n

Czyli L(z)=A1(z)A2(z)L(z) = A_1(z) A_2(z), wówczas: ln=∑k=0nak(1)⋅an−k(2) l_n = \sum_{k=0}^n a^{(1)}_k \cdot a^{(2)}_{n-k}


2. Wzorce ukryte

Mamy pewny ciąg liter, który ma w sobie ukryte dane słowo.

Np. mamy tekst:

Komu bije dzwon
A tego raczej nie wiem.
Być może każdemu.

I ukryte słowo «kombinatoryka».

2.1. Przykład

Ile jest słów nad alfabetem A\mathcal{A} (mamy mm symboli), które zawierają ukryty wzorzec ze słowem «kombinatoryka»?

2.1.1. Złe rozwiązanie

B≅SEQ⁡(A) {k} SEQ⁡(A) {o} … SEQ⁡(A) B \cong \operatorname{SEQ}(\mathcal{A})\, \{k\}\, \operatorname{SEQ}(\mathcal{A})\, \{o\}\, \dots\, \operatorname{SEQ}(\mathcal{A})

Wówczas OGF: B(z)=z13(1−mz)14. B(z) = \frac{z^{13}}{(1 - mz)^{14}}.

2.1.2. Dobre rozwiązanie

Naszą klasę trzeba nieco zmodyfikować: SEQ⁡(A∖{k}) {k} SEQ⁡(A∖{o}) {o} … SEQ⁡(A∖{a}) {a} SEQ⁡(A) \operatorname{SEQ}(\mathcal{A} \setminus \{k\})\, \{k\}\, \operatorname{SEQ}(\mathcal{A} \setminus \{o\})\, \{o\}\, \dots\, \operatorname{SEQ}(\mathcal{A} \setminus \{a\})\, \{a\}\, \operatorname{SEQ}(\mathcal{A})

Czyli OGF wynosi: B(z)=z13(1−(m−1)z)13⋅11−mz B(z) = \frac{z^{13}}{\left( 1 - (m-1)z \right)^{13}} \cdot \frac{1}{1-mz}


3. Automaty skończone

3.1. Przykład

Czy słowo zawiera ciąg abbabb? (A={a,b}\mathcal{A} = \{a,b\})

Li\mathcal{L}_i — klasa słów akceptowanych przez powyższy automat jeśli zaczynamy ze stanu ii.

Czyli:

a po rozwiązaniu układu równań: L0(z)=z3(1−z)(1−2z)(1−z−z2)=Apart⁡=11−2z−2+z1−z−z2+11−z L_0(z) = \frac{z^3}{(1-z)(1-2z)(1-z-z^2)} \overset{\operatorname{Apart}}{=}\\ = \frac{1}{1-2z} - \frac{2+z}{1-z-z^2} + \frac{1}{1-z}

Liczymy współczynnik: [zn]L0(z)=2n−Fn+3+1 [z^n]L_0(z) = 2^n - F_{n+3} + 1


4. Wzorce blokowe

Tym razem, w odróżnieniu od wzorców ukrytych, musimy mieć w tekście dany blok liter koło siebie, w odpowiedniej kolejności.

Np. Dobry pterodaktyl jest! ma w sobie wzorzec blokowy «daktyl».

4.1. Zgodność prefiksowo-sufiksowa

Określamy ciąg c=(c0,c1,…,ck−1)c = (c_0, c_1, \dots, c_{k-1}) oraz liczby ci=⟦p1p2…pk−i=pi+1…pk⟧c_i = \llbracket p_1 p_2 \dots p_{k-i} = p_{i+1} \dots p_k \rrbracket gdzie ⟦⋅⟧\llbracket \cdot \rrbracket jest notacją Iversona. Czyli porównujemy końcówki z początkami danego słowa. Ciąg cc nazywamy *ciągiem charakterystycznym dla słowa p‾\overline{p}.

Np. weźmy aabbaaaabbaa — jego ciągiem charakterystycznym jest c=(c0,c1,…,ck−1)=(1,0,0,0,1,1)c = (c_0, c_1, \dots, c_{k-1}) = (1,0,0,0,1,1) bo tylko dwie literki aaaa na początku i na końcu czynią zadość równości.

Określamy również wielomian charakterystyczny: C(z)=∑j=0k−1cjzj C(z) = \sum_{j=0}^{k-1} c_j z^j i znowu dla aabbaaaabbaa będzie to po prostu C(z)=1+z4+z5C(z) = 1 + z^4 + z^5.


4.2. Ciągi długości nn z wzorcem p‾\overline{p}

Ile jest ciągów długości nn nad alfabetem A\mathcal{A}, które zawierają wzorzec blokowy p‾\overline{p}?

Mamy:

Szukamy języka (klasy) słów zawierających blok p‾\overline{p}.

Weźmy

Wówczas S+T≅{ϵ}+S×A \mathcal{S} + \mathcal{T} \cong \{\epsilon\} + \mathcal{S} \times \mathcal{A} ponieważ możemy wziąć takie słowo, które nie ma na pewno na końcu p‾\overline{p} albo wziąć takie, któremu brakuje jednej literki i tutaj wystarczy dokleić jedną literkę z alfabetu A\mathcal{A}.

Dodatkowo S∗p‾≅T∗∑∀ici≠0{pk−i+1,…,pk} \mathcal{S} * \overline{p} \cong \mathcal{T} * \sum_{\forall i\enspace c_i \neq 0} \left\{ p_{k-i+1}, \dots, p_k \right\} (∗* to konkatenacja)
a to dlatego, że w T\mathcal{T} będzie końcówka, która będzie się zgadzać z początkiem tego wzorca:

Z powyższych własności mamy: S(z)+T(z)=1+S(z)⋅mz S(z) + T(z) = 1 + S(z) \cdot mz oraz S(z)⋅zk=T(z)⋅C(z) S(z) \cdot z^k = T(z) \cdot C(z) co daje nam S(z)=C(z)zk+(1−mz)⋅C(z) S(z) = \frac{C(z)}{z^k + (1 - mz) \cdot C(z)}