លក្ខណៈសម្បត្តិនៃការដោះស្រាយនៃភាសាធម្មតា។ កន្សោមធម្មតាពីខាងក្នុង

ត្រូវការដោយម៉ាស៊ីនរដ្ឋមិនកំណត់ = (សំណួរ, , , q 0 , ) បង្កើតម៉ាស៊ីនកំណត់ស្ថានភាពកំណត់ = (សំណួរ", , ឃ", q" 0 , F") ស្ថានភាពដំបូងសម្រាប់ automaton ដែលកំពុងសាងសង់គឺជាការបិទε-បិទនៃស្ថានភាពដំបូងនៃ automaton ដំបូង។ ε-បិទ - សំណុំនៃរដ្ឋដែលអាចទៅដល់ពីមួយដែលបានផ្តល់ឱ្យដោយការផ្លាស់ប្តូរតាមបណ្តោយε។ លើសពីនេះទៀតខណៈពេលដែលមានរដ្ឋដែលការផ្លាស់ប្តូរមិនត្រូវបានសាងសង់ (ការផ្លាស់ប្តូរត្រូវបានធ្វើឡើងដោយនិមិត្តសញ្ញាការផ្លាស់ប្តូរដែលតាមរយៈនោះមាននៅក្នុង automaton ដើម) សម្រាប់និមិត្តសញ្ញានីមួយៗ ε-បិទនៃសំណុំរដ្ឋដែលអាចទៅដល់បានពីរដ្ឋក្រោម ការពិចារណាដោយការផ្លាស់ប្តូរតាមរយៈនិមិត្តសញ្ញាដែលបានពិចារណាត្រូវបានគណនា។ ប្រសិនបើស្ថានភាពដែលត្រូវគ្នានឹងសំណុំដែលបានរកឃើញមានរួចហើយ នោះការផ្លាស់ប្តូរត្រូវបានបន្ថែមនៅទីនោះ។ ប្រសិនបើមិនមានទេ រដ្ឋដែលទទួលបានថ្មីត្រូវបានបន្ថែម។

ឧទាហរណ៍

ការចាប់ផ្តើម

រដ្ឋដែលត្រូវគ្នានឹងε-បិទនៃរដ្ឋដំបូងត្រូវបានសម្គាល់។ រដ្ឋទាំងនេះនឹងត្រូវគ្នាទៅនឹងរដ្ឋ DKA នាពេលអនាគត។


ការធ្វើម្តងទៀតជាលើកដំបូង

មានការផ្លាស់ប្តូរពីការបិទεទៅរដ្ឋ NCA 3 និង 10 (យោងទៅតាម និង រៀងៗខ្លួន)។ សម្រាប់រដ្ឋ 3 ការបិទ ε គឺជាសំណុំនៃរដ្ឋ (3, 4, 6) សម្រាប់រដ្ឋ 10 - (10) ។ អនុញ្ញាតឱ្យយើងកំណត់រដ្ឋ DFA ថ្មីដែលត្រូវនឹងសំណុំទាំងនេះជា និង .

រដ្ឋ DKAសំណុំនៃរដ្ឋ NFA
{1, 2, 9} -
{3, 4, 6} - - -
{10} - - -


ការធ្វើម្តងទៀតទីពីរ

ពីសំណុំនៃរដ្ឋនៃ NFA (3, 4, 6) ដែលត្រូវគ្នាទៅនឹងស្ថានភាពនៃ DFA មានការផ្លាស់ប្តូរពីរ - ទៅរដ្ឋ 5 (ដោយ ) និង 7 (ដោយ ) ការបិទ ε របស់ពួកគេប្រសព្វគ្នា ប៉ុន្តែសំណុំខ្លួនពួកគេខុសគ្នា ដូច្នេះពួកគេត្រូវបានចាត់តាំងរដ្ឋ DFA ថ្មីពីរ - និង អ៊ី. ពីរដ្ឋនៃ NFA ដែលត្រូវគ្នាទៅនឹងស្ថានភាពនៃ DFA , មិនមានការផ្លាស់ប្តូរទេ។

រដ្ឋ DKAសំណុំនៃរដ្ឋ NFAតួអក្សរដែលអាចលោតបាន។
{1, 2, 9} -
{3, 4, 6} - អ៊ី
{10} - - -
{2, 5, 8, 9} - - -
អ៊ី{2, 7, 8, 9} - - -


ការធ្វើម្តងទៀតទីបី

ពីសំណុំនៃរដ្ឋនៃ NFA ដែលត្រូវគ្នាទៅនឹងរដ្ឋនៃ DFA និង អ៊ីការផ្លាស់ប្តូរត្រូវបានធ្វើឡើងចំពោះសំណុំនៃរដ្ឋដែលត្រូវគ្នានឹងរដ្ឋដែលមានស្រាប់ (ពីសំណុំ (2, 5, 8, 9) ដែលត្រូវគ្នានឹងរដ្ឋ លើ ការផ្លាស់ប្តូរទៅរដ្ឋ 3 ដែលជាកម្មសិទ្ធិរបស់សំណុំ (3, 4, 6) ដែលត្រូវគ្នាទៅនឹងស្ថានភាពនៃ DFA លើ - ការផ្លាស់ប្តូរទៅជារដ្ឋ 10 ដែលត្រូវគ្នានឹងរដ្ឋ ; ដូចគ្នានេះដែរសម្រាប់សំណុំដែលត្រូវគ្នាទៅនឹងស្ថានភាពនៃ DFA អ៊ី) ដំណើរការនៃការសាងសង់តារាងរដ្ឋ និងការផ្លាស់ប្តូរនៃ DFA ត្រូវបានបញ្ចប់។

រដ្ឋ DKAសំណុំនៃរដ្ឋ NFAតួអក្សរដែលអាចលោតបាន។
{1, 2, 9} -
{3, 4, 6} - អ៊ី
{10} - - -
{2, 5, 8, 9} -
អ៊ី{2, 7, 8, 9} -


លទ្ធផល៖

ការកសាងវេយ្យាករណ៍លីនេអ៊ែរស្តាំពី automaton កំណត់

រដ្ឋនីមួយៗត្រូវបានភ្ជាប់ជាមួយ non-terminal ។ ប្រសិនបើមានការផ្លាស់ប្តូររដ្ឋ Xចូលទៅក្នុងរដ្ឋមួយ។ នៅលើ បន្ថែមច្បាប់ Xអាយ. សម្រាប់រដ្ឋចុងក្រោយ បន្ថែមច្បាប់ X→ អ៊ី. សម្រាប់ ε-transitions - X.

ឧទាហរណ៍ទី 1 (ម៉ាស៊ីនកំណត់ស្ថានភាព)

  • ក → ខ |
  • ខ → ឃ | អ៊ី
  • គ → អ៊ី
  • ឃ → ខ |
  • អ៊ី → ខ |

ឧទាហរណ៍ទី 2 (ម៉ាស៊ីនរដ្ឋមិនកំណត់)

  • 1 → 2 | 9
  • 2 → 3
  • 3 → 4 | 6
  • 4 → 5
  • 5 → 8
  • 6 → 7
  • 7 → 8
  • 8 → 2 | 9
  • 9 → 10
  • ១០ → ε

ការសាងសង់ DFA ដោយ RV

ចូរ​បញ្ចេញ​មតិ​ជា​ប្រចាំ r. ដោយផ្អែកលើកន្សោមធម្មតានេះ វាចាំបាច់ក្នុងការបង្កើត automaton finite deterministic បែបនោះ។ អិល() = អិល(r).

ការកែប្រែការបញ្ចេញមតិជាទៀងទាត់

ចូរបន្ថែមនិមិត្តសញ្ញាទៅវាមានន័យថាចុងបញ្ចប់នៃ RV - "#" ។ ជាលទ្ធផល យើងទទួលបានកន្សោមធម្មតា ( r)#.

សាងសង់ដើមឈើ

ចូរយើងស្រមៃមើលកន្សោមធម្មតាជាមែកធាង ស្លឹកដែលជាតួអក្សរស្ថានីយ ហើយថ្នាំងខាងក្នុងគឺជាប្រតិបត្តិការនៃ concatenation ".", union "∪" និង iteration "*" ។ យើងកំណត់លេខតែមួយគត់ទៅស្លឹកនីមួយៗនៃដើមឈើ (លើកលែងតែស្លឹកε) ហើយសំដៅលើវានៅលើដៃម្ខាងជាទីតាំងនៅក្នុងដើមឈើ និងម្យ៉ាងវិញទៀតជាទីតាំងនៃនិមិត្តសញ្ញាដែលត្រូវនឹង ស្លឹក។

ការគណនានៃអនុគមន៍ដែលមិនអាចរាប់បាន, firstpos, lastpos

ឥឡូវនេះដោយឆ្លងកាត់មែកធាង T ពីបាតទៅកំពូលពីឆ្វេងទៅស្តាំយើងគណនាមុខងារបី: ទុកជាមោឃៈ, អត្ថបទដំបូង, និង ចុងក្រោយ. មុខងារ ទុកជាមោឃៈ, អត្ថបទដំបូងនិង ចុងក្រោយកំណត់នៅថ្នាំងនៃដើមឈើ។ តម្លៃនៃមុខងារទាំងអស់លើកលែងតែ ទុកជាមោឃៈ, គឺជាសំណុំនៃមុខតំណែង។ មុខងារ អត្ថបទដំបូង() សម្រាប់ថ្នាំងនីមួយៗនៃមែកធាងវាក្យសម្ព័ន្ធ regex ផ្តល់សំណុំនៃមុខតំណែងដែលត្រូវគ្នានឹងតួអក្សរដំបូងនៅក្នុងខ្សែអក្សររងដែលបង្កើតដោយកន្សោមរងដែលបញ្ចប់នៅ . ដូចគ្នានេះដែរ ចុងក្រោយ() ផ្តល់ឱ្យសំណុំនៃមុខតំណែងដែលត្រូវគ្នាទៅនឹងតួអក្សរចុងក្រោយនៅក្នុងខ្សែអក្សររងដែលបង្កើតដោយកន្សោមរងជាមួយកំពូល . សម្រាប់ថ្នាំង មែកធាងរង (នោះគឺដើមឈើដែលមានថ្នាំង is a root) អាចបង្កើតពាក្យទទេ យើងកំណត់ ទុកជាមោឃៈ() = ពិតនិងសម្រាប់ថ្នាំងផ្សេងទៀត។ មិនពិត. តារាងគណនា ទុកជាមោឃៈ, អត្ថបទដំបូង, ចុងក្រោយ:

knot ទុកជាមោឃៈ() អត្ថបទដំបូង() ចុងក្រោយ()
ε ពិត
ខ្ញុំ ≠ ε មិនពិត {ខ្ញុំ} {ខ្ញុំ}
u ∪ vទុកជាមោឃៈ(យូ) ឬ ទុកជាមោឃៈ(v) អត្ថបទដំបូង(យូ) ∪ អត្ថបទដំបូង(v) ចុងក្រោយ(យូ) ∪ ចុងក្រោយ(v)
យូ. vទុកជាមោឃៈ(យូ) និង ទុកជាមោឃៈ(v) ប្រសិនបើ ទុកជាមោឃៈ(យូ) បន្ទាប់មក អត្ថបទដំបូង(យូ) ∪ អត្ថបទដំបូង(v) ផ្សេងទៀត។ អត្ថបទដំបូង(យូ) ប្រសិនបើ ទុកជាមោឃៈ(v) បន្ទាប់មក ចុងក្រោយ(យូ) ∪ ចុងក្រោយ(v) ផ្សេងទៀត។ ចុងក្រោយ(v)
v*ពិត អត្ថបទដំបូង(v) ចុងក្រោយ(v)

ការ​កសាង​តាម​ក្រោយ​

