البرمجة القائمة على الأتمتة

البرمجة القائمة على الأوتوماتا هي نموذج برمجي يُنظر فيه إلى البرنامج، أو جزء منه، على أنه نموذج لآلة ذات حالات محدودة (FSM) أو أي أوتوماتا رسمية أخرى (غالباً ما تكون أكثر تعقيداً) (انظر نظرية الأوتوماتا ). في بعض الأحيان، يتم إدخال مجموعة لا نهائية محتملة من الحالات الممكنة، ويمكن أن يكون لهذه المجموعة بنية معقدة، وليست مجرد تعداد.

البرمجة القائمة على الآلات ذات الحالة المحدودة هي نفسها بشكل عام، ولكن من الناحية الرسمية، لا تغطي جميع المتغيرات الممكنة، حيث أن FSM تعني آلة الحالة المحدودة، والبرمجة القائمة على الأتمتة لا تستخدم بالضرورة آلات الحالة المحدودة بالمعنى الدقيق.

الخصائص التالية هي مؤشرات رئيسية للبرمجة القائمة على الأوتوماتا:

  • يُقسّم وقت تنفيذ البرنامج بوضوح إلى خطوات آلية . كل خطوة هي في الواقع تنفيذ لجزء من التعليمات البرمجية (ينطبق الأمر نفسه على جميع الخطوات) وله نقطة دخول واحدة. يمكن تقسيم هذا الجزء إلى أجزاء فرعية تُنفّذ بناءً على حالات مختلفة، مع أن هذا ليس ضروريًا.
  • لا يمكن التواصل بين خطوات الأوتوماتون إلا عبر مجموعة المتغيرات المحددة صراحةً والتي تُسمى حالة الأوتوماتون . بين أي خطوتين، لا يمكن للبرنامج أن يحتوي على مكونات ضمنية لحالته، مثل قيم المتغيرات المحلية، وعناوين الإرجاع، ومؤشر التعليمات الحالية، وما إلى ذلك. أي أن حالة البرنامج ككل، عند أي لحظتين من دخول خطوة الأوتوماتون، لا يمكن أن تختلف إلا في قيم المتغيرات التي تُعتبر حالة الأوتوماتون.

إن تنفيذ الكود القائم على الأوتوماتا بالكامل هو عبارة عن دورة من خطوات الأوتوماتا.

سبب آخر لاستخدام مفهوم البرمجة القائمة على الأوتوماتا هو أن أسلوب تفكير المبرمج في البرنامج في هذه التقنية يشبه إلى حد كبير أسلوب التفكير المستخدم لحل المسائل الرياضية باستخدام آلات تورينج وخوارزميات ماركوف وما إلى ذلك.

مثال

مهمة

لنفترض مهمة قراءة نص من المدخلات القياسية سطرًا سطرًا وكتابة الكلمة الأولى من كل سطر إلى المخرجات القياسية . أولًا، نتجاهل جميع المسافات البيضاء البادئة ، إن وجدت. ثم نطبع جميع أحرف الكلمة الأولى. وأخيرًا، نتجاهل جميع الأحرف اللاحقة حتى نصادف حرف سطر جديد . عندما نصادف سلسلة من أحرف السطر الجديد في غير بداية السلسلة، نطبع الحرف الأول فقط ونتجاهل الباقي؛ وإلا، نتجاهلها جميعًا. بعد ذلك، نعيد تشغيل العملية من السطر التالي. عند الوصول إلى نهاية الملف (بغض النظر عن المرحلة)، نتوقف.

البرنامج التقليدي

قد يبدو برنامج تقليدي مكتوب بلغة C يقوم بالمهمة المذكورة أعلاه على النحو التالي:

