Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
automaty
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Package registry
Model registry
Operate
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Martin Mareš
automaty
Commits
371cc229
Commit
371cc229
authored
1 year ago
by
Martin Mareš
Browse files
Options
Downloads
Patches
Plain Diff
Přepsán důkaz věty o obousměrných automatech
Takhle postupuje mnohem intuitivněji zleva doprava.
parent
be0a54dd
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
03-recursive/recursive.tex
+57
-56
57 additions, 56 deletions
03-recursive/recursive.tex
with
57 additions
and
56 deletions
03-recursive/recursive.tex
+
57
−
56
View file @
371cc229
...
...
@@ -906,87 +906,88 @@ Nyní dokážeme, že to vyjde nastejno -- každý jazyk přijímaný obousměrn
\proof
Připomeňme definici TFA: je to Turingův stroj, který dostane vstup
$
\|
<|
\alpha\|
>|
$
a nemá ho povoleno měnit. Navíc na levé zarážce~
$
\|
<|
$
nesmí vykonat pohyb doleva
a na pravé zarážce~
$
\|
>|
$
nesmí jít doprava. Aby byl TFA podobnější konečným automatům,
výpočet začíná s~hlavou na prvním znaku slova~
$
\alpha
$
. To je ale detail: TFA můžeme snadno upravit,
aby výpočet začínal na~
$
\|
<|
$
-- stačí přidat nový počáteční stav, v~němž provedeme jeden pohyb
hlavou doprava a přejdeme do původního počátečního stavu.
a na pravé zarážce~
$
\|
>|
$
nesmí jít doprava.
Každý regulární jazyk je určitě přijímán nějakým TFA, který vznikne přímočarým
překladem příslušného DFA. Opačná implikace je méně triviální.
Uvažme TFA rozpoznávající nějaký jazyk~
$
L
$
a jeho výpočet nad nějakým vstupem~
$
\alpha
$
délky~
$
n
$
. Do vstupu ještě doplníme zarážky
$
\alpha
[-
1
]
=
\|
<|
$
a
$
\alpha
[
n
]
=
\|
>|
$
.
Potřebujeme se nějak vyrovnat s~tím, že automat se může během výpočtu na jedno
políčko vracet opakovaně. Představme si, že se díváme dovnitř výpočtu, hlava zrovna stojí
na
$
i
$
-tém políčku slova~
$
\alpha
$
, stroj se právě přepíná ze stavu~
$
s
$
do~
$
s'
$
a chystá se
odejít doprava do nějakého suffixu
$
\alpha
[
i
+
1
:
{}
]
$
.
Jak bude výpočet pokračovat? Jedna možnost je, že se stroj po čase vrátí zprava na
$
i
$
-té políčko v~nějakém novém stavu,
přičemž nic kromě stavu stroje se nezměnilo (na pásku nemůžeme zapisovat).
Nebo se předtím stroj stihl zastavit a přijmout/odmítnout.
Případně se stroj zacyklil v~nekonečné smyčce, což rovněž odpovídá odmítnutí vstupu.
Z~této úvahy plyne, že kdybychom znali chování stroje na suffixu
$
\alpha
[
i
+
1
:
{}
]
$
(jakému vstupnímu stavu odpovídá jaký výstupní), mohli bychom pomocí něj určit,
co bude stroj dělat na políčku~
$
\alpha
[
i
]
$
, aniž bychom se dívali na následující
znaky. Z~toho bychom mohli určit chování na suffixu
$
\alpha
[
i:
{}
]
$
a tak dále.
Zkusme to provést.
Chování stroje na suffixu vstupu
$
\alpha
[
i:
{}
]
$
popíšeme nějakou funkcí~
$
f
_
i
(
s
)
$
.
Ta dostane počáteční stav~
$
s
\in
Q
\setminus\{
q
_
+
, q
_
-
\}
$
, v~němž stroj vstoupí
na
$
\alpha
[
i
]
$
. Výsledkem funkce je koncový stav~
$
s'
\in
Q
$
, v~němž stroj odchází
ze suffixu doleva. Pokud je
$
s'
=
q
_
+
$
, stroj se místo odejití doleva zastavil a přijal.
Pokud
$
s'
=
q
_
-
$
, stroj odmítl zastavením nebo zacyklením se.
Ukážeme, jak sestrojit funkci~
$
f
_
i
$
, pokud už známe~
$
f
_{
i
+
1
}$
.
Chceme-li stanovit
$
f
(
s
)
$
, budeme konstruovat posloupnost stavů
$
s
_
0
$
,
$
s
_
1
$
,
$
s
_
2
$
,
\dots
{}
Představme si výpočet obousměrného automatu, který právě navštívil znak~
$
\alpha
[
i
]
$
.
Pokud se automat pohne doprava, můžeme tento krok provést i~konečným automatem.
Pokud vyčkává na místě, jenom mění stavy, takže DFA může celou posloupnost změn provést
najednou.
Problém nastane, pokud se TFA pohybem doleva vrátí do prefixu
$
\alpha
[
{}
:i
]
$
,
který už jednou zpracoval. Uvnitř prefixu se může libovolně dlouho toulat, než nastane
jedna ze tří možností: buď prefix opustí doprava v~nějakém novém stavu a~je opět
na znaku~
$
\alpha
[
i
]
$
. Anebo se zastaví ve stavu
$
q
_
+
$
či~
$
q
_
-
$
, případně se zacyklí
(tím také odmítne vstup, takže je to ekvivalentní se zastavením v~
$
q
_
-
$
).
Jelikož TFA nemůže měnit obsah pásky, můžeme jeho chování v~prefixu
$
\alpha
[
{}
:i
]
$
jednoznačně popsat nějakou funkcí
$
f
_
i: Q
\setminus\{
q
_
+
, q
_
-
\}
\rightarrow
Q
$
.
Ta jako argument dostane stav~
$
s
$
, ve kterém stroj začíná na posledním znaku prefixu, tedy
$
\alpha
[
i
-
1
]
$
. Výsledkem funkce je stav~
$
s'
$
, v~němž stroj prefix opustí pohybem vpravo.
Pokud je
$
s'
=
q
_
+
$
, stroj z~prefixu neodešel, nýbrž se zastavil a přijal.
Je-li
$
s'
=
q
_
-
$
, stroj odmítl zastavením nebo zacyklením se.
Budeme se snažit sestrojit DFA, který si bude ve stavu udržovat chování prefixu~
$
f
_
i
$
nalevo od aktuální pozice.
Začněme tou nejzajímavější částí: konstrukcí~
$
f
_{
i
+
1
}$
z~
$
f
_
i
$
.
Nechť chceme spočítat
$
f
_{
i
+
1
}
(
s
)
$
. TFA tedy stojí na políčku
$
\alpha
[
i
]
$
ve stavu~
$
s
$
.
Jelikož se na toto políčko může vracet, budeme konstruovat posloupnost stavů
$
s
_
0
$
,
$
s
_
1
$
,
$
s
_
2
$
,
\dots
{}
při jednotlivých návštěvách políčka
$
\alpha
[
i
]
$
.
Na počátku položíme
$
s
_
0
=
s
$
.
Nyní budeme z~libovolného~
$
s
_
j
$
počítat
$
s
_{
j
+
1
}$
.
Podíváme se, co stroj provede, přečte-li ve stavu~
$
s
_
j
$
znak~
$
\alpha
[
i
]
$
.
Vyhodno
tíme tedy
přechodov
ou
funkc
i
$
\delta
(
s
_
j,
\alpha
[
i
])
$
, čímž
získáme instrukci, která
Vyhodno
cením
přechodov
é
funkc
e
$
\delta
(
s
_
j,
\alpha
[
i
])
$
získáme instrukci, která
přechází do nějakého stavu~
$
s'
_
j
$
, zapisuje nezměněný znak~
$
\alpha
[
i
]
$
a možná pohybuje hlavou:
\list
{
o
}
\:
Pokud hlava odchází do
le
va, položíme
$
f
_
i
(
s
)
=
s'
_
j
$
a jsme hotovi.
\:
Pokud hlava odchází do
pra
va, položíme
$
f
_
{
i
+
1
}
(
s
)
=
s'
_
j
$
a jsme hotovi.
\:
Pokud hlava zůstává na místě, položíme
$
s
_{
j
+
1
}
=
s'
_
j
$
a pokračujeme ve vytváření posloupnosti
s~několika výjimkami: Je-li
$
s'
_
j
$
rovno
$
q
_
+
$
nebo~
$
q
_
-
$
, položíme
$
f
_
i
(
s
)
=
s'
_
j
$
a skončíme.
s~několika výjimkami: Je-li
$
s'
_
j
$
rovno
$
q
_
+
$
nebo~
$
q
_
-
$
, položíme
$
f
_
{
i
+
1
}
(
s
)
=
s'
_
j
$
a skončíme.
Je-li
$
s'
_
j
$
rovno některému z~předešlých~
$
s
_
k
$
pro
$
k
\le
j
$
, stroj se zacyklil, takže položíme
$
f
_
i
(
s
)
=
q
_
-
$
a skončíme.
\:
Pokud hlava odchází do
pra
va, využijeme známou funkci
$
f
_
{
i
+
1
}
$
popisující chování na
suf
fixu
$
\alpha
[
i
+
1
:
{}
]
$
, takže
polož
íme
$
s
_{
j
+
1
}
=
f
_
{
i
+
1
}
(
s'
_
j
)
$
. Opět ošetříme případy, kdy je tento
$
f
_
{
i
+
1
}
(
s
)
=
q
_
-
$
a skončíme.
\:
Pokud hlava odchází do
le
va, využijeme známou funkci
$
f
_
i
$
popisující chování na
pre
fixu
$
\alpha
[
{}
:i
-
1
]
$
. Stačí
polož
it
$
s
_{
j
+
1
}
=
f
_
i
(
s'
_
j
)
$
. Opět ošetříme případy, kdy je tento
stav roven
$
q
_
+
$
,
$
q
_
-
$
, případně některému z~předchozích stavů v~posloupnosti.
\endlist
Všimněte si, že funkce~
$
f
_
i
$
je jednoznačně určena funkcí~
$
f
_{
i
+
1
}$
a znakem
$
\alpha
[
i
]
$
.
To nám dává návod na sestrojení konečného automatu, který bude procházet vstupem zprava doleva
a postupně přepočítávat funkci~
$
f
_
i
$
. Stavy automatu odpovídají všem funkcím z~
$
Q
\setminus\{
q
_
+
,q
_
-
\}
$
do~
$
Q
$
,
takže jich je konečně mnoho.
Všimněme si, že funkce~
$
f
_{
i
+
1
}$
je jednoznačně určena funkcí~
$
f
_
i
$
a znakem
$
\alpha
[
i
]
$
.
Můžeme tedy sestrojit konečný automat, který bude procházet vstupem zprava doleva
a postupně přepočítávat funkci~
$
f
_
i
$
. Stavy automatu odpovídají všem funkcím z~
$
Q
\setminus\{
q
_
+
,q
_
-
\}
$
do~
$
Q
$
a~těch je konečně mnoho. Přechody jsou dány konstrukcí~
$
f
_{
i
+
1
}$
z~
$
f
_
i
$
.
Po zpracování znaku
$
\alpha
[
i
]
$
se tedy automat nachází ve stavu~
$
f
_{
i
+
1
}$
.
Zbývá dořešit, jak automat začne a jak skončí.
Ještě je potřeba domyslet, jak automat začne.
Zkusme použít naši konstrukci pro funkci~
$
f
_
0
$
-- chování TFA na prázdném prefixu.
Hlava TFA tedy stojí na levé zarážce~
$
\|
<|
$
, odkud se nesmí pohnout doleva.
Konstrukce se proto nikdy nezeptá na neexistující~
$
f
_{
-
1
}$
.
Funkce~
$
f
_
0
$
je tudíž nezávislá na vstupu a může posloužit jako počáteční stav automatu.
Použijeme-li naši konstrukci pro funkci~
$
f
_
n
$
, tedy chování výpočtu na pravé zarážce~
\|
>|,
nikdy se nezeptá na neexistující~
$
f
_{
n
+
1
}$
. To proto, že stroj se na pravé zarážce nemůže
pohybovat doprava. Funkce~
$
f
_
n
$
je tedy nezávislá na vstupu, takže může posloužit jako
počáteční stav automatu.
Máme tedy automat, který po přečtení vstupu
$
\alpha\|
>|
$
zná funkci~
$
f
_{
n
+
1
}$
--
chování na celém vstupu, stojíme-li na pravé zarážce~
$
\|
>|
$
.
Až automat přečte levou zarážku~
$
\|
<|
$
, bude jeho stav roven funkci~
$
f
_{
-
1
}$
.
Ta popisuje chování na celém vstupu. Takže do ní chceme dosadit počáteční stav~
$
q
_
0
$
původního TFA.
Je-li
$
f
_{
-
1
}
(
q
_
0
)
$
rovno~
$
q
_
+
$
, vstup přijmeme.
Pokud je rovno~
$
q
_
-
$
, tak odmítneme.
Nic jiného nemůže funkce vrátit, protože by to znamenalo, že automat z~
\|
<| odešel doleva, a~to nesmí.
Přijímací stavy tedy odpovídají těm funkcím~
$
f
$
, pro něž je
$
f
(
q
_
0
)=
q
_
+
$
.
Teď se nabízí do této funkce dosadit počáteční stav TFA~
$
q
_
0
$
, a~tím zjistit,
jaký výsledek TFA vydá. To ale nemůžeme provést: hlava TFA začíná na levém
okraji vstupu, nikoliv na~
$
\|
>|
$
. Pomoc je naštěstí snadná: TFA upravíme, aby
začínal na~
$
\|
>|
$
v~nějakém novém stavu~
$
q'
_
0
$
. V~něm půjde doleva, dokud nenarazí
na~
$
\|
<|
$
, načež udělá krok doprava a přepne se do původního počátečního stavu~
$
q
_
0
$
.
Tím jsme sestrojili automat dosvědčující regularitu. Ovšem ne původního jazyka~
$
L
$
,
nýbrž jazyka
$
L'
=
L
\rev\cdot\{\|
<|
\}
$
, v~němž jsou slova pozpátku a ukončená zarážkou.
Je-li tedy
$
f
_{
n
+
1
}
(
q'
_
0
)
$
rovno~
$
q
_
+
$
, TFA vstup přijal, takže DFA přijme také.
Podobně je-li rovno~
$
q
_
-
$
, tak odmítne.
Nic jiného nemůže funkce vrátit, protože by to znamenalo, že automat z~
\|
>| odešel doprava, a~to nesmí.
Přijímací stavy tedy odpovídají těm funkcím~
$
f
$
, pro něž je
$
f
(
q'
_
0
)=
q
_
+
$
.
Teď si stačí uvědomit, že z~regularity~
$
L'
$
plyne regularita~
$
L
\rev
$
a z~ní zase regularita~
$
L
$
.
Regularitu
$
L
\rev
$
můžeme zdůvodnit cvičením
\exref
{
quotex
}
, protože
$
L
\rev
$
je kvocient
$
L'
/
\{\|
<|
\}
$
.
Tím jsme sestrojili automat dosvědčující regularitu. Ovšem ne původního jazyka~
$
L
$
,
nýbrž jazyka
$
L'
=
L
\cdot\{\|
>|
\}
$
, v~němž jsou slova ukončená zarážkou.
Uvědomíme si, že z~regularity~
$
L'
$
plyne regularita~
$
L
$
.
To můžeme zdůvodnit cvičením
\exref
{
quotex
}
, protože
$
L
$
je kvocient
$
L'
/
\{\|
>|
\}
$
.
Nebo to lze provést přímo úpravou koncových stavů: za koncové prohlásíme ty stavy, z~nichž vede přechod
před znak~
$
\|
<|
$
do některého z~původních koncových stavů.
Regularitu~
$
L
$
dostaneme z~uzavřenosti regulárních jazyků na otočení (cvičení
\exref
{
regrev
}
).
před znak~
$
\|
>|
$
do některého z~původních koncových stavů.
\qed
\exercises
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment