تكنيك ها وزبانهاي برنامه نويسي هوش مصنوعي

آبجی

عضو جدید
کاربر ممتاز
تكنيك ها وزبانهاي برنامه نويسي هوش مصنوعي
ما در عصري زندگي مي كنيم كه جامعه شناسان آن را عصر انقلاب كامپيوتر نام نهاده اند و مانند هر انقلاب واقعي ديگر، انقلابي است گسترده و فراگير و تأثير پايداري برجامعه خواهد داشت.

اين انقلاب در اقتصاد امروز و نظم جامعه، به همان ميزان انقلاب صنعتي در قرن 19 تأثير دارداين تحولات قادر است الگوي فكري و فرم زندگي هر فرد را تغيير دهد.

انقلاب كامپيوتر توان ذهني ما را گسترش مي دهد.

عملكرد اولية برنامه نويسي هوش مصنوعي (AI) ايجاد ساختار كنترلي مورد لزوم براي محاسبه سمبوليك است خصوصيات اين ساختارها به مقدار زيادي موجب تشخيص خصوصياتي مي شود كه يك زبان كاربردي مي بايستي فراهم كند.

در اين مقدمه به يك سري خصوصيات مورد نظر براي زبان برنامه نويسي سمبوليك مي پردازيم و زبانهاي برنامه نويسي LISP و PROLOG را معرفي خواهيم كرد.

اين دو زبان علاوه بر اين كه از مهمترين زبانهاي مورد استفاده در هوش مصنوعي هستند، خصوصيات semantic و syntactic آنها نيز باعث شده كه آنها شيوه ها و راه حل هاي قوي براي حل مسئله ارئه كنند.

تأثير قابل توجه اين زبانها بر روي توسعه AI از جمله توانائي آنها به عنوان «ابزارهاي فكر كردن» مي باشد كه از جمله نقاط قوت آنها در زبانهاي برنامه نويسي مي باشد.

همان طور كه هوش مصنوعي مراحل رشد خود را طي مي كند زبانهاي LISP و PROLOG بيشتر مطرح مي شوند.

اين زبانها كار خود را در محدودة توسعه و prototype سازي سيستم هاي AI در صنعت و دانشگاهها دنبال مي كنند.

اطلاعات در مورد اين زبانها به عنوان بخشي از مهارت هر برنامه نويس AI مي باشد ما به بررسي اين دو زبان در هوش مصنوعي مي پردازيم.

آنــــچه را كـــه نمي دانيم موجب دردسر و گرفتاري ما نخواهد شد، بلكه دردسرها از دانسته ها سرچشمه مي گيرند.

W.ROGERS



زبان ، شناخت و خلاصه پردازي

توانايي شكل گيري خلاصه برداري از تجربيات از توانمند ترين و اساسي ترين توانائي هاي ذهن انسان است خلاصه پردازي به ما اين اجازه را مي دهد كه به فهم جزئيات از يك محدوده ي كلي اطلاعات مربوط به يك خصوصيت كلي سازمان و رفتار برسيم . اين خلاصه ها به ما اجازه شناخت و درك كامل موارد دريافت شده در حوزه خاص را مي دهند . اگر ما وارد يك خانه شويم كه به خوبي ساخته شده باشد ، راههاي خود را به اطراف پيدا خواهيم كرد . ساختار خصوصيات اطاق نشيمن ، اطاق خواب ،‌آشپزخانه و حمام عموماً از ويژگيهاي يك مدل خانة استاندارد مي باشد .

خلاصه پردازي به ما حس شناخت خانه هاي متفاوت را مي دهد . يك تصوير ممكن است بياني قوي تر از هزاران كلمه داشته باشد ، اما يك خلاصه مشخصاً بيان كنندة خصوصيات مهم يك كليت از نوع تصوير است .

وقتي كه ما به تئوري براي توصيف كلاس هاي يك پديده مي پردازيم ، خصوصيات و ويژگيهاي كمي و كيفي مربوط به كلاس از كل جزئيات خلاصه مي شود .

كه اعضاء به خصوص خود را مشخص مي كند . اين كاهش جزئيات به وسيله قدرت توصيف و پيش بيني يك نظريه ارزشمند جبران مي شود .

خلاصه سازي يكي از ابزارهاي اساسي شناخت و ارزيابي كليت هاي جهان اطراف ما و همچنين ساختار ذهني ما است . در حقيقت اين پروسه به طور مداوم براساس دانش و اطلاعات صورت مي گيرد . دانش و اطلاعا نيز در لايه ها و بخش هايي از خلاصه پردازي ساخته مي شود كه از مكانيسم هايي كه ساختار را فشرده ساخته و از حس اوليه به سمت يك سري تئوري هاي علمي سوق داده مي شود و در نهايت بيشتر اين ايده ها دربارة ايده هاي ديگر و نشأت گرفته از آنها مي باشد .

خلاصه پردازي طبقه بندي شده (سلسله مراتبي ) :

ساختار و سازمان آزمايش و تجربه در ارتباط با توصيفات كلاس هاي خلاصه سازي يكي از ابزارهاي شناخت رفتار و ساختار سيستم هاي مركب است كه شامل برنامه هاي كامپيوتر مي شوند .

همانند رفتار يك حيوان كه ممكن است بدون توجه به فيزيولوژي سيستم عصبي نهفته در پشت آن مورد مطالعه قرار گيرد .

يك الگوريتم داراي خصوصيات مربوط به خود مي باشد كه كاملاً آن را از برنامه اي كه آن را به كار مي برد جدا مي سازد .

به عنوان مثال دو نوع كاربر متفاوت جستجوي باينري را در نظر بگيريد .

يكي از آنها يعني Fortran از محاسبات و طبقه بندي استفاده مي كند و ديگري يعني Ctt از Pointer استفاده مي كند كه بتواند در جستجوي درون شاخه هاي binary كاربرد داشته باشد .

اگر دقيق تر نگاه كنيم اين برنامه ها مثل هم مي باشند چون اگر جز اين باشد كاربردهاي آنها نيز تفاوت خواهد شد . جداسازي الگوريتم از كه مورد استفاده در كاربرد آن يكي از نمونه هاي خلاصه سازي سلسله مراتبي مي باشد .

Allen New ell بين سطح دانش و سطح نشانه ها براي توصيف يك سيستم هوشمند تفاوت قائل شده است.

سطح نشانه ها همراه سازماندهي به خصوصي مورد توجه قرار گرفته كه براي بيان اطلاعات حل مسئله مورد استفاده قرار مي گيرد. بحث مربوط به توجه به منطق به عنوان يك زبان يك نمونه از مواردي است كه به سطح نشانه پرداخته است.

علاوه بر سطح نشانه سطح دانش است كه توجه آن به مقدار و محتوي اطلاعات يك برنامه و شيوه استفاده از آن اطلاعات مي باشد.

اين نوع تمايز در ساختار و معماري سيستم هايي كه بر اساس دانش و اطلاعات و سبك توسعه اي كه آن را پشتيباني مي كتد منعكس مي گردد.

به دليل اينكه كاربرها برنامه ها را در قالب دانش و توانايي خودشان مي شناسند بنابراين حائز اهميت است كه برنامه هاي AI داراي يك سطح خصوصيات اطلاعاتي باشند.

جداسازي اصل دانش و اطلاعات از ساختار كنترل اين نظريه را آشكار مي سازد و توسعه رفتار سطح دانش را ساده مي سازد.

همانند اين نيز سطح نشانه اي يك زبان توصيفي را تشريح مي كند كه شبيه قوانين و روشهاي توليد يا منطق براساس دانش و اطلاعات مي باشد.

جداسازي آن از سطح و دانش و اطلاعات نه برنامه نويس اين اجازه را مي دهد كه به سمت خلاصه پردازي ت،ثير پذيري و راحتي برنامه نويسي سوق پيدا كندكه در ارتباط با رفتار و عملكرد بالاي برنامه نمي باشد.

كاربرد بيان سطح نشانه اي شامل يك سطح دوره پائين تر از ساختار برنامه مي شود و بيانگر يك سري ملاحظات طراحي اضافي مي شود.

اهميت نظريه چند مرحله اي نسبت به طراحي سيستم نمي تواند بيش از اين مورد توجه قراار گيرد.

يعني اينكه به برنامه نويس اجازه مي دهد كه با پيچيدگي نهفته شده در سطوح پائين تر خود را درگير نكند و توجه و تاكيدش بر روي منابع مناسب با سطح فعلي خلاصه پردازي كند.

همچنين موجب مي شود كه اصول تئوري هوش مصنوعي عاري از كاربردهاي خاص يا زبان برنامه نويسي باشد . اين همچنين به ما قدرت توصيف يك كاربرد را مي دهد و تاثير گذاري خود را بر روي ماشين ديگر اثبات مي كند بدون اينكه بر رفتارش در سطوح بالاتر تاثير بگذارد .




سطح اطلاعات توصيف كننده توانائي هاي يك سيستم هوشمند است. محتوي دانش و اطلاعات مستقل از شكل پذيري مورد استفاده براي بيان آن است به همان اندازه كه زبان بيان كاملا مؤثر مي باشد .

توجه به سطح دانش شامل سؤالاتي از اين قبيل است:

از اين سيستم چه چيزي ساخته خواهد شد؟ چه اشيا و چه ارتباطي در آن محدوده مؤثر و مفيد است ؟ چگونه يك اطلاعات جديد به سيستم اضافه مي گردد؟

آيا واقعيات در طي زمان تغيير مي كنند؟ چگونه و چطور سيستم نيازمند است كه دلائل اطلاعات خود را ثابت كند؟ آيا محدوده ارتباطي داراي يك طبقه بندي درست و شناخته شده است؟

آيا اين محدوده شامل يك سري اطلاعات نادرست و غير ممكن است؟

تجزيه و تحليل دقيق در اين سطح يك گام مبهم در طراحي كلي ساختار يك برنامه مي باشد.

در سطح نشانه تصميمات درباره ساختارها صورت مي گيرد كه براي بيان و ايجاد دانش مورد استفادده قرار مي گيرند. انتخاب يك زبان براي بيان يك مورد مربوط به سطح نشانه مي باشد.

منطق يكي از چندين نوع اشكال است كه اصولا در حال حاضر براي بيان دانش و اطلاعات در دسترس مي باشد.

زبان بيان نه تنها مي بايستي توانايي بيان اطلاعات مورد لزوم براي كاربر را داشته باشد بلكه مي بايستي خلاصه و قابل توصيف و داراي كاربرد مؤثر باشد و مي بايستي به برنامه نويس براي دستيابي و سازماندهي اصل و اساس اطلاعات كمك كند.

وقتي كه بين سطح اطلاعات و سطح نشانه يك برنامه تمايز به وجود آمد ما مي توانيم بين سطح نشانه و الگوريتم و ساختمان داده ها مورد استفاده براي كاربرد آن نيز تمايز قايل شويم. به عنوان مثال بدون تاثيرگذاري رفتار و عملكرد يك تحليل گر برنامه كه اساس منطقي داشته باشد مي بايستي تاثير ناپذير از انتخاب بين يك سري جزئيات و يك مجموعه و دسته بايزي باشد تا بتواند يك جدول مربوط به نشانه ها را به كار برد.

اين تصميمات كاربردي هستند و مي بايستي در سطح نشانه قابل رؤيت باشند . بسياري از الگوريتم و ساختمان داده ها در كاربرد بيان زبان AI به كار مي روند كه از روشهاي معمول علم كامپيوتر مي باشند مثل شاخه ها و جداول بايزي.

ديگر موارد در رابطه با AI بسيار تخصصي هستند و به گونه يك كه مستعار بيان مي شوند كه از طريق متن و بخش هاي مربوط به LISP و PROLOG بيان مي شوند .

در سطح پائين تر مربوط به الگوريتم و ساختمان داده ها ( سطح زبان ) واقع شده است در اين جا ست كه زبان كاربردي براي برنامه مشخص مي شود .

با اين حال سبك برنامه نويسي مطلوب احتياج به اين دارد كه ما يك خلاصه داده اي بسازيم كه بين خصوصيات ويژه يك زبان برنامه نويسي و لايه هاي بالاي آن قرار گيرد . نيازهاي منحصر به فرد برنامه نويسي سطح نشانه اي تأثير به روي طراحي و استفاده از زبانهاي برنامه نويسي AI ايجاد مي كند . علاوه بر اين طراحي زبان مي بايستي در برگيرنده و مطابق با ساختار آن كه بر گرفته از سطوح پائين تر ساختمان كامپيوتر كه شامل زبان اسمبلي و سيستم عامل و دستور العملهاي ماشين و سطوح سخت افزار ي باشد .

و محدوديت هاي فيزيكي كامپيوتر مي بايستي بر روي منابعي همچون حافظه و سرعت پردازشگر تأ كيد كند . روش هاي PROLOG , LISP در جهت مستعاذل كردن نيازهاي سطح نشانه و نيازهاي نهفته در ساختار هر دو منبع مورد استفاده مي باشند و هم چنين يك هدف هوشمند و ذهني با اهميت مي باشند . در دنباله ما از ساختارهاي سطح اطلاعات در محيطهاي برنامه نويسي بر روي يك زبان كاربردي صحبت خواهيم كرد و سپس به مصزفي زبانهاي عمده AI يعني PROLOG , LISP مي پردازيم .
 

آبجی

عضو جدید
کاربر ممتاز
تكنيك ها وزبانهاي برنامه نويسي هوش مصنوعي

متن عناوين
زبانهاي برنامه‌نويسيAI، برنامه‌نويسي تابعي ، برنامه‌نويسي تابعي در Lisp ، A- Syntax (نحو) و semantic هاي (معاني) Lisp ، ليست انواع داده ، تعريف توابع جديد ، تعريف ساختارهاي كنترلي ، تعريف توابع بازگشتي ، توابع مرتبه بالا ، ساير زبانهاي برنامه‌نويسي تابعي غير از Lisp ، برنامه‌نويسي منطقي در Prolog ، ساير روشهاي برنامه‌نويسي

واژه نامه
بندهاي برنامه Prolog
شامل مجموعه‌اي از جملات بنام بندها هستند كه براي نشان دادن داده‌ها و برنامه‌ها بكار مي‌روند.
تابع مرتبه بالا تعريف تابعي است كه اجازه مي‌دهد آرگومانها يا مقدار بازگشتي تابع، مقدار توابع باشد. نماد ساختار ليستها اغلب نشان‌دهنده نحوه استفاده از ليست ساختاري داده هستند، كه يك عنصر ليست ممكن است نماد يا ليست ديگر باشد. ليستها ساختاري مركزي Lisp هستند كه براي نشان دادن داده‌ها و برنامه‌ها بكار مي‌روند. بازگشت تكنيكي الگوريتمي براي انجام يك كار است كه يك تابع با بعضي از قسمتهاي كار خودش را فراخواني مي‌كند.
محاسبات نمادين برنامه‌نويسي AI (اساساً) شامل دستكاري نمادها است نه اعداد. اين نمادها مي‌توانند اشياء در جهان و ارتباط بين آن اشياء را نشان دهند- ساختارهاي پيچيده نمادها نياز به دانش ما از جهان دارند. واژه ساختار اساسي داده‌ها در Prolog واژه‌اي است كه مي‌تواند يك ثابت، يك متغير يا يك ساختار باشد. ساختارها موضوعات ريز محاسبات گزاره‌اي را نشان مي‌دهند و شامل يك عملگر نام و يك پارامتر ليست هستند.
زبانهاي برنامه‌نويسي هوش مصنوعي(AI) ابزار اصلي بررسي و ساخت برنامه‌هاي كامپيوتري هستند كه مي‌توانند در شبيه‌سازي فرايندهاي هوشمند مانند يادگيري،‌ استدلال و فهم اطلاعات نمادين بكار بروند. هر چند اخيراً زبان كامپيوتر اصولاً براي استفاده از كامپيوترها براي انجام محاسبات با اعداد طراحي شده بود، اما بزودي دريافتند كه رشته‌اي از بيتها نه تنها اعداد بلكه مي‌توانند اشياي دلخواه را نيز نمايش دهند. عمليات روي ويژه‌گي‌ها يا نمادها مي‌تواند با استفاده از قوانين براي ايجاد، انتساب يا دستكاري نشان داده شود. اين تصور از محاسبات نمادين بعنوان تعريف الگوريتمهايي كه هر نوع اطلاعات را پردازش مي‌كنند و بنابراين مي‌تواند براي شبيه‌سازي هوش انسان بكار برود مناسب است.
بزودي برنامه نويسي با نمادها كه نياز به سطح بالايي از چكيدگي دارند توليد مي‌شوند، غير از امكاناتي كه با زبانهاي برنامه نويسي مخصوص پردازش اعداد ممكن بود مانند فرترن