#include <ctype.h> #include <stdio.h>int main ( void ) { int c ;نفّذ { نفّذ { c = getchar (); } بينما ( isspace ( c ));بينما ( ليس الحرف c مسافة ) و c لا يساوي نهاية الملف { ضع الحرف ( c c = احصل على الحرف ()؛ } بينما ( c لا يساوي '\n' و c لا يساوي نهاية الملف ) { c = احصل على الحرف ()؛ } إذا ( c يساوي '\n' ) { ضع الحرف ( c } } بينما ( c لا يساوي نهاية الملف return 0 ; }

على سبيل المثال، تجميع وتشغيل البرنامج أعلاه على هذا المدخل:

$ clang Program.c && ( printf "\t\v\f\r \n\n\t\v\f\r foo bar baz\n\n\t\v\f\r qux quux corge" | ./a.out )

النتائج:

foo qux

برنامج قائم على الأتمتة

إجرائي

يمكن حلّ المهمة نفسها بالتفكير باستخدام آلات الحالة المحدودة . تتألف عملية تحليل السطر من ثلاث مراحل: تخطي المسافات البيضاء في بداية السطر، وطباعة أحرف الكلمة الأولى، وتخطي الأحرف الأخيرة. تُسمى هذه الحالات بـ BEFOREو INSIDEو AFTER. قد يبدو إصدار البرنامج القائم على الأوتوماتا كما يلي:

#include <ctype.h> #include <stdio.h>enum State { BEFORE , INSIDE , AFTER };int main ( void ) { int c ; enum State s = BEFORE ;بينما (( c = getchar ()) != EOF ) { switch ( s ) { case BEFORE : if ( ! isspace ( c )) { putchar ( c ); s = INSIDE ; } break ; case INSIDE : if ( c == '\n' ) { putchar ( c ); s = BEFORE ; } else if ( isspace ( c )) { s = AFTER ; } else { putchar ( c ); } break ; case AFTER : if ( c == '\n' ) { putchar ( c ); s = BEFORE ; } break ; } }return 0 ; }

على الرغم من أن البرنامج أصبح أطول، إلا أنه يتمتع بميزة هامة على الأقل: فهو يحتوي على تعليمة قراءة واحدة فقط (أي استدعاء الدالة getchar). إضافةً إلى ذلك، يحتوي على حلقة واحدة فقط بدلاً من الحلقات الأربع الموجودة في النسخة التقليدية. جسم الحلقة whileهو خطوة الأوتوماتا ، والحلقة نفسها هي دورة خطوة الأوتوماتا. يُنفذ البرنامج عمل آلة الحالة المحدودة الموضحة في مخطط الحالة.

أهم ما يميز البرنامج هو أن قسم كود خطوة الأتمتة محدد الموقع بوضوح. وباستخدام دالة صريحة stepلخطوة الأتمتة، يُظهر البرنامج هذه الخاصية بشكل أفضل.

#include <ctype.h> #include <stdio.h>enum State { BEFORE , INSIDE , AFTER };void step ( enum State * const s , int const c ) { switch ( * s ) { case BEFORE : if ( ! isspace ( c )) { putchar ( c ); * s = INSIDE ; } break ; case INSIDE : if ( c == '\n' ) { putchar ( c ); * s = BEFORE ; } else if ( isspace ( c )) { * s = AFTER ; } else { putchar ( c ); } break ; case AFTER : if ( c == '\n' ) { putchar ( c ); * s = BEFORE ; } break ; } }int main ( void ) { int c ; enum State s = BEFORE ;بينما (( c = getchar ()) != EOF ) { step ( & s , c ); }return 0 ; }

يُظهر البرنامج الآن بوضوح الخصائص الأساسية للبرمجيات القائمة على الأوتوماتا:

  • قد لا تتداخل الفترات الزمنية لتنفيذ خطوات الأتمتة؛
  • المعلومات الوحيدة التي يتم نقلها من الخطوة السابقة إلى الخطوة التالية هي حالة الآلة المحددة بشكل صريح .

يمكن تعريف الآلة المحدودة بواسطة جدول انتقال الحالة الذي تمثل صفوفه الحالات الحالية، وتمثل أعمدته المدخلات، وتمثل خلاياه الحالات والإجراءات التالية التي يجب تنفيذها.