មុខងារ តាមដានគណនាតាមរយៈ ទុកជាមោឃៈ, អត្ថបទដំបូងនិង ចុងក្រោយ. មុខងារ តាមដានកំណត់លើមុខតំណែងជាច្រើន។ អត្ថន័យ តាមដានគឺជាសំណុំនៃមុខតំណែង។ ប្រសិនបើ ក ខ្ញុំ- ទីតាំងបន្ទាប់មក តាមដាន(ខ្ញុំ) មានមុខតំណែងជាច្រើន។ jដូចជាមានខ្សែខ្លះ ... ស៊ីឌី... រួមបញ្ចូលនៅក្នុងភាសាដែលបានពិពណ៌នាដោយ RW បែបនោះ។ ខ្ញុំផ្គូផ្គងធាតុនេះ។ , ក j- ចូល . មុខងារ តាមដានក៏អាចត្រូវបានគណនានៅក្នុងផ្លូវឆ្លងកាត់មួយនៃដើមឈើនេះបើយោងតាមច្បាប់ពីរខាងក្រោម

  1. អនុញ្ញាតឱ្យ - ថ្នាំងខាងក្នុងជាមួយ "." (ការភ្ជាប់គ្នា); , - កូនចៅរបស់គាត់។ បន្ទាប់មកសម្រាប់មុខតំណែងនីមួយៗ ខ្ញុំរួមបញ្ចូលនៅក្នុង ចុងក្រោយ( តាមដាន(ខ្ញុំ) មាន​ច្រើន អត្ថបទដំបូង().
  2. អនុញ្ញាតឱ្យ - ថ្នាំងខាងក្នុងដែលមានប្រតិបត្តិការ "*" (ការធ្វើឡើងវិញ), - កូនចៅរបស់គាត់។ បន្ទាប់មកសម្រាប់មុខតំណែងនីមួយៗ ខ្ញុំរួមបញ្ចូលនៅក្នុង ចុងក្រោយ() បន្ថែមទៅសំណុំនៃតម្លៃ តាមដាន(ខ្ញុំ) មាន​ច្រើន អត្ថបទដំបូង().

ឧទាហរណ៍

គណនាតម្លៃមុខងារ តាមដានសម្រាប់ការបញ្ចេញមតិធម្មតា ( (|))*.

ទីតាំងអត្ថន័យ តាមដាន
1: ( (|))* {2, 3}
2: (( |))* {1, 4}
3: ((| ))* {1, 4}
4: ((|))* {5}

ការកសាង DFA

DFA គឺជាសំណុំនៃរដ្ឋ និងសំណុំនៃការផ្លាស់ប្តូររវាងពួកគេ។ រដ្ឋ DFA គឺជាសំណុំនៃមុខតំណែង។ ការសាងសង់ DFA មាននៅក្នុងការបន្ថែមបន្តិចម្តង ៗ នៃរដ្ឋចាំបាច់ទៅវានិងការសាងសង់ការផ្លាស់ប្តូរសម្រាប់ពួកគេ។ ដំបូងមានរដ្ឋមួយ។ អត្ថបទដំបូង(ឫស) (ឫស- ឫសនៃដើមឈើ) ដែលមិនមានការផ្លាស់ប្តូរ។ ការផ្លាស់ប្តូរត្រូវបានអនុវត្តដោយតួអក្សរពីកន្សោមធម្មតា។ តួអក្សរនីមួយៗត្រូវគ្នាទៅនឹងសំណុំនៃមុខតំណែង ( ទំ ខ្ញុំ) រួបរួមទាំងអស់គ្នា តាមដាន(x) គឺជារដ្ឋដែលចាំបាច់ត្រូវទៅ ដែល x គឺជាទីតាំងដែលមានទាំងមុខតំណែងរបស់រដ្ឋ និងក្នុងចំណោមមុខតំណែងនៃនិមិត្តសញ្ញាពី RE ដែលការផ្លាស់ប្តូរត្រូវបានធ្វើឡើង។ ប្រសិនបើមិនមានរដ្ឋបែបនេះទេនោះវាត្រូវតែបន្ថែម។ ដំណើរការត្រូវតែធ្វើម្តងទៀតរហូតដល់ការផ្លាស់ប្តូរទាំងអស់សម្រាប់រដ្ឋទាំងអស់ត្រូវបានបង្កើតឡើង។ រដ្ឋទាំងអស់ដែលមានទីតាំងនៃនិមិត្តសញ្ញា # ដែលត្រូវបានបន្ថែមទៅចុងបញ្ចប់នៃ RE ត្រូវបានប្រកាសថាចុងក្រោយ។

DFA ទទួលបានពី RV ( (|))*

ឧទាហរណ៍

បង្កើត DFA ដោយកន្សោមធម្មតា ( (|))*.

រដ្ឋ DKAនិមិត្តសញ្ញា
a(1)b(2)គ(៣, ៤)
A(1, 4)ខ(២,៣) - C(5)
ខ(២,៣) - A(1, 4)A(1, 4)
C(5) - - -

ការកសាង DFA ជាមួយនឹងចំនួនរដ្ឋអប្បបរមា

DFA ដែលមានចំនួនរដ្ឋអប្បបរមាត្រូវបានសាងសង់សម្រាប់ DFA ដែលបានកំណត់គ្រប់ទីកន្លែង ពោលគឺ បែបនោះ។ សម្រាប់ DFA ណាមួយ មាន DFA ដែលកំណត់គ្រប់ទីកន្លែងដែលស្មើនឹងវា។

ការសាងសង់ DFA ដែលបានកំណត់គ្រប់ទីកន្លែង

ណែនាំរដ្ឋថ្មី និងកំណត់សំណុំរដ្ឋថ្មី។ .

ចូរកំណត់មុខងារផ្លាស់ប្តូរថ្មីដូចនេះ៖

ការបង្កើតភាគថាស (ជាផ្លូវការ)

តោះបង្កើតភាគថាសដំបូង ទំកំណត់រដ្ឋជាពីរក្រុម៖ រដ្ឋចុងក្រោយ ហើយ​ផ្សេងទៀត S/F, i.e. ទំ = {, Q\F}.

អនុវត្តចំពោះក្រុមនីមួយៗ ជីទំតាមនីតិវិធី។ កម្ទេច ជីចូលទៅក្នុងក្រុមរងដើម្បីឱ្យរដ្ឋ និង tពី ជីបានបញ្ចប់នៅក្នុងក្រុមតែមួយប្រសិនបើ និងប្រសិនបើសម្រាប់និមិត្តសញ្ញាបញ្ចូលនីមួយៗ រដ្ឋ និង tមានការផ្លាស់ប្តូរ ទៅរដ្ឋពីក្រុមដូចគ្នានៅក្នុង ទំ.

ក្រុមរងលទ្ធផលត្រូវបានបន្ថែមទៅភាគថាសថ្មី។ ទំថ្មី។

ទទួលយក ទំ = ទំថ្មី ហើយ​ធ្វើ​ការ​សាងសង់​ភាគថាស​ឡើងវិញ​រហូត​ទាល់តែ​មាន​ស្ថេរភាព ពោលគឺ​រហូតដល់​ភាគថាស​ឈប់​ផ្លាស់ប្តូរ។

ការបង្កើតភាគថាស (ក្បួនដោះស្រាយ)

ដើម្បីបង្កើតភាគថាសមានក្បួនដោះស្រាយដូចខាងក្រោម។ យើងបង្កើតតារាងផ្លាស់ប្តូរសម្រាប់ automaton ដើម បង្កើតភាគថាសដំបូង។

យើងកំណត់អត្តសញ្ញាណទៅក្រុមនីមួយៗពីភាគថាស (សម្រាប់ភាគថាសដំបូង ឧទាហរណ៍ 0 និង 1)។

រដ្ឋនីមួយៗ (ជួរនីមួយៗនៃតារាង) ត្រូវបានកំណត់ជាខ្សែអក្សរនៃទម្រង់ “a.bcd…xyz” ដែលជាកន្លែងកំណត់អត្តសញ្ញាណក្រុមដែលរដ្ឋជាកម្មសិទ្ធិពី [ជួរទីមួយ (កន្លែងដែលយើងទៅ) ជួរទីពីរ (កន្លែងដែលយើងទៅដោយតួអក្សរទីមួយ), …, ជួរចុងក្រោយ (កន្លែងដែលយើងទៅដោយតួអក្សរចុងក្រោយ)] ។

យើង​បង្កើត​ក្រុម​ថ្មី​ដោយ​យោង​ទៅ​តាម​ភាព​ចៃដន្យ​នៃ​ខ្សែ​អក្សរ ពោល​គឺ​ដូច្នេះ​ថា​រដ្ឋ​ដែល​មាន​ខ្សែ​ដែល​បាន​កំណត់​ដូចគ្នា​ធ្លាក់​ចូល​ទៅ​ក្នុង​ក្រុម​មួយ។

បន្ទាប់​មក ការ​ធ្វើ​ឡើង​វិញ។ យើងកំណត់អត្តសញ្ញាណថ្មីទៅក្រុមលទ្ធផល ឧទាហរណ៍ (0, 1, ..., n)។ ហើយយើងធ្វើម្តងទៀតនូវការសាងសង់ភាគថាសរហូតដល់ស្ថេរភាព។

ចំណាំថានៅពេលដែលមានរដ្ឋតែមួយដែលនៅសល់ក្នុងក្រុម នៅដំណាក់កាលបន្តបន្ទាប់នៃការសាងសង់ភាគថាស អ្នកមិនអាចសរសេរខ្សែអក្សរនៃការកំណត់អត្តសញ្ញាណសម្រាប់រដ្ឋនេះទៀតទេ ដោយសារខ្សែអក្សរនេះនឹងមានតែមួយគត់ក្នុងករណីណាក៏ដោយ ដោយសារតែតួអក្សរទីមួយនៃ ខ្សែអក្សរ។ នៅក្នុងពាក្យផ្សេងទៀតនៅពេលដែលការបំបែកគ្មានអ្វីនឹងកើតឡើងចំពោះក្រុមពីរដ្ឋមួយ - វាត្រូវបានផ្ទេរទៅការបំបែកថ្មីដូចដែលមាន។

ការសាងសង់ automaton កាត់បន្ថយ

ក្រុមលទ្ធផលនីមួយៗក្លាយជាស្ថានភាពនៃ DFA ថ្មី។ ប្រសិនបើក្រុមមានស្ថានភាពដំបូង (ចុងក្រោយ) នៃ automaton ដើម ក្រុមនេះនឹងក្លាយជារដ្ឋដំបូង (រៀងគ្នាចុងក្រោយ) នៃ DFA ថ្មី។ ដំណើរផ្លាស់ប្តូរត្រូវបានសាងសង់តាមរបៀបជាក់ស្តែង៖ ការផ្លាស់ប្តូរទៅរដ្ឋពីក្រុមមួយត្រូវបានចាត់ទុកថាជាការផ្លាស់ប្តូរទៅជាក្រុម។

យើងនាំយកម៉ាស៊ីន។ ដំបូងយើងដកធាតុមិនបង្កើត (មាប់មគ "ស្លាប់") បន្ទាប់មករដ្ឋដែលមិនអាចទៅដល់បាន (និយមន័យត្រូវបានផ្តល់ឱ្យសម្រាប់និមិត្តសញ្ញា ប៉ុន្តែនៅក្នុងវិធីជាក់ស្តែង ពួកគេត្រូវបានផ្ទេរទៅរដ្ឋនៃ automaton) ។

និយាយជាទូទៅ ការដកចេញនូវរដ្ឋដែលស្លាប់ ប្រែ DFA ទៅជា NFA ចាប់តាំងពីនៅក្នុង DFA រាល់ការផ្លាស់ប្តូរទាំងអស់ត្រូវតែត្រូវបានកំណត់។ ទោះជាយ៉ាងណាក៏ដោយនៅក្នុងសៀវភៅនាគ ការឃ្លាតឆ្ងាយពីនិយមន័យផ្លូវការនៅតែចាត់ទុកថាអាចទទួលយកបាន។

ឧទាហរណ៍

ដើម្បីបង្កើត DFA ជាមួយនឹងចំនួនរដ្ឋអប្បបរមាសម្រាប់ DFA នៃទម្រង់ខាងក្រោម៖

  • ការបំបែកដំបូង៖ (C) ( ស្ថានភាពចុងក្រោយ), (A, B, D, E) ( រដ្ឋផ្សេងទៀតទាំងអស់។).
  • (C)( ដោយគ្មានការផ្លាស់ប្តូរ), (A, D, E), (B), ( ចាប់តាំងពីយើងឆ្លងកាត់ពី A, D, E តាមបណ្ដោយ a, c ទៅ B និង C រៀងគ្នា។).
  • យើងមិនអាចធ្វើការបំបែកទៀតទេ។

អនុញ្ញាតឱ្យក្រុម (C) ទាក់ទងទៅនឹងរដ្ឋ C ក្រុម (A, D, E) ទៅរដ្ឋ A និងក្រុម (B) ទៅរដ្ឋ B ។ បន្ទាប់មកយើងទទួលបាន DFA ជាមួយនឹងចំនួនរដ្ឋអប្បបរមា៖

ឧទាហរណ៍ (ក្បួនដោះស្រាយសម្រាប់បង្កើតភាគថាស)

តារាងផ្លាស់ប្តូរសម្រាប់គ្រប់ទីកន្លែងដែលបានកំណត់ (រដ្ឋ Z បានបន្ថែម) DFA ដែលត្រូវគ្នានឹង RV (ab|ε)a*|abb|b*a ។ ពីសំណួរប្រឡងឆ្នាំ 2012 ។

ខ្ញុំ ០ខ្ញុំ ១
→ A*0.01 0.12
ខ*អ៊ី0.00 1.01
1.01
ឃ*Z0.01 0.04
អ៊ី*Z0.00 1.03
F*ZZ0.11
ZZZ1.11

ការធ្វើម្តងទៀត៖

  • I 0: ACDEF(0), CZ(1)។
  • I 1: AD(0), BE(1), C(2), F(3), Z(4)។
  • ខ្ញុំ 2: A, B, C, D, E, F, Z ។

លទ្ធផល៖ ម៉ាស៊ីនមានចំនួនរដ្ឋអប្បបរមារួចហើយ :-)

DFA ដែលអនុញ្ញាតឱ្យបញ្ចប់ភាសា

ក្បួនដោះស្រាយសម្រាប់សាងសង់ DFA ដែលទទួលយកការបំពេញបន្ថែមនៃភាសា L (L̅) មានពីរជំហាន៖

  • បង្កើត DFA ពេញលេញ
  • ការសាងសង់ automaton ដែលចង់បានពីវា។

តាមការពិត មិនមានអ្វីដូច DFA ពេញលេញនោះទេ។ នៅក្រោម DKA ពេញលេញ ខ្លះគ្រូបង្រៀនយល់ពី automaton នៅក្នុងតារាងផ្លាស់ប្តូរដែលមិនមានក្រឡាទទេ។ ទោះយ៉ាងណាក៏ដោយ យោងតាមនិយមន័យ DFA - δ: Q × Σ → Q - មិនអាចមានក្រឡាទទេក្នុងករណីណាក៏ដោយ។ ទោះយ៉ាងណាក៏ដោយ automaton "ជាមួយកោសិកាទទេ" បំពេញនិយមន័យនៃ NFA ។ នៅក្នុងដំណើរការនៃការដោះស្រាយ វាមិនមែនជារឿងចម្លែកទេក្នុងការទទួលបាន NFA បែបនេះ ដែលខ្វះតែការផ្លាស់ប្តូរមុន DFA ប៉ុណ្ណោះ។

ដើម្បីបំពេញបន្ថែមវាគ្រប់គ្រាន់ដើម្បីបន្ថែមរដ្ឋថ្មី។ Xនិង "ជំនួសឱ្យ" ការផ្លាស់ប្តូរដែលមិនមានស្រាប់ បន្ថែមការផ្លាស់ប្តូរទៅរដ្ឋថ្មីនេះ។ កុំភ្លេចបន្ថែមការផ្លាស់ប្តូរពី Xក្នុង X. វាងាយមើលឃើញថាកន្លែងដែល automaton ដើមមិនទទួលយកខ្សែសង្វាក់មួយចំនួនដោយសារតែអវត្តមាននៃការផ្លាស់ប្តូរ automaton ថ្មីនឹងចូលទៅក្នុងស្ថានភាព។ Xហើយព្យួរលើវា។ ដោយសាររដ្ឋថ្មីមិនមែនជារដ្ឋទទួលយក (ចុងក្រោយ) នោះ automaton ថ្មីក៏នឹងមិនទទួលយកខ្សែសង្វាក់នេះដែរ។

ឥឡូវនេះដើម្បីកសាង automaton ដែលចង់បានវាគ្រាន់តែជាការចាំបាច់ក្នុងការផ្លាស់ប្តូរតួនាទីនៃរដ្ឋទទួលយកនិងមិនទទួលយក។ និយាយម្យ៉ាងទៀត F" = Q \\ F ។

ការបង្កើតឧបករណ៍វិភាគ LL(k)

ការផ្លាស់ប្តូរវេយ្យាករណ៍

មិនមែនគ្រប់វេយ្យាករណ៍គឺ LL(k)-parsable។ វេយ្យាករណ៍​គ្មាន​បរិបទ​ជា​កម្មសិទ្ធិ​របស់​ថ្នាក់ LL(1) ប្រសិន​បើ​វា​មិន​មាន​ការ​ប៉ះទង្គិច FIRST-FIRST (ការ​ហៅ​ឡើង​វិញ​ខាង​ឆ្វេង​គឺ​ជា​ករណី​ពិសេស​នៃ​ជម្លោះ​បែប​នេះ) និង FIRST-FOLLOW ។

ពេលខ្លះវាអាចបំប្លែងវេយ្យាករណ៍ដែលមិនមែនជា LL(1) ដើម្បីឱ្យវាក្លាយជា LL(1)។ ការផ្លាស់ប្តូរមួយចំនួន (ច្បាស់ជាងនេះទៅទៀត ដែលត្រូវបានពិចារណាក្នុងវគ្គសិក្សា) ត្រូវបានផ្តល់ឱ្យខាងក្រោម។

ការ​ដក​ការ​លើក​ឡើង​ខាង​ឆ្វេង

ឧបមាថាយើងមានច្បាប់នៃទម្រង់ (តទៅនេះក្នុងផ្នែកនេះ អក្សរធំ - និមិត្តសញ្ញាមិនមែនស្ថានីយ, អក្សរ​តូច - ខ្សែសង្វាក់នៃតួអក្សរណាមួយ។):

  • ក → ក | ក | … | ក k | | | … | z

វាមិនអាចទទួលយកបានចំពោះការវិភាគដែលមិនច្បាស់លាស់ទេ ដូច្នេះវាគួរតែត្រូវបានបំប្លែង។

វាងាយស្រួលក្នុងការបង្ហាញថាច្បាប់នេះគឺស្មើនឹងច្បាប់ទាំងពីរខាងក្រោម៖

  • ក → ខ | ខ | … | z
  • ខ → ខ | ខ | … | kខ | ε

កត្តាកត្តាខាងឆ្វេង

ខ្លឹមសារនៃនីតិវិធីនេះគឺការលុបបំបាត់ភាពមិនច្បាស់លាស់នៅក្នុងជម្រើសនៃច្បាប់សម្រាប់តួអក្សរខាងឆ្វេង។ ដើម្បីធ្វើដូច្នេះ បុព្វបទខាងឆ្វេងទូទៅត្រូវបានរកឃើញ ហើយអ្វីដែលអាចធ្វើតាមវាត្រូវបានដកចេញនៅក្នុងច្បាប់ថ្មី (អក្សរតូច - ខ្សែសង្វាក់នៃតួអក្សរណាមួយ។)

ឧទាហរណ៍
  • ក → | df | dg |

បានបំប្លែងទៅជា

  • ក → ខ |
  • ខ → | f | g

ដែលនៅក្នុងវេនក្លាយជា

  • ក → ខ |
  • ខ → | ពី
  • គ → f | g

ឧទាហរណ៍នៃការបំប្លែងវេយ្យាករណ៍

ជី=((S,A,B),(a,b,c),P,S)

  • S →SAbB | ក
  • A→ab | អេ | ε
  • ខ → គ | ε

ការ​ដក​ពាក្យ​ដដែលៗ​ចេញ​សម្រាប់ S:

  • S → aS ១
  • S 1 → AbBS 1 | ε

កត្តា​ខាង​ឆ្វេង​សម្រាប់ A:

  • A → aA ១ | ε
  • ក 1 → ខ | ក

វេយ្យាករណ៍ចុងក្រោយ៖

  • S → aS ១
  • S 1 → AbBS 1 | ε
  • A → aA ១ | ε
  • ក 1 → ខ | ក
  • ខ → គ | ε

សាងសង់ FIRST និង FOLLOW

FIRST(α) ដែល α ∈ (N ∪ T)* គឺជាសំណុំនៃស្ថានីយដែល α អាចចាប់ផ្តើម។ ប្រសិនបើ α ⇒ ε នោះ ε ∈ FIRST (α) ។ ដូច្នោះហើយតម្លៃនៃ FOLLOW ( ) សម្រាប់មិនមែនស្ថានីយ - ស្ថានីយជាច្រើនដែលអាចលេចឡើងភ្លាមៗបន្ទាប់ពី នៅក្នុងទម្រង់មនោសញ្ចេតនាមួយចំនួន។ ប្រសិនបើ ក អាចជាតួអក្សរដែលត្រឹមត្រូវបំផុតក្នុងទម្រង់មនោសញ្ចេតនាមួយចំនួន បន្ទាប់មកនិមិត្តសញ្ញា $ ចុងក្រោយក៏ជាកម្មសិទ្ធិរបស់ FOLLOW( )

ការគណនាដំបូង

សម្រាប់ស្ថានីយ
  • សម្រាប់ស្ថានីយណាមួយ។ x, x, FIRST( x) = {x}
សម្រាប់មិនមែនស្ថានីយ
  • ប្រសិនបើ ក Xមិនមែនជាស្ថានីយ បន្ទាប់មកយើងដាក់ FIRST( X) = {∅}
  • ប្រសិនបើវេយ្យាករណ៍មានច្បាប់ X→ ε បន្ទាប់មកបន្ថែម ε ទៅ FIRST ( X)
  • សម្រាប់ស្ថានីយនីមួយៗ Xនិងសម្រាប់ក្បួនសន្និដ្ឋាននីមួយៗ X 1 … k បន្ថែម​ទៅ FIRST( X) សំណុំដំបូងនៃនិមិត្តសញ្ញាទាំងអស់នៅផ្នែកខាងស្តាំនៃច្បាប់រហូតដល់សញ្ញាទីមួយដែល ε មិនត្រូវបានយកមក រួមទាំង
សម្រាប់ខ្សែសង្វាក់
  • សម្រាប់ខ្សែអក្សរ X 1 …X k FIRST គឺ​ជា​ការ​រួបរួម​នៃ​តួអក្សរ FIRST ដែល​រួម​បញ្ចូល​ក្នុង​ខ្សែ​អក្សរ​រហូត​ដល់​អក្សរ​ទីមួយ​ដែល​មាន ε ∉ FIRST រួម​ទាំង​វា​ផង​ដែរ។
ឧទាហរណ៍
  • S → aS ១
  • S 1 → AbBS 1 | ε
  • A → aA ១ | ε
  • ក 1 → ខ | ក
  • ខ → គ | ε

ទីមួយមិនមែនស្ថានីយនៅក្នុងលំដាប់ដំណោះស្រាយភាពអាស្រ័យ៖

  • FIRST(S) = (a)
  • FIRST(A) = (a, ε)
  • FIRST(A 1) = (b, a)
  • FIRST(B) = (c, ε)
  • FIRST(S 1) = (a, b, ε)

FIRST សម្រាប់ច្បាប់សន្និដ្ឋាន៖

  • FIRST(aS 1) = (a)
  • FIRST(AbBS 1) = (a, b)
  • FIRST(ε) = (ε)
  • FIRST(aA 1) = (a)
  • FIRST(a) = (a)
  • FIRST(b) = (b)
  • FIRST(c) = (c)

អនុវត្តតាមការគណនា