I-زبانهاي برنامه نويسي AI
در AI خودكار كردن يا برنامه‌نويسي همه جنبه‌هاي شناخت انساني بوسيله بنيادهاي شناخت علمي روشهاي نمادين و غير نمادين AI، پردازش زبان طبيعي، ديد كامپيوتري و سيستمهاي تكامل يا سازگار مطرح مي‌شود. لازم است دامنه مسئله‌هاي خيلي پيچيده در ابتداي مرحله برنامه‌نويسي يك مسئله AI معين، مشخص شود كه كافي نيست. تنها بوسيله تعامل و افزايش اصلاحات خصوصيات بسيار دقيق ممكن است. در حقيقت مسئله‌هاي معمول AI به بسياري از زمينه‌هاي خاص گرايش دارند، بنابراين روشهاي ذهني بايد بوسيله توليد و آزمايش روشها بطور تجربي توسعه يابند(مشهور به نمونه سازي سريع). در اينصورت برنامه‌نويسي AI بطور قابل توجهي با روشهاي استاندارد مهندسي نرم‌افزار متفاوت بوده زيرا برنامه‌نويسي معمولا از يك مشخصات رسمي با جزئيات شروع مي‌شود. در برنامه‌نويسي AI پياده‌سازي در واقع جزئي از پردازش مشخصات مسئله است. به اقتضاي طبيعت مسئله‌هاي AI برنامه‌نويسي AI مزاياي بسياري دارد اگر زبانهاي برنامه نويسي، برنامه‌نويسAI را آزاد بگذارند و در بسياري از ساختارهاي فني محدود نكنند (مانند ساختار انواع داده‌اي جديد سطح پايين، دستيابي دستي به حافظه). ترجيحاً سبك برنامه‌نويسي اعلاني براي استفاده در ساختارهاي پيش‌ساخته داده‌اي سطح بالا(مانند ليستها و درختها) و عمليات(مانند تطبيق الگوها) مناسب است، بنابراين محاسبات نمادين سطح خلاصه‌سازي بيشتري نسبت به آنچه كه با زبانهاي دستوري استاندارد مانند فرترن، پاسكال يا C امكان‌پذير خواهد بود را پشتيباني مي‌كند. البته طبقه‌بندي خلاصه سازي آسان نيست،‌ زيرا تدوين برنامه‌هاي AI روي كامپيوترهاي استاندارد وان نيومن نمي‌تواند به كارآمدي زبانهاي دستوري باشد. هر چند يك مسئله مسلم AI فهم آن است (حداقل جزئيات) امكان دارد با تنظيم مجدد آن به شكل خصوصيات جزئي شده با بكار بردن يك زبان دستوري پياده‌ سازي مجدد شود. با توجه به نيازمنديهاي محاسبات نمادين و برنامه‌نويسي AI دو الگوي جديد برنامه‌نويسي كه به سبك دستوري پيشنهاد مي‌شوند بوجود مي‌‌آيد: سبك برنامه‌نويسي تابعي و منطقي. هر دو بر مبناي رياضيات طرح‌ريزي شده‌اند، يعني نظريه توابع بازگشتي و منطق رسمي. اولين زبان برنامه‌نويسي AI كاربردي كه هنوز هم بطور گسترده استفاده مي‌شود زبان برنامه‌نويسي Lisp است كه در اواخر دهه 1950 توسط جان مك كارتي توسعه يافته است. Lisp برمبناي نظريه توابع رياضي و خلاصه‌سازي Lambda است. تعدادي از كاربردهاي مهم و موثرAI در Lisp نوشته شده است. كه ما بعضي از جزئيات اين زبان برنامه‌نويسي را در اين مقاله شرح خواهيم داد. در اوايل دهه 1970 يك الگوي برنامه‌نويسي جديد بنام برنامه‌نويسي منطقي بر اساس محاسبات گزاره‌اي بوجود آمد. اولين و مهمترين زبان برنامه‌نويسي منطقي Prolog است كه توسط آلن كالمرار، رابرت كوالسكي و فيليپ راسل توسعه يافته است. مسئله‌ها در prolog بصورت حقايق، بديهيات و قوانين منطقي براي استنباط حقايق جديد بيان مي‌شوند. Prolog با قانون رياضي در محاسبات گزاره‌اي و نتايج نظري بدست آمده در زمينه اثبات قضيه خودكار در اواخر دهه 1960 بنا نهاده شده است.
 

آبجی

عضو جدید
کاربر ممتاز
خصوصيات مطلوب يك زبان AI

يكي از خصوصيات و ويژگيهاي مهم خلاصه سازي سلسله مراتبي در ساختار برنامه غير حساس بودن سطوح بالاتر نهفته در كاربرد زبان مي باشد .

اين مشاهده در عمل سنجيده مي شود كه همراه با سيستم هاي موفق دانش مدار مي باشد كه در زبانهاي برنامه نويسي مختلفي مثل Pascal , C , Ctt , Java , PROLOG , LISP و حتي Fortran به كار مي رود .

برنامه هاي مختلفي اصولاً در PROLOG , LISP و سپس در C به كار گرفته مي شوند تا بتواند تاثيرپذيري و انتقال پذيري بهتر ايجاد كنند. در هر دوي اين موارد رفتار و عملكرد در سطح نشانه به طور قطع بي اثر مي باشد.

با اين حال محدوديتهاي خلاصه سازي در يك برنامه جامع بيان مي شود كه كامل نمي باشد . ساختار سطح بالاتر باعث ايجاد ساختارهاي قوي بر روي لايه هاي زيرين مي شود و نياز به اين دارد كه برنامه نويسي AI بر روي سطح نشانه اي قرار گيرد كه در سطح زبان تكرار مي شوند.

به عنوان مثال ساختارهاي اطلاعاتي مورد لزوم براي ادغام سمبوليك خود را مقيد به اشكال تكراري مثل فلش ها و ليست ها نمي كنند.

اهداف و پيش بيني هاي منطقي ابزارهاي كاربردي طبيعي تر و انعطاف پذيرتر خواهند بود.

علاوه بر اين به دليل مشكلات موجود در بسياري از مسائل مربوط به AI اغلب توسعه را قبل از اينكه يك شناخت كامل از نهايت فرم برنامه داشته باشيم شروع مي كنيم.

توسعه AI لزوما در طبيعت به صورت كشف و تجزيه و آزمايش است.

اين نياز هم چنين وابسته به يك زبان و ابزارهايي است كه بايد فراهم ساخت . يك زبان نه تنها مي بايستي متناسب با كاربرد ساختارهاي سطح بالا باشد بلكه مي بايستي يك ابزار مناسب براي انتقال كل چرخه نرم افزار از آناليز و تجزيه و تحليل تا حصول برنامه باشد.

در پنــج زير گـــروه بعدي ما به صورت جزئي و كامل در مورد نيازهايي كه ساختارهاي سطح نشانه اي برنامه هاي AI كه بر روي كاربرد زبان دارند بحث مي كنيم.
 

آبجی

عضو جدید
کاربر ممتاز
اين موارد عبارتند از :

1. پشتيباني از محاسبه سمبوليك
2. انعطاف پذيري كنترل

3. پشتيباني از متدولوژي و روش هاي برنامه نويسي جستجويي

4. پويايي

5. مستنند سازي خوب و واضح

