"Abschlusseigenschaften sind ein weiteres nützliches Werkzeug um verschiedene Sprachklassen zu charakterisieren.\n",
"Damit kann man untersuchen, ob eine Sprache zu einer Sprachklasse gehört oder nicht.\n",
"\n",
"Die regulären Sprachen sind abgeschlossen unter:\n",
"* Vereinigung A ∪ B\n",
"* Komplement A̅\n",
"* Schnitt A ∩ B\n",
"* Differenz A/B\n",
"* Konkatenation AB\n",
"* Iteration A*\n",
"* Spiegelung sp(A)\n",
"\n",
"In den Folien wird diese Aussage zwar aufgestellt, aber nicht bewiesen.\n",
"Hier schauen wir uns für einige Operationen Beweisideen an konkreten Beispielen an."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Zuerst betrachten wir die Vereinigung.\n",
"\n",
"Zu jeder regulären Sprache kann man auch einen NFA angeben.\n",
"Wenn $M_1=(Σ, Z1, δ1, S1, F1)$ und $M_2=(Σ, Z2, δ2, S2, F2)$ zwei NFAs sind, dann lässt sich ein Vereinigungs-NFA $M=(Σ, Z1 ∪ Z2, δ1∪δ2, S1∪S2, F1∪F2)$ erstellen, so dass $L(M) = L(M_1) ∪ L(M_2)$. Man erhält M, indem man alle Mengen der Tupel von $M_1$ und $M_2$ paarweise vereinigt (analog zum Beweis des Satzes von Kleene Folie 52)."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Loaded machine: NFA"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"::load\n",
"MACHINE NFA\n",
"SETS\n",
" Z = {z10,z11,z12,z13, z20,z21,z22}\n",
"CONSTANTS Σ, M, S, F, δ,\n",
" M1, Z1, δ1, S1, F1,\n",
" M2, Z2, δ2, S2, F2\n",
" \n",
"PROPERTIES\n",
" Σ = {0,1} ∧\n",
" Z1 ∩ Z2 = ∅\n",
" ∧\n",
" // Der Automat M1 von Folie 21 (L(M1)={u1v|u∈{0,1}* ∧ v∈{0,1}}):\n",
" M1=(Σ, Z1, δ1, S1, F1) ∧\n",
" Z1 ⊆ Z ∧ \n",
" F1 ⊆ Z1 ∧ S1 ⊆ Z1 ∧\n",
" δ1 ∈ (Z1×Σ) → ℙ(Z1)\n",
" ∧\n",
" Z1 = {z10,z11,z12,z13} ∧\n",
" S1 = {z10} ∧ F1 = {z12} ∧\n",
" δ1 = { (z10,0)↦{z10}, (z10,1)↦{z10,z11},\n",
" (z11,0)↦{z12}, (z11,1)↦{z12},\n",
" (z12,0)↦{z13}, (z12,1)↦{z13},\n",
" (z13,0)↦{z13}, (z13,1)↦{z13} }\n",
" \n",
" ∧\n",
" // Der Automat M2 von Folie 28 (L(M2)={u1|u∈{0,1}*}):\n",
"Eine weitere Eigenschaft, die man leicht zeigen kann ist, dass das Komplement einer Sprache $L$ regulär ist. Sei $M=(Σ, Z, δ, z0, F)$ ein DFA mit $L(M)=L$. Dann gilt für $M'=(Σ, Z, δ, z0, Z/F)$, dass $L(M')= \\overline{L}$. Dies kann man auch mit folgender Machiene darstellen:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Loaded machine: DFA"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"::load\n",
"MACHINE DFA\n",
"SETS\n",
" Z = {z0,z1,z2,z3}\n",
"CONSTANTS Σ, M, δ, F, M2, z_start\n",
"PROPERTIES\n",
" M = (Σ, Z, δ, z_start, F) ∧\n",
" M2 = (Σ, Z, δ, z_start, Z\\F) ∧\n",
" z_start ∈ Z ∧\n",
" F ⊆ Z ∧\n",
" δ ∈ (Z×Σ) → Z ∧\n",
" Σ = {0,1}\n",
"DEFINITIONS // Für den Zustandsgraphen:\n",
" CUSTOM_GRAPH_NODES1 == rec(shape:\"doublecircle\",nodes:Z\\F); // Endzustände von M2\n",
" CUSTOM_GRAPH_NODES2 == rec(shape:\"circle\",nodes:F); // andere Zustände von M2\n",
" CUSTOM_GRAPH_EDGES3 == rec(color:\"black\",label:\"\",edges:{\"\" |-> z_start}) // Kante für den Startknoten\n",
"END"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Diese Maschiene hat die feste Zustandsmenge Z={z0,z1,z2,z3} und das Alphabet Σ = {0,1}, aber die restlichen Elemente werden der Anweisung ```:constants``` übergeben. Somit kann das Komplement eines beliebigen DFAs erzeugt werden."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Machine constants set up using operation 0: $setup_constants()"
"Im folgenden schauen wir uns die Differenz zweier Sprachen L1-L2 genauer an.\n",
"Das Vorgehen ist hierbei, dass man zwei NFAs parallel ausführt und die Endzustandsmenge so wählt, dass man in einem Endzustand des ersten, aber nicht des zweiten NFAs landet."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Loaded machine: NFA"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"::load\n",
"MACHINE NFA\n",
"SETS\n",
" Z = {z10,z11, z12, z20,z21,z22}\n",
"CONSTANTS Σ, Z_gesamt, S, F, δ, f,\n",
" Z1, S1, F1, δ1,\n",
" Z2, S2, F2, δ2\n",
" \n",
"PROPERTIES\n",
" Σ = {0,1}\n",
" \n",
" ∧\n",
" \n",
" Z1 ⊆ Z ∧ Z1 = {z10,z11,z12} ∧\n",
" F1 ⊆ Z1 ∧ S1 ⊆ Z1 ∧\n",
" δ1 ∈ (Z1×Σ) → ℙ(Z1)\n",
" ∧\n",
" // Der Automat M1 (L(M1)={w| |w|=0 ∨ w=u0 mit u∈{0,1}*}):\n",
"Indem man die Endzustände so wählt, dass man in einem Enzustand beider NFAs landet, kann man auch zeigen, dass der Schnitt zweier regulärer Sprachen regulär ist."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Loaded machine: NFA"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"::load\n",
"MACHINE NFA\n",
"SETS\n",
" Z = {z10,z11, z12, z20,z21,z22}\n",
"CONSTANTS Σ, Z_gesamt, S, F, δ, f,\n",
" Z1, S1, F1, δ1,\n",
" Z2, S2, F2, δ2\n",
" \n",
"PROPERTIES\n",
" Σ = {0,1}\n",
" \n",
" ∧\n",
" \n",
" Z1 ⊆ Z ∧ Z1 = {z10,z11,z12} ∧\n",
" F1 ⊆ Z1 ∧ S1 ⊆ Z1 ∧\n",
" δ1 ∈ (Z1×Σ) → ℙ(Z1)\n",
" ∧\n",
" // Der Automat M1 (L(M1)={w| |w|=0 ∨ w=u0 mit u∈{0,1}*}):\n",
" S1 = {z10} ∧ F1 = {z10, z12} ∧\n",
" δ1 = { (z10,0)↦{z12}, (z10,1)↦{z11},\n",
" (z11,0)↦{z12}, (z11,1)↦{z11},\n",
" (z12,0)↦{z12}, (z12,1)↦{z11}} ∧\n",
" \n",
" \n",
" Z2 ⊆ Z ∧ Z2 = {z20,z21,z22} ∧\n",
" F2 ⊆ Z2 ∧ S2 ⊆ Z2 ∧\n",
" δ2 ∈ (Z2×Σ) → ℙ(Z2)\n",
" ∧\n",
" // Der Automat M2 (L(M2)={1^n|n∈ℕ_0}):\n",
" S2 = {z20, z21} ∧ F2 = {z20, z21} ∧\n",
" δ2 = { (z20,0)↦{z22}, (z20,1)↦{z21},\n",
" (z21,0)↦{z22}, (z21,1)↦{z21},\n",
" (z22,0)↦{z22}, (z22,1)↦{z22}} ∧\n",
"\n",
" //Konstruktion analog zu TODO Referenz auf Buch\n",
Abschlusseigenschaften sind ein weiteres nützliches Werkzeug um verschiedene Sprachklassen zu charakterisieren.
Damit kann man untersuchen, ob eine Sprache zu einer Sprachklasse gehört oder nicht.
Die regulären Sprachen sind abgeschlossen unter:
* Vereinigung A ∪ B
* Komplement A̅
* Schnitt A ∩ B
* Differenz A/B
* Konkatenation AB
* Iteration A*
* Spiegelung sp(A)
In den Folien wird diese Aussage zwar aufgestellt, aber nicht bewiesen.
Hier schauen wir uns für einige Operationen Beweisideen an konkreten Beispielen an.
%% Cell type:markdown id: tags:
Zuerst betrachten wir die Vereinigung.
Zu jeder regulären Sprache kann man auch einen NFA angeben.
Wenn $M_1=(Σ, Z1, δ1, S1, F1)$ und $M_2=(Σ, Z2, δ2, S2, F2)$ zwei NFAs sind, dann lässt sich ein Vereinigungs-NFA $M=(Σ, Z1 ∪ Z2, δ1∪δ2, S1∪S2, F1∪F2)$ erstellen, so dass $L(M) = L(M_1) ∪ L(M_2)$. Man erhält M, indem man alle Mengen der Tupel von $M_1$ und $M_2$ paarweise vereinigt (analog zum Beweis des Satzes von Kleene Folie 52).
%% Cell type:code id: tags:
``` prob
::load
MACHINE NFA
SETS
Z = {z10,z11,z12,z13, z20,z21,z22}
CONSTANTS Σ, M, S, F, δ,
M1, Z1, δ1, S1, F1,
M2, Z2, δ2, S2, F2
PROPERTIES
Σ = {0,1} ∧
Z1 ∩ Z2 = ∅
∧
// Der Automat M1 von Folie 21 (L(M1)={u1v|u∈{0,1}* ∧ v∈{0,1}}):
M1=(Σ, Z1, δ1, S1, F1) ∧
Z1 ⊆ Z ∧
F1 ⊆ Z1 ∧ S1 ⊆ Z1 ∧
δ1 ∈ (Z1×Σ) → ℙ(Z1)
∧
Z1 = {z10,z11,z12,z13} ∧
S1 = {z10} ∧ F1 = {z12} ∧
δ1 = { (z10,0)↦{z10}, (z10,1)↦{z10,z11},
(z11,0)↦{z12}, (z11,1)↦{z12},
(z12,0)↦{z13}, (z12,1)↦{z13},
(z13,0)↦{z13}, (z13,1)↦{z13} }
∧
// Der Automat M2 von Folie 28 (L(M2)={u1|u∈{0,1}*}):
CUSTOM_GRAPH_EDGES4 == rec(color:"black",label:"",edges:{""}*S) // Kanten für Startknoten
END
```
%% Output
Loaded machine: NFA
%% Cell type:code id: tags:
``` prob
:constants
```
%% Output
Machine constants set up using operation 0: $setup_constants()
%% Cell type:code id: tags:
``` prob
:dot custom_graph
```
%% Output
<Dot visualization: custom_graph []>
%% Cell type:markdown id: tags:
Eine weitere Eigenschaft, die man leicht zeigen kann ist, dass das Komplement einer Sprache $L$ regulär ist. Sei $M=(Σ, Z, δ, z0, F)$ ein DFA mit $L(M)=L$. Dann gilt für $M'=(Σ, Z, δ, z0, Z/F)$, dass $L(M')= \overline{L}$. Dies kann man auch mit folgender Machiene darstellen:
%% Cell type:code id: tags:
``` prob
::load
MACHINE DFA
SETS
Z = {z0,z1,z2,z3}
CONSTANTS Σ, M, δ, F, M2, z_start
PROPERTIES
M = (Σ, Z, δ, z_start, F) ∧
M2 = (Σ, Z, δ, z_start, Z\F) ∧
z_start ∈ Z ∧
F ⊆ Z ∧
δ ∈ (Z×Σ) → Z ∧
Σ = {0,1}
DEFINITIONS // Für den Zustandsgraphen:
CUSTOM_GRAPH_NODES1 == rec(shape:"doublecircle",nodes:Z\F); // Endzustände von M2
CUSTOM_GRAPH_NODES2 == rec(shape:"circle",nodes:F); // andere Zustände von M2
CUSTOM_GRAPH_EDGES3 == rec(color:"black",label:"",edges:{"" |-> z_start}) // Kante für den Startknoten
END
```
%% Output
Loaded machine: DFA
%% Cell type:markdown id: tags:
Diese Maschiene hat die feste Zustandsmenge Z={z0,z1,z2,z3} und das Alphabet Σ = {0,1}, aber die restlichen Elemente werden der Anweisung ```:constants``` übergeben. Somit kann das Komplement eines beliebigen DFAs erzeugt werden.
%% Cell type:code id: tags:
``` prob
:constants M=({0,1}, //Σ
{z0,z1,z2,z3}, //Z
{(z0,0)↦z1, (z0,1)↦z3,
(z1,0)↦z3, (z1,1)↦z2,
(z2,0)↦z2, (z2,1)↦z2,
(z3,0)↦z3, (z3,1)↦z3 }, //δ
z0, {z0, z2}) //z0, F
```
%% Output
Machine constants set up using operation 0: $setup_constants()
%% Cell type:code id: tags:
``` prob
:dot custom_graph
```
%% Output
<Dot visualization: custom_graph []>
%% Cell type:markdown id: tags:
Als nächstes befassen wir uns mit der Konkatenation zweier Sprachen. Um dies zu erreichen schaltet man 2 NFAs hintereinander.
%% Cell type:code id: tags:
``` prob
::load
MACHINE NFA
SETS
Z = {z10,z11, z12, z20,z21,z22}
CONSTANTS Σ, S, F, δ,
Z1, S1, F1, δ1,
Z2, S2, F2, δ2
PROPERTIES
Σ = {0,1}
∧
Z1 ⊆ Z ∧ Z1 = {z10,z11,z12} ∧
F1 ⊆ Z1 ∧ S1 ⊆ Z1 ∧
δ1 ∈ (Z1×Σ) → ℙ(Z1)
∧
// Der Automat M1 (L(M1)={w| |w|=0 ∨ w=u0 mit u∈{0,1}*}):
CUSTOM_GRAPH_EDGES4 == rec(color:"black",label:"",edges:{""}*S2) // Kanten für Startknoten
END
```
%% Output
Loaded machine: NFA
%% Cell type:code id: tags:
``` prob
:constants
```
%% Output
Machine constants set up using operation 0: $setup_constants()
%% Cell type:code id: tags:
``` prob
:dot custom_graph
```
%% Output
<Dot visualization: custom_graph []>
%% Cell type:markdown id: tags:
Im folgenden schauen wir uns die Differenz zweier Sprachen L1-L2 genauer an.
Das Vorgehen ist hierbei, dass man zwei NFAs parallel ausführt und die Endzustandsmenge so wählt, dass man in einem Endzustand des ersten, aber nicht des zweiten NFAs landet.
%% Cell type:code id: tags:
``` prob
::load
MACHINE NFA
SETS
Z = {z10,z11, z12, z20,z21,z22}
CONSTANTS Σ, Z_gesamt, S, F, δ, f,
Z1, S1, F1, δ1,
Z2, S2, F2, δ2
PROPERTIES
Σ = {0,1}
∧
Z1 ⊆ Z ∧ Z1 = {z10,z11,z12} ∧
F1 ⊆ Z1 ∧ S1 ⊆ Z1 ∧
δ1 ∈ (Z1×Σ) → ℙ(Z1)
∧
// Der Automat M1 (L(M1)={w| |w|=0 ∨ w=u0 mit u∈{0,1}*}):
Machine constants set up using operation 0: $setup_constants()
%% Cell type:code id: tags:
``` prob
:init
```
%% Output
Machine initialised using operation 1: $initialise_machine()
%% Cell type:code id: tags:
``` prob
:show
```
%% Output
<table style="font-family:monospace"><tbody>
<tr>
<td style="padding:10px">Zustand</td>
<td style="padding:10px">δ(Zustand,0)</td>
<td style="padding:10px">δ(Zustand,1)</td>
</tr>
<tr>
<td style="padding:10px">(z10|->z20)</td>
<td style="padding:10px">{(z12|->z22)}</td>
<td style="padding:10px">{(z11|->z21)}</td>
</tr>
<tr>
<td style="padding:10px">(z10|->z21)</td>
<td style="padding:10px">{(z12|->z22)}</td>
<td style="padding:10px">{(z11|->z21)}</td>
</tr>
<tr>
<td style="padding:10px">(z10|->z22)</td>
<td style="padding:10px">{(z12|->z22)}</td>
<td style="padding:10px">{(z11|->z22)}</td>
</tr>
<tr>
<td style="padding:10px">(z11|->z20)</td>
<td style="padding:10px">{(z12|->z22)}</td>
<td style="padding:10px">{(z11|->z21)}</td>
</tr>
<tr>
<td style="padding:10px">(z11|->z21)</td>
<td style="padding:10px">{(z12|->z22)}</td>
<td style="padding:10px">{(z11|->z21)}</td>
</tr>
<tr>
<td style="padding:10px">(z11|->z22)</td>
<td style="padding:10px">{(z12|->z22)}</td>
<td style="padding:10px">{(z11|->z22)}</td>
</tr>
<tr>
<td style="padding:10px">(z12|->z20)</td>
<td style="padding:10px">{(z12|->z22)}</td>
<td style="padding:10px">{(z11|->z21)}</td>
</tr>
<tr>
<td style="padding:10px">(z12|->z21)</td>
<td style="padding:10px">{(z12|->z22)}</td>
<td style="padding:10px">{(z11|->z21)}</td>
</tr>
<tr>
<td style="padding:10px">(z12|->z22)</td>
<td style="padding:10px">{(z12|->z22)}</td>
<td style="padding:10px">{(z11|->z22)}</td>
</tr>
</tbody></table>
<Animation function visualisation>
%% Cell type:markdown id: tags:
Indem man die Endzustände so wählt, dass man in einem Enzustand beider NFAs landet, kann man auch zeigen, dass der Schnitt zweier regulärer Sprachen regulär ist.
%% Cell type:code id: tags:
``` prob
::load
MACHINE NFA
SETS
Z = {z10,z11, z12, z20,z21,z22}
CONSTANTS Σ, Z_gesamt, S, F, δ, f,
Z1, S1, F1, δ1,
Z2, S2, F2, δ2
PROPERTIES
Σ = {0,1}
∧
Z1 ⊆ Z ∧ Z1 = {z10,z11,z12} ∧
F1 ⊆ Z1 ∧ S1 ⊆ Z1 ∧
δ1 ∈ (Z1×Σ) → ℙ(Z1)
∧
// Der Automat M1 (L(M1)={w| |w|=0 ∨ w=u0 mit u∈{0,1}*}):