ការគណនាអនុគមន៍ FOLLOW សម្រាប់តួអក្សរ X៖

  • អនុញ្ញាតឱ្យ FOLLOW(X) = (∅)
  • ប្រសិនបើ X គឺជា axiom វេយ្យាករណ៍ បន្ទាប់មកបន្ថែមសញ្ញាសម្គាល់ $ ទៅ FOLLOW
  • សម្រាប់ច្បាប់ទាំងអស់នៃទម្រង់ A → αXβ បន្ថែម FIRST(β)\(ε) ទៅ FOLLOW(X) (X អាចត្រូវបានអនុវត្តតាមតួអក្សរទាំងនោះដែលចាប់ផ្តើមដោយ β)
  • សម្រាប់ច្បាប់ទាំងអស់នៃទម្រង់ A → αX និង A → αXβ, ε ∈ FIRST(β) បន្ថែម FOLLOW(A) ទៅ FOLLOW(X) (នោះគឺ X អាចត្រូវបានអនុវត្តដោយតួអក្សរទាំងអស់ដែលអាចធ្វើតាម A ប្រសិនបើនៅក្នុង ក្បួនការសន្និដ្ឋាន X អាចនៅខាងស្តាំបំផុត)
  • ធ្វើម្តងទៀតនូវកថាខណ្ឌពីរមុន ដរាបណាអាចបន្ថែមតួអក្សរទៅសំណុំ
ឧទាហរណ៍
  • S → aS ១
  • S 1 → AbBS 1 | ε
  • A → aA ១ | ε
  • ក 1 → ខ | ក
  • ខ → គ | ε

លទ្ធផល៖

  • ធ្វើតាម(S) = ($)
  • FOLLOW(S 1) = ($) (S 1 គឺជាតួអក្សរខាងស្តាំបំផុតនៅក្នុងច្បាប់ S → aS 1)
  • FOLLOW(A) = (b) (A ក្នុងក្បួន S 1 → AbBS 1 ត្រូវបានតាមដោយ ខ)
  • FOLLOW(A 1) = (b) (A 1 គឺជាតួអក្សរខាងស្តាំបំផុតក្នុងក្បួន A → aA 1 ដូច្នេះការបន្ថែម FOLLOW(A) ទៅ FOLLOW(A 1))
  • FOLLOW(B) = (a, b, $) (បន្ថែម FIRST(S 1)\(ε) (អនុវត្តតាមច្បាប់ S 1 → AbBS 1), FOLLOW(S 1) (ព្រោះមាន S 1 → ε))

ការចងក្រងតារាង

តុ សម្រាប់គូដែលមិនមែនជាស្ថានីយ-ស្ថានីយ (ក្នុងក្រឡា [, ]) បញ្ជាក់ច្បាប់ដែលពាក្យបញ្ចូលត្រូវតែកាត់បន្ថយ។ តារាងត្រូវបានបំពេញដូចខាងក្រោម៖ សម្រាប់ក្បួនការសន្និដ្ឋាននីមួយៗនៃវេយ្យាករណ៍ A → α (ដែល α ត្រូវបានយល់ថាជាខ្សែសង្វាក់នៅផ្នែកខាងស្តាំនៃច្បាប់) សកម្មភាពខាងក្រោមត្រូវបានអនុវត្ត៖

  1. សម្រាប់ស្ថានីយនីមួយៗ ∈ FIRST(α) បន្ថែមច្បាប់ α ទៅ [, ]
  2. ប្រសិនបើ ε ∈ FIRST (α) បន្ទាប់មកសម្រាប់នីមួយៗ ∈ តាមដាន ( ) បន្ថែម α ទៅ [, ]
  3. ε ∈ FIRST(α) និង $∈ FOLLOW( ), បន្ថែម α ទៅ [, $]
  4. ក្រឡាទទេទាំងអស់គឺជាកំហុសនៅក្នុងពាក្យបញ្ចូល

ឧទាហរណ៍

បង្កើតតារាងសម្រាប់វេយ្យាករណ៍

  • S → aS ១
  • S 1 → AbBS 1 | ε
  • A → aA ១ | ε
  • ក 1 → ខ | ក
  • ខ → គ | ε

លទ្ធផល៖

$
S → aS ១ (ច្បាប់ទីមួយ ការសន្និដ្ឋាន S → aS 1 , a ∈ FIRST(aS 1)) កំហុស (ច្បាប់ទីបួន) កំហុស (ច្បាប់ទីបួន) កំហុស (ច្បាប់ទីបួន)
ស១ S 1 → AbBS ១ (ច្បាប់ទីមួយ លទ្ធផល S 1 → AbBS 1 , a ∈ FIRST (AbBS 1)) S 1 → AbBS ១ (ច្បាប់ទីមួយ លទ្ធផល S 1 → AbBS 1 , b ∈ FIRST (AbBS 1)) កំហុស (ច្បាប់ទីបួន) ស 1 → ε (ច្បាប់ទីបី ការសន្និដ្ឋាន S 1 → ε, ε ∈ FIRST(ε), $ ∈ FOLLOW(S 1))
A → aA ១ (ច្បាប់ទីមួយ លទ្ធផល A → aA 1 , a ∈ FIRST (aA 1)) អេ→ε (ក្បួនទីពីរ លទ្ធផល A 1 → ε, b ∈ ធ្វើតាម (A 1)) កំហុស (ច្បាប់ទីបួន) កំហុស (ច្បាប់ទីបួន)
ក ១ ក ១ → ក (ច្បាប់ទីមួយ លទ្ធផល A 1 → a, a ∈ FIRST(a)) ក 1 → ខ (ច្បាប់ទីមួយ លទ្ធផល A 1 → b, b ∈ FIRST(b)) កំហុស (ច្បាប់ទីបួន) កំហុស (ច្បាប់ទីបួន)
ខ → អ៊ី ខ → អ៊ី (ក្បួនទីពីរ ការសន្និដ្ឋាន B → ε, a ∈ FOLLOW(B)) ខ → គ (ច្បាប់ទីមួយ លទ្ធផល B → c, c ∈ FIRST(c)) ខ → អ៊ី (ច្បាប់ទីបី ការសន្និដ្ឋាន B → ε, $ ∈ FOLLOW(B))

ការញែកខ្សែអក្សរ

ដំណើរការនៃការញែកខ្សែអក្សរគឺសាមញ្ញណាស់។ ខ្លឹមសាររបស់វាមានដូចខាងក្រោម៖ នៅជំហាននីមួយៗ និមិត្តសញ្ញាកំពូលត្រូវបានអាន v ខ្សែសង្វាក់បញ្ចូល។

  • ប្រសិនបើ ក v- តួអក្សរស្ថានីយ
    • ប្រសិនបើ ក vស្របពេលជាមួយ ជាមួយបន្ទាប់មកពួកគេទាំងពីរត្រូវបានបំផ្លាញ មានការផ្លាស់ប្តូរ
    • ប្រសិនបើ ក vមិនត្រូវគ្នាជាមួយ ជាមួយបន្ទាប់មក កំហុសញែកត្រូវបានផ្តល់សញ្ញា
  • ប្រសិនបើ ក v- និមិត្តសញ្ញាមិនមែនស្ថានីយ, ត្រឡប់​ទៅ​ដើម​បន្ទាត់​ជំនួស​វិញ។ vផ្នែកខាងស្តាំនៃច្បាប់ដែលត្រូវបានយកចេញពីក្រឡាតារាងត្រូវបានត្រលប់ទៅជង់វិញ។ [v, ]