جدول انتقال الحالة
مدخل
الوضع الحالي
سطر جديدمساحة بيضاءآخر
قبلقبلقبلطباعة داخلية
داخلقبل/طباعةبعدطباعة داخلية
بعدقبل/طباعةبعدبعد
مخطط الحالة
مخطط حالة آلة ذات حالات محدودة تطبع الكلمة الأولى من كل سطر من سلسلة الإدخال. تتبع الآلة انتقالًا واحدًا فقط في كل خطوة، اعتمادًا على الحالة الحالية والحرف المُصادف. الإجراء المصاحب للانتقال إما عدم القيام بأي عملية أو طباعة الحرف المُصادف، ويُرمز له بـ print .

بشكل عام، يمكن لبرنامج قائم على الأوتوماتا استخدام هذا الأسلوب بشكل طبيعي. باستخدام مصفوفة ثنائية الأبعاد صريحة transitionsلجدول انتقال الحالة، يستخدم البرنامج هذا الأسلوب:

#include <ctype.h> #include <stdio.h>enum State { BEFORE , INSIDE , AFTER };void nop ( int const c ) {}void print ( int const c ) { putchar ( c ); }struct Branch { enum State const next_state ; void ( * action )( int ); };struct Branch const transitions [ 3 ][ 3 ] = { // مسافة سطر جديد مدخلات/حالات أخرى {{ BEFORE , & nop }, { BEFORE , & nop }, { INSIDE , & print }}, // قبل {{ BEFORE , & print }, { AFTER , & nop }, { INSIDE , & print }}, // داخل {{ BEFORE , & print }, { AFTER , & nop }, { AFTER , & nop }} // بعد };void step ( enum State * const s , int const c ) { int const row = ( * s == BEFORE ) ? 0 : ( * s == INSIDE ) ? 1 : 2 ; int const column = ( c == '\n' ) ? 0 : isspace ( c ) ? 1 : 2 ; struct Branch const * const b = & transitions [ row ][ column ]; * s = b- > next_state ; b- > action ( c ); }int main ( void ) { int c ; enum State s = BEFORE ;بينما (( c = getchar ()) != EOF ) { step ( & s , c ); }return 0 ; }

البرمجة الكائنية

إذا كانت لغة البرمجة تدعم البرمجة كائنية التوجه ، فإن إعادة هيكلة بسيطة للبرنامج تتمثل في تغليف الآلة في كائن، وبالتالي إخفاء تفاصيل تنفيذها. قد يبدو البرنامج المكتوب بلغة C++ باستخدام أسلوب البرمجة كائنية التوجه كما يلي:

#include <ctype.h> #include <stdio.h>enum State { BEFORE , INSIDE , AFTER };struct Branch { enum State const next_state ; void ( * action )( int ); };class StateMachine { public : StateMachine (); void feedChar ( int );محمي : ثابت void nop ( int ); ثابت void print ( int );خاص : تعداد الحالة _state ؛ بنية ثابتة الفرع const _transitions [ 3 ][ 3 };StateMachine :: StateMachine () : _state ( BEFORE ) {}void StateMachine :: feedChar ( int const c ) { int const row = ( _state == BEFORE ) ? 0 : ( _state == INSIDE ) ? 1 : 2 ; int const column = ( c == '\n' ) ? 0 : isspace ( c ) ? 1 : 2 ; struct Branch const * const b = & _transitions [ row ][ column ]; _state = b- > next_state ; b- > action ( c ); }void StateMachine :: nop ( int const c ) {}void StateMachine :: print ( int const c ) { putchar ( c ); }struct Branch const StateMachine :: _transitions [ 3 ][ 3 ] = { // مسافة سطر جديد مدخلات/حالات أخرى {{ BEFORE , & nop }, { BEFORE , & nop }, { INSIDE , & print }}, // قبل {{ BEFORE , & print }, { AFTER , & nop }, { INSIDE , & print }}, // داخل {{ BEFORE , & print }, { AFTER , & nop }, { AFTER , & nop }} // بعد };int main () { int c ; StateMachine m ;بينما (( c = getchar ()) != EOF ) { m . feedChar ( c ); }return 0 ; }