`پشتيباني از محاسبات سمبوليك

گرچه روش هاي زيادي براي سازماندهي اطلاعات در يك سطح نشانه وجود دارد . ولي تمامي آنها نهايتاً به عنوان عملكردهايي بر روي نشانه ها به كار مي روند .

اين روش در تئوري نشانه هاي آقاي Simon , Newell آمده است . تئوري هاي سيستم فيزيكي نشانه نياز اصلي براي زبان برنامه نويسي است كه كاربردهاي يك سري از عمليات سمبوليك را آسان مي كند .

حتي شبكه هاي عصبي و ديگر شكل هاي ضروري محاسبه مي بايستي شامل اطلاعات سمبوليك در وروديها و خروجي هايشان باشند . انواع كاربردها و اطلاعات دادهاي عددي تاكيد شان بر روي زبانهاي برنامه نويسي معمول است كه براي كاربردهاي جستجوي الگوريتمي يا بيان زبان AI مناسب نمي باشند.

علاوه بر اين يك زبان AI مي بايستي ساختار ايجاد نشانه هاي اوليه را ساده سازد و بر روي آنها كار كند. اين يكي از مهمترين نيازهاي يك زبان برنامه نويسي AI مي باشد.

محاسبات و پيش بيني يكي از قوي ترين و عمومي ترين ابزارهاي ايجاد ساختار كيفي يك محدوده از مسئله مي باشد.

خصوصيات بارز يك محدوده ممكن است به گونه يك سري واقعيات منطقي بيان شود. از طريق استفاده از متغيرها امكان ايجاد واقعيات كلي درابره ارتباط بين اهداف در يك محدوده به وجود مي آيد.

PROLOG يك زبان برنامه نويسي كلي است كه بر اساس پيش بيني محاسباتي است.

به عنوان يك كاربرد رسمي منطق PROLOG بعضي اوقات مستقيما به عنوان يك زبان در سطح نشانه مورد استفاده قرار مي گيرد.

با اين حال قدرت واقعي آن به عنوان يك زبان براي كاربرد دقيق تر و كامل همانند چهارچوب ها و شبكه ها در يك روش سيستماتيك و فشرده مي باشد بسياري از ساختارهاي سطح نشانه اي به سادگي با استفاده از ساختارهاي سطح بالاي PROLOG ساخته مي شوند.

PROLOG ممكن است براي كاربرد در جستجوي الگوريتم ها يك سيستم محافظ و يك شبكه سمانتيكي مورد استفاده قرار گيرد.

يك ابزار مهم ديگر براي ساخت ساختارهاي نشانه ليست مي باشد يك ليست شامل يك سري عناصر مي شود كه در آن هر عنصر ممكن است حتي يك ليست و يك نشانه باشد.

چند نمونه از ليست ها با استفاده از ساختار برنامه نويسي LISP عبارتند از :

(اين يك ليست است)

(اين هست) (يك ليست) (از ليست ها)

(زمانها (بعلاوه 13)(بعلاوه 23) )

((123)(456)(789))

توجه داشته باشيم كه اينها نمونه هايي مي باشند كه شامل ليستهاي درون ليست هاي ديگر مي شود اين موجب مي شود كه ارتباطات ساختاري ايجاد گردد. قدرت ليست ها عمدتا در نتيجه توانايي بيان هر نوع ساختار نشانه اي بدون در نظر گرفتن پيچيدگي يا عملكردهايي كه مي بايد از آن پشتيباني كند مي باشد.

اين شامل شاخه ها گراف هاي اوليه يك سري مشخصه هاي منطقي جهت ها اصول اطلاعاتي كليدي مي شود. به طور خلاصه هر نوع ساختار ممكن است بر اساس يك تركيب مناسب متشكل از ليست ها و عملكردهاي واقع شده بر روي آنها حاصل شوند.

ليست ها يك سري بلوك هاي مهم مي باشند كه PROLOG , LASP كه موجب مي شود كه كاربر را با عناصر اطلاعاتي و عملياتي براي دستيابي و تاكيد بر آنها در درون يك سري ساختارهاي پيچيده مهيا سازد. در حاليكه PROLOG مستقيما به محاسبات پيش بيني شده وابسته است و شامل يك سري ليست به عنوان ابزارهاي بيان مي شود.

LISP ليست را به عنوان اصول انواع داده ها و برنامه ها مورد استفاده قرار مي دهد. تمامي ساختارهاي LISP از ليست ها ساخته مي شوند و زبان فراهم كردن يك سري ابزارهاي قوي براي تركيب اينها (ساختارها) را به عهده دارد و توصيف كننده عمليات جديد براي ايجاد توسعه و تغيير آنها است. يك شكل كردن ساختار LISP و توانائي توسعه آن توصيف هر نوع زباني را براي ساختار آن ساده مي سازد . بوسيله پرداختن به نظريه جمع آوري اطلاعات فشرده برنامه نويس LISP مي تواند ساختارهاي نشانه را توصيف كند و عمليات مورد نياز هر نوع شكل گيري سطح بالا شامل كنترل كننده هاي جستجو حل كننده هاي تئوريهاي منطقي و ديگر اظهارات سطح بالا مي باشد.
 

آبجی

عضو جدید
کاربر ممتاز
انعطاف پذير بودن كنترل:

يكي از مشخصه هاي اساسي رفتار هوشمند قابليت انعطاف پذيري آن مي باشد . در حقيقت مشكل بتوان تصور كرد كه هوشمندي مي تواند از طريق توسعه گام به گام مراحل ثابت كه بوسيله برنامه هاي معمول كامپيوتري نشان داده مي شود حاصل شود. خوشبختانه اين تنها راه سازماندهي محاسبات نمي باشد.

يكي از مهمترين و در عين حال قديمي ترين نمونه هاي مربوط به ساخت يك برنامه ai سيستم توليد مي باشد.

در سيستم توليدي برنامه شامل يك سري قوانين مي شود. در منطق اطلاعات اين قوانين به گونه اي تنظيم مي شود كه بوسيله الگوي اطلاعات در يك نوع مسئله داده شده قابل تشخيص باشد.

قوانين توليد مي تواند به هر گونه كه پاسخگوي آ“ موقعيت خاص باشد برنامه ريزي شود. بدين طريق يك سيستم تولسد مي تواند ايجاد كننده انعطاف پذيري و ارتباط لازم براي رفتار هوشمند باشد.

بنــــابراين ai از يك تعداد متفاوتي ساختارهاي كنترلي استفاده مي كند كه بسياري از انها مرتبط با سيستم هاي توليد مي باشند و همه آنها تابع الگو مي باشند . كنترل الگويي موجب مي شود كه اطلاعات با توجه به نياز به خصوصيات يك نوع مسئله خاص به كار گرفته شود. الگوي الگوريتم هاي انطباقي مثل به صورت واحد در آوردن باعث مي شود كه بتواند تشخيص دهد كه چه موقع خصوصيات يك مسئله منطبق با يك برنامه اطلاعاتي است كه بر اين اساس اطلاعات لازم براي كاربرد در مسئله را انتخاب مي كند.

بنابراين حائز اهميت مي باشد كه يك زبان ai بتواند آن را مستقيما ايجاد كند و يا توسعه الگوي كنترل را ساده سازد.

در prolog يكي كردن و جستجوي الگوريتم ها در درون خود زمان ساخته مي شوند و قلب و اساس prolog را تشكيل مي دهند .

با استفاده از اين يكي كردن الگوريتم ها به سادگي مي توان هر نوع الگوي ساختاري كنترلي را ايجاد كرد .

Lisp مستقيماً الگوي انطبقي ايجاد نمي كند اما محاسبات سمبوليك آن موجب گسترش ساده مربوط به زبان ساده ساختار الگوي منطق شونده و توصيف كننده اوليه ساختار مي شود.

يكي از مزاياي اين نظريه اين است كه الگوي تطبيق و كنترل ساختارهاي همراه با آن ممكن است به سادگي براي تطبيق با نيازهاي يك مسئله بخصوص خود را منطبق سازد.

اغلــــب نظـــريات فعلي در ارتباط با هوش مصنوعي همانند شبكه هاي عصبي عوامل تنظيم كننده و ديگر فرم هاي محاسبات ضروري ممكن است اجتناب از عمليات بر روي ساختارهاي سمبوليك باشد.

ولي آنها نياز به يك كنترل انعطاف پذير را نفي نمي كنند. شبكه هاي عصبي مي بايستي توانايي حركتي شكل گيري خودشان را داشته باشند . عوامل متكي به پيام هستند كه از بين ماحوبهاي مختلف مي گذرد.

الگوريتم هاي ژنتيكي نياز به ايجاد واحد هاي شمارش به عنوان جمعيت كانديد شده حل مسئله دارند. توانايي زبان هاي ai براي ايجاد مشخصه تركيب ساده طبقه بندي اتوماتيك حافظه امكان اطلاع رساني ساده ايجاد متغيرها و روش هاي پويا و شكل هاي قوي ايجاد برنامه مثل يك برنامه شيء گرا موجب خواهد شد كه آنها را به سمت استفاده گسترده در كاربرد اين ابزارهاي جديدتر ai سوق دهد.
 

آبجی

عضو جدید
کاربر ممتاز
هوش مصنوعی:
هوش مصنوعی روشی است در جهت هوشمند کردن کامپیوتر تا قادر باشد در هر لحظه تصمیم گیری کرده و اقدام به بررسی یک مسئله نماید. هوش مصنوعی، کامپیوتر را قادر به تفکر می کند و روش آموختن انسان را تقلید می نماید. بنابراین اقدام به جذب اطلاعات جدید جهت بکارگیری مراحل بعدی می پردازد.
مغز انسان به بخش هایی تقسیم شده است که هر بخش وظیفه خاص خود را جدا از بقیه انجام می دهد. اختلال در کار یک بخش تاثیری در دیگر قسمت های مغز نخواهد گذاشت. در برنامه های هوش مصنوعی نیز این مسئله رعایت می شود درحالی که در برنامه های غیر هوش مصنوعی مثل C یا Pascal تغییر در برنامه روی سایر قسمت های برنامه و اطلاعات تاثیر دارد.
مباحث کاربردی و مهم در تحقق یک سیستم هوش مصنوعی :
۱- سیستم های خبره(Expert Systems)
2- شبکه های عصبی(Neural Network)
3- الگوریتم های ژنتیک(Genetic Algorithms)
4- سیستم های منطق فازی(Fuzzy Logic Systems)
هوش مصنوعی:
هوش مصنوعی روشی است در جهت هوشمند کردن کامپیوتر تا قادر باشد در هر لحظه تصمیم گیری کرده و اقدام به بررسی یک مسئله نماید. هوش مصنوعی، کامپیوتر را قادر به تفکر می کند و روش آموختن انسان را تقلید می نماید. بنابراین اقدام به جذب اطلاعات جدید جهت بکارگیری مراحل بعدی می پردازد.
مغز انسان به بخش هایی تقسیم شده است که هر بخش وظیفه خاص خود را جدا از بقیه انجام می دهد. اختلال در کار یک بخش تاثیری در دیگر قسمت های مغز نخواهد گذاشت. در برنامه های هوش مصنوعی نیز این مسئله رعایت می شود درحالی که در برنامه های غیر هوش مصنوعی مثل C یا Pascal تغییر در برنامه روی سایر قسمت های برنامه و اطلاعات تاثیر دارد.
مباحث کاربردی و مهم در تحقق یک سیستم هوش مصنوعی :
۱- سیستم های خبره(Expert Systems)
2- شبکه های عصبی(Neural Network)
3- الگوریتم های ژنتیک(Genetic Algorithms)
4- سیستم های منطق فازی(Fuzzy Logic Systems)
سیستم های خبره:
برنامه هایی هستند که رفتار یک انسان متخصص در یک زمینه بخصوص را تقلید می کنند. این برنامه از اطلاعاتی که استفاده کننده در آن ها ذخیره می کند جهت اعلام یک عقیده در یک موضوع بخصوص استفاده می کند. از اینرو سیستم های خبره تا هنگامی که بتوانند موضوعی را که با پاسخ های شما مطابقت داشته باشد بیابند به سوال کردن از شما ادامه می دهند. به منظور درک کردن آنچه که یک سیستم متخصص انجام می دهد مکالمه زیر که بین یک متخصص در امور میوه و فرد دیگری که می خواهد از وی توصیه ای در این مورد دریافت کند را در نظر بگیرید:
- متخصص: آیا میوه سبز است؟
- استفاده کننده: خیر.
- متخصص: آیا میوه قرمز است؟
- استفاده کننده: بله.
- متخصص: آیا این میوه روی درخت رشد می کند؟
- استفاده کننده: خیر.
- متخصص: آیا این میوه روی یک بوته رشد می کند؟
- استفاده کننده: بله.
- متخصص: آیا این بوته تیغ دارد؟
- استفاده کننده: بله.
- متخصص: این میوه تمشک است!
هدف از طراحی یک سیستم متخصص کامپیوتری در امر میوه تولید این مکالمه است.
در حالت عمومی تر سیستم متخصص سعی می کند که به استفاده کننده از خود در مورد موضوعی که از آن مطلع است راهنمایی دهد.
مزایای یک سیستم خبره چیست؟
میزان مطلوب بودن یک سیستم خبره اصولا به میزان قابلیت دسترسی به آن و میزان سهولت کار با آن بستگی دارد.
می توان مزایایی که یک سیستم خبره در برابر انسان خبره دارد را به این صورت نام برد:
- برخلاف انسان متخصص که نیاز به خواب، استراحت و غذا و … دارد، یک سیستم متخصص ۲۴ ساعت در شبانه روز و ۳۶۵ روز در سال قابل دسترس است.
- دانش سیستم خبره از بین نمی رود بلکه می توان آنرا ذخیره نمود و حتی بسادگی می توان آنرا کپی برداری کرد.
- یک سیستم متخصص همواره دارای حداکثر کارآیی خود است ولی به محض آنکه یک انسان متخصص خسته شود صحت توصیه های وی ممکن است کاهش یابد.
- یک سیستم متخصص دارای شخصیت نیست. همانطور که شما هم درک کرده اید شخصیت های افراد مختلف اغلب با یکدیگر سازگار نیستند. اگر شما با یک متخصص رفیق یا دوست یا حداقل موافق نباشید، آنگاه احتمالا شانس اندکی برای استفاده از دانش این فرد خواهید داشت. عکس این حالت نیز صحیح است.
- آخرین برتری سیستم های خبره این است که به سادگی و با کپی برداری این برنامه از دستگاهی به دستگاه دیگر و در کمترین زمان ممکن می توان یک سیستم متخصص دیگر بوجود آورد در حالی که تبدیل یک انسان به یک متخصص زمانی طولانی نیاز دارد.
مثال هایی از سیستم های متخصص تجاری:
MYCIN اولین سیستم متخصص موفق جهان بود که در سال ۱۹۷۰ در دانشگاه استنفورد طراحی شد. هدف از ساخت این سیستم کمک به پزشکان در تشخیص بیماری های ناشی از باکتری بود. مشکل عمده در تشخیص بیماری برای یک پزشک آن است که تشخیص سریع و قاطع یک بیماری با توجه به تعداد بسیار زیاد بیماری موجود، عملی دشوار است.MYCIN با تشخیص دادن قاطع بیماری ها توانست که این نیاز را برآورده سازد.
PROSPECTOR یک متخصص در امر زمین شناسی است که احتمال وجود رسوبات معدنی در یک ناحیه بخصوص را پیش بینی می کند. این سیستم در سال ۱۹۸۷ توسط « ریچارد دودا» و « پیتر هارد» و « رنه ربو» ساخته شد.
در اوایل دهه ۸۰ سیستم های متخصص به بازار عرضه شد که می توانستند مشورت های مالیاتی، توصیه های بیمه ای و یا قانونی را به استفاده کنندگان خود ارائه دهند.
سیستم های متخصص چگونه کار می کنند؟
هر سیستم متخصص از دو بخش تشکیل می شود:
- بانک اطلاعاتی
- تولید کننده مکالمه
بانک اطلاعاتی :
منظور از بانک اطلاعاتی در اینجا مکانیسم نگهداری اطلاعات و قوانین ویژه ای در مورد یک موضوع بخصوص می باشد. با این توصیف دو اصطلاح زیر تعریف می شود:
- شیء(Object): منظور از شیء در اینجا نتیجه ای است که با توجه به قوانین مربوط به آن تعریف می گردد.
- شاخص(Attribute): منظور از شاخص یا «صفت» یک کیفیت ویژه است که با توجه به قوانینی که برای آن در نظر گرفته شده است به شما در تعریف شیء یاری می دهد.
بنابراین می توان بانک اطلاعاتی را بصورت لیستی از اشیاء که در آن قوانین و شاخص های مربوط به هر شیء نیز ذکر شده است در نظر گرفته شود.
در ساده ترین حالت( که در اکثر کاربرد ها نیز همین حالت بکار می رود) قانونی که به یک شاخص اعمال می شود این مطلب را بیان می کند که آیا شیء مورد نظر شاخص دارد یا ندارد؟
یک سیستم متخصص که انواع مختلف میوه را شناسایی می کند احتمالا دارای بانک اطلاعاتی به صورت زیر خواهد بود:
شیء
قانون
شاخص
سیب
دارد
روی درخت رشد می کند.

دارد
گرد است

دارد
رنگ قرمز یا زرد است

ندارد
در کویر رشد می کند
انگور
—–
——————-

بانک ساده شده بالا با تنها استفاده از قانون دارد:
شیء شاخص هایی که دارد
سیب رشد روی درخت
گرد بودن
رنگ قرمز یا زرد
رشد نکردن در کویر
تولید کننده مکالمه:
آن بخش از سیستم متخصص است که سعی می کند از اطلاعاتی که شما ذخیره کرده اید جهت یافتن یک شیء منطبق با خواسته شما استفاده نماید. دو نوع عمده از تولید کننده های مکالمه وجود دارد :
- قطعی
- احتمالی
برخی قوانین قطعی هستند. به عنوان مثال یک شیمیدان می تواند با قطعیت و یقین اعلام کند که اگر اتم مورد نظر دارای ۲ الکترون باشد آنگاه این اتم به عنصر هلیم تعلق دارد. اکثر قوانین قطعی نیستند بلکه با یک درصد مشخص، احتمال وقوع آن ها می رود. با این وجود در بسیاری از اینگونه موارد عامل عدم قطعیت از نظر آماری اهمیت چندانی ندارد و از این رو شما می توانید با این قوانین بصورت قوانین جبری برخورد کنید.
در رابطه با این دو گروه عمده( یعنی قطعی و عدم قطعی) سه روش اساسی برای ساخت «تولید کننده مکالمه» وجود دارد:
- استدلال پیشرو Forward Chaining
- زنجیره سازی پسرو Backward Chaining
- ارزشیابی Rule-Value
تفاوت بین این سه روش به شیوه ای که «تولید کننده مکالمه» توسط آن سعی می کند به هدف خود برسد بستگی دارد.
 

آبجی

عضو جدید
کاربر ممتاز
هوش‌ مصنوعي‌ چيست‌؟

تلاش‌ در راه‌ برخوردار نمودن‌ رايانه‌ از توانائيهاي‌ شناخت‌ وتقليد جنبه‌هاي‌ هوشي‌ انسان‌ از دهه‌ 1950 ميلادي‌ آغاز شده‌ است‌.در سال‌ 1956 ميلادي‌، گروهي‌ از دانشمندان‌ از جمله‌ ماروين‌مينسكي‌(2) (از دانشگاه‌ فني‌ ماساچوست‌)، كلود شانن(3) (ازآزمايشگاه‌ نامدار بل‌) و جان‌ مك‌كارتي‌(4) (از دانشگاه‌ دارت‌موت‌(همايش‌ در دارت‌ موت‌ (5)كانادا برگزار نمودند تا در اين‌زمينه‌ به‌ گفتگو بپردازند. جان‌ مك‌ كارتي‌ دانشيار كرسي‌ رياضي‌دانشگاه‌ و ميزبان‌ همايش‌، عنوان‌ پهوش‌ مصنوعي‌) را بر اين‌ نشست‌نهاد.از آن‌ زمان‌ تاكنون‌ ميان‌ دانشمندان‌ و خبرگان‌ آگاه‌ همچنان‌بحث‌ در مفهوم‌ هوش‌ مصنوعي‌ جريان‌ دارد.

هوش‌ مصنوعي‌ را كوششهايي‌ تعريف‌ مي‌كنند كه‌ در پي‌ ساختن‌نظامهاي‌ رايانه‌اي‌ )سخت‌افزار و نرم‌افزار) است‌ كه‌ رفتاري‌ انسان‌ وارداشته‌ باشند. چنين‌ نظامهايي‌ توان‌ يادگيري‌ زبانهاي‌ طبيعي‌، انجام‌وظيفه‌هاي‌ انساني‌ به‌ صورت‌ آدمواره‌ (ربات‌) و رقابت‌ با خبرگي‌ و توان‌تصميم‌گيري‌ انسان‌ را دارند.

يك‌ سيستم‌ هوش‌ مصنوعي‌ به‌ راستي‌ (نه‌ مصنوعي‌ (و )نه‌هوشمند (است‌. بلكه‌ دستگاهي‌ است‌ هدف‌گرا كه‌ مشكل‌ را به‌ روش‌ مصنوعي‌ حل‌مي‌كند اين‌ سيستم‌ها بر پايه‌ دانش‌، تجربه‌ و الگوهاي‌ استدلايي‌ انسان‌بوجود آمده‌اند.

سيستم‌هاي‌ هوش‌ مصنوعي‌ مانند كتاب‌ با ديگر آثار فكري‌ انسان‌مي‌باشند، تا زماني‌ كه‌ نوشته‌ نشوند معلوماتي‌ در خود ندارند. پس‌ از آماده‌شدن‌ نيز نمي‌توانند چيزي‌ تازه‌ بسازند و يا راه‌حل‌ نويني‌ ابداع‌ كنند.سيستم‌هاي‌ هوشمند، تنها و توانايي‌هاي‌ كارشناسان‌ را بالا مي‌برند وهرگز نمي‌توانند جانشين‌ آنها شوند. اين‌ سيستم‌ها فاقد عقل‌ سليم‌ هستند.
 

آبجی

عضو جدید
کاربر ممتاز
II- برنامه نويسي تابعي
يك تابع رياضي نگاشتي از يك مجموعه (دامنه) به مجموعه ديگر(برد) است. تعريف يك تابع توصيف اين نگاشت است كه يا بطور صريح بوسيله شمارش و يا بطور ضمني بوسيله يك عبارت است. تعريف يك تابع بوسيله نام تابع كه بدنبال آن ليستي از پارامترها در داخل پرانتز قرار دارند و به دنبال آن نيز عبارت توصيفي نگاشت است مشخص مي شود مانند:
X يك عدد حقيقي است cube(X) ≡ X X X , where X is a real number.
آلونسو چارچ توابع بي نام را با استفاده از نمادLambda معرفي مي كند. يك عبارت Lambda پارامترها و نگاشت تابع را با استفاده از عملگر X مشخص مي كند, مانند λ (X)X X X آن خودش تابع است, بنابراين شرح بكار رفته در مثال تابع بي نام با يك آرگومان مشخص است. براي مثال
λ (X) X X X)(4).
برنامه نويسي در يك زبان تابعي شامل ساختمان تعريف توابع و بكاربردن كامپيوتر براي ارزيابي عبارات است. يعني بكاربردن توابع با آرگومانهاي واقعي. كار اصلي برنامه نويسي پس از ساخت يك تابع براي يك مساله خاص تركيب توابع تعريف شده قبلي با توجه به اصول رياضي است. كار اصلي كامپيوتر ارزيابي توابع فراخواني شده و چاپ حاصل مقادير تابع است. در اين روش كامپيوتر مشابه يك كامپيوتر جيبي معمولي بكار مي رود البته بسيار انعطاف پذيرتر و قدرتمندتر. يك خاصيت برنامه نويسي تابعي اين است كه اگر عبارت به خوبي مقداردهي شود آنگاه ترتيب انجام ارزيابي كامپيوتر در نتايج ارزيابي تاثيري ندارد. بنابراين نتيجه ارزيابي يك عبارت تنها مقدار آن است. بدين معني است كه در يك زبان تابعي ناب اثرات جانبي وجود ندارد. اثرات جانبي در مدل موقعيت هاي حافظه به متغيرها متصل شده اند.بنابراين در يك زبان برنامه نويسي ناب در مفهوم زبانهاي دستوري متغير وجود ندارد. روشهاي اصلي كنترل جريان، بازگشت (تكرار) و عبارات شرطي هستند. اين كاملاً با زبانهاي دستوري در مفهوم اساسي كنترل ترتيب و تكرار متفاوت است. برنامه نويسي تابعي نيز خصوصيات توابع مرتبه بالا را پشتيباني مي كند. تابع مرتبه بالا تعريف تابعي است كه اجازه مي دهد آرگومانها يا مقدار بازگشتي تابع, مقدار توابع باشند. همه اين جوانب با هم مخصوصاً آخري از اصلي ترين مزاياي سبك برنامه نويسي تابعي در برابر سبك برنامه نويسي دستوري هستند. خلاصه برنامه نويسي تابعي سطح بالايي از درجه پيمانه اي بودن را فراهم مي كند. وقتي يك مسئله با تقسيم آن به مجموعه اي از زير مسئله ها تعريف مي شود, موضوع اصلي روشهايي است كه مي توان زير مسئله ها را به يكديگر چسباند. بنابراين براي افزايش قابليت پيمانه اي بودن يك مسئله مفهومي, ابتدا بايد نوع جديدي از چسب در زبان برنامه نويسي فراهم شود- قدرت اصلي برنامه نويسي تابعي .

III- برنامه نويسي تابعي در Lisp
Lisp اولين زبان برنامه نويسي تابعي است: آن براي پشتيباني محاسبات نمادين با استفاده از ليستهاي پيوندي بعنوان ساختار مركزي داده ها ابداع شده بود ( Lisp يعني پردازشگر ليست). جان مك كارتي دريافت كه روشهاي كنترل جريان توابع رياضي (بازگشت و تكرار) وسيله نظري مناسبي براي انجام محاسبات نمادين هستند. علاوه براين مفاهيم خلاصه سازي تابعي و كاربرد تابعي تعريف شده در محاسبات Lambda , سطح بالايي از خلاصه سازي موردنياز براي مسئله هاي AI مشخص شده را فراهم مي كنند.
Lisp در سال 1958 توسط مك كارتي ابداع شد و اولين نگارش محيط برنامه نويسي Lisp در سال 1960 آماده شد كه شامل يك مفسر, يك كامپايلر و مكانيسم تخصيص و بازپسگيري حافظه پويا بود (بعنوان مجموعه فضاي هرز شناخته شده است). يكسال بعد اولين زبان استاندارد با نام Lisp1.5 معرفي شد. پس از آن تعدادي از نسخه ها و محيط هاي برنامه نويسي Lisp توسعه يافته اند. مانند MacLisp، FranzLisp، InterLisp، CommonLisp، Scheme هر چند آنها در بعضي جزئيات خاص متفاوتند ولي هسته Syntax (نحو) و Semantic (معني) آنها اساساً يكسان است. هسته را در جاي ديگر معرفي خواهيم كرد. پر استفاده ترين نسخه‌هاي
Lisp ، Common Lisp و scheme هستند. در اين مقاله ما Common Lisp را براي نشان دادن جنبه هاي مختلف Lisp با مثالهاي معمولي انتخاب كرده ايم. هرچند مثالها نيز به راحتي مي توانند در نسخه هاي ديگر Lisp سازگار شوند.
 

آبجی

عضو جدید
کاربر ممتاز
Syntax .A. (نحو) و semantics (معاني) Lisp
1. عبارات نمادين: عناصر نحوي Lisp عبارات نمادين ناميده مي شوند (كه به صورتS-expressionsشناخته شده‌اند). داده ها و توابع (يعني برنامه هاي Lisp ) بصورت عبارات نمادين نشان داده شده اند كه مي توانند اتم ها يا ليست ها باشند. اتم ها كلمه اي شبيه اشيا‌ هستند. اتم‌ها وابسته به نوع كاراكترهايي كه براي شكل دادن يك اتم مجازند مي توانند به انواع مختلفي تقسيم شوند. انواع اصلي عبارتنداز:
Numbers:1 234-43.14159265358979 -7.5 6.02E+23

Symbols:SymbolSym23another-one t false NILBLUE

Strings: ”This is a string””977?” ”setq””He said: \” I’m here.\” ”
توضيح اينكه هرچند نماد خاصي مثل BLUE استفاده مي‌شود چون مفهوم مشخص براي برنامه‌نويسي دارد، اما بزودي Lisp تنها ترتيبي از حروف يا تنها يك نماد است. ليستها بندي شبيه اشياء هستند. يك ليست شامل يك پرانتز باز( دنباله‌اي از اعداد دلخواه كه بوسيله فاصله خالي از هم جدا مي‌شوند) و يك پرانتز بسته هستند. هر عنصر ليست مي‌تواند يك اتم يا ليست باشد. اينها مثالهايي از ليستها هستند:
(This is a list) ((this) ((too))) () (((((((())))))))

(a b c d) (john mary tom) (loves john ?X)

(* (+ 3 4) 8) (append (a b c) (1 2 3))

(defun member (elem list)

(if (eq elem (first list)) T

(member elem (rest list))))
توضيح اينكه در بسياري از مثالها عناصر ليست خود ليستها هستند.چنين ليستهايي، ليستهاي تو در تو ناميده مي‌شوند. در مورد تو در تويي محدوديتي وجود ندارد. براي مثال يكي از قويترين Lisp ها را شرح مي‌دهيم: پيچيده‌ترين اشياء را به راحتي مي‌توان نوشت. تنها چيزي كه در نظر گرفته مي‌شود درستي عدد داخل پرانتزهاست. مهم توضيح اين است كه معني وابسته به يك ليست نمايش ويژه يا اتم در ليست نمايش وارد نمي‌شود. به اين معني كه همه عبارات نمادين كه در بالا توصيف شده است از لحاظ نحو برنامه‌هاي Lisp را اصلاح مي‌كنند ولي الزاماً از لحاظ معني (semantic) برنامه‌ها رااصلاح نمي‌كنند.
2. Semantics (معاني): هسته هر سيستم برنامه‌نويسي Lisp مفسر است كه كارش محاسبه مقدار براي يك عبارات نمادين داده شده است. اين فرآيند ارزيابي نام دارد. نتيجه يا مقدار يك عبارت نمادين، يك عبارت نمادين است. كه بعد از كامل شدن ارزيابي برگردانده شده است. توضيح اينكه در واقع Lispداراي Semantics (معاني) عملياتي است كه با يك تعريف رياضي دقيق از نظريه تابع بازگشتي بدست مي‌آيد.
حلقه خواندن- محاسبه- چاپ چگونه مي‌تواند مفسر Lisp را فعال كرده و براي محاسبه عبارات نمادين و بنابراين اجراي واقعي برنامه‌هاي Lisp بكار برود؟
مسئله‌‌هاي Prolog بصورت حقايق، بديهيات و قوانين منطقي براي استنباط حقايق جديد بيان مي‌‌ شوند . Prolog با قانون رياضي در محاسبات گزاره‌ اي و ونتايج نظري بدست آمده در زمينه اثبات قضيه خودكار در اواخر دهه1960 بنا شده است. مفسر Lisp در واقع بعنوان يك تابع معمولاً بنام eval و جزئي از هر محيط برنامه‌‌‌نويسي Lisp است تعريف شده است (مانند تابعي كه پيش‌ساخته نام دارد). آن بوسيله فراخواني حلقه خواندن- محاسبه- چاپ در يك سيستم Lisp جاسازي مي‌شود، وقتي يك عبارت نمادين توسط كاربر داده مي‌‌ شود ابتدا به داخل سيستم Lisp خوانده مي‌شود( خواندن هم يك تابع پيش‌ساخته است). سپس مفسر Lisp كه via نام دارد تابع eval را فراخواني مي‌كند تا عبارت نمادين را محاسبه و نتيجه عبارت نمادين را با چاپ در دستگاه كاربر برگرداند ( شگفت‌آورنيست گفتن اينكه چاپ هم يك تابع پيش‌‌ساخته است). وقتي سيستم Lispدر كامپيوتر شروع به اجرا مي‌‌شود اين حلقه خواندن- محاسبه- چاپ بطور خودكار شروع به اجرا كرده و بوسيله علامت ويژه اعلان Lisp در ابتداي خط جديد به كاربر علامت مي‌دهد در اين مقاله ما علامت سئوا ل (?) را به عنوان اعلان Lisp بكار خواهيم برد. براي مثال:
( 4 3 +) ?
7
هر وقت سيستم Lisp اجرا شود حلقه خواندن- محاسبه- چاپ فعال خواهد بود.
عبارت نمادين ( 4 3 + ) كه بوسيله هكر Lisp وارد شده است بوسيله مفسر Lisp بصورت فراخواني تابع جمع تفسير شده و نتيجه عبارت نمادين در ابتداي خط جديد 7 چاپ مي‌‌شود ارزيابي مفسر Lisp مطابق سه قانون زير انجام مي‌‌شود:
1- يكساني: يك عدد،‌ يك رشته يا نمادهاي t و nil خودشان را ارزيابي مي‌كنند (بر مي‌گردانند) به اين معني كه ارزش عدد 3،3 و ارزش رشته ”house”، رشته ”house”است. نمادt مقدار t برمي‌گرداند كه به معناي true تفسير مي‌شود وnil ، nil به معني false برمي‌‌گرداند
2- نمادها: ارزيابي يك نماد عبارت نمادين مربوط به آن را برمي‌‌‌گرداند. ( چگونگي‌ اش را در زير نشان خواهيم داد) بنابراين اگر ما فرض كنيم نماد‌ *names* به ليست
(john mary tom) وابسته است آنگاه ارزيابي *names* آن ليست را نتيجه مي‌دهد. اگر نماد color را به نماد green وابسته كنيم آنگاه green بعنوان مقدار color برگردانده مي‌‌شود.
به بيان ديگر نمادها بعنوان متغيرهايي كه به مقاديري متصل(باند) شده‌اند تفسير مي‌‌شوند.
3- ليستها: هر ليست بعنوان يك فراخواني تابع تفسير مي‌‌شود. مفسر اول ليست دلالت بر تابعي دارد كه بايد براي بقيه عناصر( بالقوه خالي)‌ كه آرگومانهاي آن تابع را نشان مي‌دهند بكار رود. در واقع آرگومانهاي يك تابع قبلا بصورت نمادهاي پيشوندي مشخص مي‌‌شوند. اين مزيت را دارد كه توابع به سادگي مي‌توانند با تعداد دلخواهي آرگومان مشخص و استفاده شوند. ليست خالي ( ) داراي عبارت نمادين nil بعنوان مقدارش مي‌باشد. توضيح اينكه نماد nil در واقع داراي دو معني است: يك نمايش مقدار منطقي false و ديگري نمايش ليست خالي. هر چند ممكن است اين يك بيت فرد بنظر برسد، ولي در واقع در Lisp مشكلي در شناسايي مفهوم nil بكاررفته وجود ندارد.
‌ ولي بطور كل آرگومانها قبل از اينكه توابع مقادير آنها را استفاده كنند ارزيابي مي‌شوند. اولويت ارزيابي ترتيبي از آرگومانها از چپ به راست است. يك آرگو‌مان ممكن است يك اتم يا يك ليست باشد،‌درهر حالت بعنوان يك فراخواني تابع تفيسر شده و مفسر Lisp براي ارزيابي آن فراخواني مي‌شود. براي مثال، ارزيابي زير در سيستم Lisp يك تابع به حساب مي‌آيد:
?(max 4 (min 9 8) 7 5)

8
در اينجا آرگومانها 5, 7, (min 9 8), 4 هستند كه در اولويتي قبل از تابعي به نام max كه نتيجه مقادير آرگومانها را به كار مي‌برد ارزيابي مي‌شوند. آرگومان اول 4 ،‌ يك عدد است پس مقدار آن 4 است. آرگومان دوم (min 9 8) است كه خودش يك فراخواني تابع است. بنابراين بايد قبل از آرگومان سوم فراخواني شود، (min 9 8) بايد توسط مفسر Lisp ارزيابي شود. چون ما بايد مفسر Lispرا براي بعضي آرگومانها در طول ارزيابي همه فراخواني‌هاي توابع استفاده كنيم مي‌‌توان گفت مفسر Lisp بصورت بازگشتي فراخواني شده است. مفسر Lisp همان مراحل را به كار مي‌برد، پس آرگومان اول 9 قبل از آرگومان دوم 8، ارزيابي مي‌شود. با بكار برروي تابع min حاصل 8 مي‌شود يعني تابع كوچكترين عدد يك مجموعه از اعداد صحيح را محاسبه مي‌‌كند. براي تابع بيروني max هم به اين معني است كه آرگومان دوم آن 8 ارزيابي مي‌شود.
آرگومانهاي بعدي 7و5هستند كه نتيجه ارزيابي آنها مقادير 7و5 مي‌شود. حال تابع بزرگترين عدد كه max نام دارد مي‌تواند ارزيابي شود كه 8 برمي‌گرداند. اين مقدار نهايي،‌ مقدار فراخواني همه توابع مي‌‌باشد. از آنجايي كه گفته مي‌‌‌شود مفسر Lisp هميشه سعي مي‌كند مقدار يك نماد يا تفسير يك ليست بعنوان يك فراخواني تابع را تشخيص دهد ما چگونه مي‌توانيم با نمادها و ليستها بعنوان داده رفتار كنيم؟ براي مثال، اگر ما ليست (peter walks home) را وارد كنيم، آنگاه مفسر Lisp فوراً يك خطا مي‌دهد كه چيزي شبيه اين خطا مي‌گويد: تابع peter ناشناخته است (مفسرLisp بايد بقدري باهوش باشد كه بتواند ابتدا كنترل كند كه آيا تعريف تابعي براي نام تابع تعيين شده وجود دارد يا نه، قبل از اينكه هر آرماگوني را ارزيابي كند). يا اگر ما فقط house را وارد كنيم، آنگاه مفسر Lisp با خطايي شبيه اين خطا خاتمه مي‌يابد: مقداري به house متصل نيست (تخصيص نيافته است). حل اين مسئله كاملاً آسان است. زيرا عنصر اصلي هر ليست بعنوان نام تابع تفسير مي‌شود،‌هر سيستم Lisp با يك تابع پيش‌ساخته quote مي‌‌آيد كه يك عبارت نمادين را بعنوان آرگومان پذيرفته و اين عبارت نمادين را بدون ارزيابي آن برمي‌گرداند. براي مثال: ليست(quote(peter walks home)) ، به سادگي مقدار
(peter walks home) را برمي‌گرداند، و براي (quote house)، آن house را بر مي‌‌گرداند. از آنجايي كه تابع quote زياد استفاده مي‌‌‌شود، مي‌توان آن را با كاراكتر ويژه ' بيان كرد. بنابراين براي مثال بالا مي‌توانيم معادل’(Peter walks home) و’house را مشخص كنيم. برنامه‌ها بعنوان داده، يعني تابع quote به ما امكان مي‌‌‌دهد تا با فراخواني تابع بعنوان داده رفتار كنيم. براي مثال: (quote (max 4 (min 9 8) 7 5)) يا ’(max 4 (min 9 8) 7 5)
قبلاً گفتيم كه مفسر Lisp يك تابع يكتايي پيش‌ساخته است كه eval نام دارد. آن صريحاً آرگومانهايش را وادار مي‌كند تا مطابق قوانين مذكور در بالا ارزيابي شوند. در بعضي حالات، آن مي‌تواند مقابل تابع quote قرار بگيرد بنابراين به وضوح لازم است كه يك ليست بعنوان داده مشخص شود تا سيستم Lisp بتواند يك فراخواني تابع تفسير شود، ما مي‌توانيم(eval ’(max 4 (min 9 8) 7 5)) را مشخص كنيم كه مقدار 8 را بطوري كه در بالا توصيف شد بر مي‌گرداند. به همان صورت مشخص كردن (eval ’(peter walks home)) سبب يك خطاي Lisp مي‌شود زيرا Lisp سعي مي‌كند يك تابع peter فراخواني كند. مزيت اصلي رفتار برنامه‌ها بعنوان داده اين است كه ما مي‌توانيم برنامه‌هاي Lisp (توابع) را طوري تعريف كنيم كه قادر به ساخت يا توليد برنامه‌ها باشند بطوريكه ابتدا ليست نمايش متناظر را ساخته و سپس با استفاده از تابع eval ، مفسر Lisp را به منظور ارزيابي ليست ايجاد شده بعنوان يك تابع فراخواني مي‌كند. شگفت‌آور نيست كه به اقتضاي اين خصوصيات، Lisp هنوز زبان برنامه‌نويسي برتر در زمينه برنامه‌نويسي ژنتيك AI است.
 

آبجی

عضو جدید
کاربر ممتاز
وقتي مقادير را به نمادها تخصيص مي‌دهيم كه برنامه‌نويسي برنامه‌هاي كاربردي
real-life به ذخيره مقاديري محاسبه شده در يك متغير نياز داشته باشد تا اگر در آينده در برنامه‌ ديگري نياز باشند از هزينه محاسبه مجدد آن جلوگيري شود. در يك نگارش كاملاً تابعي Lisp ‌مقدار يك تابع تنها به تعريف تابع و مقدار آرگومانهايش در فراخواني بستگي دارد. براي اينكه Lisp را يك زبان كاربردي بكنيم (كاربردي حداقل در اين مفهوم كه بتواند بر روي كامپيوترهاي وان نيومن به خوبي اجرا شود)، ما نياز به روشي داريم تا مقادير را به نمادها تخصيص دهيم.common Lisp با يك تابع پيش‌ساخته بنام Setq مي‌آيد. Setq دو آرگومان مي‌خواهد: نماد (بنام متغير) كه يك مقدار به آن متصل شده است و يك عبارت نمادين كه بايد مقداري را فراهم كند. مفسر Lisp ارزيابي Setq را در روش خاصي انجام مي‌دهد بطوريكه آرگومان اول Setq را ارزيابي مي‌كند(متغير)،‌ اما مقدار آرگومان دوم Setq را به متغير متصل مي‌كند(براي فهم چگونگي اتصال يك مقدار به يك نماد نياز به جزئيات فني زيادي خواهيم داشت كه در اين معرفي كوتاه نمي‌توان به آن پرداخت). مقدار آرگومان دوم Setq مقدار Setq را بر مي‌گرداند. اينها مثالهايي هستند:
?color

error: unbound symbol color

?(setq color ’green)

green

?(setq max (max 3 2 5 1))
3
توضيح اينكه در واقع Setq حالت مفسر Lisp را تغيير مي‌دهد تا دفعه بعدي كه همان متغير استفاده مي‌شود، داراي مقدار بوده و بنابراين مفسرLisp قادر به بازگرداندن آن خواهد بود. اگر اين اتفاق نيفتد آنگاه مفسر Lisp يك اخطار خواهد داد زيرا نماد متصل نشده است.
(گام 2 مفسر Lisp پيدا نشد). بنابراين آن مي‌گويدكه Setq يك اثر جانبي توليد مي‌كند زيرا حالت مفسر Lisp بطور پويا تغيير مي‌دهد. وقتي استفاده از Setq اجباري شد، به هرحال متوجه شد كه در واقع از مسير semantics (معاني) Lisp ناب دور مي‌شود. پس Setq بايد با دقت بسيار استفاده شود.

B. نوع داده ليست
برنامه‌نويسي در Lisp در واقع به معني تعريف توابعي است كه روي ليست عمل مي‌كنند. مانند ايجاد، پيمايش،‌كپي، تغيير و حذف ليستها. از آنجايي كه اين در Lisp مركزي است، هر سيستم Lisp بر مبناي مجموعه‌اي از توابع پيش‌ساخته ابتدايي كه بطور موثري عمليات اصلي ليست را پشتيباني مي‌كند مي‌آيد. ما بطور خلاصه يكي از مهمترين آنها معرفي مي‌كنيم. ابتدا نوع گزاره‌اي،‌ ما مي‌دانيم كه يك عبارت نمادين جاري يا يك ليست است يا نيست (يعني يك اتم). اين كار بوسيله تابع Listp انجام مي‌شود كه هر عبارت نمادين expr را بعنوان آرگومان پذيرفته و اگر expr ليست باشد نماد t و در غير اين صورت nil برمي‌گرداند. مثالها هستند (ما از فلش راست => براي نشان دادن نتيجه فراخواني تابع استفاده خواهيم كرد):
(listp ’(1 2 3))==>t

(listp ’( ))==>t

(listp ’3)==>nil

در انتخاب عناصر ليست دو تابع اساسي براي دست‌يابي به عناصر يك ليست وجود دارد: car وcdr هر دو تابع يك ليست را بعنوان آرگومان مي‌پذيرند. تابع car اولين عنصر ليست يا اگر ليست خالي از آرگومان باشد nil بر مي‌گرداند،‌و cdr همان ليست را بطوري كه عنصر اول آن حذف شده است يا اگر ليست خالي از آرگومان بود nil برمي‌گرداند. مثالها:
(car ’(a b c)) ==>a (cdr ’(a b c)) ==>(b c)

(car ’( )) ==>nil(cdr ’(a)) ==>nil

(car ’((a b) c))==>(a b)

با استفاده از ترتيبي از فراخواني‌هاي توابع car و cdr مي‌توان يك ليست را از چپ به راست و از عناصر بيروني به سمت عناصر داخلي ليست پيمايش كرد.
براي مثال، در طول ارزيابي (car (cdr ’(see the quote))) مفسر Lisp ابتدا عبارت
(cdr ’(see the quote))را ارزيابي خواهد كرد كه ليست (the quote) را برمي‌گرداند، سپس به تابع car پاس مي‌شود كه نماد the را بر مي‌گرداند. اينها مثالهايي ديگر هستند:

(car (cdr (cdr ’(see the quote)))) ==>quote

(car (cdr (cdr (cdr ’(see the quote))))) ==>nil

(car (car ’(see the quote))) ==>?
در طول ارزيابي مثال اخير چه اتفاقي خواهد افتاد؟ ارزيابي (car ’(see the quote)) نماد see را بر‌مي‌گرداند.سپس اين به عنوان آرگومان به فراخواني بيروني car پاس مي‌شود. چون تابع car يك ليست را به عنوان آرگومان مي پذيرد پس مفسر Lisp بلافاصله ارزيابي ديگر را با خطايي مانند اين خطا متوقف خواهد كرد: سعي مي‌شود Car SEE بدست آيد ولي Listp نيست. يك توضيح كوتاه تاريخي: نامهاي Car,cdr از روشهاي قديمي هستند زيرا آنها در اولين نگارش Lisp كه بر مبناي مجموعه عمليات كد ماشين كامپيوتر انتخاب و پياده سازي شده بودند (car از محتواي ثبات آدرس استفاده مي‌كند و cdr از محتواي ثبات كاهش استفاده مي‌كند). به منظور نوشتن كد Lisp خواناتر، common Lisp يا در تابع first و rest بوجود آمد. ما نامهاي قديمي را استفاده مي‌كنيم تا براي خواندن و فهم كد AI Lisp قديمي قادر باشيم. براي ساخت ليستها، يك تابع ابتدايي Cons مانند Car و cdr وجود دارد كه براي ساخت يك ليست بكار مي‌رود. Cons دو عبارت نمادين را مي‌پذيرد كه اولي بعنوان يك عنصر جديد در جلوي دومي وارد مي‌شود. در مثالهاي زير ملاحظه مي‌كنيد:
(cons ’a ’(b c)) ==>(a b c)

(cons ’(a d) ’(b c))==>((a d) b c)

(cons (first ’(1 2 3)) (rest ’(1 2 3))) ==>(1 2 3)

در اصل، Cons و ليست خالي با هم براي ساخت ليستهاي خيلي پيچيده كافي هستند، براي مثال:
(cons ’a (cons ’b (cons ’c ’( )))) ==>(a b c)

(cons ’a (cons (cons ’b (cons ’c ’( ))) (cons ’d ’( )))) ==>(a (b c) d)
چون اين كار كاملاً طاقت‌فرساست،‌ سيستمهاي Lispبسياري با توابع ليست پيش‌ساخته بسيار پيشرفته بوجود مي‌آيند. براي مثال، تابع List با تعداد دلخواهي عبارت نمادين يك ليست مي‌سازد، و تابع append با الحاق آرگومانهايش كه بايد ليست باشند يك ليست جديد مي‌سازد. equal تابعي است كه اگر عناصر و ترتيب آنها در دو ليست يكسان باشد t ، در غير اين صورت nil بر ميگرداند. مثال:
(list ’a ’b ’c) ==>(a b c)

(list (list 1) 2 (list 1 2 3)) ==>((1) 2 (1 2 3))

(append ’(1) (list 2)) ==>(1 2)

(append ’(1 2) nil ’(3 4))==>(1 2 3 4)

(equal ’(a b c) ’(a b c)) ==>t

(equal ’(a b c) ’(a c b)) ==>nil
 

آبجی

عضو جدید
کاربر ممتاز
C. تعريف توابع جديد
برنامه‌نوسي در Lisp با تعريف توابع جديد انجام مي‌شود. در اصل اين به اين معني است كه: مشخص كردن ليستها در يك روش نحوي معين. مشابه تابع setq كه بوسيله مفسر Lisp در يك روش خاص رفتار مي‌كرد. تابع خاص defun است كه براي ايجاد اشياي تابع جديد توسط مفسر Lisp بكار مي‌رود. defunيك نماد دال برنام تابع، يك ليست از پارامترها(ممكن است خالي باشد) براي تابع جديد و تعداد دلخواهي از عبارات نماديني كه بدنه تابع جديدرا تعريف مي‌كند را به عنوان آرگومانهايش مي‌پذيرد. اين تعويض از يك تابع ساده به نام my-sum است كه دو آرگومان مي‌پذيرد و با استفاده از تابع پيش‌ساخته آنها را جمع مي‌كند.
(defun my-sum (x y)

(+ x y))
اين عبارت به همان روشي كه بعنوان يك تابع فراخواني مي‌شود در سيستم Lisp وارد مي‌شود. ارزيابي يك تعريف تابع نام تابع را بعنوان مقدار برمي‌گرداند، اما يك شئ تابع را بعنوان اثر جانبي ايجاد خواهد كرد و وقتي Lisp شروع به اجرا مي‌‌كند آن را به مجموعه تعاريف توابع شناخته شده توسط سيستم Lisp اضافه مي‌كند (حداقل مجموعه توابع پيش‌ساخته)
توضيح اينكه در اين مثال بدنه شامل تنها يك عبارت نمادين است. هر چند بدنه مي‌تواند شامل ترتيب دلخواهي از عبارات نمادين باشد مقدار آخرين عبارت نمادين از بدنه مقدار تابع را تعيين مي‌كند. به اين معني است كه در واقع همه عناصر بدنه بي تاثير هستند مگر اينكه اثرات جانبي تصميم‌گيري توليد كنند.
لسيت پارامتر تابع جديدmy-sum به ما مي‌گويد وقتي فراخواني مي‌شود درست دو عبارت نمادين را بعنوان آرگومان مي‌پذيرد. بنابراين اگر شما(my-sum 3 5) را در سيستمLisp وارد كنيد مفسرLisp قادر خواهد بود كه تعريف براي نام تابع مشخص شده بيابد و سپس آرگومانهاي داده شده را از چپ به راست پردازش كند وقتي اين كار انجام شد آن مقدار هر آرگومان را مطابق پارامتر مشخص شده در ليست پارامتر تعريف تابع وصل خواهد كرد(تخصيص خواهد داد) در مثال ما بدين معني است كه مقدار آرگومان اول كه3 است(3 همان عدد3 است كه خودش را ارزيابي كرده است) به پارامترx متصل مي‌كند. سپس مقدار آرگومان دوم كه 5 است به پارامترy متصل مي‌شود. چون مقدار يك آرگومان به يك پارامتر متصل مي‌شود، اين روش فراخواني با مقدار ناميده شده است. بعد از مقدار‌يابي براي همه پارامترها مفسرLisp قادر به ارزيابي بدنه تابع خواهد بود. مثال بدين معني است كه ( 3 5 +) فراخواني خواهد شد. نتيجه فراخواني8 است كه بعنوان نتيجه فراخواني(my-sum 3 5) برگردانده مي‌شود. بعد از تكميل فرا‌خواني تابع اتصالات موقت پارامترهايx وy حذف مي‌شوند. هنگامي كه يك تعريف تابع جديد در سيستمLisp وارد مي‌شودمي‌تواند به عنوان جزئي از تعريف تابع جديد به همان روش كه بعنوان تابع پيش ساخته استفاده شده است بكار برده شود بطوريكه در مثال زير نشان داده شده است.
(defun double-sum (x y)

(+ (my-sum x y) (my-sum x y)))
كه با دوبار فراخوانيmy-sum جمع آرگومانهايش را دو برابر خواهد كرد اين مثال ديگري از يك تعريف تابع است نشان دادن استفاده از عبارات نمادين چند‌گانه در بدنه تابع است.
(defun hello-world () (print ”Hello World!”) ’done)

اين تعريف تابع پارامتري ندارد زيرا ليست پارامتر آن خالي است بنابراين وقتي(hello-world) فراخواني مي‌شود مفسرLisp بلافاصله (print ”Hello World!”) را ارزيابي و رشته
”Hello World!”را روي نمايشگر شما بعنوان يك اثر جانبي چاپ مي‌كند سپس نماد’done را ارزيابي خواهد كرد وdone را به عنوان نتيجه فراخواني تابع برمي‌گرداند.

D. تعريف ساختارهاي كنترلي
هر چنداكنون تعريف توابع جديد با تعريف توابع پيش ساخته و توابعي كه كاربر تعريف مي‌كند ممكن است برنامه‌نويسي درLisp بسيار خسته كننده خواهد شداگر كنترل جريان اطلاعات بوسيله شاخه‌هاي شرطي ممكن نبود شايد بارها تكرار مي‌شد تا اينكه يك روند توقف اجرا شود گزينشLisp بر مبناي ارزيابي توابع است توابع كنترل تستهايي روي عبارات نمادين واقعي انجام مي‌دهد و ارزيابي عبارات نمادين متناوب را بسته به نتايج انتخاب مي‌كنند تابع اساسي براي تعيين اثباتهاي شرطي درcond،Lisp است.cond تعداد دلخواهي آرگومان رامي‌پذيرد هر آرگومان يك بخش ممكن را بيان مي‌كنند و بعنوان يك ليست نمايش داده شده كه عنصر اول يك تست و بقيه عناصر اعمال (عبارات نمادين) هستند كه اگر تست انجام شود ارزيابي مي‌شوند مقدار آخرين عمل به عنوان مقدار پيشنهادي برگردانده مي‌شود همه آرگومانهاي ممكنcond (يعني بخشها) تا زماني كه بخش اول بطور مثبت تست شوداز چپ به راست ارزيابي مي‌شوند درآن حالت مقدار آن بخش مقدار كل تابعcond است. در واقع اين مفهوم بسيار پيچيده تر از آن است اجازه دهيد تابعverbalize-prop زيركه يك مقدار احتمال را بيان مي‌كند. به عنوان يك عدد حقيقي فرض مي‌كنيم.
(defun verbalize–prop (prob-value)

(cond ((> prob–value 0.75) ’very-probable)

((> prob–value 0.5) ’probable)

((> prob–value 0.25) ’improbable)

(T ’very-improbable)))
وقتي(verbalize-prop 0.33) فراخواني مي‌شود مقدار واقعي آرگومانها به پارامترprop-value متصل مي‌شود.سپسcond با آن اتصالات ارزيابي مي‌شود very-probable)’((>prop-value)است.> يك گزاره پيش ساخته است كه تست مي‌كند كه آيا آرگومان اول از دومي بزرگتر است،چونpropvalue،0.33 است. بهnil ارزيابي مي‌شود كه به معني انجام نشدن تست است. بنابراين ارزيابي اين بخش پيشنهادي بلافاصله پايان مي‌يابد. و سپس پيشنهاد
((> prob–value 0.5) ’probable)ارزيابي مي‌شود كه تابع تست باز هم nilبرمي‌گرداندبنابراين ارزيابي هم پايان مي‌يابد. سپس ((prop-value 0.25) ’improbable) ارزيابي مي‌شود حال با بكار بردن تابع تستT برگردانده مي‌شود كه به معني انجام تست است.آنگاه همه اعمال اين بخش كه بطور مثبت تست شده است. ارزيابي ومقدار آخرين عمل به عنوان مقدارcond برگردانده مي‌شود در مثال ما تنها عملimprobable’ تعيين مي‌شود كه مقدارimprobable (غيرمحتمل) را برمي‌گرداند از آنجايي كه اين مقدارcond را تعيين مي‌كند و عبارت cond تنها عبارت بدنه تابعverbalize-prop است. نتيجه فراخواني improbable ,((verbalize-prop 0.33) است. توضيح اينكهاگرما (verbalize- prop 0.1)را وارد كنيم مقدارvery- improbable را بر‌مي‌گرداند زيرا تست هر سه با شكست مواجه شده و بايد بخش (T ’very-improbable)ارزيابي شوددر اين حالت نمادT به عنوان تستي كه هميشهT بر‌مي‌گرداند استفاده شده است بنابراين مقدار اين پيشنهاد
very- improbable است.
 

آبجی

عضو جدید
کاربر ممتاز
E. تعريف توابع بازگشتي
دومين روش اصلي براي تعريف كنترل جريان درLisp تعاريف توابع بازگشتي هستند. تابعي كه از تعريفش بعنوان جزئي از تعريفش استفاده مي‌كند باز‌گشتي نام دارد. بنابراين، يك تعريف بازگشتي، تا جايي كه امكان دارد مسئله‌اي را به قسمتهاي كوچكتر تقسيم مي‌كند سپس اين قسمتهاي كوچكتر را با استفاده از توابع مشهور و جمع پاسخهاي يكسان حل كرده و حل برنامه را كامل مي‌كند. بازگشت يك روش طبيعي براي كنترل ساختارهاي داده‌اي است كه اندازه معيني ندارد. مانند ليستها، درختها و گرافها. بنابراين براي مسئله‌هايي كه در يك فاصله از حالات دنبال حل كانديد مي‌گردند مناسب است.
Lisp اولين زبان برنامه‌نويسي كاربردي بود كه با روش معين تعريف تعاريف بازگشتي را پشتيباني كرده است. ما از دو مثال كوچك براي نشان دادن بازگشت درLisp استفاده خواهيم كرد. اولين مثال براي تعيين طول يك ليست طويل دلخواه استفاده مي‌شود. طول يك ليست برابر تعداد عناصر آن است. تابع بازگشتي آن به صورت زير است.
(defun length (list)

(cond ((null list) 0)

(T (+ 1 (length (cdr list))))))
وقتي يك تعريف بازگشتي تعريف مي‌شود. ما بايد حالتهاي اساسي راشناسايي كنيم يعني آن قسمتهايي كه نمي‌توانند بيشتر تجزيه شوند. مسئله اندازه وابسته به ليست است. كوچكترين مسئله اندازه در ليست، ليست خالي است. بنابراين اولين چيزي كه ما بايد مشخص كنيم تستي براي شناسايي ليست خالي است و تعيين اينكه طول ليست خالي بايد چقدر باشد تابع پيش‌ساخته null تست مي‌كند كه آيا اين ليست خالي است در اين صورت t برمي‌گرداند. از آنجايي كه ليست خالي بدون عنصر است تعريف مي‌كنيم كه طول ليست خالي صفر باشد كار ديگري كه بايد انجام شود تجزيه مسئله اندازه به قسمتهاي كوچكتر است كه همان مسئله مي‌تواند براي فسمتهاي كوچكتر استفاده شود. تجزيه ليست مي‌تواند با استفاده از توابع cdr,car انجام شود. به اين معني كه ما بايد تعيين كنيم تا وقتي كه ليست خالي پيدا شود عنصر اول و بقيه عناصر ليست چه كار بكنند. از آنجايي كه ما ازقبل ليست خالي را بعنوان حالت اساسي شناسايي كرديم، مي‌توانيم فرض كنيم تجزيه برروي ليستي شامل حداقل يك عنصر انجام خواهد شد. بنابراين هر بار كه قادر خواهيم بود تا با بكار بردن cdr بقيه عناصر ليست را بدست آوريم، ما يك عنصر اضافي پيدا كرديم كه بايد براي افزايش تعداد عناصر ليست قبلا شناسايي شده بوسيله يك استفاده مي‌شود. استفاده از اين تعريف تابع(length ’( )) بلافاصله صفر بر‌خواهد گرداند و اگر
(length ’(a b c)) را فراخواني كنيم، نتيجه 3 خواهد بود زيرا براي اينكه ليست خالي شود بايد سه فراخواني بازگشتي member انجام دهيم بعنوان مثال دوم، تعريف بازگشتي را در نظر مي‌گيريم كه تست مي‌كند كه آيا عنصر داده شده در ليست داده شده قرار دارد اگر عنصر براستي در ليست پيدا شود زير ليستي كه با عنصر پيدا شده شروع مي‌شود را برمي‌گرداند اگر عنصر پيدا نشوددnil برگردانده مي‌شود مثال فراخواني‌ها هستند.
(member ’b ’(a f b d e b c)) ==> (b d e b c)

(member ’k ’(a f b d e b c)) ==> nil
مشابه تعريف بازگشتي ما ليست خالي را به عنوان حالت اساسي استفاده مي‌كنيم برايmember ليست خالي به اين معني است كه عنصر مورد سوال در ليست پيدا نشود. بنابراين ما بايد يك ليست را تا زماني كه عنصر مورد سوال پيدا مي‌شود يا ليست خالي است تجزيه مي‌كنيم تجزيه با استفاده ازcar وcdr انجام مي‌شود.car براي استخراج عنصر اول ليست به كار مي‌رود كه مي‌تواند براي كنترل اينكه با عنصر مورد سوال برابر است استفاده شود در اين حالت مي‌توانيم پردازشهاي اضافي را مستقيماً متوقف كنيم اگر برابر نبود آنگاه بايد تابعmember را براي بقيه عناصر تا خالي شدن ليست بكار ببريم بنابراين مي‌تواند به صورت زير تعريف شود.
(defun member (elem list)

(cond ((null list) nil)

((equal elem (car list)) list)

(T (member elem (cdr list)))))
 

آبجی

عضو جدید
کاربر ممتاز
F. توابع مرتبه بالا
درLisp توابع مي‌توانند بعنوان آرگومان استفاده شود تابعي كه بتواند توابع را بعنوان آرگومانهايش بپذيرد تابع مرتبه بالا ناميده مي‌شود. مشكلات فراواني وجود دارند كه يكي پيمايش يك ليست(يا يك درخت يا يك گراف) است كه بايد براي هر ليست عنصر تابع معيني استفاده شود. براي مثالfilter تابعي است كه تستي براي عناصر ليست به‌كار مي‌برد و آنهايي كه شكست مي‌خورند را حذف مي‌كند. نگاشتها توابعي هستند كه همان تابع را روي هر عنصر ليست به كار مي‌برند تا ليستي از نتايج را برگردانند. تعاربف توابع مرتبه بالا مي‌تواند براي تعريف توابع عمومي پيمايش ليست استفاده شود كه آنها از توابع خاصي كه براي پردازش عناصر ليست بكار مي‌روند خلاصه مي‌شوند (چكيده مي‌شوند). به منظور پشتيباني تعاريف مرتبه بالا يك تابع خاص است كه يك تابع و دنباله‌اي از آرگومانها را به عنوان آرگومان مي‌پذيرد و آن تابع را در آرگومانهاي آنها به كار مي‌برد. بعنوان مثال با استفاده ازfuncall، تابع عموميfilter را تعريف خواهيم كرد كه مي‌تواند به اين صورت فراخواني شود:
(filter ’(1 3 -9 -5 6 -3) #’plusp) ==>(1 3 6)
plusp يك تابع پيش ساخته است كه كنترل مي‌كند آيا يك عدد داده شده مثبت است يا نه؟ اگر باشد آن عدد را بر‌مي‌گرداند در غير اين صورتnil بر‌مي‌گرداند نماد خاص# بكار مي‌رود تا به مفسرLisp بگويد كه مقدار آرگومان يك شي تابعي است . تعريف به صورت زير است:
(defun filter (list test)

(cond ((null list) list)

((funcall test (car list))

(cons (car list) (filter (cdr list) test)))

(T (filter (cdr list) test))))
اگر ليست خالي باشد آنگاه بسادگي برمي‌گردد در غير اين صورت تابع تست روي عنصر اول ليست بكار مي‌رود. اگر تابع تست موفق شودcons بكار مي‌رود تا ليست حاصل را با استفاده از اين عنصر و همه عناصري كه در طول فراخواني بازگشتيfilter ازcdr و تابع تست استفاده مي‌كنند بسازد. اگر تابع تست براي عنصر اول با شكست مواجه شود اين عنصر بسادگي با بكاربردنfilter بصورت بازگشتي روي عناصر باقيمانده پرش مي‌كند. يعني اين عنصر نمي‌تواند جزئي از ليست حاصل باشد تابع مي‌تواند براي بسياري از توابع مختلف تست استفاده شود مانند:

(filter ’(1 3 A B 6 C 4) #’numberp) ==> (1 3 6 4)

(filter ’(1 2 3 4 5 6) #’even) ==> (2 4 6)

به عنوان مثال ديگري از تعريفfilter تابع مرتبه بالا، مامي‌خواهيم يك تابع نگاشت ساده تعريف كنيم كه يك تابع روي همه عناصر يك ليست بكاررفته، ليستي از همه مقادير بر‌مي‌گرداند. اگر تابع my-map را فراخواني كنيم آنگاه تعريفي شبيه اين داريم:
(defun my-map (fn list)

(cond ((null list) list)

(T (cons (funcall fn (car list)) (my-map fn (cdr list))))))
اگر يك تابع Double وجود داشته ياشد كه تنها عدد را دو برابر كند آنگاه يك فراخواني ممكن my-map به اين صورت مي‌تواند باشد:
(my-map #’double ’(1 2 3 4))==> (2 4 6 8)
بارها شده كه يك تابع بايد يكبار استفاده مي‌شد. بنابراين اگر ما بتوانيم مستقيما تعريفي از يك تابع بعنوان آرگومان از تابع نگاشت فراهم كنيم كاملا مناسب خواهد بود براي اينكار تعريف عبارت lambda را پشتيباني مي‌كند. ما قبلا به طور غير رسمي نماد‌سازي عبارات را در بخش II بعنوان تعريف توابع بي نام يا مستعار معرفي كرديم. در Lisp عبارات lambda با استفاده از نوع خاصي از lambda تعريف مي‌شوند نوع عمومي عبارت lambda به اين صورت است:

(lambda ( parameter . . . ) body . . . )

يك عبارت lambda امكان مي‌دهد تا ما تعريف تابع را از نام تابع تشخيص دهيم عبارات lambda مي‌توانند به جاي نام تابع در تابع funcall استفاده شوند مانند عبارت كه تابع double ما مي‌تواند باشد:
(lambda (x) (+ x x))
براي مثال: فراخواني تابع my-map بالا مي‌تواند با استفاده از عبارت lambda مجدداً به صورت زير بيان شود:
(my-map #’(lambda (x) (+ x x)) ’(1 2 3 4) ==> (2 4 6 8)
يك عبارت lambda يك شئ تابعي بر مي‌گرداند كه به نام تابع متصل نيست در تعريف
my-map ، پارامتر fn را بعنوان متغير نام تابع استفاده مي‌كنيم. وقتي شكل lambda محاسبه شد مفسر Lisp شئ تابعي را به متغير نام تابع متصل خواهد كرد. به اين طريق يك پارامتر تابع بصورت يك نام تابع پويا استفاده مي‌شود. نماد # صروري است تا به Lisp بگويد كه نه تنها يك شئ تابعي را وصل كند بلكه بايد اتصالات محلي و سراسري مقادير وابسته به شئ تابعي را نيز نگه دارد. اين تنها با استفاده از عملگر quote امكان‌پذير نخواهد بود (متأسفانه به دليل محدوديت جا جزئيات بيشتري داده نمي‌شود).
 

آبجی

عضو جدید
کاربر ممتاز
G. ساير زبانهاي برنامه‌نويسي تابعي غير از Lisp
ما Lisp را به عنوان نماينده اصلي زبان برنامه‌نويسي تابعي معرفي كرديم (مخصوصاً نسخه پر استفاده Common Lisp )، زيرا هنوز هم زبان برنامه‌نويسي پر استفاده‌اي براي تعدادي از مسئله‌هاي هوش مصنوعي مانند فهم زبان طبيعي، استخراج اطلاعات، يادگيري ماشين،‌ برنامه‌ريزي AI يا برنامه‌نويسي ژنتيك است. دركنار Lispتعدادي از زبانهاي برنامه‌نويسي تابعي ديگر توسعه يافتند. ما بطور خلاصه دو عضو مشهور را ذكر مي‌كنيم، ML و Haskell.
ML برگرفته از Meta-Language است يك زبان برنامه‌نويسي تابعي با دامنه ايستاست. تفاوت اصلي‌اش با Lisp درsyntax (نحو) است (كه بيشتر شبيه پاسكال است)، و يك نوع سيستم چند ريختي محض است (يعني بكاربردن انواع قوي و نوع استنتاجي بوسيله متغيرهايي كه نياز به اعلان ندارند). نوع هر متغير اعلان شده و عبارت مي‌تواند در زمان كامپايل تعيين شود. MLتعريف انواع داده خلاصه را پشتيباني مي‌كند، به صورتي كه در مثال زير شرح داده شده است:

datatype tree = L of int
| int * tree * tree;

خوانده مي‌شود’’ هر درخت دو دويي داراي يك برگ شامل يك عدد صحيح و يا يك گره
شامل يك عدد صحيح و دو درخت است( زير درختها)‘‘ در مثال بعدي، مثالي از تعريف يك تابع بازگشتي كه روي يك ساختار درخت بكار مي‌رود نشان داده شده است:

fun depth(L ) = 1

| depth(N(i,l,r)) =

1 + max(depth l, depth r);


تابع depth نگاشتي از درختها به اعداد است. عمق هر برگ 1 است و عمق هر درخت ديگر 1 بعلاوه بيشترين عمق زير درختهاي چپ و راست آن است.
Haskell شبيه ML است: Syntax مشابهي بكار مي‌برد، دامنه‌اش هم ايستاست و از همان روش استنتاج استفاده مي‌كند. با ML در اين تفاوت دارد كه يك زبان كاملاً تابعي است. به اين معني است كه به اثرات جانبي اجازه نداده و شامل هيچ نوع ويژگي دستوري نيست، در اصل متغير و جملات انتسابي ندارد. بعلاوه از يك تكنيك ارزيابي كند استفاده مي‌‌كند، كه زير عبارت را ارزيابي نمي‌كند تا موقع نياز مقدارش معلوم باشد. ليستها رايجترين ساختار داده در Haskell هستند. براي مثال [1,2,3] ليستي از سه عدد صحيح 3,2,1 است ليست [1,2,3] در Haskell در واقع خلاصه‌نويسي شده ليست 1
2
3:[ ] )) است، كه[ ] ليست خالي است و: عملگري ميانوندي است كه آرگومان اولش را جلوي آرگومان دومش اضافه مي‌كند( يك ليست). بعنوان مثالي از يك تابع كاربر تعريفي كه روي ليستها عمل مي‌كند، مسئله شمارش تعداد عناصر در يك ليست با تعريف تابع length ملاحظه مي‌شود.

length :: [a] -> Integer

length [ ] = 0

length (x
s) = 1 + length xs

خوانده مي‌شود’’طول ليست خالي 0 است، و طول ليستي كه عنصر اولش x است و بقيه xs است،1 بعلاوه طول xs است‘‘. در Haskell تابع invocation احضار با تطبيق الگو راهنمايي مي‌كند، براي مثال طرف چپ معادله داري الگوهايي مانند[ ] و x
s است. در يك كاربرد تابع اين الگوها با پارامترهاي واقعي تطبيق داده مي‌شوند [ ] ) تنها با ليست خالي مطابقت مي‌كند، و x
s با هر ليست با حداقل يك عنصر با موفقيت تطبيق مي‌كند، x به عنصر اول و xs به بقيه ليست متصل مي‌شوند). اگر تطبيق موفقيت‌آميز باشد طرف راست معادله ارزيابي و بعنوان نتيجه كاربرد برگردانده مي‌شود. اگر با شكست مواجه شود معادله بعدي سعي مي‌شود، و اگر همه معادلات با شكست مواجه شوند،‌ حاصل يك خطا مي‌شود.
اين پايان كوتاه ما از’’سفر در Lisp ‘‘ است. ما تنهاي توانستيم جنبه بسيار مهم Lisp را مطرح كنيم. خوانندگان علاقمند به جزئيات خاص بيشتر بايد حداقل يكي از كتابهاي مذكور در آخر مقاله را كنكاش كنند. بقيه اين مقاله معرفي الگوي برنامه‌نويسي ديگري بنام ‌Prolog است كه در برنامه‌نويسي AI بطور گسترده مورد استفاده قرار مي‌‌گيرد.
 

آبجی

عضو جدید
کاربر ممتاز
IV. برنامه‌‌نويسي منطقي در Prolog
در دهه 1970 يك الگوي ديگر براي محاسبات نمادين در برنامه‌نويسي AI از موفقيت در زمينه اثبات قضيه خودكار ارئه شد. حل رويه اثبات بطور قابل توجهي توسط رابينسون
(1965) توسعه يافته كه كه با منطق رسمي نشان داده شده است، در محاسبات گزاره‌اي خاص مي‌‌توان بعنوان نمادي براي تعيين الگوريتم‌ها و بنابراين براي انجام محاسبات نمادين استفاده شود. در اوايل (دهه 1970) Prolog ، مخفف(برنامه‌نويسي در منطق) اولين زبان‌‌ برنامه‌‌نويسي بر مبناي منطق پديدار شد. آن توسط آلن كالمرار، رابرت كووا لسكي و فيليپ راسل توسعه يافته است. اساس Prolog شامل يك روش براي مشخص كردن گزاره‌هاي محاسبات گزاره‌اي و تصميات محدود است. برنامه‌‌نوسي در Prolog شامل مشخصات حقيقي در مورد اشياء و ارتباط آنها و قوانيني كه ارتباطات را مشخص مي‌كند، است. برنامه‌هاي Prolog مجموعه‌اي از جملات اعلاني در مورد يك مسئله هستند زيرا آنها نحوه محاسبه نتيجه را مشخص نمي‌‌‌كند.بلكه ساختار منطقي نتيجه را مشخص مي‌‌كنند Prolog با برنامه‌نويسي دستوري و حتي برنامه‌‌نويسي تابعي در تعريف نحوه محاسبه نتيجه كاملاً متفاوت است. با استفاده از Prolog برنامه‌نويسي مي‌تواند در يك سطح خيلي خلاصه و كاملاً نزديك به مشخصات رسمي يك مسئله انجام مي‌‌گيرد. Prolog هنوز هم مهمترين زبان برنامه‌نوسي منطقي است. تعدادي از سيستمهاي برنامه‌نوسي تجاري در بازار موجود است كه شامل ماجولهاي مدرن برنامه‌‌‌نويسي هستند، يعني كامپايلر، Debugger و ابزارهاي تجسم. Prolog در تعدادي از زمينه‌هاي AI مانند سيستم‌هاي خبره و پردازش زبان طبيعي بطور موفقيت‌آميزي استفاده شده است. اما در زمينه‌هاي ديگري مانند سيستم‌ هاي مديريت پايگاه داده رابطه‌اي يا در آموزش نيز استفاده مي‌شود. يك برنامه Prolog بسيار ساده برنامه‌اي است كه شامل دو حقيقت و يك قاعده است.

scientist(godel).

scientist(einstein).

logician(X) :- scientist(X).

دو جمله اول مي‌تواند بصورت ’’Godel is a scientist ‘‘ و ’’Einstein is a scientist ‘‘ تفسير شود.جمله قانون مي‌‌‌گويد: ’’X is a logician if x is a scientist ‘‘. براي تست اين برنامه بايد عبارات پرس و جو( يا قضايا) را مشخص كنيم كه Prolog سعي مي‌كند با استفاده از برنامه مشخص شده به آنها جواب دهد(يا اثبات كند). يك پرس و جوي ممكن اين است: ?- scientist(godel).
كه مي‌تواند به صورت ’’Is Godel a scientist?‘‘ بيان شود. Prolog با بكار بردن رويه اثبات پيش‌ساخته خودش ’’yes‘‘ جواب خواهد داد، زيرا ممكن است يك حقيقت پيدا شود كه كاملاً مطابق با پرس و جو باشد. ديگر پرس و جوي ممكن بصورت سئوال:
’’who is a scientist?‘‘و در Prolog بصورت زير بيان مي‌شود:
?- scientist(X).
Prolog نتيجه خواهد داد’’X = godel , X= Einstein ‘‘. در اين حالت Prolog نه‌تنها جواب مي‌دهد’’yes ‘‘ بلكه همه متغيرهاي متصل به x را كه در طول اثبات موفق پرس و جو پيدا مي‌كند را بر مي‌گرداند. مثال ديگر، ممكن است ما با پرس و جوي Prolog زير سئوال كنيم ’’who is a logician ‘‘:
?- logician(X).

اثبات اين پرس و جو همان مجموعه‌اي از حقايق را كه قانون مشخص كرده است را نتيجه مي‌دهد. سرانجام ممكن است ما پرس و جوي زير را مشخص كنيم:
?- logician(mickey-mouse).
در اين حالت Prolog جواب خواهد داد با ’’No ‘‘. هر چند قانون مي‌گويد كسي منطق‌دان است كه دانشمند هم باشد، ‌ولي Prolog حقيقتي نمي‌يابد كه بگويدMickey Mouse دانشمند است. توضيح اينكه Prolog تنها نسبت به برنامه داده شده مي‌تواند پاسخ بدهد. در واقع به اين معني است كه ‘‘ No, I couldn’t deduce the fact‘‘. اين ويژگي بعنوان فرض جهان بسته يا رد آن بصورت شكست،‌ مشهور است. به اين معني كه Prolog همه اطلاعات لازم براي حل مسئله موجود در پايگاه داده را فرض مي‌‌كند.
جملات برنامه‌هاي Prolog شامل مجموعه‌اي از جملات بنام بند هستند كه براي نمايش داده‌ها و برنامه‌ها استفاده مي‌شوند. نماد نقطه‌ براي پايان دادن بند بكار مي‌رود. يك واژه مي‌تواند يك ثابت(نامهاي نمادين كه با يك حرف كوچك شروع مي‌شوند مانند godel يا eInstein )، يك متغير(نمادهايي كه با يك حرف بزرگ شروع مي‌شوند مانند x يا ‌ Scientist)، يا يك ساختار باشد. ساختارهاي گزاره‌هاي اتمي محاسبات گزار‌ه‌اي را نمايش مي‌دهند و شامل عملگر نام و يك ليست پارامتر هستند. هر پارامتر مي‌تواند يك واژه باشد به اين معني كه واژه‌ها،‌ اشياء‌ بازگشتي هستند. Prolog سه نوع بند را تشخيص مي‌دهد: حقايق،‌قوانين و پرس و جوها. يك حقيقت با يك ساختار واحد نمايش داده مي‌شود كه بعنوان يك گزاره درست ساده تفسير مي‌شود. قبلاً در مثال ساده برنامه بالا دو حقيقت ساده را معرفي كرديم.
اينها چند مثال ديگر هستند:

male(john).

male(bill).

female(mary).

female(sue).

father(john, mary).

father(bill,john).

mother(sue,mary).

توضيح اينكه اين حقايق داراي معاني ذاتي نيستند يعني معني عملگر نام father تعريف نشده است. براي مثال با بكار بردن حواس معمول ممكن است آن را بصورت
’’John is the father of mary‘‘ تفسير كنيم. هر چند براي Prolog اين معني وجود ندارد و تنها يك نماد است.
قوانين متعلق به نوع ديگري از بندها هستند. يك بند قانون شامل دو قسمت است،‌ سر كه تنها يك واژه است و بدنه كه تنها يك واژه يا يك اتحاد است. يك اتحاد يك مجموعه از واژه‌هاست كه با نماد كاما از هم جدا مي‌شوند.
منطقاً يك بند قانون بعنوان يك استدلال تفسير مي‌شود، اگر همه عناصر بدنه درست باشند، آنگاه عنصر سر نيز درست است. بنابراين بدنه بند به صورت قسمت if (اگر) و سر بند بصورت قسمت then (آنگاه) قانون مشخص مي‌شوند.
اين مثال براي مجموعه‌اي از بندهاي قانون است:
parent(X,Y) :- mother(X, Y).

parent(X,Y) :- father(X, Y).

grandparent(X,Z) :- parent(X,Y), parent(Y,Z).

قانون اخير خوانده مي‌شود:
’’X is a grand parent of z if X is a parent of y and y is a parent of z ‘‘

دو قانون اولي مي‌گويند:
’’some one is parent if it is the father or mother of some one else‘‘

دليل رفتار دو قانون اول را هنگام معرفي رويه اثبات Prolog بعنوان فصلي بطور آشكار خواهد آمد. قبل از انجام اين كار بايد آخرين نوع بند را معرفي كنيم،‌ بند پرس و جو (كه بند هدف ناميده مي‌شود). يك پرس و جو براي فعال كردن رويه اثبات Prolog بكار مي‌رود.
منطقاً يك پرس و جو مشابه يك قضيه مجهول است. آن شكلي مشابه حقيقت دارد تا به Prolog بگويد كه يك پرس و جو بايد اثبات شود، عملگر مخصوص پرس و جو –?است معمولاً در جلوي پرس و جو نوشته مي‌شود. در مثالهاي ساده برنامه Prolog معرفي شده در بالا، قبلاً توصيفي غير رسمي از چگونگي استفاده پرس و جو در Prologرا ديديم.
فرايند استنتاج Prolog شامل دو مؤلفه اساسي است: روش جستجو و يكي كننده. روش جستجو براي جستجو ميان حقيقت و قانون پايگاه داده بكار مي‌رود در حالي كه يكي‌سازي براي تطبيق الگو و بازگرداندن اتصالاتي كه يك عبارت صحيح مي‌سازد بكار مي‌رود.
يكي‌ساز روي دو واژه بكار مي‌رود و سعي مي‌كند با تركيب آن دو يك واژه جديد شكل بدهد. اگر يكي سازي ممكن نباشد آنگاه گفته مي‌شود يكي‌سازي شكست خورده است. اگر دو واژه مادي هيچ متغيري نباشند آنگاه يكي‌سازي در واقع از بررسي اينكه آيا واژه‌ها برابرند، خواهد كاست. براي مثال، يكي‌سازي دو واژه father (john,mary) و father(john,mary) موفق مي‌شود در حاليكه يكي‌سازي جفت واژه‌هاي زير با شكست مواجه خواهند شد.
father(X,mary) و father(john,sue)

sequence(a,b,c) و sequence(a,b)
اگر يك واژه حاوي يك متغير (يا بيشتر) باشد آنگاه يكي كننده بررسي مي‌كند كه آيا متغير مي‌تواند با بعضي از اطلاعات واژه دوم متصل شود، هر چند تنها اگر قسمتهاي باقيمانده واژه‌ها يكي شوند. براي مثال، براي دو واژه زير:
father(X,mary) and father(john,mary)
يكي كننده X را به john متصل خواهد كرد زيرا واژه‌هاي باقيمانده برابرند. هرچند براي
زوج زير:
father(X,mary) and father(john,sue)
مفهوم اتصال ساخته نمي‌شود چون mary و sue مطابق نيستند. روش جستجويي كه براي پيمايش فضاي جستجو بكار مي‌رود بوسيله حقايق و قوانين برنامه Prolog محدود شده است. Prolog يك روش بالا به پائين، روش جستجوي عمقي (dfs) استفاده مي‌كند. اين به چه معنا است؟ همه مراحل كاملاً شبيه به روش تابع ارزيابي استفاده شده در Lisp است اگر يك پرس و جوي Q مشخص شده باشد آنگاه ممكن است آن مطابق يك حقيقت يا يك قاعده باشد. در حالتي از قاعده Prolog ,R ابتدا سعي مي‌كند سر R را تطبيق دهد و اگر موفق شود آنگاه سعي مي‌كندهمه عناصر بدنه R كه زير پرس و جو ناميده مي‌شوند را تطبيق دهد اگر سر R حاوي متغيرها باشد آنگاه اتصالات در طول اثبات از زير پرس و جوها استفاده خواهند كرد. از آنجايي كه اتصالات تنها براي زير پرس و جوها معتبر هستند، گفته مي‌شود كه براي يك قاعده محلي هستند. يك زير پرس و جو هم مي‌تواند يك قاعده باشد و هم يك حقيقت. اگر يك قاعده باشد آنگاه فرايند استنتاج Prolog بطور بازگشتي براي بدنه اين پرس و جو بكار مي‌رود. اين، قسمت بالا به پائين روش جستجو را مي‌سازد. عناصر بدنه يك قاعده از چپ به راست بكار مي‌روند و تنها اگر عنصر جاري بتواند با موفقيت اثبات شود عنصر بعدي سعي مي‌شود. اين روش جستجوي عمقي را مي‌سازد. ممكن است براي اثبات يك زير پرس و جو دو يا چند حقيقت يا قاعده ديگر تعريف شوند. در آن صورت A, Prolog را انتخاب مي‌كند و سعي مي‌كند آن را اثبات كند، اگر لازم باشد زير پرس و جوهاي A را نيز پردازش مي‌كند. اگر A با شكست مواجه شود Prolog به نقطه‌اي كه اثبات A شروع شده بر مي‌گردد(با حذف همه اتصالهايي كه در طول اثبات A انتساب داده شده است) و سعي مي‌كند ديگري را اثبات كند. اين فرايند عقب‌گرد نام دارد . به منظور شرح همه روشها پرس و جوهاي نمونه زير را مي‌توانيم ملاحظه كنيد (مثال معرفي شده در بندهاي پاراگراف قبلي را بعنوان پايگاه داده Prolog استفاده مي‌كنيم):
?- grandparent(bill,mary).
تنها بندي كه با اين پرس و جو تطبيق مي‌كند قاعده زير است.
grandparent(X,Z) :- parent(X,Y), parent(Y,Z).
و يكي‌سازي پرس و جو با سر قاعده اتصالهاي زير را بر مي‌گرداند: Z=mary,X=bill براي اثبات قاعده، بايد دو عنصر بدنه قاعده از چپ به راست اثبات شوند. توضيح اينكه متغيرهاي مشترك قواعد با سر قاعده و بنابراين اتصالهاي محاسبه شده در طول تطبيق سر با پرس و جو براي پاسخ به زير پرس و جوها موجودند. بنابراين زير پرس و جوي اول در واقع بصورت parent(bill,y) و زير پرس و جوي دوم بصورت parent (y,mary) معرفي شود. حال براي اثبات بند اول prolog دو قاعده parent ديگر مي‌يابد. اجازه دهيد فرض كنيم prolog اولي را انتخاب مي‌كند.( براي ياد‌آوري بيش از يك انتخاب، prolog يك نقطه انتخاب مشخص مي‌كند)
parent(X,Y) :- mother(X, Y).
يكي‌سازي زير پرس و جوها با سه قاعده به راحتي ممكن است و متغيرx به واژه bill متصل خواهد شد . اين عنصر تك بدنه‌اي بصورت (bill,y) mother معرفي مي‌شود. متاسفانه هيچ حقيقتي كه اين زير پرس و جو را معتبر كند در پايگاه داده وجود ندارد. چون يكي‌سازي (bill,y) mother با شكست مواجه مي‌شود. پس همه قاعده انجام مي‌شود. سپس prolog به نقطه انتخابي كه اولين قاعده parent ممكن را انتخاب كرده بود، برگشته و دومي را انتخاب مي‌كند.
parent(X,Y) :- father(X, Y)
يكي‌سازي زير پرس و جوي (هنوز فعال) parent(bill,y) ، father(bill,y) معرفي خواهد شد. اينبار يكي‌سازي ممكن است،‌اتصال y=john برگردانده مي‌شود. حال اولين زير پرس و جوي parent از قاعده grand parent اثبات شده متغيرهاي واقعي X=bill Z=mary,Y=john, هستند. عنصر دوم از بدنه قاعده grandparent،
parent (john, mary) معرفي مي‌شود (توضيح اينكه مقدار z بعد از انتخاب قاعده grand parent فوراً متصل شده است).
همان روش براي اين زير پرس و جو بكار رفته و prolog حقايق كافي براي اثبات موفقيت‌آميز آن خواهد يافت. وقتي كه دو عنصر بدنه قاعده grand parent به طور معتبر اثبات شد، prolog به پايان مي‌رسد كه اولين پرس و جو true مي‌شود. توسعه prolog ، به منظور استفاده از prolog براي برنامه‌نويسي كاربردي است. كه با توسعه‌هايي مانند ليست ساختارهاي داده، عملكردهايي براي كنترل واضح پيمايش از فاصله جستجو با يك برنامه prolog(بنام عملگر برش) و روالهايي براي رابطهاي ورودي /خروجي، تست درستي (رديابي) و اشكالزدايي مي‌آيد. ما نمي‌توانيم همه اين توسعه‌ها را در متن اين مرور كوتاه شرح دهيم. ما تنها بطور خلاصه نشان مي‌دهيم كه ليستها در prolog چگونه مي‌توانند استفاده شوند. Prolog ليستها را بعنوان يك ساختار داده‌اي پايه‌اي با استفاده از syntax متداول پشتيباني مي‌كند. عناصر ليست با كاما جدا مي‌شوند. كل ليست با براكت تعيين مي‌شود. يك عنصر ليست مي‌تواند يك واژه دلخواه يا يك ليست باشد، بنابراين كاملاً شبيه ساختارهاي ليست در Lisp است. اين مثالي از يك ليست prolog است:
[john, mary, bill]
ليست خالي بصورت [ ] نمايش داده مي‌شود. براي ايجاد و پيمايش ليستها، prolog يك تركيب خاص مبني بر سر و دنبال يك ليست فراهم مي‌كند. [X | Y]يك ليست است شامل يك سرليست x و يك دنباله y است. براي مثال ليست بالا مي‌تواند بصورت زير مشخص شود.
 

آبجی

عضو جدید
کاربر ممتاز
[john | mary, bill]
ما گزارهmember را بصورت مثالي براي نحوه رفتار ليستها در prolog استفاده خواهيم كرد. اين گزاره تعيين خواهد كرد كه آيا يك عنصر داده شده در يك ليست داده شده واقع مي‌شود؟ با توجه به توضيحات بالا يك عنصر در يك ليست است اگر سر ليست آن ليست باشد يا اگر در جايي از دنباله ليست واقع شود، با استفاده از تعريف غيررسمي گزاره member ما مي‌توانيم برنامه prolog زير را طرح كنيم. (نمادي كه يك متغير بي‌نام را مشخص مي‌كند،‌استفاده مي‌شود تا به prolog بگويد مهم نيست مقدار يكي كننده به آن متصل شود)
member(Element,[Element | ]).
member(Element,[ | List]) :- member(Element,List).
با فرض پر س و جوي زير
?- member(a, [b,c,a,d]).
Prolog ابتدا كنترل مي‌كند كه آيا سر ليست [b | c,a,d]برابر a است.
به اين علت بند اول با شكست مواجه مي‌شود، پس دومي سعي مي‌شود. اين زير پرس و جوي member (a,[c,a,d]) معرفي خواهد شد كه معني‌اش اين است كه از روي عنصر اول بسادگي مي‌پرد با بكار بردن بازگشي member،prolog سعي مي‌كند تا اثبات كند كه آيا سر ليست [c | a,d]با a برابر است، كه با شكست مواجه مي‌شود.، زير پر س و جوي جديد member (a,[a,d]) را با معرفي بند دوم بدست مي‌آوريم. گام بازگشتي بعدي ليست [a | d]را كنترل خواهد كرد. اينبار a براستي با عنصر سر ليست اين ليست برابر مي‌شود، بنابراين prolog با "yes" پايان خواهد يافت.
برنامه‌نويسي منطقي محدوديت (clp)تصميمي از سبك برنامه‌نويسي (ساده)‌prologاست. در clp واژه يكي‌سازي به حل محدوديت تعميم يافته است. در برنامه‌نويسي منطقي محدوديت مولفه‌هاي اصلي يك مسئله بصورت محدوديت‌ها حالت يافته‌اند (يعني ساختار اشياء در سؤال) و مسئله بصورت يك كل كه با گذاشتن محدوديتهاي مختلف بوسيله قواعد ارائه شده است. (اساساً بوسيله تعريف بندها) براي مثال بند معين زير نمونه يك تجزيه ريز از گرامر يك زبان طبيعي مانند انگليسي است.
sign(X0) ←
sign(X1),

sign(X2),

X0 syn cat = s,

X1 syn cat = np,

X2 syn cat = vp,

X1 syn agr = X2 syn ag

بيان مي‌شود يك شي زباني بصورت يك عبارت S طبقه‌بندي مي‌شود كه بايد مركب از يك شيء طبقه‌بندي شد كه بصورت يك NP (عبارت اسمي) و يك شئ طبقه‌بندي شده بصورت يك VP(عبارت لفظي) باشد و قرارداد اطلاعات (مانند شخص، حالت) بايد بين NP و VP يكسان باشد. همه اشيايي كه حداقل اين محدوديتها را انجام مي‌دهند جزء‌اشياي S هستند. توضيح اينكه هيچ ترتيب پيش فرضي براي VP,NPبعنوان حالتي براي گرامر زبان طبيعي مبني بر ظواهر وجود ندارد كه متن بدون استحكام به آن تكيه كند. اگر يك محدوديت نياز به محدوديتهاي اضافي داشته باشد. بايد به قاعده اضافه شود، براي نمونه زير ريشه‌ها بايد با الحاق تركيب شوند از نجاطيآنآن
آنجايي كه محدوديتهاي مثال بالا تنها شرايط لازم براي شئ از كلاس S را مشخص مي‌كند آنها اطلاعات مختصري بيان مي‌كنند. اين براي دانش مبني بر استدلال خيلي مهم است زيرا در كل ما تنها اطلاعات مختصري درباره جهان (محيط)‌داريم، ‌ما براي پردازش چنين خصوصياتي دليل مبني بر حل محدوديت و الگوي برنامه‌نويسي منطقي مي‌خواهيم. چون يكي‌سازي، فقط حالت خاصي از حل محدوديت است، برنامه‌هاي منطقي محدوديت توان بيان بالايي دارند.
تعدادي از زبانهاي برنامه‌نويسي منطقي محدوديت (همراه با رابط كاربر سطح بالا و ابزارهاي توسعه) تحقق يافته‌اند. مانند CHIP يا زبان OZ كه برنامه‌نويسي اعلاني، برنامه‌نويسي شئ گرا، برنامه‌نويسي محدوديت و همزماني را بعنوان جزئي از كل منسجم پشتيباني مي‌كند. OZ زباني محدوديت قدرتمندي با متغيرهاي منطقي،‌دامنه‌متناهي، مجموعه‌هاي متناهي، درختهاي عقلاني و ركورد محدوديت‌هاست. آن در صدد است تا يك روش يكتا و انعطاف‌پذير بدون شاخ و بندها براي برنامه‌نويسي منطقي فراهم كند. OZ بين روشهاي مستقيم و غير مستقيم برنامه‌نويسي منطقي اعلاني تفاوت قايل مي‌شود.

V. ساير روشهاي برنامه‌نويسي
‌در اين مقاله قبلاً زبانهاي AI را با روشهاي برنامه‌نويسي دستوري مقايسه كرديم. زبانهاي شيء گرا به الگوي برنامه‌نويسي مشهور ديگري تعلق دارند. در اين جور زبانها اولين وسيله براي تعيين مسئله‌ها، تعيين خلاصه ساختارهاي داده است كه كلاس‌ها، اشياء‌نام دارند. يك كلاس شامل يك ساختار داده همراه با عمليات اصلي‌اش كه اغلب اسلوبها (روشها) نام دارند است. يك ويژگي مهم اين است كه ممكن است كلاسها در سلسله مراتبي از كلاسها و زير كلاسها مرتب شوند. يك كلاس مي‌تواند صفات سوپر كلاسهايش كه پيمانه‌اي بودن را پشتيباني مي‌كنند را به ارث ببرد.
مشهورترين زبانهاي شيءگرا C++,Eiffel و Java (جاوا) هستند. سيستم Common Lisp شيءگرا يك توسعه از common Lisp است. آن يكپارچه‌سازي كامل برنامه‌نويسي تابعي و شيءگرا را پشتيباني مي‌كند. اخيراً جاوا در بعضي از زمينه‌ها AI، خصوصاً در فن‌آوري عامل هوشمند، موتورهاي جستجوي اينترنت يا استخراج داده‌ها كاملاً مشهور شده است. جاوا بر مبناي C++ است و زبان اصلي براي برنامه‌نويسي كاربردهاي اينترنتي است. مهمترين ويژگيهاي زبان كه جاوا را از چشم‌آنداز AI جذاب مي‌سازد فضاي هرز خودكار پيش‌ساخته آن و مكانيزم چند نخي (چند وظيفه‌اي) آن است.
با افزايش تحقيقات در زمينه وب هوشمند يك الگوي برنامه‌نويسي جديد- برنامه‌نويسي عامل‌‌گرا – پديدار شد. برنامه‌نويسي عامل‌گرا يك الگوي جديد برنامه‌نويسي است كه يك نماي اجتماعي از محاسبه را به خوبي پشتيباني مي‌كند. در AOP اشياء بعنوان عاملهايي شناخته مي‌شوند كه براي دستيابي به اهداف شخصي عمل مي‌كنند. عامل در يك ساختار مي‌تواند به پيچيدگي شبكه سراسري اينترنت يا به سادگي يك پيمانه (ماجول) از يك برنامه معمولي باشد. عاملها مي‌توانند موجوديتهاي مستقل باشند يعني بدون دخالت كاربر براي گام بعدي‌شان تصميم بگيرند، يا مي‌توانند قابل كنترل باشند، يعني بعنوان وسيله‌اي بين كاربر و عاملهاي ديگر بكار بردند. از آنجايي كه عاملها زنده در نظر گرفته مي‌شوند، با رشد موجوديتهاي نرم‌افزار، به نظر مي‌رسد انتقالي از نقطه‌نظر زبانهاي برنامه‌نويسي به طرف نقطه‌نظر سكوي پيشرفت نرم‌افزار پديدار مي‌شود. اينجا تأكيد روي طراحي سيستم، سكوي پيشرفت و اتصال است. سئوالات حساس عبارتنداز: چگونه تعدادي از منابع پيشرفته AI كه در زبانها و سكوهاي مختلف موجودند مي‌توانند با ساير منابع استفاده‌كننده از ابزارهاي پيشرفت سيستم جديد مانند CORBA (معماري عادي رابط درخواست شئ) تركيب شوند (يكپارچه شوند)، خلاصه‌سازي عمومي انواع داده و زبانهاي تفسيري(يادداشت حاشيه‌اي) مانند XML و زبان استاندارد ارتباطات عامل‌گرا مانند KQML (زبان شناخت پرس و جو و دستكاري).
بنابراين آينده برنامه‌نويسي AI كمتر نگران سئوالاتي مثل: ” مناسب‌ترين الگوي برنامه‌نويسي چيست؟ “ است ولي بايد به سئوالاتي مثل: ” چگونه مي‌توانم الگوهاي مختلف برنامه‌نويسي را زير يك سايبان يكپارچه كنم؟ “ و ” بهترين زبان ارتباطي براي نرم‌افزارهاي مستقل پيمانه‌اي هوشمند چيست؟ “ پاسخ دهيم
 

Similar threads

بالا