ដំណើរការបញ្ចប់នៅពេលដែលទាំងខ្សែអក្សរ និងជង់បានទៅដល់សញ្ញាសម្គាល់ចុង (#)។

ឧទាហរណ៍

តោះញែកខ្សែអក្សរ "aabbaabcb"៖

ជង់បន្ទាត់សកម្មភាព
# abbaabcb$S → aS ១
S1# abbaabcb$ផ្លាស់ប្តូរ
ស១# bbabcb$S 1 → AbBS ១
bbs 1# bbabcb$A → aA ១
A 1 bBS 1 # bbabcb$ផ្លាស់ប្តូរ
ក ១ bbs 1# baabcb$ក 1 → ខ
bbs 1# baabcb$ផ្លាស់ប្តូរ
B.S. 1# aabcb$ផ្លាស់ប្តូរ
S1# abcb$ខ → អ៊ី
ស១# abcb$S 1 → AbBS ១
bbs 1# abcb$A → aA ១
bbs 1# abcb$A → aA ១
A 1 bBS 1 # abcb$ផ្លាស់ប្តូរ
ក ១ bbs 1# bcb$ក ១ → ក
bbs 1# bcb$ផ្លាស់ប្តូរ
B.S. 1# cb$ផ្លាស់ប្តូរ
S1# b$ខ → គ
S1# b$ផ្លាស់ប្តូរ
ស១# $ S 1 → AbBS ១
bbs 1#$ អេ→ε
B.S. 1#$ ផ្លាស់ប្តូរ
S1#$ ខ → អ៊ី
ស១# $ ស 1 → ε
# $ រួចរាល់

បង្កើតឧបករណ៍វិភាគ LR(k)

ការគណនា k ក្នុង LR(k)

មិន​មាន​ក្បួន​ដោះស្រាយ​ដែល​អនុញ្ញាត​ឱ្យ​ក្នុង​ករណី​ទូទៅ​ក្នុង​ការ​គណនា k សម្រាប់​វេយ្យាករណ៍​តាម​អំពើ​ចិត្ត​ទេ។ ជាធម្មតាវាមានតម្លៃក្នុងការព្យាយាមបង្កើតឧបករណ៍ញែក LR (1) ។ ប្រសិនបើវាមានប្រតិបត្តិការច្រើនបំផុតមួយក្នុងមួយឈុត (Shift, Reduce ឬ Accept) នោះវេយ្យាករណ៍គឺ LR(0)។ ទោះយ៉ាងណាក៏ដោយ ប្រសិនបើការប៉ះទង្គិច និងការប៉ះទង្គិចកើតឡើងនៅពេលបង្កើតឧបករណ៍ញែក LR(1) នោះវេយ្យាករណ៍នេះមិនមែនជា LR(1) ហើយវាមានតម្លៃព្យាយាមបង្កើត LR(2)។ ប្រសិនបើវាបរាជ័យក្នុងការសាងសង់វាបន្ទាប់មក LR (3) ជាដើម។

ការបញ្ចប់វេយ្យាករណ៍

ចូរបន្ថែមច្បាប់ថ្មី S" → S ហើយធ្វើឱ្យ S" ជា axiom នៃវេយ្យាករណ៍។ ច្បាប់បន្ថែមនេះត្រូវបានទាមទារដើម្បីកំណត់នៅពេលដែលអ្នកវិភាគបញ្ចប់ ហើយខ្សែសង្វាក់បញ្ចូលត្រូវបានអនុញ្ញាត។ ការ​ចូល​រៀន​ធ្វើ​ឡើង​ប្រសិន​បើ​អាច​ធ្វើ​ការ​បង្រួប​បង្រួម​បាន​តាម​ច្បាប់ S → S”។

ការសាងសង់ប្រព័ន្ធ Canonical នៃសំណុំនៃ LR ដែលអាចទទួលយកបាន (1) - ស្ថានភាព

នៅពេលចាប់ផ្តើមមានសំណុំ I 0 ជាមួយនឹងការកំណត់រចនាសម្ព័ន្ធរបស់ឧបករណ៍វិភាគ S" → .S, $ ។ បន្ទាប់មកប្រតិបត្តិការបិទត្រូវបានអនុវត្តចំពោះការកំណត់រចនាសម្ព័ន្ធនេះរហូតដល់លទ្ធផលនៃកម្មវិធីរបស់វាមិនមានការកំណត់ថ្មីត្រូវបានបន្ថែមទេ។ ការផ្លាស់ប្តូរទៅសំណុំថ្មីត្រូវបានសាងសង់ដោយការផ្លាស់ប្តូរចំណុចដោយតួអក្សរមួយទៅខាងស្តាំ (ការលោតត្រូវបានធ្វើឡើងដោយតួអក្សរដែលបន្ទាប់ពីចំនុចមុនពេលលោត និងមុនវាបន្ទាប់ពីការលោត) និងការកំណត់ទាំងនោះដែលទទួលបានពីតួអក្សរដែលមានស្រាប់។ តាមវិធីនេះត្រូវបានបន្ថែមទៅឈុតទាំងនេះ។ ប្រតិបត្តិការបិទក៏ត្រូវបានអនុវត្តចំពោះពួកវាដែរ ហើយដំណើរការទាំងមូលត្រូវបានធ្វើម្តងទៀតរហូតដល់មិនមានសំណុំថ្មីលេចឡើងទៀតទេ។

ឧទាហរណ៍

បង្កើតប្រព័ន្ធ Canonical នៃសំណុំ LR (1) ដែលអាចទទួលយកបានសម្រាប់វេយ្យាករណ៍ដែលបានបញ្ជាក់៖

  • ស" → ស
  • S → ABA
  • A → Aa | ε
  • ខ → cBc | ឃ

ដំណោះស្រាយ៖

  • យើងបង្កើតការបិទសម្រាប់ការកំណត់រចនាសម្ព័ន្ធ S" → .S, $:
    • S → .ABA,$
  • សម្រាប់ការកំណត់រចនាសម្ព័ន្ធលទ្ធផល (S → .ABA, $) យើងក៏បង្កើតការបិទផងដែរ៖
    • A → .Aa, គ
    • A → .Aa, ឃ
    • ក →., គ
    • ក →., ឃ
  • សម្រាប់ការកំណត់រចនាសម្ព័ន្ធលទ្ធផល (A → .Aa, c; A → .Aa, d) យើងក៏បង្កើតការបិទផងដែរ៖
    • A → .Aa, ក
    • ក → ., ក
  • មិនមានការកំណត់រចនាសម្ព័ន្ធទៀតទេនៅក្នុងរដ្ឋ I 0 អាចត្រូវបានសាងសង់ - ការបិទត្រូវបានសាងសង់
  • ចាប់ពី I 0 អ្នកអាចធ្វើការផ្លាស់ប្តូរតាម S និង A ហើយទទួលបានសំណុំនៃការកំណត់ I 1 និង I 2 ដែលមានធាតុផ្សំដូចខាងក្រោមៈ
    • ខ្ញុំ 1 = (S" → S., $)
    • I 2 = (S → A.BA, $; A → A.a, c; A → A.a, d; A → A.a, ក)
  • I 1 មិនតម្រូវឱ្យបិទទេ។
  • ចូរយើងបង្កើតការបិទ I 2៖
    • B → .cBc, ក
    • B → .cBc, $
    • B → .d, ក
    • B → .d, $
  • ឈុតផ្សេងទៀតទាំងអស់ត្រូវបានសាងសង់ស្រដៀងគ្នា។

ការកសាងតារាងញែក

ជំហានចុងក្រោយក្នុងការបង្កើត LR(1) parser គឺការកសាងតារាង សកម្មភាពនិង ទៅ. តុ សកម្មភាពបង្កើតឡើងសម្រាប់បញ្ចូលតួអក្សរខ្សែអក្សរ ពោលគឺសម្រាប់ស្ថានីយ និងសញ្ញាសម្គាល់ចុងបន្ទាត់ $, តារាង ទៅត្រូវបានបង្កើតឡើងសម្រាប់និមិត្តសញ្ញាវេយ្យាករណ៍ ពោលគឺសម្រាប់ស្ថានីយ និងមិនមែនស្ថានីយ។

ការកសាងតារាង Goto

តារាង Goto បង្ហាញស្ថានភាពដែលត្រូវទៅ នៅពេលដែលនិមិត្តសញ្ញាវេយ្យាករណ៍បន្ទាប់ត្រូវបានជួបប្រទះ។ ដូច្នេះប្រសិនបើនៅក្នុងប្រព័ន្ធ Canonical នៃសំណុំមានការផ្លាស់ប្តូរពី ខ្ញុំ iក្នុង Ijដោយនិមិត្តសញ្ញា A បន្ទាប់មកនៅក្នុង Goto ( ខ្ញុំ ខ្ញុំ, ក) យើងដាក់រដ្ឋ ខ្ញុំ j. បន្ទាប់ពីបំពេញតារាង យើងសន្មត់ថានៅក្នុងក្រឡាទទេទាំងអស់ Goto( ខ្ញុំ ខ្ញុំ, ក) = កំហុស

ការកសាងតារាងសកម្មភាព

  • ប្រសិនបើមានការផ្លាស់ប្តូរនៅលើស្ថានីយ a ពីរដ្ឋ I ទៅរដ្ឋ I j នោះ Action(I i, a) = Shift(I j)
  • ប្រសិនបើ A ≠ S" ហើយមានការកំណត់ A → α។ , a បន្ទាប់មក Action(I i , a) = កាត់បន្ថយ(A → α)
  • សម្រាប់រដ្ឋ I i ដែលមានការកំណត់រចនាសម្ព័ន្ធ S" → S., $, Action(I i, $) = ទទួលយក
  • សម្រាប់ក្រឡាទទេទាំងអស់ Action(I i, a) = កំហុស

ឧទាហរណ៍

បង្កើតតារាងសកម្មភាព និង Goto សម្រាប់វេយ្យាករណ៍

  • ស" → ស
  • S → ABA
  • A → Aa | ε
  • ខ → cBc | ឃ

ដំណោះស្រាយ៖

សកម្មភាពទៅ
$ ស"
ខ្ញុំ ០កាត់បន្ថយ (A → ε)កាត់បន្ថយ (A → ε)កាត់បន្ថយ (A → ε) ខ្ញុំ ១ ខ្ញុំ ២
ខ្ញុំ ១ ទទួលយក
ខ្ញុំ ២ប្ដូរ (I 6)ប្ដូរ (I 4)ប្ដូរ (I 5) ខ្ញុំ ៣ខ្ញុំ ៦ខ្ញុំ ៤ខ្ញុំ ៥
ខ្ញុំ ៣កាត់បន្ថយ (A → ε) កាត់បន្ថយ (A → ε) ខ្ញុំ ១៣
ខ្ញុំ ៤ ប្ដូរ (I 8)ប្ដូរ (I 9) ខ្ញុំ ៧ ខ្ញុំ ៨ខ្ញុំ ៩
ខ្ញុំ ៥កាត់បន្ថយ (B → ឃ) កាត់បន្ថយ (B → ឃ)
ខ្ញុំ ៦កាត់បន្ថយ (A → Aa)កាត់បន្ថយ (A → Aa)កាត់បន្ថយ (A → Aa)
ខ្ញុំ ៧ ប្ដូរ (I 10) ខ្ញុំ ១០
ខ្ញុំ ៨ ប្ដូរ (I 8)ប្ដូរ (I 9) ខ្ញុំ ១១ ខ្ញុំ ៨ខ្ញុំ ៩
ខ្ញុំ ៩ កាត់បន្ថយ (B → ឃ)
ខ្ញុំ ១០កាត់បន្ថយ (B → cBc) កាត់បន្ថយ (B → cBc)
ខ្ញុំ ១១ ប្ដូរ (I 12) ខ្ញុំ ១២
ខ្ញុំ ១២ កាត់បន្ថយ (B → cBc)
ខ្ញុំ ១៣ប្ដូរ (I 14) កាត់បន្ថយ (S → ABA) ខ្ញុំ ១៤
ខ្ញុំ ១៤កាត់បន្ថយ (A → Aa) កាត់បន្ថយ (A → Aa)

ការញែកខ្សែសង្វាក់

នៅជំហាននីមួយៗតួអក្សរកំពូលត្រូវបានអាន vពីជង់អ្នកវិភាគ ហើយយកតួអក្សរចុងក្រោយ ខ្សែសង្វាក់បញ្ចូល។

ប្រសិនបើនៅក្នុងតារាងនៃសកម្មភាពនៅចំណុចប្រសព្វ vនិង ទីតាំង៖

  • ប្ដូរ ( ខ្ញុំ k) បន្ទាប់មកដាក់លើជង់ ជាមួយហើយ​បន្ទាប់​មក ខ្ញុំ k. ឯណា ដកចេញពីខ្សែអក្សរ។
  • កាត់បន្ថយ ( យូ) បន្ទាប់មកនិមិត្តសញ្ញាស្ថានីយ និងមិនមែនស្ថានីយទាំងអស់ដែលបង្កើតខ្សែសង្វាក់ត្រូវបានជម្រះចេញពីកំពូលនៃជង់ យូបន្ទាប់ពីនោះរដ្ឋមើលទៅ ខ្ញុំ មនៅសល់នៅលើកំពូល។ នេះបើយោងតាមតារាងផ្លាស់ប្តូរនៅចំណុចប្រសព្វ ខ្ញុំ មនិង ស្វែងរករដ្ឋបន្ទាប់ ខ្ញុំ ស. បន្ទាប់មក A ត្រូវបានរុញទៅលើជង់ ហើយបន្ទាប់មក ខ្ញុំ ស. បន្ទាត់នៅតែមិនផ្លាស់ប្តូរ។
  • យល់ព្រម បន្ទាប់មកការញែកត្រូវបានបញ្ចប់
  • ភាពទទេគឺជាកំហុសមួយ។

ឧទាហរណ៍

ចូរយើងបង្កើតការញែកខ្សែអក្សរ aaaccdcc៖

ជង់បន្ទាត់សកម្មភាព
ខ្ញុំ ០ aaccdcc$កាត់បន្ថយ (A → ε) ចូលទៅ I 2
ខ្ញុំ 0 ក ខ្ញុំ ២ aaccdcc$ប្ដូរ (I 6)
I 0 A I 2 ក ខ្ញុំ ៦ accdcc$កាត់បន្ថយ (A → Aa) ចូលទៅ I 2
ខ្ញុំ 0 ក ខ្ញុំ ២ accdcc$ប្ដូរ (I 6)
I 0 A I 2 ក ខ្ញុំ ៦ ccdcc$កាត់បន្ថយ (A → Aa) ចូលទៅ I 2
ខ្ញុំ 0 ក ខ្ញុំ ២ ccdcc$ប្ដូរ (I 6)
I 0 A I 2 ក ខ្ញុំ ៦ cdcc$កាត់បន្ថយ (A → Aa) ចូលទៅ I 2
ខ្ញុំ 0 ក ខ្ញុំ ២ cdcc$ប្ដូរ (I 4)
I 0 A I 2 s ខ្ញុំ ៤ dcc$ប្ដូរ (I 8)
I 0 A I 2 គ I 4 គ ខ្ញុំ ៨ cc$ប្ដូរ (I 9)
I 0 A I 2 c I 4 c I 8 ឃ ខ្ញុំ ៩ c$កាត់បន្ថយ (B → d) ចូលទៅ I 11
I 0 A I 2 c I 4 c I 8 B ខ្ញុំ ១១ c$ប្ដូរ (I 12)
I 0 A I 2 c I 4 c I 8 B I 11 គ ខ្ញុំ ១២ $ កាត់បន្ថយ (B → cBc) ចូលទៅ I 7
I 0 A I 2 C I 4 B ខ្ញុំ ៧ $ ប្ដូរ (I 10)
I 0 A I 2 c I 4 B I 7 គ ខ្ញុំ ១០ $ កាត់បន្ថយ (B → cBc) ចូលទៅ I 3
I 0 A I 2 B ខ្ញុំ ៣ $ កាត់បន្ថយ (A → ε) ចូលទៅ I 13
I 0 A I 2 B I 3 A ខ្ញុំ ១៣ $ កាត់បន្ថយ (S → ABA) ចូលទៅ I 1
ខ្ញុំ 0 ស ខ្ញុំ ១ $ ទទួលយក

ការបកប្រែកន្សោមនព្វន្ធ (ក្បួនដោះស្រាយ Seti-Ullman)

ចំណាំ។កូដ​នេះ​ត្រូវ​បាន​បង្កើត​ឡើង​ដោយ​ស្ទីល doggy Motorola-like, i.e.

Op Arg1, Arg2

តំណាង​ឱ្យ

Arg2 = Arg1 Op Arg2

សាងសង់ដើមឈើ

មែកធាងត្រូវបានសាងសង់ជាធម្មតាសម្រាប់កន្សោមនព្វន្ធ៖ នៅឫស ប្រតិបត្តិការដែលមានអាទិភាពទាបបំផុត បន្តដោយប្រតិបត្តិការដែលមានអាទិភាពខ្ពស់ជាងបន្តិច ហើយដូច្នេះនៅលើ។ វង់ក្រចកមានអាទិភាពខ្ពស់បំផុត។ ប្រសិនបើមានប្រតិបត្តិការជាច្រើនដែលមានអាទិភាពដូចគ្នា - a op b op c នោះមែកធាងត្រូវបានសាងសង់ដូចជាសម្រាប់កន្សោម (a op b) op c ។

ឧទាហរណ៍

បង្កើតមែកធាងសម្រាប់កន្សោម a + b / (d + a − b × c / d − e) + c × d

ដំណោះស្រាយ៖យើងសរសេរកន្សោមក្នុងទម្រង់

((a) + ((b) / (((((d)+(a)) − ((b) × (c)) / (d)) − (e)))) + ((c) × ( ឃ))

បន្ទាប់មកនៅឫសនៃមែកធាងរងនីមួយៗ នឹងមានប្រតិបត្តិការមួយ ហើយកន្សោមក្នុងតង្កៀបនៅខាងឆ្វេង និងខាងស្តាំរបស់វានឹងក្លាយជាមែកធាងរងរបស់វា។ ឧទាហរណ៍ សម្រាប់កន្សោមរង ((ខ) × (គ)) / (ឃ) ឫសនៃអនុមែកធាងដែលត្រូវគ្នានឹងជាប្រតិបត្តិការ "/" ហើយមែកធាងរងរបស់វានឹងក្លាយជាកន្សោមរង ((ខ) × (គ)) និង (ឃ) ។

ប្លង់ដើមឈើ (ការគណនាចំនួនចុះឈ្មោះ)

  • ប្រសិនបើចំនុចកំពូលគឺជាស្លឹកខាងឆ្វេង (នោះគឺជាអថេរ) នោះយើងសម្គាល់វាដោយសូន្យ។
  • ប្រសិនបើ vertex គឺជាស្លឹកត្រឹមត្រូវ នោះយើងសម្គាល់វាដោយមួយ។
  • ប្រសិនបើយើងសម្គាល់មែកធាងរងទាំងពីរសម្រាប់ចំណុចកំពូលមួយចំនួន នោះយើងសម្គាល់វាដូចខាងក្រោម៖
    • ប្រសិនបើអនុមែកធាងខាងឆ្វេង និងស្តាំត្រូវបានដាក់ស្លាកដោយលេខផ្សេងគ្នា បន្ទាប់មកជ្រើសរើសធំបំផុតនៃពួកវា
    • ប្រសិនបើដើមឈើរងខាងឆ្វេង និងស្តាំត្រូវបានដាក់ស្លាកលេខដូចគ្នានោះ មែកធាងរងនេះត្រូវបានផ្តល់លេខមួយដែលធំជាងមួយដែលដាក់ស្លាកដើមឈើរង។
ការសម្គាល់ស្លឹកប្លង់មែកធាងដែលមានដើមឈើរងដូចគ្នា។មែកធាងរងខាងឆ្វេងត្រូវបានដាក់ស្លាកលេខធំមែកធាងរងខាងស្តាំត្រូវបានដាក់ស្លាកលេខធំ
ស្តាំ - ដូចគ្នាដូចជាបុព្វបុរស។
  • ប្រសិនបើស្លាក ឆ្វេងកូនចៅ ច្រើនទៀតស្លាក ត្រឹមត្រូវ។បន្ទាប់មក ត្រឹមត្រូវ។កុមារត្រូវបានចាត់តាំងឱ្យចុះឈ្មោះ មួយទៀតជាងបុព្វបុរស និង ឆ្វេង - ដូចគ្នាដូចជាបុព្វបុរស។
  • កូដត្រូវបានបង្កើតឡើងដោយឆ្លងកាត់មែកធាងពីក្រោមទៅកំពូលដូចខាងក្រោម:

    1. គ្មានលេខកូដត្រូវបានបង្កើតសម្រាប់ vertex ដែលមានស្លាកលេខ 0

    2. ប្រសិនបើផ្នែកខាងលើជាសន្លឹក X ដែលមានស្លាកលេខ 1 ហើយចុះឈ្មោះ R ខ្ញុំបន្ទាប់មកលេខកូដ

    ផ្លាស់ទី X, រី

    3. ប្រសិនបើផ្នែកខាងលើគឺខាងក្នុងជាមួយនឹងការចុះឈ្មោះ R ខ្ញុំហើយកូនខាងឆ្វេងរបស់វាគឺសន្លឹក X ដែលមានស្លាកលេខ 0 បន្ទាប់មកវាត្រូវគ្នានឹងលេខកូដ

    <Код правого поддерева>OpX, រី

    4. ប្រសិនបើ subtrees នៃ vertex ជាមួយ register R ខ្ញុំ- មិនមានស្លឹកទេ ហើយស្លាកនៃចំនុចកំពូលខាងស្តាំគឺធំជាង ឬស្មើនឹងស្លាកខាងឆ្វេង (ដែលមានលេខ Rj, j = i + 1) បន្ទាប់មកលេខកូដត្រូវគ្នានឹងចំនុចកំពូល។

    <Код ត្រឹមត្រូវ។មែកធាងរង ><Код ឆ្វេងដើមឈើរង > Op Rj, Ri

    5. ប្រសិនបើ subtrees នៃ vertex ជាមួយ register R ខ្ញុំ- មិនទុក និងស្លាកសញ្ញានៃកំពូលខាងស្តាំ (សម្រាប់ការចុះឈ្មោះ Rj, j = i + 1) តិចជាងស្លាកសញ្ញាខាងឆ្វេង បន្ទាប់មកលេខកូដត្រូវគ្នានឹងចំនុចកំពូល។

    ការចែកចាយការចុះឈ្មោះត្រូវបានបង្ហាញនៅក្នុងក្រាហ្វនៅខាងស្តាំ។ លេខកូដដែលបានបង្កើត៖

    ផ្លាស់ទី d, R0 ;R0 = d ផ្លាស់ទី c, R1 ;R1 = c MUL b, R1 ;R1 = (b × c) DIV R1, R0 ;R0 = (b × c) / d ផ្លាស់ទី a, R1 ;R1 = a បន្ថែម d, R1 ;R1 = a + d SUB R1, R0 ;R0 = (a + d) − ((b × c) / d) ផ្លាស់ទី e, R1 ;R1 = e SUB R0, R1 ;R1 = ((a + ឃ) − ((b × គ) / ឃ)) − អ៊ី ផ្លាស់ទី R1, R0; R0 = ((a + d) − ((b × c) / d)) − e DIV b, R0 ;R0 = b / (((a + d) − ((b × c) / d))) − e) បន្ថែម a, R0 ;R0 = a + (b / (((a + d) − ((b × c) / d )) − e)) ផ្លាស់ទី d, R1 ;R1 = d MUL c, R1 ;R1 = c×d ADD R0, R1 ;R1 = (a + (b / (((a + d)) − ((b × c ) / d)) − e))) + (c × d) MOVE R1, R0;R0 = (a + (b / (((a + d) − ((b × c) / d))) − e) )) + (គ × ឃ)

    ការបកប្រែកន្សោមឡូជីខល

    ផ្នែកនេះបង្ហាញពីរបៀបបង្កើតកូដសម្រាប់ការវាយតម្លៃខ្ជិលនៃកន្សោមប៊ូលីន។ ជាលទ្ធផលនៃក្បួនដោះស្រាយ បំណែកនៃកូដត្រូវបានទទួល ដែលដោយប្រើប្រតិបត្តិការ TST, BNE, BEQ គណនាកន្សោមឡូជីខលដោយប្តូរទៅស្លាកមួយក្នុងចំណោមស្លាក: TRUELAB ឬ FALSELAB ។

    សាងសង់ដើមឈើ

    មែកធាងនៃកន្សោមឡូជីខលឆ្លុះបញ្ចាំងពីលំដាប់ដែលវាត្រូវបានវាយតម្លៃយោងទៅតាមអាទិភាពនៃប្រតិបត្តិការ ពោលគឺដើម្បីវាយតម្លៃតម្លៃនៃថ្នាំងមែកធាង (ដែលជាប្រតិបត្តិការលើ operands ពីរដែលជា subtrees នៃ node) យើងត្រូវ ដំបូងគណនាតម្លៃនៃដើមឈើរងរបស់វា។

    អាទិភាពប្រតិបត្តិការ៖ប្រតិបត្តិករ NOT មានអាទិភាពខ្ពស់បំផុត តាមពីក្រោយដោយ AND ហើយបន្ទាប់មក OR ។ ប្រសិនបើប្រតិបត្តិការឡូជីខលផ្សេងទៀតត្រូវបានប្រើនៅក្នុងកន្សោម នោះពួកគេត្រូវតែបង្ហាញតាមរយៈវិធីទាំងបីនេះតាមវិធីជាក់លាក់មួយ (ជាធម្មតាមិនមានប្រតិបត្តិការផ្សេងទៀតទេ ហើយការបំប្លែងកន្សោមមិនត្រូវបានទាមទារ)។ សមាគមសម្រាប់ប្រតិបត្តិការដែលមានអាទិភាពដូចគ្នាគឺពីឆ្វេងទៅស្តាំ ពោលគឺ A និង B និង C ត្រូវបានចាត់ទុកជា (A និង B) និង C

    ឧទាហរណ៍

    សាងសង់មែកធាងសម្រាប់កន្សោមឡូជីខលមិនមែន A ឬ B និង C និង (B ឬមិនមែន C) ។

    ដំណោះស្រាយ៖សូមមើលដ្យាក្រាមនៅខាងស្តាំ។

    សម្រាប់ចំនុចកំពូលនីមួយៗនៃមែកធាង គុណលក្ខណៈ 4 ត្រូវបានគណនា៖

    • លេខថ្នាំង
    • ស្លាកដែលត្រូវលោតទៅប្រសិនបើកន្សោមនៅក្នុងថ្នាំងមិនពិត (ស្លាកមិនពិត, fl)
    • ស្លាកដែលត្រូវលោតទៅប្រសិនបើកន្សោមនៅក្នុងថ្នាំងគឺពិត (ស្លាកពិត, tl)
    • ស្លាកសញ្ញា (សញ្ញា) (សម្រាប់ព័ត៌មានលម្អិត សូមមើលខាងក្រោម)

    បញ្ឈរត្រូវបានរាប់តាមលំដាប់ចៃដន្យ លក្ខខណ្ឌតែមួយគត់គឺភាពប្លែកនៃលេខថ្នាំង។

    ការរៀបចំដើមឈើត្រូវបានធ្វើដូចខាងក្រោម:

    • fl បញ្ជាក់ចំនួននៃ vertex ដែលការផ្លាស់ប្តូរត្រូវបានធ្វើឡើង ឬ falselab ប្រសិនបើ vertex នេះមិនពិត
    • tl បង្ហាញពីចំនួននៃ vertex ដែលការផ្លាស់ប្តូរត្រូវបានធ្វើឡើង ឬ truelab ប្រសិនបើ vertex នេះពិត

    សញ្ញាបញ្ជាក់ក្នុងករណីដែលការវាយតម្លៃនៃអនុមែកធាងបច្ចុប្បន្នអាចត្រូវបានបញ្ចប់។

    សម្រាប់ឫសដើមឈើ fl=falselab, tl=truelab, sign=false ។

    តាមវិធីនេះ៖

    ឧទាហរណ៍

    សម្គាល់មែកធាងដែលបានសាងសង់សម្រាប់កន្សោមឡូជីខលមិនមែន A ឬ B និង C និង (B ឬមិនមែន C) ។

    ការបង្កើតកូដ

    ពាក្យបញ្ជាម៉ាស៊ីនប្រើក្នុងកូដដែលបានបង្កើត៖

    • TST - ពិនិត្យមើលអំណះអំណាងសម្រាប់ការពិត និងកំណត់ទង់ ប្រសិនបើអាគុយម៉ង់មិនពិត
    • BNE - លោតទៅស្លាកប្រសិនបើទង់មិនត្រូវបានកំណត់ ពោលគឺលក្ខខណ្ឌដែលបានពិនិត្យជាមួយ TST ពិត
    • BEQ - លោតលើស្លាកប្រសិនបើទង់ត្រូវបានកំណត់ ពោលគឺលក្ខខណ្ឌដែលបានពិនិត្យជាមួយ TST មិនពិត

    កូដត្រូវបានបង្កើតឡើងដូចខាងក្រោម៖

    • ដើមឈើត្រូវឆ្លងកាត់ពីឫស សម្រាប់ AND និង OR មែកធាងរងខាងឆ្វេងត្រូវឆ្លងកាត់មុន បន្ទាប់មកខាងស្តាំ
    • សម្រាប់ vertex នីមួយៗបានឆ្លងកាត់ លេខរបស់វា (ស្លាក) ត្រូវបានបោះពុម្ព
    • សម្រាប់សន្លឹក A (number, tl, fl, sign) TST A ត្រូវបានបោះពុម្ព
      • ប្រសិនបើសញ្ញា == ពិត BNE tl ត្រូវបានបោះពុម្ព
      • ប្រសិនបើសញ្ញា == មិនពិត BEQ fl ត្រូវបានបោះពុម្ព

    ឧទាហរណ៍

    សម្រាប់កន្សោមខាងលើ កូដខាងក្រោមនឹងត្រូវបានបង្កើត៖

    1:2:4: TST A BEQ TRUELAB 3:5:7: TST B BEQ FALSELAB 8: TST C BEQ FALSELAB 6:9: TST B BNE TRUELAB 10:11: TST C BNE FALSELAB TRUELAB: FALSELAB:

    វិធីសាស្រ្តផ្គូផ្គងគំរូ

    គំនិតនៃវិធីសាស្រ្តគឺថាសម្រាប់ផ្នែកដូចគ្នានៃកម្មវិធីកូដអាចត្រូវបានបង្កើតតាមវិធីផ្សេងគ្នាហើយជាលទ្ធផលការបង្កើនប្រសិទ្ធភាពអាចត្រូវបានសម្រេចសម្រាប់ប៉ារ៉ាម៉ែត្រមួយឬផ្សេងទៀត។

    ការបង្កើតបញ្ហា

    មានគំរូជាច្រើន ដែលនីមួយៗត្រូវបានកំណត់ដោយបំណែកនៃតំណាងកម្រិតមធ្យម ដែលវាអាចអនុវត្តបាន ទម្ងន់ និងលេខកូដដែលបានបង្កើត។ មានមែកធាងតំណាងកម្រិតមធ្យម ដែលជាបំណែកនៃកម្មវិធីដែលវាចាំបាច់ដើម្បីបង្កើតកូដ។ គោលដៅគឺដើម្បីកសាងដូចជាការគ្របដណ្តប់នៃមែកធាងតំណាងកម្រិតមធ្យមជាមួយនឹងគំរូដើម្បីឱ្យទម្ងន់សរុបនៃគំរូគឺមានតិចតួចបំផុត។

    លំនាំគឺជាការណែនាំអំពីការជួបប្រជុំគ្នា និងដើមឈើញែកដែលត្រូវគ្នានឹងពួកវា។ សម្រាប់គំរូនីមួយៗ ពេលវេលាប្រតិបត្តិរបស់វា (ជារង្វង់) ត្រូវបានគេស្គាល់។ ដោយមានជំនួយរបស់ពួកគេ យើងនឹងបង្កើតកូដល្អបំផុត (ក្នុងលក្ខខណ្ឌនៃពេលវេលាប្រតិបត្តិ)។

    ឧទាហរណ៍គំរូ

    ការកសាងតំណាងកម្រិតមធ្យម

    ដំបូង យើងបង្កើតមែកធាងញែកសម្រាប់កន្សោមទាំងមូល។

    ការកសាងការគ្របដណ្តប់

    ឥឡូវនេះសម្រាប់កំពូលនីមួយៗ (យើងឆ្លងកាត់ពួកវាតាមលំដាប់លំដោយពីស្លឹកទៅឫស) យើងនឹងបង្កើតកូដដ៏ល្អប្រសើរសម្រាប់មែកធាងរងរបស់វា។ ដើម្បីធ្វើដូចនេះយើងគ្រាន់តែឆ្លងកាត់គំរូទាំងអស់ដែលអាចអនុវត្តបាននៅចំនុចកំពូលដែលបានផ្តល់ឱ្យ។ ពេលវេលាប្រតិបត្តិនៅពេលប្រើលំនាំជាក់លាក់មួយនឹងជាផលបូកនៃពេលវេលាដែលវាត្រូវការដើម្បីវាយតម្លៃអាគុយម៉ង់របស់វា (ហើយយើងដឹងរួចហើយនូវកូដដ៏ល្អប្រសើរសម្រាប់ការគណនាពួកវាដោយអរគុណចំពោះលំដាប់ឆ្លងកាត់មែកធាង) និងពេលវេលាប្រតិបត្តិនៃគំរូខ្លួនឯង។ ក្នុងចំណោមជម្រើសទាំងអស់ដែលទទួលបាន យើងជ្រើសរើសយកមួយណាដែលល្អបំផុត - វានឹងក្លាយជាកូដដ៏ល្អបំផុតសម្រាប់អនុមែកធាងនៃចំនុចកំពូលនេះ។ នៅឫសនៃមែកធាង យើងទទួលបានកូដល្អបំផុតសម្រាប់កន្សោមទាំងមូល។

    ការបង្កើតកូដ

    វាមិនចាំបាច់ក្នុងការសរសេរកូដសម្រាប់បញ្ឈរទាំងអស់នោះទេ - វាគ្រប់គ្រាន់ក្នុងការសរសេរពេលវេលាដែលត្រូវការអប្បបរមា និងគំរូដែលអ្នកត្រូវការប្រើ។ អ្វីៗផ្សេងទៀតពីនេះត្រូវបានស្ដារឡើងវិញយ៉ាងងាយស្រួល។

    យើងមានចំនួនចុះឈ្មោះមិនកំណត់ក្នុងបញ្ហាទាំងនេះ ដូច្នេះរាល់ពេលដែលអ្នកអាចប្រើថ្មីមួយ។

    ការសាងសង់ RV យោងទៅតាម DKA

    ការស្ថាបនា NFA យោងតាមវេយ្យាករណ៍លីនេអ៊ែរស្តាំ

    ការបញ្ចូលវេយ្យាករណ៍

    ដើម្បីបំប្លែង COP-វេយ្យាករណ៍តាមអំពើចិត្តទៅជាទម្រង់កាត់បន្ថយ អ្នកត្រូវតែអនុវត្តជំហានខាងក្រោម៖

    • លុបតួអក្សរដែលមិនចេះរីងស្ងួតទាំងអស់;
    • លុបតួអក្សរដែលមិនអាចទៅដល់បានទាំងអស់;

    ការដកតួអក្សរដែលគ្មានប្រយោជន៍ចេញ

    ច្រកចូល៖ COP-វេយ្យាករណ៍ G = (T, N, P, S) ។

    ចេញ៖វេយ្យាករណ៍ COP-G' = (T, N', P', S) ដែលមិនមាននិមិត្តសញ្ញាមិនច្បាស់លាស់ ដែល L(G) = L(G')។

    វិធីសាស្រ្ត៖

    សំណុំបង្កើតឡើងវិញ N 0 , N 1 , ...

    1. N 0 = ∅, i = 1 ។
    2. N i = (A | (A → α) ∈ P និង α ∈ (N i − 1 ∪ T)*) ∪ N i-1 ។
    3. ប្រសិនបើ N i ≠ N i - 1 បន្ទាប់មក i = i + 1 ហើយទៅជំហានទី 2 បើមិនដូច្នេះទេ N ' = N i ; P' មានក្បួននៃសំណុំ P ដែលមានតែនិមិត្តសញ្ញាពី N ' ∪ T; G' = (T, N', P', S) ។

    និយមន័យ៖និមិត្តសញ្ញា x ∈ (T ∪ N) ត្រូវបានគេនិយាយថាមិនអាចទៅដល់ក្នុងវេយ្យាករណ៍ G = (T, N, P, S) ប្រសិនបើវាមិនបង្ហាញក្នុងទម្រង់មនោសញ្ចេតនាណាមួយនៃវេយ្យាករណ៍នេះ។

    ឧទាហរណ៍

    លុបតួអក្សរដែលគ្មានប្រយោជន៍ចេញពីវេយ្យាករណ៍ G((A, B, C, D, E, F, S), (a, b, c, d, e, f, g), P, S)

    • S → AcDe | CaDbCe | សាកា | aCb | dFg
    • A → SeAd | cSA
    • B → CaBd | aDBc | BSC | bfg
    • C → Ebd | សែប | aAc | cfF
    • ឃ → fCE | ac | dEdAS | ε
    • អ៊ី → ESacD | អេក | អ៊ីអេហ្វ

    ដំណោះស្រាយ

    • N 0 = ∅
    • N 1 = (B (B → bfg), D (D → ac), E (E → aec))
    • N 2 = (B, D, E, C (C → Ebd))
    • N 3 = (B, D, E, C, S (S → aCb))
    • N 4 \u003d (B, D, E, C, S) \u003d N 3

    G"((B,C,D,E,S), (a, b, c, d, e, f, g), P", S)

    • S → CaDbCe | សាកា | aCb
    • B → CaBd | aDBc | BSC | bfg
    • C → Ebd | សេប
    • ឃ → fCE | ac | ε
    • អ៊ី → ESacD | អេក

    ការដកតួអក្សរដែលមិនអាចទាក់ទងបាន។

    ច្រកចូល៖វេយ្យាករណ៍ COP G = (T, N, P, S)

    ចេញ៖ COP-វេយ្យាករណ៍ G' = (T', N', P', S) ដែលមិនមាននិមិត្តសញ្ញាដែលមិនអាចទៅដល់បាន ដែល L(G) = L(G')។

    វិធីសាស្រ្ត៖

    1. V 0 = (S); ខ្ញុំ = 1 ។
    2. V i = (x | x ∈ (T ∪ N), (A → αxβ) ∈ P និង A ∈ V i − 1 ) ∪ V i-1 ។
    3. ប្រសិនបើ V i ≠ V i - 1 បន្ទាប់មក i = i + 1 ហើយទៅជំហានទី 2 បើមិនដូច្នេះទេ N ' = V i ∩ N; T ' = V i ∩ T ; P' មានច្បាប់នៃសំណុំ P ដែលមាននិមិត្តសញ្ញាតែពី V i ; G' = (T', N', P', S) ។

    និយមន័យ៖ COP-វេយ្យាករណ៍ G ត្រូវបានគេនិយាយថាត្រូវបានកាត់បន្ថយប្រសិនបើវាមិនមាននិមិត្តសញ្ញាដែលមិនអាចសម្រេចបាន និងគ្មានមេរោគ។

    ឧទាហរណ៍

    លុបតួអក្សរដែលមិនអាចទៅដល់បានពីវេយ្យាករណ៍ G"((B, C, D, E, S), (a, b, c, d, e, f, g), P", S)

    • S → CaDbCe | សាកា | aCb
    • B → CaBd | aDBc | BSC | bfg
    • C → Ebd | សេប
    • ឃ → fCE | ac | ε
    • អ៊ី → ESacD | អេក

    ដំណោះស្រាយ

    • V 0 = (S)
    • V 1 = (S, C (S → CaDbCe), D (S → CaDbCe), a (S → CaDbCe), b (S → CaDbCe), e (S → CaDbCe))
    • V 2 = (S, C, D, a, b, e, E, E (C → Ebd), d (C → Ebd), f (D → fCE))
    • V 3 = (S, C, D, E, a, b, d, e, f, c (E → ESacD))
    • V 4 \u003d (S, C, D, E, a, b, d, e, f, c) \u003d V 3

    G""((C,D,E,S), (a, b, c, d, e, f), P"", S)

    • S → CaDbCe | សាកា | aCb
    • C → Ebd | សេប
    • ឃ → fCE | ac | ε
    • អ៊ី → ESacD | អេក

    វាងាយស្រួលជាងក្នុងការពិពណ៌នាវាក្យសព្ទនៃភាសាក្នុងទម្រង់នៃកន្សោមធម្មតា និងដើម្បីស្គាល់ភាសាដោយមានជំនួយពី KA ។ ដូច្នេះ វាមានសារៈសំខាន់ណាស់ក្នុងការបំប្លែងនិយមន័យភាសាក្នុងទម្រង់នៃកន្សោមធម្មតាទៅជានិយមន័យក្នុងទម្រង់ FA។ ការផ្លាស់ប្តូរបែបនេះត្រូវបានស្នើឡើងដោយ Kennet Thompson ។

    ម៉ាស៊ីនរដ្ឋគឺប្រាំ (S, S, d, S 0, F)

    S គឺជាសំណុំនៃរដ្ឋ។

    S គឺជាសំណុំកំណត់នៃសញ្ញាបញ្ចូលត្រឹមត្រូវ។

    ឃ - មុខងារផ្លាស់ប្តូរ។ វាឆ្លុះបញ្ចាំងពីសំណុំ Sx(SÈ(e)) ទៅក្នុងសំណុំនៃរដ្ឋនៃ automaton កំណត់ដែលមិនកំណត់។ សម្រាប់ automaton កំណត់ មុខងារផ្លាស់ប្តូរឆ្លុះបញ្ចាំងពីសំណុំ SxS ទៅក្នុងសំណុំនៃរដ្ឋ automaton ។ នៅក្នុងពាក្យផ្សេងទៀតអាស្រ័យលើស្ថានភាពនិងនិមិត្តសញ្ញាបញ្ចូល d កំណត់ស្ថានភាពថ្មីនៃ automaton ។

    S 0 - ស្ថានភាពដំបូងនៃ automaton កំណត់ S 0 О S ។

    F គឺជាសំណុំនៃរដ្ឋចុងក្រោយនៃ automaton F О S ។

    ប្រតិបត្តិការនៃម៉ាស៊ីនរដ្ឋគឺជាលំដាប់នៃជំហាន។ ជំហានត្រូវបានកំណត់ដោយស្ថានភាពនៃ automaton និងនិមិត្តសញ្ញាបញ្ចូល។ ជំហានខ្លួនវាមាននៅក្នុងការផ្លាស់ប្តូរស្ថានភាពនៃ automaton និងអាននិមិត្តសញ្ញាបន្ទាប់នៃលំដាប់បញ្ចូល។

    មានច្បាប់ខាងក្រោមសម្រាប់បំប្លែងកន្សោមធម្មតាទៅជាម៉ាស៊ីនរដ្ឋ។

    1 កន្សោមធម្មតា “e” ត្រូវបានបំប្លែងទៅជា automaton នៃរដ្ឋពីរ និងការផ្លាស់ប្តូរ e-transition រវាងពួកវា (រូបភាពទី 1)។

    រូបភាពទី 1. - Automaton សម្រាប់ការផ្លាស់ប្តូរអេឡិចត្រូនិច

    2 កន្សោមធម្មតាពីតួអក្សរមួយ “a” ត្រូវបានបំប្លែងទៅជាម៉ាស៊ីនរដ្ឋកំណត់ពីរដ្ឋពីរ និងការផ្លាស់ប្តូររវាងពួកវាយោងទៅតាមសញ្ញាបញ្ចូល a (រូបភាពទី 2) ។

    រូបភាពទី 2. - Automaton សម្រាប់លោតដោយនិមិត្តសញ្ញា a

    3 សូមឱ្យមានកន្សោមធម្មតា rs និង finite automata សម្រាប់កន្សោម r ហើយកន្សោម s ត្រូវបានសាងសង់រួចហើយ។ បន្ទាប់មក automata ទាំងពីរត្រូវបានភ្ជាប់ជាស៊េរី។ រូបភាពទី 3 បង្ហាញ automata ដំបូងសម្រាប់ភាសា r និង s ។ តួលេខនេះបង្ហាញពីស្វ័យប្រវត្តិកម្មសម្រាប់ការទទួលស្គាល់ការភ្ជាប់គ្នានៃភាសាទាំងនេះ។

    ស្វ័យប្រវត្តិសម្រាប់ r ស្វ័យប្រវត្តិសម្រាប់ s

    រូបភាពទី 3. - automata ដំបូង


    រូបភាពទី 4. - ម៉ាស៊ីនសម្រាប់ភ្ជាប់ភាសា

    4 ចូរមានកន្សោមធម្មតា r| s និង finite automata ត្រូវបានបង្កើតឡើងរួចហើយសម្រាប់កន្សោម r និងកន្សោម s (រូបភាពទី 3) ។ បន្ទាប់មកនៅក្នុង automaton លទ្ធផលត្រូវតែមានជម្រើសនៃការប្រតិបត្តិ automata មួយក្នុងចំណោមពីរ។ នោះគឺ automaton សម្រាប់កន្សោម r | s សម្រាប់ automata សម្រាប់ r និង s ពីរូបភាពទី 3 មានទម្រង់បង្ហាញក្នុងរូបភាពទី 5 ។

    រូបភាពទី 5. - ម៉ាស៊ីនសម្រាប់ផ្សំភាសា

    5 អនុញ្ញាតឱ្យមានកន្សោមធម្មតា r* ជាមួយ constructed finite automaton r ។ ក្នុងករណីនេះ រដ្ឋថ្មីពីរត្រូវបានណែនាំសម្រាប់លទ្ធភាពនៃការរំលង automaton នៃកន្សោម r ហើយការផ្លាស់ប្តូរ e-transition រវាងរដ្ឋចុងក្រោយ និងដំបូងត្រូវបានណែនាំសម្រាប់លទ្ធភាពនៃការធ្វើម្តងទៀតច្រើននៃ automaton r ។ ប្រសិនបើ automaton ស្រដៀងនឹងរូបភាពទី 3 ត្រូវបានបង្កើតឡើងសម្រាប់កន្សោមធម្មតា r នោះ automaton កំណត់ដែលបង្ហាញក្នុងរូបភាពទី 6 ត្រូវគ្នាទៅនឹងកន្សោមធម្មតា r* ។


    ការកំណត់

    យោងតាមទ្រឹស្ដីរបស់ Kleene កន្សោមធម្មតាណាមួយអាចត្រូវបានផ្សារភ្ជាប់ជាមួយនឹង automaton finite ដែលជាគំរូផ្លូវការនៃក្បួនដោះស្រាយសម្រាប់ការទទួលស្គាល់ lexemes ដែលតំណាងដោយកន្សោមធម្មតានេះ។ នៅក្នុងលក្ខខណ្ឌទូទៅបំផុត ឧបករណ៍សម្គាល់ស្វ័យប្រវត្តិ កំណត់ត្រូវបានកំណត់ដោយការកំណត់ជាក់លាក់នៃចរន្តបញ្ចូលនៃលក្ខណៈរបស់វា និងការផ្លាស់ប្តូររវាងពួកវា។ ការផ្លាស់ប្តូរស្ថានភាពកើតឡើងនៅពេលដែលទទួលបានតួអក្សរនៃស្ទ្រីមបញ្ចូលពីអក្ខរក្រមដែលបានផ្តល់ឱ្យដោយអនុលោមតាមមុខងារផ្លាស់ប្តូរដែលកំណត់ស្ថានភាពជាបន្តបន្ទាប់ដែលអាចកើតមានពីតួអក្សរបញ្ចូលនិងស្ថានភាពបច្ចុប្បន្ន។ ក្នុងចំណោមរដ្ឋដែលអាចធ្វើបាន រដ្ឋដំបូង (ដំបូង) និងចុងក្រោយ (អនុញ្ញាត) ត្រូវបានដាក់ចេញ ដែលក្នុងនោះអ្នកសម្គាល់ម៉ាស៊ីនរដ្ឋអាចរៀងគ្នានៅដើមដំបូង និងការបញ្ចប់ដំណើរការនៃសញ្ញាស្ទ្រីមបញ្ចូល។ ប្រសិនបើលំដាប់បញ្ចូលនៃតួអក្សរអាចបង្កើតលំដាប់នៃការផ្លាស់ប្តូរដែលអាចផ្ទេរ automaton កំណត់ពីស្ថានភាពដំបូងទៅជាចុងក្រោយមួយ នោះវាត្រូវបានចាត់ទុកថាជាការទទួលយក និងជាកម្មសិទ្ធិរបស់សំណុំធម្មតាដែលវាទទួលស្គាល់។


    (00|11)*((01|10)(00|11)*(01|10)(00|11)*)*

    តារាងទី 1

    0 1
    សំណួរទី 1សំណួរទី 4សំណួរទី 2
    សំណួរទី 2សំណួរទី 3សំណួរទី 1
    សំណួរទី 3សំណួរទី 2សំណួរទី 4
    សំណួរទី 4សំណួរទី 1សំណួរទី 3

    ជួរឈរនៃតារាងផ្លាស់ប្តូរតំណាងឱ្យតួអក្សរនៃអក្ខរក្រមបញ្ចូល ហើយជួរដេកត្រូវគ្នាទៅនឹងស្ថានភាពបច្ចុប្បន្ននៃ DFA ។ ធាតុនៃបន្ទាត់នីមួយៗបង្ហាញពីស្ថានភាពនៃ DFA ដែលវាគួរតែផ្លាស់ប្តូរពីស្ថានភាពបច្ចុប្បន្ន នៅពេលទទួលបានតួអក្សរដែលត្រូវគ្នានៃអក្ខរក្រមបញ្ចូល។ ជាពិសេស វាធ្វើតាមពីជួរទីមួយនៃតារាងផ្លាស់ប្តូរនេះ ដែលការទទួលនិមិត្តសញ្ញា 0 និង 1 នៅក្នុងរដ្ឋដំបូង Q1 ផ្ទេរ DFA ទៅរដ្ឋ Q4 និង Q2 រៀងគ្នា។

    នៅពេលទទួលស្គាល់លំដាប់បញ្ចូលពីតារាងផ្លាស់ប្តូរ វាងាយស្រួលក្នុងការតាមដានការផ្លាស់ប្តូររដ្ឋនៃ DFA ដើម្បីកំណត់ថាតើរដ្ឋទទួលយកណាមួយត្រូវបានឈានដល់ឬអត់។ ជាពិសេស សម្រាប់វ៉ិចទ័រគោលពីរ 01001000 ដែលមានលេខគូនៃលេខសូន្យ និងលេខមួយនោះ DFA ដែលបានពិចារណាបង្កើតលំដាប់នៃការផ្លាស់ប្តូរខាងក្រោម ដែលការផ្លាស់ប្តូរនីមួយៗត្រូវបានដាក់ស្លាកដោយតួអក្សរនៃអក្ខរក្រមបញ្ចូលដែលហៅវាថា:


    Q1 0 Q4 1 Q3 0 Q2 0 Q3 1 Q4 1 Q1 0 Q4 0 Q1


    លំដាប់នៃការផ្លាស់ប្តូរនេះបញ្ចប់ដោយស្ថានភាពទទួលយក Q1 ដូច្នេះ វ៉ិចទ័រគោលពីរ 01001000 ជាកម្មសិទ្ធិរបស់សំណុំធម្មតាដែលទទួលស្គាល់ដោយ DFA ដែលបានពិចារណា និងបំពេញកន្សោមធម្មតាខាងលើ។

    នៅក្នុងការសន្និដ្ឋានវាគួរតែត្រូវបានកត់សម្គាល់ថាវិធីសាស្រ្តក្រៅផ្លូវការដែលត្រូវបានចាត់ទុកថាជាការសាងសង់

    កន្សោមធម្មតា (REs) គឺជាទម្រង់នៃការសរសេរដ៏ងាយស្រួលបំផុត ដែលហៅថាភាសាធម្មតា ឬដោយស្វ័យប្រវត្តិ។ ដូច្នេះ RT ត្រូវបានប្រើជាភាសាបញ្ចូលក្នុងប្រព័ន្ធជាច្រើនដែលដំណើរការខ្សែសង្វាក់។ ពិចារណាឧទាហរណ៍នៃប្រព័ន្ធបែបនេះ៖

    • ពាក្យបញ្ជា Unix grep ឬពាក្យបញ្ជាស្រដៀងគ្នាសម្រាប់ការស្វែងរកខ្សែអក្សរ ដូចដែលមាននៅក្នុងកម្មវិធីរុករកតាមអ៊ីនធឺណិត ឬប្រព័ន្ធធ្វើទ្រង់ទ្រាយអត្ថបទ។ នៅក្នុងប្រព័ន្ធបែបនេះ REs ត្រូវបានប្រើដើម្បីពិពណ៌នាអំពីលំនាំដែលអ្នកប្រើប្រាស់កំពុងស្វែងរកនៅក្នុងឯកសារមួយ។ ម៉ាស៊ីនស្វែងរកផ្សេងៗបំប្លែង RT ទៅជាម៉ាស៊ីនកំណត់រដ្ឋកំណត់ (DFA) ឬម៉ាស៊ីនរដ្ឋកំណត់មិនកំណត់ (NFA) ហើយអនុវត្តម៉ាស៊ីនរដ្ឋនេះទៅនឹងឯកសារដែលកំពុងស្វែងរក។
    • ម៉ាស៊ីនភ្លើងវិភាគ Lexical ។ ឧបករណ៍វិភាគ Lexical គឺជាធាតុផ្សំនៃអ្នកចងក្រង ពួកវាបំបែកកម្មវិធីប្រភពទៅជាឯកតាតក្កវិជ្ជា (និមិត្តសញ្ញា) ដែលអាចមានតួអក្សរមួយ ឬច្រើន និងមានអត្ថន័យជាក់លាក់។ ម៉ាស៊ីនបង្កើតឧបករណ៍វិភាគ lexical យកការពិពណ៌នាផ្លូវការនៃសញ្ញាសម្ងាត់ ដែលសំខាន់គឺ REs ហើយបង្កើត DFA ដែលទទួលស្គាល់ថាសញ្ញាសម្ងាត់ណាដែលបង្ហាញនៅក្នុងការបញ្ចូលរបស់វា។
    • RT ជាភាសាសរសេរកម្មវិធី។

    នៅក្នុងអត្ថបទនេះ ជាដំបូងយើងនឹងស្គាល់ automata កំណត់ និងប្រភេទរបស់ពួកគេ (DFA និង NFA) ហើយបន្ទាប់មកយើងនឹងពិចារណាឧទាហរណ៍នៃការកសាង DFA តិចតួចដោយប្រើកន្សោមធម្មតា។

    ម៉ាស៊ីនរបស់រដ្ឋ

    A finite automaton (FA) គឺជាកម្មវិធីបំប្លែងដែលអនុញ្ញាតឱ្យអ្នកភ្ជាប់ធាតុបញ្ចូលជាមួយទិន្នផលដែលត្រូវគ្នា ហើយលទ្ធផលនេះអាចអាស្រ័យមិនត្រឹមតែលើការបញ្ចូលបច្ចុប្បន្នប៉ុណ្ណោះទេ ប៉ុន្តែថែមទាំងលើអ្វីដែលបានកើតឡើងពីមុន នៅបុរេប្រវត្តិនៃ automaton កំណត់ផងដែរ។ សូម្បីតែអាកប្បកិរិយារបស់មនុស្ស និងមិនត្រឹមតែប្រព័ន្ធសិប្បនិម្មិតប៉ុណ្ណោះទេ អាចត្រូវបានពិពណ៌នាដោយប្រើ CA ។ ដោយប្រើ KA មនុស្សម្នាក់អាចពិពណ៌នាមិនត្រឹមតែអាកប្បកិរិយានៃប្រព័ន្ធសិប្បនិម្មិតប៉ុណ្ណោះទេថែមទាំងអាកប្បកិរិយារបស់មនុស្សផងដែរ។ ជាឧទាហរណ៍ ប្រតិកម្មរបស់អ្នកចំពោះការពិតដែលថាអ្នកជិតខាងរបស់អ្នកស្តាប់តន្ត្រីខ្លាំងនៅពេលយប់នឹងមានតែមួយបន្ទាប់ពីការកើតឡើងបែបនេះជាលើកដំបូង និងខុសគ្នាទាំងស្រុងបន្ទាប់ពីការកើតឡើងបែបនេះជាច្រើន។ វា​អាច​មាន​ចំនួន​មិន​កំណត់​នៃ​រឿង​រ៉ាវ​បែប​នេះ backstories សំណួរ​កើត​ឡើង​; តើ​យាន​អវកាស​គួរ​មាន​ការចងចាំ​ប្រភេទ​ណា ដើម្បី​មាន​ឥរិយាបទ​ខុសៗ​គ្នា​សម្រាប់​ការរៀបចំ​ជាមុន​នីមួយៗ? វាច្បាស់ណាស់ថាវាមិនអាចរក្សាទុកនូវចំនួនបុរេប្រវត្តិសាស្ត្រដែលគ្មានកំណត់បានទេ។ ដូច្នេះ automaton ដូចដែលវាធ្លាប់បានបែងចែកបុរេប្រវត្តិដែលអាចធ្វើបានទាំងអស់ទៅជាថ្នាក់សមមូល។ ប្រវតិ្តសាស្រ្តពីរគឺស្មើនឹងប្រសិនបើពួកគេមានឥទ្ធិពលស្មើគ្នាលើអាកប្បកិរិយារបស់ automaton នាពេលអនាគត។ ថ្នាក់សមមូលដែល automaton សន្មតថាជាប្រវត្តិបច្ចុប្បន្នរបស់វាត្រូវបានគេហៅថាស្ថានភាពខាងក្នុងនៃ automaton ផងដែរ។

    ឥឡូវនេះសូមក្រឡេកមើលវិធីដែល CA អាចបញ្ជាក់បាន។ ពួកវាអាចត្រូវបានបញ្ជាក់ជាទម្រង់ក្រាហ្វ ឬក្នុងទម្រង់តារាងត្រួតពិនិត្យ។ ក្នុងទម្រង់ក្រាហ្វ KA ត្រូវបានបញ្ជាក់តាមវិធីខាងក្រោម៖

    • ចំនុចកំពូលនៃក្រាហ្វត្រូវគ្នាទៅនឹងរដ្ឋនៃ CA ។
    • គែមដែលដឹកនាំត្រូវគ្នាទៅនឹងមុខងារផ្លាស់ប្តូរ (នៅជិតគែមនីមួយៗ និមិត្តសញ្ញាដែលការផ្លាស់ប្តូរត្រូវបានអនុវត្តត្រូវបានចង្អុលបង្ហាញ) ។
    • ចំនុចកំពូលដែលមានគែមបញ្ចូលវាដែលមិនទុករដ្ឋច្រើនជាងមួយត្រូវគ្នាទៅនឹងស្ថានភាពដំបូង។
    • រដ្ឋចុងក្រោយនៃ CA ត្រូវបានសម្គាល់ដោយគ្រោងដិត។

    នៅក្នុងទម្រង់នៃតារាងត្រួតពិនិត្យដូចនេះ៖

    • រដ្ឋ KA មានទីតាំងនៅជួរតារាង។
    • តួអក្សរនៃភាសាដែលបានទទួលស្គាល់ - នៅក្នុងជួរឈរ។
    • នៅចំនុចប្រសព្វ រដ្ឋត្រូវបានចង្អុលបង្ហាញ ដែលអាចទៅដល់ពីស្ថានភាពដែលបានផ្តល់ឱ្យដោយនិមិត្តសញ្ញាដែលបានផ្តល់ឱ្យ។

    ឧទាហរណ៍នៃ KA ក្នុងទម្រង់ជាក្រាហ្វ និងជាទម្រង់តារាងត្រួតពិនិត្យនឹងត្រូវបានបង្ហាញខាងក្រោម។

    DKA និង NKA

    ភាពខុសគ្នាសំខាន់រវាង DFA និង NFA គឺថា DFA អាចស្ថិតនៅក្នុងរដ្ឋតែមួយក្នុងអំឡុងពេលប្រតិបត្តិការ ខណៈពេលដែល NFA អាចស្ថិតនៅក្នុងរដ្ឋជាច្រើនក្នុងពេលតែមួយ។ ជាឧទាហរណ៍នៃការងាររបស់ NCA មនុស្សម្នាក់អាចដកស្រង់គំនិតរបស់អ្នករូបវិទ្យាជនជាតិអាមេរិកលោក Hugh Everett ថាព្រឹត្តិការណ៍ណាមួយបំបែកពិភពលោកទៅជាពិភពលោកជាច្រើន ដែលព្រឹត្តិការណ៍នីមួយៗនេះបានបញ្ចប់តាមរបៀបរបស់ខ្លួន។ ជាឧទាហរណ៍ ក្នុងពិភពលោកមួយ ហ៊ីត្លែរបានឈ្នះពិភពលោកទី២។ សង្គ្រាមនៅក្នុងមួយទៀត - ញូតុនជំនួសឱ្យរូបវិទ្យាបានចូលទៅក្នុងអាជីវកម្មហើយការរកឃើញច្បាប់នៃមេកានិចបុរាណត្រូវពន្យារពេល 50 ឆ្នាំ។ ដើម្បីទាញសេចក្តីសន្និដ្ឋានណាមួយពីប្រតិបត្តិការរបស់ម៉ាស៊ីនគួរតែសិក្សា "ពិភពលោក" ទាំងអស់។ បន្ទាប់ពីខ្សែសង្វាក់បញ្ចូលទាំងមូលត្រូវបានអានរួច យើងសន្មត់ថា NFA ទទួលយកខ្សែសង្វាក់នេះ ប្រសិនបើវាបានបញ្ចប់ការងាររបស់ខ្លួននៅក្នុងស្ថានភាពទទួលយកនៅក្នុង "ពិភពលោក" យ៉ាងហោចណាស់មួយក្នុងចំណោម "ពិភពលោក" ជាច្រើន។ ដូច្នោះហើយ automaton ច្រានចោលការរត់ចោលប្រសិនបើវាត្រូវបានបញ្ចប់នៅក្នុងស្ថានភាពដែលមិនអាចទទួលយកបាននៅក្នុង "ពិភពលោក" នីមួយៗ។ ម្យ៉ាងវិញទៀត DFA ទទួលយកខ្សែអក្សរ នេះច្បាស់ណាស់ ប្រសិនបើបន្ទាប់ពីអានខ្សែអក្សរបញ្ចូលទាំងមូល វាឃើញខ្លួនឯងនៅក្នុងស្ថានភាពទទួលយក។

    ក្នុងករណីភាគច្រើន ការកសាង NFA គឺងាយស្រួលជាងការកសាង DFA ច្រើន។ ប៉ុន្តែទោះបីជានេះក៏ដោយ ការប្រើប្រាស់ NFA សម្រាប់ការធ្វើគំរូមិនមែនជាគំនិតល្អទេ។ ជាសំណាងល្អ សម្រាប់ NFA នីមួយៗ វាអាចបង្កើត DFA ដែលទទួលយកភាសាបញ្ចូលដូចគ្នា។ នៅក្នុងអត្ថបទនេះ យើងនឹងមិនបង្ហាញក្បួនដោះស្រាយសម្រាប់ការសាងសង់ DFA ពី NFA ទេ ប៉ុន្តែសូមពិចារណាក្បួនដោះស្រាយនេះដោយផ្អែកលើឧទាហរណ៍ដែលមើលឃើញខាងក្រោម។

    ការកសាង DFA អប្បបរមាពីកន្សោមធម្មតា។

    ដើម្បីចាប់ផ្តើម ខាងក្រោមនេះជាវាក្យសម្ព័ន្ធ RW ដែលប្រើក្នុងអត្ថបទនេះ៖

    • ការភ្ជាប់គ្នាត្រូវបានបញ្ជាក់ដោយដកឃ្លា ឬខ្សែអក្សរទទេ (ឧទាហរណ៍៖ ab)
    • សហជីពដោយប្រើនិមិត្តសញ្ញា "|"
    • ការធ្វើឡើងវិញ (ការបិទ Kleene) ដែលមានតួអក្សរ "*"

    ពិចារណាឧទាហរណ៍មួយដែលផ្តល់កន្សោមធម្មតា៖

    xy* (x | y*) | ab (x | y *) | (x | a*) (x | y*)

    វាចាំបាច់ក្នុងការបង្កើត DFA តិចតួចពីកន្សោមធម្មតា និងបង្ហាញពីការទទួលស្គាល់ខ្សែអក្សរត្រឹមត្រូវ និងមិនត្រឹមត្រូវ។

    ដើម្បីចាប់ផ្តើម យើងសម្រួល RT នេះ ដោយប្រើច្បាប់ចែកចាយដៃស្តាំនៃការភ្ជាប់គ្នាទាក់ទងនឹងសហជីព យើងទទួលបាន RT ខាងក្រោម៖

    (xy* | ab | (x | a*)) (x | y*)

    ឥឡូវនេះយើងបង្កើត automaton សម្រាប់ RV នេះ៖

    យោងទៅតាមច្បាប់នៃការផ្លាស់ប្តូរការភ្ជាប់គ្នា (យើងនឹងមិនផ្តល់ច្បាប់សម្រាប់បំលែង RV ទៅជា KA ទេព្រោះវាច្បាស់ណាស់) យើងទទួលបាន automaton ដូចខាងក្រោម:

    តាមវិធាននៃការផ្លាស់ប្តូរសហជីព៖

    យោងទៅតាមច្បាប់នៃការផ្លាស់ប្តូរ concatenation:

    ហើយនៅចុងបញ្ចប់ យើងអនុវត្តច្បាប់បំលែងការបិទ ហើយទទួលបានεNCA៖

    យើងកម្ចាត់ ε-transitions ("សញ្ញាផ្កាយ" តំណាងឱ្យរដ្ឋចុងក្រោយ):

    នៅក្នុង NFA នេះ រដ្ឋ s3 និង s5 គឺសមមូល ចាប់តាំងពី δ(s3, x) = δ(s5, x) = s1 និង δ(s3, y) = δ(s5, y) = s5, s7 ។ ប្តូរឈ្មោះរដ្ឋ s6 -> s5 និង s7 -> s6:

    យើងបង្កើត DFA យោងតាម ​​NFA៖

    នៅក្នុង DFA នេះ រដ្ឋ p1 និង p5 គឺសមមូល ចាប់តាំងពី
    δ(p1, x) = δ(p5, x) = p4 និង δ(p1, y) = δ(p5, y) = p5 ។ ប្តូរឈ្មោះរដ្ឋ p6 -> p5 និង p7 -> p6:

    ស្វ័យប្រវត្តិនេះគឺជា DFA អប្បបរមា។

    អនុញ្ញាតឱ្យ δ ជាអនុគមន៍ផ្លាស់ប្តូរ បន្ទាប់មកអនុគមន៍ផ្លាស់ប្តូរដែលបានពង្រីកពី δ នឹងត្រូវបានតាងដោយ δ' ហើយ ω គឺជាខ្សែអក្សរបញ្ចូល។

    អនុញ្ញាតឱ្យខ្សែសង្វាក់ ω = aaax ត្រូវបានបញ្ចូល យើងរំពឹងថា automaton នឹងស្ថិតនៅក្នុងរដ្ឋមួយដែលទទួលយក។

    δ'(p0, ε) = p0
    δ'(p0, a) = δ(δ'(p0, ε), a) = δ(p0, a) = p3
    δ'(p0, aa) = δ(δ'(p0, a), a) = δ(p3, a) = p5
    δ'(p0, aaa) = δ(δ'(p0, aa), a) = δ(p5, a) = p5
    δ'(p0, aaax) = δ(δ'(p0, aaa), a) = δ(p5, a) = p4

    p4 គឺជាស្ថានភាពបញ្ចប់ត្រឹមត្រូវ ដូច្នេះខ្សែអក្សរ aaax មានសុពលភាពសម្រាប់ automaton នេះ។

    ឥឡូវឧបមាថា ω = xyyb៖

    δ'(p0, ε) = p0
    δ'(p0, x) = δ(δ'(p0, ε), x) = δ(p0, x) = p1
    δ'(p0, xy) = δ(δ'(p0, x), y) = δ(p1, y) = p1
    δ'(p0, xyy) = δ(δ'(p0, xy), y) = δ(p1, y) = p1
    δ'(p0, xyyb) = δ(δ'(p0, xyy), b) = δ(p1, b) = ∅

    នៅទីនេះយើងឃើញថាប្រសិនបើនិមិត្តសញ្ញា b ត្រូវបានបញ្ចូលទៅ automaton នៅពេលដែលវាស្ថិតនៅក្នុងស្ថានភាព p1 នោះ automaton នេះនឹងស្លាប់ ដូច្នេះសង្វាក់ xyyb មិនត្រឹមត្រូវទេ។

    P. S. នៅក្នុងអត្ថបទនេះ ក្បួនដោះស្រាយសម្រាប់សាងសង់ DFA ដោយ RT ត្រូវបានពិចារណា ប៉ុន្តែមានក្បួនដោះស្រាយងាយស្រួលជាង ជាពិសេសសម្រាប់ការសរសេរកម្មវិធី ប៉ុន្តែនេះគឺជាប្រធានបទសម្រាប់អត្ថបទមួយទៀត ...


    សម្រាប់ការសិក្សាបន្ថែមអំពីលក្ខណៈសម្បត្តិរបស់ finite automata និងជាពិសេសសម្រាប់ការដោះស្រាយបញ្ហាសំយោគ ទ្រឹស្តីបទខាងក្រោមមានសារៈសំខាន់។


    ទ្រឹស្តីបទ ៧.៧ (ទ្រឹស្តីបទកំណត់) ។ សម្រាប់ automaton finite ណាមួយ automaton finite deterministic សមមូលអាចត្រូវបានសាងសង់។


    ដើម្បីបញ្ជាក់ទ្រឹស្តីបទ វាជាការចាំបាច់ដំបូងដើម្បីពិពណ៌នាអំពីក្បួនដោះស្រាយសម្រាប់ការសាងសង់ automaton finite deterministic ពីដើមមួយ; ទីពីរ បង្ហាញអំពីភាពត្រឹមត្រូវនៃក្បួនដោះស្រាយនេះដោយបញ្ជាក់យ៉ាងម៉ឺងម៉ាត់ថា វាពិតជាផ្តល់នូវ automaton កំណត់ដែលកំណត់ និងសមមូលទៅនឹងឧបករណ៍ដើម។ នៅទីនេះយើងបង្ហាញតែក្បួនដោះស្រាយសម្រាប់បង្កើត automaton កំណត់ប៉ុណ្ណោះ។


    ការផ្លាស់ប្តូរនៃ automaton កំណត់តាមអំពើចិត្តទៅជា deterministic សមមូលត្រូវបានអនុវត្តជាពីរដំណាក់កាល៖ ដំបូង arcs ជាមួយ label \lambda ត្រូវបានដកចេញ បន្ទាប់មកការប្តេជ្ញាចិត្តពិតប្រាកដត្រូវបានអនុវត្ត។


    1. ការយកចេញនៃការផ្លាស់ប្តូរ λ (ធ្នូដែលមានស្លាក \lambda ) ។


    ដើម្បីផ្លាស់ទីពីម៉ាស៊ីនរដ្ឋដើម M=(V,Q,q_0,F,\delta)ទៅ automaton កំណត់ដែលសមមូល M"=(V,Q",q_0,F",\delta")ដោយគ្មានការផ្លាស់ប្តូរ λ វាគ្រប់គ្រាន់ដើម្បីអនុវត្តការបំប្លែងដូចខាងក្រោមនៅក្នុងក្រាហ្វដើម M.


    ក. រដ្ឋទាំងអស់ លើកលែងតែរដ្ឋដំបូងដែលត្រូវបានបញ្ចូលដោយធ្នូដែលមានស្លាក \lambda ប៉ុណ្ណោះត្រូវបានដកចេញ។ វាកំណត់សំណុំ Q" នៃ automaton M" ។ វាច្បាស់ណាស់ថា Q"\subseteq Q ក្នុងករណីនេះ យើងសន្មត់ថាស្ថានភាពដំបូងនៅដដែល។


    ខ. សំណុំនៃធ្នូនៃ automaton កំណត់ M" និងស្លាករបស់ពួកគេ (ដូច្នេះមុខងារផ្លាស់ប្តូរ M") ត្រូវបានកំណត់ដូចខាងក្រោម: សម្រាប់រដ្ឋទាំងពីរណាមួយ p,r\in Q",~ p\to_(a)rកាន់ប្រសិនបើ a\in V ហើយមួយក្នុងចំណោមខាងក្រោមមាននៅក្នុងក្រាហ្វ M: ទាំងមានធ្នូពី p ដល់ r ដែលស្លាកមាននិមិត្តសញ្ញា a ឬមានស្ថានភាព q ដូចនោះ។ p\Rightarrow_(\lambda)^(+)qនិង q\to_(a)r . ក្នុងករណីនេះ vertex q ដែលនិយាយជាទូទៅ ប្រហែលជាមិនមែនជារបស់ set Q "ទេ ពោលគឺ វាអាចបាត់នៅពេលឆ្លងកាត់ automaton M" (រូបភាព 7.11)។ ប៉ុន្តែប្រសិនបើ q\in Q" នោះតាមធម្មជាតិ ធ្នូ (q,r) នឹងត្រូវបានរក្សាទុកជា M" ហើយនិមិត្តសញ្ញា a នឹងក្លាយជានិមិត្តសញ្ញាមួយក្នុងចំណោមនិមិត្តសញ្ញាដែលជាកម្មសិទ្ធិរបស់ស្លាកនៃធ្នូនេះ (រូបភាព 7.12)។


    ដូច្នេះនៅក្នុង M" arcs M ទាំងអស់ត្រូវបានរក្សាទុកដែលស្លាករបស់វាខុសពី \lambda ហើយដែលភ្ជាប់គូ (បញ្ឈរ) នៃរដ្ឋពីសំណុំ Q" (មិនត្រូវបានដកចេញយោងទៅតាមធាតុ a) ។ លើសពីនេះទៀតសម្រាប់រដ្ឋបីដង p,q,r (មិនចាំបាច់ខុសគ្នាទេ!) ដូចជា p,r\in Q" ហើយមានផ្លូវនៃប្រវែងមិនសូន្យពី p ទៅ q ដែលស្លាកគឺស្មើនឹង \lambda (ឧ. ផ្លូវដោយ λ-transitions) និងពី q ទៅ r អ័ក្សនាំមុខ ស្លាកដែលមាននិមិត្តសញ្ញា a នៃអក្ខរក្រមបញ្ចូលក្នុង M" arc ត្រូវបានសាងសង់ពី p ដល់ r ស្លាកដែលមាន និមិត្តសញ្ញា a (សូមមើលរូប 7.11)។


    នៅក្នុង សំណុំនៃរដ្ឋចុងក្រោយ F" នៃ finite automaton M" មានរដ្ឋទាំងអស់ q\in Q" ពោលគឺរដ្ឋនៃ automaton កំណត់ M ដែលមិនត្រូវបានលុបដោយយោងតាមធាតុ a ដែល q\Rightarrow_(\lambda)^(\ast)q_fសម្រាប់ q_f\in F មួយចំនួន (នោះគឺថារដ្ឋ q ខ្លួនវាគឺជាស្ថានភាពចុងក្រោយនៃ automaton កំណត់ M ឬពីវាមានផ្លូវនៃប្រវែងមិនសូន្យតាមអ័ក្សដែលមានស្លាក \lambda ទៅរដ្ឋចុងក្រោយមួយនៃដែនកំណត់។ automaton M ) (រូបភាព 7.13) ។


    2. ការប្តេជ្ញាចិត្តពិតប្រាកដ។


    អនុញ្ញាតឱ្យ M=(Q,V,q_0,F,\delta)គឺជា automaton កំណត់ដោយគ្មាន λ-transitions ។ ចូរយើងបង្កើត automaton finite finite automaton M_1 ដែលមានតម្លៃស្មើ។


    automaton កំណត់នេះត្រូវបានកំណត់តាមវិធីដែលកំណត់សភាពរបស់វាគឺជាសំណុំនៃសំណុំរងទាំងអស់នៃ state set of the finite automaton M . នេះមានន័យថារដ្ឋនីមួយៗនៃ automaton កំណត់ M_1 ត្រូវបានកំណត់ជាសំណុំរងមួយចំនួននៃរដ្ឋកំណត់នៃ automaton M . ក្នុងករណីនេះ ស្ថានភាពដំបូងនៃ automaton finite ថ្មី (ឧទាហរណ៍ M_1 ) គឺជាសំណុំរង singleton ដែលមានស្ថានភាពដំបូងនៃ automaton finite ចាស់ (ឧទាហរណ៍ M ) ហើយស្ថានភាពចុងក្រោយនៃ finite automaton ថ្មី គឺជាសំណុំរង Q ទាំងអស់ដែលមាន យ៉ាងហោចណាស់មួយចុងក្រោយនៃកំពូលនៃ automaton កំណត់ដើម M .


    ចាប់ពីពេលនេះតទៅ ដោយអនុញ្ញាតឱ្យមានសេរីភាពក្នុងការនិយាយ ពេលខ្លះយើងនឹងហៅស្ថានភាពនៃ automaton កំណត់ M_1 states-sets ។ ទោះជាយ៉ាងណាក៏ដោយ វាមានសារៈសំខាន់ណាស់ក្នុងការយល់យ៉ាងច្បាស់ថា សំណុំរដ្ឋនីមួយៗគឺជាស្ថានភាពដាច់ដោយឡែកនៃ automaton កំណត់ថ្មី ប៉ុន្តែមិនមែនជាសំណុំនៃរដ្ឋរបស់វានោះទេ។ ក្នុងពេលជាមួយគ្នានេះសម្រាប់ automaton ដើម ("ចាស់") finite automaton M នេះពិតជាសំណុំនៃរដ្ឋរបស់វា។ និយាយជាន័យធៀប សំណុំរងនីមួយៗនៃរដ្ឋនៃ automaton កំណត់ចាស់ត្រូវបាន "ដួលរលំ" ទៅជាស្ថានភាពមួយនៃ automaton កំណត់ថ្មី*។


    *ជាផ្លូវការ សំណុំ Q_1 គួរតែត្រូវបានកំណត់ថាជាសំណុំដែលមាននៅក្នុងការឆ្លើយឆ្លងមួយទល់មួយជាមួយនឹងសំណុំ 2^Q ប៉ុន្តែវានៅតែងាយស្រួលជាងសម្រាប់យើងក្នុងការពិចារណាថា Q_1 ស្របគ្នានឹង 2^Q ពីព្រោះសំណុំ នៃរដ្ឋនៃ automaton កំណត់អាចជាសំណុំកំណត់មិនទទេណាមួយ។


    មុខងារផ្លាស់ប្តូរនៃ automaton finite ថ្មីត្រូវបានកំណត់ ដូច្នេះពី state-set S ដោយនិមិត្តសញ្ញា input a automaton finite M_1 ទៅកាន់ state-set ដែលជាការរួបរួមនៃ state ទាំងអស់នៃ finite automaton ចាស់ទៅ ដែល automaton កំណត់ចាស់នេះឆ្លងកាត់ដោយនិមិត្តសញ្ញា a ពីរដ្ឋនីមួយៗកំណត់ S ។ ដូច្នេះ automaton កំណត់ M_1 គឺកំណត់ដោយការសាងសង់។


    ការពិពណ៌នាពាក្យសំដីខាងលើអាចត្រូវបានបកប្រែទៅជារូបមន្តដូចខាងក្រោម: យើងបង្កើតម៉ាស៊ីនរដ្ឋ M_1 ដូច្នេះ


    M_1=(Q_1,V,\(q_0\),F_1,\delta_1)កន្លែងណា


    \begin(cases)Q_1=2^Q,\quad F_1=\(T\colon\, T\cap F\ne\varnothing,~T\in2^Q\),\\ (\forall S\subseteq Q) (\forall a\in V)\Bigl(\delta_1(S,a)=\bigcup\limits_(q\in S)\delta(q,a)\Bigr)។ \end(ករណី)


    អនុញ្ញាតឱ្យយើងយកចិត្តទុកដាក់លើការពិតដែលថាក្នុងចំណោមរដ្ឋនៃ automaton កំណត់ថ្មីមានរដ្ឋ \ varnothing , និង, នេះបើយោងតាម ​​(7.8), \delta_1(\varnothing,a)=\varnothingសម្រាប់តួអក្សរបញ្ចូលណាមួយ a . នេះមានន័យថា នៅពេលដែលស្ថិតក្នុងស្ថានភាពបែបនេះ ម៉ាស៊ីនរដ្ឋ M_1 នឹងមិនទុកវាចោលទេ។ ជាទូទៅ ស្ថានភាព q នៃ automaton កំណត់ណាមួយ ដែលសម្រាប់និមិត្តសញ្ញាបញ្ចូលណាមួយ យើងមាន \delta(q,a)=q ត្រូវបានគេហៅថាស្ថានភាពស្រូបយកនៃ automaton កំណត់។ ដូច្នេះ ស្ថានភាព \varnothing នៃម៉ាស៊ីនរដ្ឋកំណត់ M_1 កំពុងស្រូបយក។ វាក៏មានប្រយោជន៍ផងដែរក្នុងការកត់សម្គាល់វា។ \delta_1(S,a)=\varnothingប្រសិនបើ និងសម្រាប់តែ q\in S នីមួយៗ (ស្ថានភាពនៃ automaton កំណត់ចាស់ពីសំណុំនៃរដ្ឋ S) \delta(q,a)=\varnothing, i.e. នៅក្នុងក្រាហ្វ M រដ្ឋនីមួយៗ q មិនទុកធ្នូណាមួយដែលសម្គាល់ដោយនិមិត្តសញ្ញា a ។


    វា​អាច​ត្រូវ​បាន​បង្ហាញ​ថា automaton កំណត់​ដែល​បាន​ទទួល​ដោយ​ក្បួន​ដោះស្រាយ​បែប​នេះ​គឺ​ស្មើ​នឹង​មួយ​ដើម​។

    ឧទាហរណ៍ 7.9 ។យើងកំណត់ automaton កំណត់ដែលបង្ហាញក្នុងរូប។ ៧.១៤.


    automaton កំណត់សមមូលដោយគ្មានការផ្លាស់ប្តូរ λ ត្រូវបានបង្ហាញក្នុងរូបភព។ ៧.១៥. ចំណាំថា vertex q_2 បាត់ ព្រោះមានតែ "ទទេ" arcs បញ្ចូលវា។



    ដើម្បីកំណត់លទ្ធផល automaton វាពិតជាមិនចាំបាច់ក្នុងការសរសេរចេញនូវរដ្ឋ 2^3=8 ទាំងអស់របស់វា ដែលភាគច្រើនមិនអាចទៅដល់បានពីស្ថានភាពដំបូង \(q_0\) ។ ដើម្បីទទួលបានការដែលអាចទៅដល់បានពីរដ្ឋ \(q_0\) ហើយមានតែពួកវាទេ យើងប្រើវិធីដែលហៅថាទាញ។


    វិធីសាស្រ្តនេះអាចត្រូវបានពិពណ៌នានៅក្នុងករណីទូទៅដូចខាងក្រោម។


    នៅក្នុង automaton កំណត់ដើម (ដោយគ្មានធ្នូទទេ) យើងកំណត់សំណុំនៃរដ្ឋទាំងអស់ដែលអាចទៅដល់បានពីដំបូង ពោលគឺឧ។ សម្រាប់តួអក្សរបញ្ចូលនីមួយៗ a យើងរកឃើញសំណុំ \delta(q_0,a) ។ សំណុំបែបនេះនីមួយៗនៅក្នុង automaton ថ្មីគឺជារដ្ឋដែលអាចចូលដំណើរការបានដោយផ្ទាល់ពីដំបូង។


    សម្រាប់ការកំណត់រដ្ឋដែលបានកំណត់នីមួយៗ S និងនិមិត្តសញ្ញាបញ្ចូលនីមួយៗ a យើងរកឃើញសំណុំ \textstyle(\mathop(\bigcup\limits_(q\in S) \delta(q,a))\limits^(\phantom(A)^(.))). រដ្ឋទាំងអស់ដែលទទួលបាននៅជំហាននេះនឹងជាស្ថានភាពនៃស្វ័យប្រវត្តិកម្មថ្មី (កំណត់) ដែលអាចទៅដល់បានពីចំនុចកំពូលដំបូងតាមបណ្តោយផ្លូវនៃប្រវែង 2។ យើងធ្វើបែបបទដែលបានពិពណ៌នាម្តងទៀតរហូតដល់មិនមានការកំណត់រដ្ឋថ្មី (រួមទាំងទទេ) លេចឡើង។ វាអាចត្រូវបានបង្ហាញថាក្នុងករណីនេះស្ថានភាពបែបនេះទាំងអស់នៃ automaton កំណត់ M_1 ត្រូវបានទទួលដែលអាចទៅដល់ពីស្ថានភាពដំបូង \(q_0\) ។


    សម្រាប់ម៉ាស៊ីនរដ្ឋកំណត់នៅក្នុងរូបភព។ ៧.១៥ យើងមាន៖


    \begin(aligned)&\delta_1(\(q_0\),a)=\(q_1\);\qquad \delta_1(\(q_0\),b)=\(q_1,q_3\);\\ & \ delta_1(\(q_1\),a)=\(q_1\);\qquad \delta_1(\(q_1\),b)=\(q_1\);\\ & \delta_1(\(q_1,q_3\) ,a)= \delta(q_1,a)\cup \delta(q_3,a)= \(q_1\)\cup\(q_1\)=\(q_1\);\\ & \delta_1(\(q_1, q_3\),b)=\delta(q_1,b)\cup \delta(q_3,b)=\(q_1\)\cup\(q_1\)=\(q_1\)។ \end(តម្រឹម)


    ដោយសារមិនមានការកំណត់រដ្ឋថ្មីទៀតទេ នីតិវិធី "ទាញ" បញ្ចប់នៅទីនេះ ហើយយើងទទួលបានក្រាហ្វដែលបង្ហាញក្នុងរូបភព។ ៧.១៦.

    ការបំពេញបន្ថែមភាសាធម្មតា។

    លទ្ធផលទ្រឹស្តីដ៏សំខាន់មួយនៃទ្រឹស្តីបទកំណត់គឺទ្រឹស្តីបទខាងក្រោម។


    ទ្រឹស្តីបទ 7.8 ។ ការបំពេញបន្ថែមនៃភាសាធម្មតាគឺជាភាសាធម្មតា។


    អនុញ្ញាតឱ្យ L ជាភាសាធម្មតានៅក្នុងអក្ខរក្រម V ។ បន្ទាប់មកការបំពេញបន្ថែមនៃភាសា L (ជាសំណុំនៃពាក្យ) គឺជាភាសា \overline(L)=V^(\ast)\setminus L.


    យោងតាមទ្រឹស្តីបទ 7.7 សម្រាប់ភាសាធម្មតា L ស្វ័យប្រវត្តិកម្មកំណត់កំណត់ M អាចត្រូវបានសាងសង់ដែលទទួលស្គាល់ L ។ ដោយសារនៅក្នុង automaton កំណត់ពី vertex នីមួយៗ សម្រាប់និមិត្តសញ្ញាបញ្ចូលនីមួយៗ ការផ្លាស់ប្តូរទៅចំនុចកំពូលមួយត្រូវបានកំណត់ បន្ទាប់មក ខ្សែអក្សរ x ក្នុងអក្ខរក្រម V វាមានផ្លូវតែមួយគត់សម្រាប់វានៅក្នុង M ដោយចាប់ផ្តើមពីដំបូង។ ស្ថានភាពដែលខ្សែអក្សរ x ត្រូវបានអាន។ វាច្បាស់ណាស់ថា ខ្សែអក្សរ x ត្រូវបានអនុញ្ញាតដោយ automaton M ពោលគឺ x\in L(M) ប្រសិនបើ ហើយប្រសិនបើស្ថានភាពចុងក្រោយនៃផ្លូវដែលបានបញ្ជាក់គឺចុងក្រោយ។ នេះបង្កប់ន័យថាខ្សែសង្វាក់ x\notin L(M) ប្រសិនបើ ហើយប្រសិនបើស្ថានភាពចុងក្រោយនៃផ្លូវដែលបានបញ្ជាក់គឺមិនចុងក្រោយ។ ប៉ុន្តែយើងគ្រាន់តែត្រូវការ finite automaton M" ដែលអនុញ្ញាតឱ្យខ្សែសង្វាក់ x ប្រសិនបើ ហើយលុះត្រាតែ automaton កំណត់ដើម M មិនអនុញ្ញាត។ ដូច្នេះហើយ ការបង្វែរស្ថានភាពចុងក្រោយនីមួយៗនៃ M ទៅជាធាតុមិនចុងក្រោយ ហើយផ្ទុយមកវិញ យើងទទួលបាន automaton កំណត់ដែលអនុញ្ញាតឱ្យបញ្ចប់ភាសា L ។


    ទ្រឹស្តីបទដែលបានបញ្ជាក់អនុញ្ញាតឱ្យយើងបង្កើត automaton កំណត់ដែលមិនអនុញ្ញាតឱ្យមានខ្សែសង្វាក់ជាក់លាក់មួយដោយវិធីសាស្រ្តដូចខាងក្រោម: ដំបូងយើងបង្កើត automaton ដែលអនុញ្ញាតឱ្យសំណុំនៃច្រវាក់ដែលបានផ្តល់ឱ្យបន្ទាប់មកយើងកំណត់វាហើយបញ្ជូនទៅ automaton សម្រាប់ការបំពេញបន្ថែម។ ដូចដែលបានបង្ហាញនៅក្នុងភស្តុតាងនៃទ្រឹស្តីបទ 7.8 ។

    ឧទាហរណ៍ 7.10 ។ក. តោះបង្កើត automaton កំណត់ដែលអនុញ្ញាតឱ្យមានខ្សែអក្សរទាំងអស់ក្នុងអក្ខរក្រម \(0;1\) លើកលែងតែខ្សែអក្សរ 101។


    ដំបូង យើងបង្កើត automaton កំណត់ដែលអនុញ្ញាតឱ្យមានខ្សែសង្វាក់តែមួយ 101. automaton នេះត្រូវបានបង្ហាញនៅក្នុងរូបភព។ ៧.១៧.



    automaton នេះ​គឺ​ជា​ការ​កំណត់​មិន​ត្រឹម​ត្រូវ​ ប៉ុន្តែ​មិន​បាន​កំណត់​ដោយ​សារ​តែ​វា​មិន​ត្រូវ​បាន​កំណត់​យ៉ាង​ពេញលេញ។ អនុញ្ញាតឱ្យយើងកំណត់វា និងទទួលបាន automaton កំណត់សមមូលសមមូលដែលបង្ហាញក្នុងរូបភព។ ៧.១៨.



    ហើយចុងក្រោយ ឆ្លងកាត់ការបន្ថែម (និងប្តូរឈ្មោះរដ្ឋ) យើងទទួលបាន automaton ដែលបង្ហាញក្នុងរូប។ ៧.១៩.


    ចំណាំថានៅក្នុង automaton លទ្ធផល ចំនុចកំពូលទាំងអស់ លើកលែងតែ vertex s_3 គឺជាចុងក្រោយ។


    ចំណាំផងដែរថាការផ្លាស់ប្តូរទៅការបំពេញបន្ថែមដែលត្រូវបានពិភាក្សានៅក្នុងភស្តុតាងនៃទ្រឹស្តីបទ 7.8 អាចត្រូវបានអនុវត្តតែនៅក្នុង automaton កំណត់ប៉ុណ្ណោះ។ ប្រសិនបើយើងដាក់បញ្ច្រាសតួនាទីនៃចំនុចកំពូលចុងក្រោយ និងមិនមែនចុងក្រោយនៅក្នុង automaton ដែលបង្ហាញក្នុងរូប។ 7.17 យើងនឹងទទួលបាន automaton ដែលទទួលស្គាល់ភាសា \(\lambda,1,10\) ដែលមិនមែនជា - ដូចដែលវាងាយស្រួលមើល - សំណុំនៃខ្សែទាំងអស់ក្រៅពីខ្សែអក្សរ 101 ។


    ចំណាំផងដែរថាម៉ាស៊ីនរដ្ឋកំណត់នៅក្នុងរូបភព។ 7.19 អនុញ្ញាតឱ្យខ្សែអក្សរទាំងអស់ដែលមានការកើតឡើងនៃខ្សែអក្សរ 101 ប៉ុន្តែមិនត្រូវគ្នានឹងខ្សែអក្សរខ្លួនឯងទេ។ នេះ​ជា​ឧទាហរណ៍ ជា​ផ្លូវ​ដែល​មាន​ខ្សែ​សង្វាក់ ១០១១៖ s_0,s_1,s_2,s_3,t.


    ខ. អនុញ្ញាតឱ្យយើងបង្កើត automaton កំណត់ដែលអនុញ្ញាតឱ្យមានខ្សែអក្សរទាំងអស់ក្នុងអក្ខរក្រម \(0;1\) លើកលែងតែខ្សែអក្សរដែលមានការកើតឡើងនៃខ្សែអក្សរ 101។ ពិចារណាភាសា L ខ្សែអក្សរនីមួយៗដែលមានការកើតឡើងនៃខ្សែអក្សរ 101។ វាអាចជា កំណត់ដូចខាងក្រោមៈ


    L=(0+1)^(\ast)101(0+1)^(\ast)។


    យើងត្រូវបង្កើត automaton ដើម្បីបំពេញភាសា L.


    ដោយ​ផ្ទាល់​ពី​កន្សោម​ធម្មតា​នៅ​ក្នុង​ករណី​នេះ វា​ជា​ការ​ងាយ​ស្រួល​ក្នុង​ការ​សាង​សង់ automaton កំណត់​ដែល​អនុញ្ញាត​ឱ្យ​ភាសា L (រូបភាព 7.20) ។



    បន្ទាប់មកដោយវិធីសាស្រ្ត "ទាញ" យើងនឹងអនុវត្តការប្តេជ្ញាចិត្ត។ លទ្ធផលនៃការប្តេជ្ញាចិត្តត្រូវបានបង្ហាញនៅក្នុងរូបភព។ ៧.២១.



    សម្រាប់ដំណោះស្រាយពេញលេញនៃបញ្ហាមានតែរូបភព។ 7.21 ផ្លាស់ប្តូរតួនាទីនៃចំនុចកំពូលចុងក្រោយ និងមិនមែនចុងក្រោយ (រូបភាព 7.22)។



    ក្នុង ចូរពិភាក្សាអំពីគំនិតនៃការបង្កើត automaton កំណត់ដែលអនុញ្ញាតឱ្យមានខ្សែអក្សរទាំងនោះ និងតែនៅក្នុងអក្ខរក្រម \(0;1\) ដែលមិនចាប់ផ្តើមដោយខ្សែអក្សរ 01 និងមិនបញ្ចប់ដោយខ្សែអក្សរ 11 (ឧ. ទម្រង់ 01x និងខ្សែអក្សរនៃទម្រង់ y11 មិនត្រូវបានអនុញ្ញាតទេ ទោះបីជាមានខ្សែសង្វាក់ x,y\in\(0;1\) ក៏ដោយ។


    ក្នុងករណីនេះ ការបំពេញបន្ថែមនៃភាសាដែលអ្នកចង់បង្កើត automaton កំណត់គឺជាសំណុំនៃខ្សែសូន្យ និងអក្សរទាំងអស់ដែលចាប់ផ្តើមដោយខ្សែអក្សរ 01 ឬបញ្ចប់ដោយខ្សែអក្សរ 11។ ស្វ័យប្រវត្តិដែលទទួលស្គាល់សំណុំនៃខ្សែនេះ ត្រូវបានសាងសង់ជា automaton សម្រាប់ផ្សំ 01(0+1)^(\ast)+(0+1)^(\ast)11តាមរបៀបដូចគ្នានឹងភស្តុតាងនៃទ្រឹស្តីបទ Kleene (សូមមើលទ្រឹស្តីបទ 7.6)។

    ទ្រព្យសម្បត្តិនៃថ្នាក់នៃភាសាធម្មតាដែលត្រូវបានបិទនៅក្រោមការបំពេញបន្ថែម (សូមមើលទ្រឹស្តីបទ 7.8) បង្កប់ន័យភ្លាមៗថាថ្នាក់នេះត្រូវបានបិទនៅក្រោមចំនុចប្រសព្វ ការកំណត់ទ្រឹស្តី និងភាពខុសគ្នាស៊ីមេទ្រី។


    កូរ៉ូឡារី ៧.៣. សម្រាប់ភាសាធម្មតាពីរ L_1 និង L_2 សេចក្តីថ្លែងការណ៍ខាងក្រោមគឺពិត៖


    1) ចំនុចប្រសព្វ L_1\cap L_2 គឺទៀងទាត់។
    2) ភាពខុសគ្នា L_1\setminus L_2 គឺទៀងទាត់។
    3) ភាពខុសគ្នាស៊ីមេទ្រី L_1\vartriangle L_2ទៀង​ទា​ត។


    សុពលភាពនៃសេចក្តីថ្លែងការណ៍ ធ្វើឡើងពីអត្តសញ្ញាណ៖


    \begin(aligned) &(\scriptstyle(\mathsf(1))))\quad L_1\cap L_2= \overline(\overline(L_1) \cup\overline(L_2))\,;\\ &(\scriptstyle (\mathsf(2))))\quad L_1\setminus L_2= L_1\cap \overline(L_2)\,;\\ &(\scriptstyle(\mathsf(3))))\quad L_1\,\triangle\ ,L_2 = (L_1\cup L_2)\setminus (L_1\cap L_2)។\end(តម្រឹម)


    ទីមួយ លទ្ធផលដែលទទួលបានអនុញ្ញាតឱ្យយើងអះអាងថា ថ្នាក់នៃភាសាធម្មតាទាក់ទងនឹងប្រតិបត្តិការនៃសហជីព ចំនុចប្រសព្វ និងការបន្ថែមគឺជាពិជគណិតប៊ូលីន ដែលឯកតាជាភាសាសកល ហើយសូន្យគឺជាភាសាទទេ។ . ទីពីរ លក្ខណៈសម្បត្តិពិជគណិតទាំងនេះនៃក្រុមគ្រួសារនៃភាសាធម្មតាអនុញ្ញាតឱ្យយើងដោះស្រាយបញ្ហាសំខាន់នៃការទទួលស្គាល់សមមូលនៃ finite automata បំពានពីរ។


    យោងតាមនិយមន័យ 7.10 ការកំណត់ស្វ័យប្រវត្តិគឺស្មើនឹងប្រសិនបើភាសាដែលពួកគេអនុញ្ញាតគឺដូចគ្នា។ ដូច្នេះ ដើម្បីផ្ទៀងផ្ទាត់ភាពស្មើគ្នានៃ automata M_1 និង M_2 វាគ្រប់គ្រាន់ដើម្បីបញ្ជាក់ថាភាពខុសគ្នានៃស៊ីមេទ្រីនៃភាសា L(M_1) និង L(M_2) គឺទទេ។ ដើម្បីធ្វើដូច្នេះបាន វាគ្រប់គ្រាន់ក្នុងការសាងសង់ automaton ដែលទទួលស្គាល់ភាពខុសគ្នានេះ ហើយផ្ទៀងផ្ទាត់ថាភាសាដែលវាទទួលស្គាល់គឺទទេ។ ជាទូទៅបញ្ហានៃការទទួលស្គាល់ថាភាសាម៉ាស៊ីនរបស់រដ្ឋគឺទទេត្រូវបានគេហៅថាបញ្ហាភាពទទេរបស់ម៉ាស៊ីនរដ្ឋ។ ដើម្បីដោះស្រាយបញ្ហានេះ វាគ្រប់គ្រាន់ក្នុងការស្វែងរកសំណុំនៃស្ថានភាពចុងក្រោយនៃ automaton ដែលអាចទៅដល់បានពីស្ថានភាពដំបូង។ ដោយសារម៉ាស៊ីនរដ្ឋកំណត់គឺជាក្រាហ្វដឹកនាំ បញ្ហានេះអាចត្រូវបានដោះស្រាយ ជាឧទាហរណ៍ ដោយប្រើការស្វែងរកដំបូង។ ភាសាដែលអនុញ្ញាតដោយ finite automaton គឺទទេ ប្រសិនបើសំណុំនៃរដ្ឋចុងក្រោយដែលអាចទៅដល់បានពីស្ថានភាពដំបូងគឺទទេ។ នៅក្នុងការអនុវត្ត វាជាការប្រសើរក្នុងការទទួលស្គាល់សមមូលនៃ finite automata ដោយប្រើក្បួនដោះស្រាយការបង្រួមអប្បបរមា ប៉ុន្តែឥឡូវនេះវាមានសារៈសំខាន់សម្រាប់យើងក្នុងការបញ្ជាក់ថាលទ្ធភាពជាមូលដ្ឋាននៃការដោះស្រាយបញ្ហាសមមូលបានមកពីទ្រឹស្តីបទ 7.7 និងផលវិបាកពិជគណិតរបស់វា។