لتقليل التغييرات غير المرتبطة مباشرة بموضوع المقالة، يتم استخدام المدخلات/المخرجاتgetchar والوظائف putcharمن المكتبة القياسية للغة C.

نمط تصميم الحالة هو طريقة لتغيير سلوك الكائن أثناء التشغيل وفقًا لحالته الداخلية دون اللجوء إلى عبارات شرطية مطولة أو عمليات بحث في الجداول، وذلك بفضل استدعاءات الدوال الافتراضية. تتمثل ميزته الرئيسية مقارنةً بالبرامج التي تستخدم عبارات شرطية مطولة في توزيع التعليمات البرمجية الخاصة بالحالة على كائنات مختلفة بدلًا من تجميعها في كتلة واحدة، مما يُحسّن من سهولة الصيانة. أما ميزته الرئيسية مقارنةً بالبرامج التي تستخدم جداول انتقال الحالة، فتتمثل في أن استدعاءات الدوال الافتراضية غالبًا ما تكون أكثر كفاءة من عمليات البحث في الجداول، وأن معايير انتقال الحالة أكثر وضوحًا من تلك الموجودة في الجداول، وأنه من الأسهل إضافة إجراءات مصاحبة لانتقالات الحالة. مع ذلك، يُثير هذا النمط مشكلة جديدة: فكثرة الفئات تجعل التعليمات البرمجية أقل إيجازًا من الطرق الأخرى. قد يبدو البرنامج الذي يستخدم نمط تصميم الحالة كالتالي:

#include <ctype.h> #include <stdio.h>فئة آلة الحالة ؛class State { public : virtual void feedChar ( StateMachine * , int ) const = 0 ; };class Before : public State { public : static State const * instantiate (); virtual void feedChar ( StateMachine * , int ) const override ;محمي : قبل () = افتراضي ؛private : static State const * _instance ; };class Inside : public State { public : static State const * instantiate (); virtual void feedChar ( StateMachine * , int ) const override ;محمي : داخل () = افتراضي ؛private : static State const * _instance ; };class After : public State { public : static State const * instantiate (); virtual void feedChar ( StateMachine * , int ) const override ;محمي : بعد () = افتراضي ؛private : static State const * _instance ; };class StateMachine { public : StateMachine (); void feedChar ( int );محمي : void setState ( State const * );private : State const * _state ; friend class Before ; friend class Inside ; friend class After ; };State const * Before :: instantiate () { if ( ! _instance ) { _instance = new Before ; }return _instance ; }void Before :: feedChar ( StateMachine * const m , int const c ) const { if ( ! isspace ( c )) { putchar ( c ); m- > setState ( Inside :: instantiate ()); } }State const * Before :: _instance = nullptr ;State const * Inside :: instantiate () { if ( ! _instance ) { _instance = new Inside ; }return _instance ; }void Inside :: feedChar ( StateMachine * const m , int const c ) const { if ( c == '\n' ) { putchar ( c ); m- > setState ( Before :: instantiate ()); } else if ( isspace ( c )) { m- > setState ( After :: instantiate ()); } else { putchar ( c ); } }State const * Inside :: _instance = nullptr ;State const * After :: instantiate () { if ( ! _instance ) { _instance = new After ; }return _instance ; }void After :: feedChar ( StateMachine * const m , int const c ) const { if ( c == '\n' ) { putchar ( c ); m -> setState ( Before :: instantiate ()); } }State const * After :: _instance = nullptr ;StateMachine :: StateMachine () : _state ( Before :: instantiate ()) {}void StateMachine :: feedChar ( int const c ) { _state- > feedChar ( this , c ); }void StateMachine :: setState ( State const * const s ) { _state = s ; }int main () { int c ; StateMachine m ;بينما (( c = getchar ()) != EOF ) { m . feedChar ( c ); }return 0 ; }

الأتمتة والآلات

إن البرمجة القائمة على الأتمتة تتطابق بشكل وثيق مع احتياجات البرمجة الموجودة في مجال الأتمتة .

يتم عادةً نمذجة دورة الإنتاج على النحو التالي:

  • سلسلة من المراحل التي تتدرج وفقًا لبيانات الإدخال (من أجهزة الالتقاط)؛
  • مجموعة من الإجراءات التي يتم تنفيذها بناءً على المرحلة الحالية.

تتيح لغات البرمجة المتخصصة المختلفة التعبير عن هذا النموذج بطرق أكثر أو أقل تعقيدًا.

برنامج التشغيل الآلي

يمكن التعبير عن المثال المذكور أعلاه وفقًا لهذا الرأي كما في الشفرة الزائفة التالية ('set' تُفعّل متغيرًا منطقيًا، و'reset' تُعطّل متغيرًا منطقيًا، و':' تُسند قيمة لمتغير، و'=' تختبر المساواة):

سطر جديد: '\n' المسافات البيضاء: ('\t', '\n', '\v', '\f', '\r', ' ') الحالات: (قبل، داخل، بعد) setState(c) { إذا كان قبل (و (c != سطر جديد و c ليس في مسافة بيضاء) فقم بتعيينه في الداخل إذا كان داخل (إذا كان c في مسافة بيضاء، فقم بتعيينه بعد، وإلا إذا كان c = سطر جديد، فقم بتعيينه قبل) إذا كان بعد و c = سطر جديد، فقم بتعيين قبل } doAction(c) { إذا كان قبل (c != سطر جديد و c ليس في مسافة بيضاء) فاكتب(c) إذا كان داخل المساحة البيضاء ولم يكن c في مسافة بيضاء، فاكتب(c) إذا كان بعد c = سطر جديد، فاكتب(c) } دورة { تم التعيين قبل كرر حتى (c: readCharacter) = EOL { setState(c) doAction(c) } } 

إن فصل الإجراءات التي تعبر عن تقدم الدورة من جانب، والإجراء الفعلي من الجانب الآخر (مطابقة المدخلات والمخرجات) يسمح بكتابة كود أكثر وضوحًا وبساطة.

الفعاليات

في مجال الأتمتة، يعتمد الانتقال من خطوة إلى أخرى على بيانات الإدخال الواردة من الآلة نفسها. ويتم تمثيل ذلك في البرنامج بقراءة الأحرف من نص. في الواقع، تُشير هذه البيانات إلى موقع وسرعة ودرجة حرارة العناصر الحيوية للآلة، وما إلى ذلك.

كما هو الحال في برمجة واجهات المستخدم الرسومية ، يمكن اعتبار التغييرات في حالة الآلة أحداثًا تؤدي إلى الانتقال من حالة إلى أخرى، حتى الوصول إلى الحالة النهائية. ويمكن أن يُولّد الجمع بين الحالات الممكنة مجموعة واسعة من الأحداث، مما يُحدد دورة إنتاج أكثر تعقيدًا. ونتيجة لذلك، عادةً ما تكون الدورات بعيدة كل البعد عن كونها تسلسلات خطية بسيطة. توجد عادةً فروع متوازية تعمل معًا، ويتم اختيار البدائل وفقًا لأحداث مختلفة، كما هو موضح في الرسم التخطيطي أدناه:

 المرحلة: ج: الحالة s1 | |-c2 | s2 | ---------- | | |-c31 |-c32 | | s31 s32 | | |-c41 |-c42 | | ---------- | s4

التطبيقات

تُستخدم البرمجة القائمة على الأوتوماتا على نطاق واسع في التحليلات المعجمية والنحوية . [ 1 ]

إلى جانب ذلك، فإن التفكير من حيث الأوتوماتا (أي تقسيم عملية التنفيذ إلى خطوات الأوتوماتا وتمرير المعلومات من خطوة إلى أخرى من خلال حالة الأوتوماتا الصريحة ) ضروري للبرمجة القائمة على الأحداث باعتبارها البديل الوحيد لاستخدام العمليات المتوازية أو الخيوط.

تُستخدم مفاهيم الحالات وآلات الحالة بكثرة في مجال المواصفات الرسمية . فعلى سبيل المثال، يستخدم تطوير بنية البرمجيات القائمة على لغة النمذجة الموحدة (UML) مخططات الحالة لتحديد سلوك البرنامج. كما تُحدد بروتوكولات الاتصال المختلفة غالبًا باستخدام مفهوم الحالة الصريح (مثل RFC 793 ). 

يمكن أيضًا استخدام التفكير من منظور الأوتوماتا (الخطوات والحالات) لوصف دلالات بعض لغات البرمجة . على سبيل المثال، يُوصف تنفيذ برنامج مكتوب بلغة Refal بأنه سلسلة من خطوات ما يُسمى بآلة Refal المجردة؛ وحالة الآلة هي عرض (تعبير Refal عشوائي بدون متغيرات).

تتطلب الاستمراريات في لغة Scheme التفكير من منظور الخطوات والحالات، على الرغم من أن Scheme نفسها لا ترتبط بالآلات (فهي لغة تكرارية). ولتمكين ميزة call/cc من العمل، يجب أن يكون التنفيذ قادرًا على رصد حالة كاملة للبرنامج قيد التنفيذ، وهو ما لا يتحقق إلا في حال عدم وجود جزء ضمني في الحالة. تُسمى هذه الحالة المرصودة بالاستمرارية ، ويمكن اعتبارها حالة لآلة (معقدة نسبيًا). تتمثل خطوة الآلة في استنتاج الاستمرارية التالية من السابقة، وعملية التنفيذ هي دورة هذه الخطوات.

يشرح ألكسندر أولونغرين في كتابه [ 2 ] ما يسمى بطريقة فيينا لوصف دلالات لغات البرمجة والتي تعتمد كليًا على الأوتوماتا الرسمية.

نظام STATيُعد مثالاً جيداً على استخدام النهج القائم على الأتمتة؛ يتضمن هذا النظام، إلى جانب ميزات أخرى، لغة مضمنة تسمى STATL وهي موجهة نحو الأتمتة بشكل كامل.

تاريخ

استُخدمت التقنيات القائمة على الأوتوماتا على نطاق واسع في المجالات التي توجد فيها خوارزميات تعتمد على نظرية الأوتوماتا، مثل تحليلات اللغة الرسمية. [ 1 ]

إحدى الأوراق البحثية المبكرة حول هذا الموضوع هي ورقة جونسون وآخرون، 1968. [ 3 ]

أحد أقدم الإشارات إلى البرمجة القائمة على الأوتوماتا كتقنية عامة موجودة في ورقة بيتر نور ، 1963. [ 4 ] يطلق المؤلف على هذه التقنية اسم نهج آلة تورينج ، ومع ذلك لم يتم تقديم أي آلة تورينج حقيقية في الورقة؛ بدلاً من ذلك، تم وصف التقنية القائمة على الخطوات والحالات.

مقارنة بالبرمجة الإجرائية والبرمجة الأمرية

إن مفهوم الحالة ليس حكرًا على البرمجة القائمة على الأوتوماتا. [ 5 ] بشكل عام، تظهر الحالة (أو حالة البرنامج ) أثناء تنفيذ أي برنامج حاسوبي ، كمجموعة من جميع المعلومات التي يمكن أن تتغير أثناء التنفيذ. على سبيل المثال، تتكون حالة برنامج إجرائي تقليدي من

  • قيم جميع المتغيرات والمعلومات المخزنة داخل الذاكرة الديناميكية؛
  • القيم المخزنة في السجلات؛
  • محتويات المكدس (بما في ذلك قيم المتغيرات المحلية وعناوين الإرجاع)؛
  • القيمة الحالية لمؤشر التعليمات .

يمكن تقسيم هذه إلى الجزء الصريح (مثل القيم المخزنة في المتغيرات) والجزء الضمني (عناوين الإرجاع ومؤشر التعليمات).

مع ذلك، يمكن اعتبار البرنامج القائم على الأوتوماتا حالة خاصة من البرنامج الإجرائي، حيث يتم تقليل الجزء الضمني من الحالة. تختلف حالة البرنامج ككل عند لحظتي الدخول إلى قسم التعليمات البرمجية في حالة الأوتوماتا فقط. وهذا يُبسط تحليل البرنامج.

علاقة البرمجة الكائنية التوجه

في نظرية البرمجة كائنية التوجه ، يُقال إن للكائن حالة داخلية ، وهو قادر على استقبال الرسائل والرد عليها، وإرسال الرسائل إلى كائنات أخرى، وتغيير حالته الداخلية أثناء معالجة الرسائل. وبعبارة أخرى، يُعتبر استدعاء دالة كائن ما بمثابة إرسال رسالة إليه .

وبالتالي، من جهة، يمكن اعتبار الكائنات في البرمجة كائنية التوجه بمثابة آلات (أو نماذج للآلات) حيث تكون حالتها عبارة عن مزيج من الحقول الخاصة، وتُعتبر طريقة واحدة أو أكثر بمثابة الخطوة . يجب ألا تستدعي هذه الطرق بعضها البعض أو نفسها، لا بشكل مباشر ولا غير مباشر، وإلا فلن يُعتبر الكائن مُنفذًا بطريقة قائمة على الآلات.

من ناحية أخرى، يُعدّ الكائن مناسبًا لتنفيذ نموذج آلة. عند استخدام منهج الآلات ضمن لغة برمجة كائنية التوجه، يُنفَّذ نموذج الآلة عادةً بواسطة فئة، وتُمثَّل الحالة بحقول خاصة بالفئة، وتُنفَّذ الخطوة كدالة؛ وعادةً ما تكون هذه الدالة هي الدالة العامة الوحيدة غير الثابتة في الفئة (إلى جانب الدوال البانية والمدمرة). يمكن للدوال العامة الأخرى الاستعلام عن الحالة دون تغييرها. أما جميع الدوال الثانوية (مثل دوال معالجة الحالة الخاصة) فعادةً ما تكون مخفية ضمن الجزء الخاص من الفئة.

انظر أيضاً

مراجع

  1. 1 2 أهو، ألفريد ف.؛ أولمان، جيفري د. (1973). نظرية التحليل والترجمة والتجميع . المجلد 1. إنجلوود كليفس، نيوجيرسي: برنتيس هول. ISBN  0-13-914564-8.
  2. أولونغرين، ألكسندر (1974). تعريف لغات البرمجة من خلال تفسير الأوتوماتا . لندن: أكاديميك برس. ISBN 0-12-525750-3.
  3. جونسون، دبليو إل؛ بورتر، جيه إتش؛ أكلي، إس آي؛ روس، دي تي (1968). "التوليد التلقائي لمعالجات معجمية فعالة باستخدام تقنيات الحالة المحدودة" . مجلة الاتصالات ACM . 11 (12): 805-813 . doi : 10.1145/364175.364185 . S2CID 17253809 . 
  4. نور، بيتر (سبتمبر 1963). "تصميم مُصرّف GIER ALGOL، الجزء الثاني". مجلة BIT للرياضيات العددية . 3 (3): 145-166 . doi : 10.1007/BF01939983 . S2CID 189785656 . 
  5. "البرمجة القائمة على الأوتوماتا" (ملف PDF) . المجلة العلمية والتقنية لتكنولوجيا المعلومات والميكانيكا والبصريات (53). 2008.