امتیاز موضوع:
  • 1 رأی - میانگین امتیازات: 5
  • 1
  • 2
  • 3
  • 4
  • 5
هوش مصنوعی
نویسنده پیام
اشک آفلاین
كاربر دو ستاره
**

ارسال‌ها: 108
موضوع‌ها: 14
تاریخ عضویت: آبان ۱۳۸۸

تشکرها : 758
( 532 تشکر در 136 ارسال )
ارسال: #1
هوش مصنوعی
هوش مصنوعی چیست؟
به زبان بسیار ساده هوش مصنوعی تلاش برای تولید ماشینی است که همانند انسان عمل کند.
AIیک رشته جدیدی است که در اواسط قرن 20 بوجود آمده است. اکثرا در روزنامه ها، تلویزیون، فیلمها و بازی های کامپوتری به این مقوله پرداخته شده اما درست درک نشده است. حتی بعضی ساده لوحان این طرح را غیر عملی میدانند و بعضی از دولتها هرگونه فعالیت در این زمینه را ممنوع کرده اند. اما این علم در صنعت و دانشگاهها در حال پیشرفت است اگرچه همیشه بعنوان هوش مصنوعی شناخته نمی شود، زیرا تکنیکها و ایده های مهمی از مهندسی نرم افزار را در خود دارد. بعضی دیگر از ساده لوحان نیز فکر می کنند که این علم در حال رشد سریعی است و در چند سال آینده رباتها انسانها را به زنجیر میکشند و دنیا را در اختیار خود میگیرند.
متاسفانه هیچ توضیح و یا اشاره ای ازAI در مدارس و حتی دانشگاها داده نمیشود و تعداد معدودی از دانشگاها هستند که رشته و یا درس AI را در برنامه درسی خود قرار داده اند.
AI یک علم بسیار عمیق و پیچیده در قرن اخیر است که در حالت کلی به مطالعه بر روی اطلاعات، چگونگی جمع آوری و نگهداری از آنها، بکارگیری اطلاعات و جابجایی و انتقال آنها به ماشین و یا انسان و حیوان میپردازد.
در فیزیک و شیمی بر اساس قانون اصل بقای انرژی، انرژی از بین نمیرود و فقط از صورتی بصورت دیگری در می آید. بسیاری از علوم مانند بیولوژی، داروسازی، زمین شناسی و دانشهای مهندسی براساس این اصل تکامل یافته است و تمامی این رشته ها بر اساس درک صحیحی از مکانیزم طبیعی و یا مصنوعی تبدیل نیرو، جرم و انرژی استوار است. در مورد اطلاعات نیز این اصل استوار است که اطلاعات انتقال می یابد و از صورتی بصورت دیگر در می آید.
به همین دلیل میتوان این علم را علم اطلاعات و یا علم هوش نامگداری کرد. علمی که بر اساس اصل تبدیل اطلاعات به فرم مکانیکی و شیمیایی و بالعکس استوار است.
نه تنها سیستمهای مصنوعی بلکه انسانها نیز اطلاعات را دریافت میکنند، بکار میگیرند و انتقال می دهند. انسانها حتی با اینها کنترل میشوند. برای مثال با جایزه خوشحال، با خبر بد غمگین، از صدای بلند در تاریکی هراسناک میشوند یعنی با دریافت یکسری اطلاعات از خود احساس نشان میدهند. این مورد نیز در در حال بررسی و مطالعه است. بنابراین AI برخلاف ظاهر اسمش، درباره سیستمهای طبیعی و مصنوعی تجزیه و تحلیل اطلاعات و نه فقط چگونگی دریافت اطلاعات بلکه چه میکنند و چگ.نه احساس میکنند، میباشد.
AIزمینه های پژوهشی دیگری را نیز شامل میشود
اگر ما AI را بدین صورت تعبیر کنیم که علمی است که به چگونگی دریافت، پردازش، نگهداری و استفاده اطلاعات در هوش انسان و حیوان و ماشین باشد، بطور حتم با زمینه های پژوهشی قدیمیتری مانند روانشناسی، اعصاب و روان، فلسفه و منطق نیز در ارتباط هستیم.
پیشرفت کامپیوترها راههای جدیدی برای حل مشکلات AIدر برابر ما گشوده است. در گذشته روانشناسان و دانشمندان مغز و اعصاب نمیتوانستند سیستمهای پردازش اطلاعات حیوانات و آدمی را آزمایش کنند و فلاسفه فقط میتوانستند تئوریهایی در زمینه چگونگی کارکرد مغز و زبان بدهند. حال آنکه امروزه میتوان فراتر از آنها رفت و سیستمهایی طراحی نمود که تئوریها را مورد آزمایش قرار دهد و صحت و سقم آنها را یافت.
تجربه های بدست آمده
طراحی ماشین با توانایی های خاص خیلی سخت تر از فرضیات اولیه دانشمندان است. خیلی کارها که در ابتدا ساده بنظر می رسند، موارد دقیق و عمیقی در خود دارند. برای مثال "دیدن" فقط تشخیص اشیا نیست، بیکه شامل ایجاد احساس و درک محیط و درک امن و یا نا امن بودن آن میباشد.
همچنین توانایی فهم زبانی مانند انگلیسی، فرانسه و یا فارسی خیلی پیچیده تر از آن است که محققان فکر کردند. استفاده از زبانهای برنامه نویسی مثل C و C++ و Java نیز خیلی دست و پا گیر است.
ما امروزه میدانیم که حتی افراد کودن هم به مراتب از ماشینهایی که امروزه طراحی شده اند پیشرفته تر و آگاه تر هستند. به هیچ رباتی نمیشود اطمینان داشت که برود و ظروف را از روی میز جمع کند، بشورد و در جاظرفی بچیند و همه این کارها را بدرستی انجام دهد. درحالی که همان افراد کودن هم این کارها را براحتی انجام میدهند.
امروزه این به اثبات رسیده که ماشینها قادر به انجام کارهایی هستند که در ابتدا برای محققان انجام آن توسط ماشینها سخت مینمود مانند
حساب کردن و شطرنج بازی کردن.
ما امروزه فهمیده ایم که خیلی از کارهای پیچیده انسان و حیوان مانند بالا رفتن از درخت و ساختن آشیانه، هوش بسیار بالا و دانش پیچیده ای نیاز دارد که تئوریهای ما هنوز آنها را پوشش نمی دهند. همچنین درک غرایز حیوانی نیز حتی در میان فلاسفه بسیار مشکل است.
بسیاری از محققین سعی میکنند که موارد فوق را بدرستی درک کنند و برای آنها مکانیسمهایی طراحی کنند. طراحی شبکه های عصبی و مترجمهای چند زبانه راهایی هستند که محققین برای رسیدن به این اهداف بزرگ پی گرفته اند. همچنین محققین در تلاشند روشهایی برای ساختن سیستمهای با مکانیزمی که بتواند انگیزه و احساس را دریافت و درک کند، میباشند.
بنابراین AI علاوه بر مطالعه بر روی درک و دریافت، تعلیم؛ یادگیری، احساسات، ارتباطات و غیره، زمینه های دیگر بخصوص فلسفه، منطق، روانشناسی و همچنین مهندسی نرم افزار و علم کامپیوتر را نیز مورد مطالعه قرار میدهد.

<a href="http://artificial.ir">انجمن هوش مصنوعی ایران</a>
<a href="http://artificial.ir"><img src="http://artificial.ir/logo/ai88x31.gif" alt="هوش مصنوعی" border=0 /></a>

درمورد زبان لیسپ اگر اطلاعاتی دارید ممنون میشم بیان کنید.درمورد implementation.maintenance...
ممنون.

زمانی که به پایان رسیدی بدان شروعی دوباره در کام تولد است.Wink
(آخرین ویرایش در این ارسال: ۱۵-آبان-۱۳۸۸, ۲۱:۲۷:۰۵، توسط اشک.)
۱۵-آبان-۱۳۸۸, ۲۱:۱۴:۳۷
ارسال‌ها
پاسخ
تشکر شده توسط : t3r!p3000, hamed_Arfaee, Robocup, HoseinVig, amir00, The.Ghost, godvb
اشک آفلاین
كاربر دو ستاره
**

ارسال‌ها: 108
موضوع‌ها: 14
تاریخ عضویت: آبان ۱۳۸۸

تشکرها : 758
( 532 تشکر در 136 ارسال )
ارسال: #2
RE: هوش مصنوعی
زبانهاي برنامه‌نويسي هوش مصنوعي(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 بنا نهاده شده است.

نويسنده: Gunter Neumann

German Research Center for Artificial Intelligence (LT–Lab, DFKI)


ترجمه: احد محمّدي خواجه
http://www.e-commerc.blogfa.com/post-28.aspx

آموزش مقدماتی زبان برنامه نویسی پرولوگ :


كد:
http://ece.ut.ac.ir/classpages/F83/Artif...rolog1.doc

http://ece.ut.ac.ir/classpages/F83/Artif...rolog2.doc

a href="http://artificial.ir">انجمن هوش مصنوعی ایران</a>
http://ece.ut.ac.ir/classpages/F83/Artif...rolog3.doc

http://ece.ut.ac.ir/classpages/F83/Artif...rolog4.doc

http://ece.ut.ac.ir/classpages/F83/Artif...og5.docSWI Prolog


كد:
http://ece.ut.ac.ir/classpages/F83/Artif...Prolog.zip
Strawberry Prolog


كد:
http://ece.ut.ac.ir/classpages/F83/Artif...ght2_3.exe
و یکسری دیگه يادداشت هایي در زمينه پرولوگ


كد:
http://ece.ut.ac.ir/classpages/F83/Artif...rolog1.doc

http://ece.ut.ac.ir/classpages/F83/Artif...rolog2.doc
Artificial Intelligence

اگه منبع رو برای پرولوگ میخواید میتونی به این لینک سر بزنیدو فایل پرولوگ رو دانلود کنید این اسلاید برای نوشتن یه برنامه کامل پرولوگ مثل پازل 8 یا بازیهای دیگه کافیه



كد:
http://fzmahmoudi.googlepages.com/artifi...telligence

زمانی که به پایان رسیدی بدان شروعی دوباره در کام تولد است.Wink
(آخرین ویرایش در این ارسال: ۱۶-آبان-۱۳۸۸, ۱۱:۵۶:۰۶، توسط اشک.)
۱۶-آبان-۱۳۸۸, ۱۱:۴۸:۵۸
ارسال‌ها
پاسخ
تشکر شده توسط : hamed_Arfaee, t3r!p3000, Robocup, HoseinVig, salehjg, The.Ghost, godvb
اشک آفلاین
كاربر دو ستاره
**

ارسال‌ها: 108
موضوع‌ها: 14
تاریخ عضویت: آبان ۱۳۸۸

تشکرها : 758
( 532 تشکر در 136 ارسال )
ارسال: #3
RE: هوش مصنوعی
Visual Prolog 7.1
Commercial Edition
for Windows Vista/XP/2000
مي توانيد دانلود كنيد.

http://www.visual-prolog.com/?gclid=COOY...XgodYgiAlg

زمانی که به پایان رسیدی بدان شروعی دوباره در کام تولد است.Wink
۱۶-آبان-۱۳۸۸, ۱۲:۵۹:۱۱
ارسال‌ها
پاسخ
تشکر شده توسط : t3r!p3000, Robocup, HoseinVig, salehjg, The.Ghost, godvb
اشک آفلاین
كاربر دو ستاره
**

ارسال‌ها: 108
موضوع‌ها: 14
تاریخ عضویت: آبان ۱۳۸۸

تشکرها : 758
( 532 تشکر در 136 ارسال )
ارسال: #4
RE: هوش مصنوعی
اینهم تاریخچه و مختصری درمورد لیسپ که از زبانهای هوش مصنوعی است.

لیسپ لیسپ یک زبان برنامه‌نویسی رایانه است که در سال ۱۹۵۸ به وسیلهٔ جان مک‌کارتی ابداع شده‌است. این زبان، مانند زبان برنامه‌نویسی پرولوگ، بیشتر برای برنامه‌نویسی هوش مصنوعی مورد استفاده قرار می‌گیرد. با توجه به اینکه زبان لیسپ از نحو ساده‌ای برخوردار است، تجزیه و پیاده‌سازی آن نسبتاً با سهولت انجام می‌شود.
متن برنامه‌های لیسپ عموماً از نمادها و لیست‌هایی از نمادها تشکیل می‌شود و بدین خاطر است که این زبان لیسپ (مخفف پردازش لیست) نامیده شده‌است. یکی از ویژگی‌های جالب زبان لیسپ این است که خود برنامه‌های لیسپ نیز لیست هستند و بنا بر این، می‌توان با برنامه‌ها به عنوان داده‌ها رفتار کرد و یا داده‌ها را به عنوان برنامه ارزیابی نمود.
لیسپ دارای گویش‌های مختلفی است که بعضی از آنها دارای قابلیت‌های شیءگرا نیز هستند. از این میان می‌توان به کامن لیسپ اشاره کرد.
در ابتدا لیسپ به عنوان علامتگذاری و نمادسازی ریاضیات و برای برنامه‌های کامپیوتری ابداع شد.زبان لیسپ به سرعت مورد توجه برنامه نویسان از جمله برای تحقیقات علمی هوش مصنوعی قرار گرفت.لیسپ یکی از ابتدائی ز بان‌های برنامه نویسی می‌باشد،ودر علوم کامپیوتر بر بسیاری از تفکرات و ایده‌ها پیشگام بود.لیسپ شامل ساختمان دادهٔ درخت،مدریت نگهداری اتوماتیک،برنامه نویسی پویا،برنامه نویسی شی گرا و کامپایلر مستقل می‌باشد.
نام لیسپ از زبان پردازش لیسپ گرفته شده‌است.لینک لیست یکی از قسمت‌های اصلی ساختمان دادهٔ زبان لیسپ است و سورس کد لیسپ از لیست‌ها ساخته شده‌است و می‌تواند به عنوان ساختمان داده عمل کند.پیشرفت و توسعهٔ سیستم ماکرو به برنامه نویسان اجازه می‌دهد تا ترکیب‌های جدید ویا حتی حیطهٔ زبان‌های برنامه نویسی ویژه‌ای را ایجاد کرده و در زبان لیسپ تعبیه کنند. قابلیت تبادل کدها و داده‌ها به زبان لیسپ قابلیت تشخیص ترکیب‌ها را می‌دهد،همهٔ کدهای برنامه به صورت عبارت‌های نمادین یا لیست‌های پرانتز گذاری شده نوشته شده‌اند.
یک تابع می‌تواند توسط خودش ویا توابع دیگر فراخوانی شود ویا طبق قواعد نحوی نوشتن یک لیست و استفاده از اول نام عملگرها و پیروی کردن از قواعد آرگومان‌ها ایجاد شود.به عنوان مثال تابع fدارای 3 آرگومان می‌باشد و به صورت مقابل توانائی فراخوانی را دارد و مورد استفاده قرار می‌گیرد:

(f x y z)

زبان برنامه نویسی لیسپ توسط جان مک کارتی در سال 1958 در حالی که در مؤسسهٔ فناوری ماساچوست (MIT) بود ابداع شد.مک کارتی طرح خودش را در یک مقالهٔ مرتبط با انجمن ماشین آلات کامپیوتری در سال 1960 منتشر کرد.طرح وی در ابتدا به صورت «بخش اول:توابع بازگشتی از دید عبارت‌های نمادین و محاسبهٔ آنها توسط ماشین» ارائه شد و بخش دوم آن هیچگاه منتشر نشد.وی نشان داد که با یک تعداد ساده و کمی از عملگرها و علمتگذاری توابع می‌توان یک زبان تورینگ کامل برای الگوریتم‌ها ایجاد کرد. زبان پردازش اطلاعات اولین زبان هوش مصنوعی بود. از سال 1955 یا 1956 و پیش از آن ایده‌های بسیاری بر زبان لیسپ وارد شد از جمله پردازش لیست و توابع بازگشتی که در زبان لیسپ به کار برده شد. ثبت‌های اصلی مک کارتی به صورت عبارت‌های غیر نمادین که خواستار تفسیر کردن و برگرداندن به عبارت‌های نمادین بود.به عنوان مثال عبارت غیر نمادین car[cons[A,B]] معادل عبارت نمادین (car (cons A B)بود که در زبان لیسپ به کار گرفته شده بود.برنامه نویسان به سرعت عبارت نمادین را انتخاب و عبارت‌های غیر نمادین را ترک کردند.
لیسپ برای اولین بار توسط استفان راسل روی یک کامپیوتر IBM 704 اجرا شد. راسل مقالهٔ مک کارسی را مطالعه کرد و دریافت که توابع لیسپ می‌توانند در کد ماشین اجرا شوند. این نتیجه از مطالعه و دریافت راسل نشان می‌دهد که مفسر لیسپ می‌توانست برای اجرای برنامه‌های لیسپ و ارزیابی صحیح عبارت لیسپ استفاده شود.
دو زبان اسمبلی به عنوان دو عملیات اصلی و ابتدائی تجزیه و جدا کردن عناصر اصلی لیست برای IBM 704 شد.این دو زبان اسمبلی car (مضمون آدرس ثبات) و cdr (محتوای کاهش میزان ثبات‌ها) نسخهٔ لیسپ هنوز ازcar وcdr برای عملیاتی که اولین عنصر در یک لیست و باقی ماندهٔ لیست را برمی‌گرداند،استفاده می‌کند.
اولین کامپایلر تکمیل شدهٔ لیسپ،در سال 1962توسط تام هارت و مایک لوین در MIT اجرا شد، این کامپالر معرفی شده مدل لیسپ با کامپایلر نحوی در هر کامپایل و ترجمهٔ توابع می‌تواند به طور رایگان در هم بیامیزد.
زبان به کار گرفته شده در ثبت هارت و لوین نسبت به کدهای ابتدائی مک کارتی به شیوهٔ لیسپ مدرن و جدید نزدیک تر می‌باشد.
پیوستن به هوش مصنوعی:
بعد از شروع لیسپ ، لیسپ به انجمن تحقیقاتی هوش مصنوعی پیوست ، خصوصا به سیستم‌های PDP ، زبان لیسپ به عنوان پیاده ساز طرح کوچک زبان برنامه نویسی استفاده می‌شود که مبنایی برای سیستم معروف هوش مصنوعی SHRLU بود.
در سال 1970 تحقیقات علمی هوش مصنوعی به شاخه‌های تجاری انشعاب پیدا کرد که کارایی سیستم لیسپ موجود در این زمینه یک روند رو به رشد شد.
لیسپ یک سیستم مشکل برای اجرا، مهارت کامپایلر و سخت افزار ذخیره کننده را در سال 1970 دارا باشد. بازیابی عادی حافظه ، توسط دانشجوی فارغالتحصیل MIT ( دانیل ادوارد ) گسترش داده شده ،که برای اجرای لیسپ روی سیستم‌های محاساتی ساخته شده بود اما راندمان آن هنوز یک مشکل بود. برای رهبری ماشین لیسپ: سخت افزار اختصاصی برای اجرای محیط لیسپ و برنامه‌های آن استفاده می‌شود. پیشروی در هردو سخت افزار کامپیوتر و فناوری کامپایلر از ماشین‌های لیسپ از کار افتاده الهام گرفته شده‌است.
طی شک کوشش بزرگ نسخه‌های بیشماری از زبان لیسپ را در یک زبان واحد متمرکز و متحد کردند(نسخه‌های برجسته و قابل ملاحظه‌ای شامل: اینترلیسپ ، مک لیسپ ، متالیسپ ، و فرانزلیسپ) زبان‌های جدید (لیسپ عمومی و مشترک ) در اصل یک زیر مجموعهٔ سازگاری از نسخه‌های تعویض شده بود. در سال 1994 ، ANSI یک لیسپ عمومی و مشترک استاندارد منتشر کرد. لیسپ عمومی و مشترک زبان برنامه نویسی فناوری اطلاعات ANSI X3.226-1994 در آن زمان فروشگاه‌های جهانی برای لیسپ خیلی کوچکتر از المان بود.
ترکیب و معنا شناسی:
لیسپ یک عبارت جهتدار است ، برخلاف بیشتر زبان‌های دیگر ، بین عبارت‌ها و جمله‌ها تمایز و فرقی وجود ندارد . همهٔ کدها و داده‌ها به عنوان عبارت‌ها نوشته شده‌اند – زمانی که یک عبارت ارزیابی می‌شود یک مقدار ( یا یک لیستی از مقادیر) را می‌سازد ، که آن هم در داخل عبارات دیگر جاسازی می‌شود.
مقالهٔ 1958 مک کارتی دو نوع از ترکیب‌ها را معرفی کرد: عبارت نمادین Sexps هم نامیده می‌شود ، که بازتابی از نمایش داخلی کدها و داده هاست و عبارت غیر نمادین هرگز مورد توجه قرار نگرفت و تقریبا همهٔ زبان‌ها امروزه از عبارات نمادین استفاده می‌کنند.
استفاده از پرانتزگذاری‌ها تفاوت بسیار آشکار و مشهودی میان لیسپ و دیگر زبان‌های برنامه نویسی ایجاد کرده‌است . اسم مستعار LISP از Lost In Stupid Parenthese و یا Lost of Irritating Supper fluous parenthese گرفته شده‌است . هرچند ترکیب عبارت‌های نمادین مسئولی برای توان لیسپ است ، این ترکیب به شدت با قاعده و منظم است.
هرچند ترکیبات لیسپ به نمادگذاری قدیمی محدود نشده‌اند می‌تواند به سبک‌های دیگر توسعه پیدا کند. تکیه روی عبارت‌ها ، قابلیت انعطاف پذیری زیادی به زبان می‌دهد ، زیرا توابع لیسپ به صورت لیست نوشته شده‌اند ، آنها دقیقا مانند داده‌ها می‌توانند پردازش شوند، این قابلیت اجازه می‌دهد برنامه‌های لیسپ به سادگی و راحتی نوشته شوند و به نسبت برنامه‌های دیگر به راحتی اداره شوند . (برنامه نویسی غیر نمادین)بسیاری از نسخه‌های زبان لیسپ با عناصر جدا شده توسط فاصله‌های سفید و پرانتزگذاری شده‌ها نوشته می‌شود. برای مثال (1 2 f00 ) یک لیست است که عنصرهای آن سه اتم هستند ( اتم: کوچکترین عضو لیست ) : این مقادیر 1 و 2 و F00 هستند. این مقادیر ضمنا دارای نوع داده‌ای خاصی هستند ، مثلا این لیست دارای دو عدد صحیح 1 و 2 و یک نوع دادهٔ ویژهٔ لیسپ که یک Symbol یا نماد نامیده می‌شود.
همچنین یک لیست خالی () به عنوان یک اتم ویژهٔ صفر و یا پوچ معرفی شده‌است. موجودیت یک لیسپ از اتم و لیست تشکیل می‌شود. عبات‌ها به عنوان لیست نوشته شده‌اند ، استفاده کردن از ثبت‌های پیشوندی ، عناصر ابتدایی در لیست نامی از یک شکل تابع ، عملگرها ، ماکروها و یا اپراتورهای ویژه‌است.
آرگومان‌ها باقیمانده‌هایی از لیست‌ها هستند ، برای مثال تابع list آرگومان‌ها را به عنوان یک لیست بر می‌گرداند ، بنابراین عبارت (list ‘1 ‘2 ‘foo) ارزیابی می‌شود و حاصل این ارزیابی لیست (1,2,foo) می‌باشد.
نیازی به ارزیابی کردن اعداد نیست چون ارزیابی عدد 1 عدد 1 می‌شود.آرگومان‌های مثال قبل از اعداد هستند یعنی آرگومان‌های ویژه که این آرگومان‌ها از ارزیابی کردن آرگومان‌ها جلوگیری می‌کنند چون مقادیر آن‌ها مشخص است.هر عبارتی که بیان می‌شود قبل از اینکه با عبارات دیگر پیوست داده شود به صورت بازگشتی ارزیابی می‌شود.
(list(1 2 (list(3 4)))) در این مثال حاصل اررزیابی به صورت لیست (1,2(3,4)) می‌باشد ،توجه کنید این لیست دارای 3 آرگومان می‌باشد ، لیست‌ها می‌توانند به صورت تو در تو باشند . اپراتورهای حسابگر به صورت همسان رفتار می‌کنند.
حاصل عبارت (+1 2 3 4 ) عدد 10 می‌باشد. عبارت معادل عبارت بالا به صورت 1+2+3+4 می‌باشد که از نشانگذاری میان وندی استفاد شده‌است. اپراتورهای حسابگر در زبان لیسپ variadic(n-ary) که زبان لیسپ توانایی پذیرفتن هر تعداد آرگومان را داراست.
عملگرهای ویژه ساختمان کنترل لیسپ را آماده می‌کنند. برای مثال ، اپراتور ویژه if سه آرگومان می‌پذیرد،اگر اولین آرگومان صفر و یا خالی باشد دومین آرگومان ارزیابی می‌شود و در غیر این صورت هٔرگومان سوم بررسی می‌شود . بنابر این if(nill(list 1 2 “foo”)(list 3 4 “bar”) که تنها آرگومان (list 3 4 “bar”) بررسی می‌شود.

عبارت‌های لاندا(Lambda) :
دیگر عبارت‌های ویژه لاندا می‌باشد که برای وصل کردن متغیرها به مقادیرشان که درون یک عبارت ارزیابی می‌شوند استفاده می‌شود. این عملگر همچنین برای ایجاد کردن توابع هم استفاده می‌شود. آرگومان‌های درون لاندا یک لیستی از آرگومان‌ها هستند و عبارت ارزیابی توابع می‌باشند. مقادیر بازگشتی مقادیری از عبارت قبلی که ارزیابی شده‌اند هستند.
عبارت (Lambda(arg)(+arg1)) زمانی که این تابع به کار برده می‌شود به صورت یک تابع ارزیابی می‌شود و وظیفهٔ این تابع معرفی کردن یک آرگومان و اتصال دادن آرگومان به arg و در نهایت برگرداندن یک عدد بزرگتر از آرگومان قبلی می‌باشد عبارت‌های لاندا خیلی متفاوت با نام تابع رفتار نمی‌کند بنابراین اگر در عبارت (Lambda(arg)(+arg1))5->6 عدد 5 را وارد کنیم خروجی آن 6 می‌شود. اتم‌ها : در نسخهٔ اصلی لیسپ دو نوع دادهٔ ابتدایی وجود دارد: اتم‌ها و لیست‌ها یک لیست یک رشتهٔ منظم و محدودی از عناصر می‌باشد ، که هر عنصر در درون خودش یکی از این اتم‌ها و یا لیست‌ها را دارد و یک اتم یک عدد یا یک نماد می‌باشد.
در اصل یک نماد یک رقم منحصر به فرد می‌باشدو به عنوان یک رشتهٔ عددی در سورس کد نوشته شده و هر دو به عنوان یک نام متغیر و یک رقم داده‌ای در پردازش نمادین استفاده می‌شود برای مثال list(foo(BAR 1)2) شامل سه عنصر : Symbol foo و list(BAR 1) و عدد 2 می‌باشد. تفاوت اصلی بین اتم‌ها و لیست‌ها این است که اتم‌ها تغییر ناپذیر و منحصر به فرد می‌باشند. دو اتم که دقیقا به یک صورت و به یک روش در یک شی نوشته شده باشد در مکان متفاوتی در سورس کد ظاهر می‌شوند، هر لیست یک شی مجزا می‌باشد و به خاطر اینکه مستقل از دیگر لیست هاست و از دیگر لیست‌ها به وسیلهٔ مقایسهٔ عملگرها مشخص می‌شود.

Cons‌ها و لیست‌ها:
یک لیست لیسپ یک لینک لیست جداست، هر ذره از این لیست یک Cons نامیده می‌شود و از دو اشاره گر که Car و Cdr نامیده می‌شوند ترکیب شده‌است این دو اشاره گر به ترتیب معادل دو فیلد Data و Next در مقالهٔ لینک لیست می‌باشد.
Car -> Data Cdr -> Next

بسیاری از ساختمان داده‌ها می‌توانند ترکیب‌هایی از خانه‌های Cons را داشت باشند ، یکی از این ساختمان داده‌های ابتدایی لیست مخصوص نامیده می‌شود ، یک لیست مخصوص هر دو نماد لیست خالی nill و یا خانه‌ها Cons را داراستکه در هر یک از این خانه‌ها هر اشاره گر Car به یک داده اشاره می‌کند (که ممکن است این اشاره گر Cons به یک لیست اشاره کند) و یک اشاره گر Cdr به یک لیست مخصوص دیگر اشاره می‌کند. اگر یک Cons داده به سر یک لینک لیست برده شود سپس اشاره گر Car آن به اولین عنصر از لیست و اشاره گر Cdr آن به انتهای یک لیست اشاره می‌کند به همین دلیل عملکرد Car و Cdr را به ترتیب first و rest هم نامیده می‌شود.
ارایهٔ لیست عبارت نمادین:
نمایش پرانتزگذلری عبارت نمادین ساختمان لینک لیست . چندین راه برای نمایش لیست یکسان به عنوان یک عبارت نمادین وجود دارد . یک خانه (Cons ) می‌تواند به صورت نشان گذاری جفت نقطه گذاری شده نوشته شود به عنوان مثال (a.b) که در آن a یک Car و b یک Cdr است. یک لیست مخصوص بلند ممکن است به صورت یک نشان گذاری جفت نقطه گذاری شده نوشته شود .(a.(b.(c.(d.nill))))

طبق قرارداد کوتاه شدهٔ عبارت بالا به صورت (a b c d ) در نمادسازی لیست می‌باشد یک لیست مخصوص ممکن است در یک ترکیبی از دو صورت (a b c.d) نوشته شود . برای سیستمی از سه Cons که آخرین Cdr آن d است.

دستورالعمل‌های پردازش لیست:
لیسپ دستورالعمل‌های زیادی را برای دستیابی و کنترل لیست‌ها فراهم می‌کند . لیست‌ها می‌توانند مستقیما با پردازهٔ لیست ایجاد شوند .لیست هر تعدادی از آرگومان‌ها را می‌پذیرد و تعدادی از آرگومان‌ها را بر می‌گرداند.

(list 1 2 ‘a 3 ); Output : (1 2 a 3 ) (list 1 ‘(2 3) 4 ); Output : (1 (2 3) 4)

به این دلیل راهی که لیست‌ها ایجادمی شوند از جفت‌های Cons (Car,Cdr) پردازهٔ Cons می‌تواند برای اضافه کردن یک عنصر به جلوی یک لیست استفاده شود. توجه کنید که پردازهٔ Cons در هدایت و به کار بردن آرگومان‌های لیست نامتقارن است ، بدین دلیل روش‌های لیست‌ها ایجاد می‌شوند.

(Cons 1 ‘(2 3)); Output: (1 2 3 ) (Cons ’(1 2) ‘(3 4)) Output : ((1 2) 3 4)

پردازهٔ Oppend دو یا چند لیست را با هم ادغام می‌کند و یک لیست واحد ایجاد می‌کند زیرا لیست لیسپ یک لینک لیست است و پیچیدگی زمانی الحاق کردن لیست‌ها از مرتبهٔ پیچیدگی زمانی O(n) می‌باشد.
ساختار اشتراکی: لیست‌های لیسپ لینک لیست‌های ساده می‌توانند با یکی دیگر از لیست‌ها در ساختمان مشترک باشند به عبارت دیگر دو لیست می‌توانند دم یکسانی داشته باشندیا رشتهٔ پایانی از Cons‌های یکسانی داشته باشند مثلا:

(setf foo (list 'a 'b 'c)) (setf bar (cons 'x (cdr foo)))

لیست foo و bar به ترتیب به صورت (a b c) و (X b c ) هستند هرچند دم (b c ) در هر دو لیست ساختار یکسانی دارند ولی مانند هم نیستند، خانه‌های Cons اشاره گر به b و c در محل حافظهٔ یکسانی برای هردو لیست قرار دارد.
ساختار اشتراکی سریع تر از کپی کردن می‌تواند به صورت چشمگیری کارایی را بهبود بخشند. هرچند ، این مهارت می‌تواند متقابلا در راه‌های نامطلوب با عملکردهایی که تغییرات لیست‌های گذشته روی آرگومان‌های آن تاثیر بگذارد ، اثر کند.
تغییرات یک لیست از قبیل تغییر دادن C با یک goose روی دیگری نیز تاثیر می‌گذارد setf (third foo) 'goose) که این تغییر نتیجه را به صورت (a b goose) تغییر می‌دهد اما bar هم تغییر می‌کند (X b goose) که ممکن است یک نتیجهٔ غیر منتظره باشد.
زبان‌های برنامه نویسی Lisp معمولا از یک خط دستور محاوره‌ای استفاده می‌کنند،که می‌تواند با یک محیط پیچیدهٔ گسترش یافته ترکیب شود.کاربر اصطلاحات و دستورات را در خط دستور وارد کرده یا با رهبری IDE آنها را به سیستم Lisp می‌فرستد. Lisp دستورات را می‌خواند ، آن‌ها را ارزیابی می‌کند و نتایج را چاپ می‌کند. به این دلیل است که خط دستور زبان Lisp به حلقهٔ Read-Eval-Print یا REPL معروف است.
نمونهٔ ساده‌ای از عملیات REPL در زیر آمده‌است. این یک شرح ساده‌است که بسیاری از المان‌های Lispواقعی در آن نمی‌آید مانند ماکروها و کوئت‌ها.
تابع read جملات متنی را به عنوان ورودی می‌پذیرد و آنها را به ساختار لیست تجزیه می‌کند. به عنوان مثال ، وقتی شما رشتهٔ (+ 1 2) را در اعلان تایپ می‌کنید، تابع read آن را به یک لیست پیوندی حاصل از 3 المان ترجمه می‌کند: علامت + ، عدد 1 و عدد 2 . خیلی اتفاق می‌افتد که لیست قسمت موثری از یک کد Lisp باشد که قابل ارزیابی است.به همین دلیل است که یک قطار از لیست به یک تابع نام عملگر مع می‌دهد.
تابع eval ساختار لیست را ارزیابی می‌کند و نوعی دیگر از ساختار را به عنوان نتیجه باز می‌گرداند.ارزیابی کردن لزوما تفسیر کردن معنی نمی‌دهد؛ بعضی سیستم‌های Lisp هر عبارتی را به زبان ماشین تبدیل می‌کنند. خیلی ساده است؛ به هر حال؛ برای تعریف ارزیابی به عنوان تفسیر : برای ارزیابی یک لیست که نام تابع دارد ، eval ابتدا تمام آرگومان‌های داده شده به cdr اش را ارزیابی می‌کند و سپس تابع را روی آن آرگومان‌ها اعمال می‌کند.در این مثال ، تابع عمل جمع است و به آرگومان‌های (1 2) اعمال می‌شود که نتیجه 3 است.این نتیجهٔ ارزیابی است.
این وظیفهٔ تابع print است که نتیجه را به کاربر نمایش دهد. برای نتیجهٔ سادهٔ 3 این کار ناقابل است. یک عبارت که با قسمتی از ساختار لیست ارزیابی می‌شود میاز دارد که print لیست را به حرکت در آورد و در خروجی به شکل یک عبارت S نمایش دهد.
برای اجرا کردن یک REPL در Lisp ، تنها لازم است که این سه تابع را اجرا کنید و یک تابع حلقه بی نهایت را.(به طور طبیعی اجرای eval پس از اجرای عملگرهای ویژه‌ای مانند if پیچیده خواهد شد.)یک REPL ساده به خودی خود با یک خط کد انجام شد: (loop(print(eval(red))))

لیست در اصل تعداد کمی ساختار کنترلی دارد. منتها در تکامل و گسترش زبان تعداد زیادی به آن اضافه شدند.(عملگر اصلی شرایط در زبان Lisp که cond بود بعدا متشکل شد از ساختار if-then-else )

برنامه نویسان در نسخهٔ Scheme حلقه‌ها را به صورت بازگشت دم( tail recursion ) بیان می‌کنند. موسسات متعارف علوم کامپیوتر Scheme بعضی دانشجویان را متعاقد می‌کند که تنها راه تکرار در زبان Lisp استفاده از بازگشت دم است؛ این اشتباه است. تمامی نسخه‌های متداول دیده شده از Lisp دارای ساختارهای الزامی برای تکرار هستند.درScheme دستور do به عنوان دستور حلقه پیچیدهٔ Lisp است. علاوه بر این مسالهٔ اصلی که شی گرایی را مهمتر از مسالهٔ فاعلی کرده این است که Scheme نیازهای ویژه‌ای برای کارکردن با فراخوانی دم(tail calls )دارد، در نتیجه دلیل ترغیب Scheme به استفاده از بازگشت دم این است که روش صراحتا با تعریف خود زبان پشتیبانی می‌شود . در مقابل ، ANSI Common Lisp نیازی به بهینه سازی که معمولا به حذف فراخوانی دم گفته می‌شود ندارد. در نتیجه این حقیقت که بازگشت دم به عنوان یک جایگزین تصادفی برای استفاده از ساختارهای مبتنی بر تکرار ( مانند do dolist loop ) توصیه نمی‌شود تنها یک مسالهٔ برتری ادبی نیست ، ولی بالقوه یکی از کارآمدهاست ( بعد از این که این روش فقط به عنوان یک پرش ساده به کار نرفت) و به عنوان یک تصحیح برنامه‌است .
بعضی از ساختارهای کنترلی Lisp عملگرهای ویژه‌ای هستند ، هم ارز کلیدواژه‌های ترکیبی باقی زبان‌ها. عباراتی که این عملگرها استفاده می‌کنند ظاهری شبیه فراخوانی تابع دارد، تفاوت اینجاست که آرگومان‌ها ضرورتا نباید ارزیابی شوند یا در مورد تکرار شاید بارها ارزیابی شوند. در مقابل اکثر زبان‌های برنامه نویسی ، Lisp به برنامه نویسان اجازه می‌دهد با خود زبان ساختاهای کنترلی را پیاده سازی کنند.ساختارهای کنترلی زیادی در ماکروهای Lisp پیاده سازی می‌شوند و برنامه نویسان می‌توانند هر ماکرو را گسترش دهند ،برای آنانی که می‌خواهند بدانند چطور کار می‌کند.
هر دوی Lisp Commonو Scheme دارای عملگرهای کنترلی غیر محلی هستند.تفاوت این عملگرها یکی از عمیق ترین تفاوت‌ها مابین این دو نسخهٔ زبان است. Scheme از ورودی مستمر با استفاده از روش call/cc پشتیبانی می‌کند ، که به برنامه اجازهٔ ذخیره ( و بعدا بازیابی کردن) یک عملیات ویژه را می‌دهد . Common Lisp از ورودی مستمر پشتیبانی نمی‌کند ولی از راه‌های زیادی برای انجام رهایی از تکرار پشتیبانی می‌کند.

زمانی که به پایان رسیدی بدان شروعی دوباره در کام تولد است.Wink
۱۶-آبان-۱۳۸۸, ۱۶:۵۱:۵۵
ارسال‌ها
پاسخ
تشکر شده توسط : t3r!p3000, Robocup, lord_viper, HoseinVig, salehjg, The.Ghost, godvb
اشک آفلاین
كاربر دو ستاره
**

ارسال‌ها: 108
موضوع‌ها: 14
تاریخ عضویت: آبان ۱۳۸۸

تشکرها : 758
( 532 تشکر در 136 ارسال )
ارسال: #5
RE: هوش مصنوعی
درمورد پرولوگ about prolog/

1. تاریخچه همان طور که گفته شد در پیدایش این زبان کلمرار در مارسی فرانسه بوده است(1972). و اولین سیستم مورد استفاده قرار گرفته شده توسط آلن فیلیپ راسل پیاده سازی شده است و بعدا توسط رابرت کوالسکی ارتقا یافته است. اما زمزمه‌های ایجاد یک زبان منطق گرا از دهه 70 میلادی از شمال امریکا شکل گرفته است. بعدا در نسل پنجم کامپیوترها از پرلوگ برای نوشتن کرنل سیستم عامل نیز در ایجاد پروژه سیستم FGCS استفاده شده است. 2. انواع داده ها نوع داده در پرلوگ به صورت ترم ها تعریف می‌شود که این ترم ها می‌توانند اتم ،اعداد ،متغیرها و یا ترکیبی از ترم های دیگر باشند. اتم ها به طور کلی هیچ معنای ذاتی ندارند و یک سری رشته از حروف یا ... هستند که خواننده پرلوگ آنها را تجزیه کرده است. اتم کلمات آشکار در کد می‌باشند که هیچ نحو خاصی برای آنها در نظر گرفته نشده است مثل : x, blue,some,atom اعداد که می‌توانند به صورت اعداد شناور و یا صحیح باشند و حتی اعدا گویا متغیر که یک رشتهٔ متشکل از حروف است که می‌تواند نشان دهندهٔ یک واژه باشند و ارزش آنها با توجه به پرلوگ مقداردهی داده می‌شود. یک واژه مرکب (عمل کننده یا functor) ترکیبی از اتم ها است که به صورت یک متغیر با آن رفتار می کنیم و نیز مجموعه‌ای از استدلال هاست که یک نتیجه نهایی درست یا غلط را دربرمی گیرد. .واژه‌های مرکب در یک پرانتز تعریف می‌شوند و به انها عبارت های مرکب نیز اطلاق می‌شود. مثل

truck_year('Mazda', 1986) 'Person_Friends'(zelda,[tom,jim])
لیست ها که یک حالت خاص عبارت ها ترکیبی هستند و ساختمان داده ایی پیشرفته برای نگهداشت استدلال ها و منطق هاست و به طور کلی لیستی از اتم ها هستندو بوسیله پرانتز، نقطه و کاما نشان داده می‌شود. رشته‌ها که مجموعه ایی از کارکترها هستند برای نگهداری یونیکدها و نام های شخصیت های محلی.


3. برنامه نویسی در Prolog برنامه پرلوگ مجموعه‌ای از روابط است که توسط بندهای خاص تعریف شده اند . این بندها محدود به بند های horn و تورینگ است که زیر مجموعه کاملی از منطق منظور اول است (first-order predicate logic) . بندها به دو دستهٔ قوانین و حقیقت ها تقسیم می‌شوند . یک مثال از قانون: Head :- Body. سر : -- بدن است. سر یک عضوی از بدن است . و بعد با پرس و جو های انجام شده با توجه به قوانین موجود و حقایق اولیه نتایج ثانویه که حقایق جدیدی هستند شکل می‌گیرد. پرس و جو ها می‌توانند براساس لیست های پیوندی نیز باشد و طبق قوانین از پیش تعیین شده نتایجی را در اختیار کاربر گذاشت . مثل اندازه لیست . عنصر آخر لیست و ... . بهمین خاطر مجموعه‌ای از کتابخانه‌های این زبان شکل گرفته است و در راستای آن هم دستوراتی برای چاپ داده‌ها و امثال آن شکل گرفته است . 4. بررسی بررسی ابتدا با یک پرس و جو شروع می‌شود و با توجه به حقایق موجود که درست یا غلط است نتیجه منتقل می‌شود. اساس کار بدین گونه است که به‌دنبال اولین غلط و یا تکذیب مساله می‌یابد و با توجه به نوع مساله در صورت نیافتن آن همین روال را برای دیگر داده‌ها نیز انجام می‌دهد و در صورت حصول نتیجه حقیقت داده‌های قبلی بصورت بازگشتی معلوم می‌گردد. با این استراتژی که Backtracking نیز گفته می‌شود اساس یافت جواب در زبان پرلوگ اطلاق می‌شود. به طور مثال:

mother_child(trude, sally).

father_child(tom, sally). father_child(tom, erica). father_child(mike, tom).

sibling(X, Y) :- parent_child(Z, X), parent_child(Z, Y).

parent_child(X, Y) :- father_child(X, Y). parent_child(X, Y) :- mother_child(X, Y).

و سوال پرسیده شده در دنباله آن

?- sibling(sally, erica).

Yes

طبق قانون وقتی دونفر خواهر و برادرند که والدین آنها یکی باشد پس زبان به دنبال والدین می‌گردد و آنها را بر می گرداند و جواب را به جای گزاره‌های مذکور می گذارد و طبق قانون اگر دو گزاره یکی باشند درست برمی گرداند. پس روش کلی روشی بازگشتی اثبات بندهاست و جایگزینی نتایج آنها. 5. حلقه‌ها و بازگشت الگوریتمهای Iterative (پشت سرهمی) می‌توانید بوسیله predicates بازگشتی به اجرا درآیند. سیستم های Prolog معمولا به روش بهینه سازی معروفی به نام تماس دم (tco) پایبندند که ملتزم به بازگشت قطعی است و حتما در این روش بهینه سازی می بایست به دم برسد. بهمین خاطر در روش بازگشتی از یک پشته با یک نوع محدودیت بهره می‌گیرد و بدین وسیله می‌تواند حلقه‌های متعدد و بازگشتی را با اطمینان به بازگشت به جواب را جوابگو باشد.

6. خنثی سازی

ایجاد یک مسند نفی و شکست باعث خنثی کردن یک استدلال می‌شود. حالت دیگری نیز در بر دارد بدینگونه که برای اثبات یک استدلال دنباله بازگشتی آنرا تا رسیدن به یک دم و یا انتها می‌رود و در صورتی که نتواند حقیقتی برای آن پیدا کند در حقیقت نتوانسته آنرا اثبات کند اما شاید هم حقیقتی مربوط به نفی آن پیدا شود که در صورت آنرا نفی می‌کند.

7. ملاحظات عملیاتی

یکسری قوانینی تعبیه شده است که در آن کاربر با استفاده از آن می‌تواند از ایجاد لوپ های تودرتو جلوگیری کند. و البته با نظم دادن به دستورات می‌توان از ایجاد آنها جلوگیری کرد به طور مثال:

predicate1(X) :-

predicate2(X,X).
predicate2(X,Y) :-

predicate1(X),
X \= Y.
برای پرسش

?- predicate1(atom).

ایجاد یک حلقه بی نهایت توسط کاربر می‌کند ولی اگر دستورات را اینگونه نظم دهیم چنین اتفاقی نمی افتد

predicate2(X,Y) :-

X \= Y,
predicate1(X).
8. DCGs و تجزیه

یک نماد ویژه‌ای به نام گرامرهای بند قطعی (DCGs) وجود دارد . یک قاعده تعریف شده به عنوان --> به جای -: که با استفاده از آن می‌توان به تجزیه کردن و ایجاد یک رابط مناسب برای یک لیست بکار گرفت. در زیر یک مثال از این مورد را می بینید:

<sentence> ::= <stat_part> <stat_part> ::= <statement> | <stat_part> <statement> <statement> ::= <id> = <expression> ; <expression> ::= <operand> | <expression> <operator> <operand> <operand> ::= <id> | <digit> <id> ::= a | b <digit> ::= 0..9 <operator> ::= + | - | * و با استفاده از DCG sentence(S) --> statement(S0), sentence_r(S0, S). sentence_r(S, S) --> []. sentence_r(S0, seq(S0, S)) --> statement(S1), sentence_r(S1, S).

statement(assign(Id,E)) --> id(Id), [=], expression(E), [;].

expression(E) --> term(T), expression_r(T, E). expression_r(E, E) --> []. expression_r(E0, E) --> [+], term(T), expression_r(plus(E0,T), E). expression_r(E0, E) --> [-], term(T), expression_r(minus(E0, T), E).

term(T) --> factor(F), term_r(F, T). term_r(T, T) --> []. term_r(T0, T) --> [*], factor(F), term_r(times(T0, F), T).

factor(id(ID)) --> id(ID). factor(digit(D)) --> [D], { (number(D) ; var(D)), between(0, 9, D)}.

id(a) --> [a]. id(b) --> [b]. همان طور که می بینید علاوه بر مزیت های گفته شده موجب بزرگتر شدن کد نیز می‌شود.

9. برنامه نویسی سفارشی

یکی دیگر امکاناتی که در پرلوگ با توجه به ماهیت آن بوجود آمده است برنامه نویسی سفارشی است . با توجه به روند BachTracking و روش بهینه سازی بازگشت قطعی می‌توانیم حالاتی را ایجاد کنیم که از آن طریق برنامه به طور خودکار و تنها با داشتن یک قاعده ساده به دنبال جواب در یک لیست پیوندی بگردد. به طور مثال شمارش اعداد و پیدا کردن اعداد اول. perfect(N) :-

between(1, inf, N), U is N // 2,
findall(D, (between(1,U,D), N mod D =:= 0), Ds),
sumlist(Ds, N).
10. متا - مترجم و انعکاس

یک زبان homoiconic فراهم شده است و بسیاری از امکانات را برای انعکاس را در اختیار ما می گذارد.. این زبان امکان نوشتن meta-circular evaluator را نیز فراهم می سازد که اغلب از آن به عنوان متا- مترجم یاد می‌شود. بدلیل آنکه برنامه‌های به زبان پرلوگ دنباله‌ای از اصطلاحات خود این زبان است بهمین دلیل خواندن آن راحت و مکانیزم ساده ایی جهت ترجمه را خواستار است.

11. روش های پیاده سازی

برای بهره وری از کد Prolog معمولا به صورت کد ماشین انتزاعی ترجمه می‌شود و اغلب تحت تاثیر مجموعه دستورات ثبت نامی براساس ماشین انتراعی وارن (Warren Abstract Machine (WAM)) است.برای پیاده سازی انتزاعی متناسب به نوع اصطلاحات و اطلاعات در زمان کامپایل است. برای ترجمه بهتر و نزدیک تر بودن به زبان ماشین واقعی برای عملکرد بهتر نیاز به تحقیقات مبتنی بر جامعه منطقی برنامه ریزی شده است که دو کار اساسی براساس قواعد منطقی انجام می‌دهد یک باینری کردن عبارات و بند ها و دیگری فراهم کردن پشته مبتنی بر ماشین مجازی.در نسل پنجم سعی شده است ماشین ها و سیستم های مبتنی بر پرلوگ نیاز های سخت افزاری این نوع برنامه سازی منطقی را نیز فراهم سازند تا سرعت اجرای آن هزاران برابر شود. بعلاوه این پرلوگ این توانایی را نیز دارد که با پردازش موازی بندها سرعت را بهبود بخشد.

12. مثال ها

در اینجا مثال هایی از برنامه ساخته شده به زبان پرلوگ را می بینیم.

12.1 . الگوریتم مرتب سازی سریع ((QuickSort

partition([], _, [], []). partition([X|Xs], Pivot, Smalls, Bigs) :-

( X @< Pivot ->
Smalls = [X|Rest],
partition(Xs, Pivot, Rest, Bigs)
; Bigs = [X|Rest],
partition(Xs, Pivot, Smalls, Rest)
).
quicksort([]) --> []. quicksort([X|Xs]) -->

{ partition(Xs, X, Smaller, Bigger) },
quicksort(Smaller), [X], quicksort(Bigger).
12.2 . ماشین تورینگ turing(Tape0, Tape) :-

perform(q0, [], Ls, Tape0, Rs),
reverse(Ls, Ls1),
append(Ls1, Rs, Tape).
perform(qf, Ls, Ls, Rs, Rs) :- !. perform(Q0, Ls0, Ls, Rs0, Rs) :-

symbol(Rs0, Sym, RsRest),
once(rule(Q0, Sym, Q1, NewSym, Action)),
action(Action, Ls0, Ls1, [NewSym|RsRest], Rs1),
perform(Q1, Ls1, Ls, Rs1, Rs).
symbol([], b, []). symbol([Sym|Rs], Sym, Rs).

action(left, Ls0, Ls, Rs0, Rs) :- left(Ls0, Ls, Rs0, Rs). action(stay, Ls, Ls, Rs, Rs). action(right, Ls0, [Sym|Ls0], [Sym|Rs], Rs).

left([], [], Rs0, [b|Rs0]). left([L|Ls], Ls, Rs, [L|Rs]). مثالی ساده از برنامه پیاده سازی ماشین تورینگ rule(q0, 1, q0, 1, right). rule(q0, b, qf, 1, stay).

?- turing([1,1,1], Ts). Ts = [1, 1, 1, 1] ;

12.3 . برنامه نویسی پویا

برنامه Prolog زیر استفاده می‌کند برنامه نویسی پویا برای یافتن توالی مشترک طولانی از دو فهرست در زمان چند جملهای: پایگاه داده بند برای memoization استفاده شده است :

- dynamic(stored/1).
memo(Goal) :- ( stored(Goal) -> true ; Goal, assertz(stored(Goal)) ).

lcs([], _, []) :- !. lcs(_, [], []) :- !. lcs([X|Xs], [X|Ys], [X|Ls]) :- !, memo(lcs(Xs, Ys, Ls)). lcs([X|Xs], [Y|Ys], Ls) :-

memo(lcs([X|Xs], Ys, Ls1)), memo(lcs(Xs, [Y|Ys], Ls2)),
length(Ls1, L1), length(Ls2, L2),
( L1 >= L2 -> Ls = Ls1 ; Ls = Ls2 ).
مثال پرس و جو ?- lcs([x,m,j,y,a,u,z], [m,z,j,a,w,x,u], Ls). Ls = [m, j, a, u]

13. ضمیمه ها

درحال حاضرتلاش در راستای توسعه این زبان برای گسترش قابلیت های برنامه سازی در جهات مختلف می‌باشند که این قابلیت ها عبارتند از محدودیت های برنامه نویسی منطقی (CLP)(بیشتر در تنظیمات صنعتی مانند جدول های زمان بندی) ، برنامه نویسی شی گرای منطقی (OOLP) ، همزمانی ، منطق خطی و قابلیت همکاری با پایگاه‌های دانش. بدین منظور نسخه‌هایی همچون نمونه‌های زیر تهیه شده است: HiLog و λProlog تمدید Prolog با بالاتربردن ویژگی های برنامه نویسی سفارشی. اف منطق گسترش Prolog با قاب / اشیاء را برای نمایش دانش. OW Prolog ایجاد شده است به منظور پاسخ به عدم Prolog است از گرافیک و رابط. Logtalk یک شیء گرا منطق زبان برنامه نویسی است (بهمراه ایجاد خاصیت چندریختی و وراثت و همچنین چند نخی و همزمانی) Prolog - MPI یک منبع باز SWI - Prolog می‌باشد که برای محاسبات توزیع شده از طریق واسط پیام رسان اینکار را انجام می‌دهد. Oblog کوچک ، قابل حمل ، شیء گرا را به فرمت - Prolog توسط McDougall مارگارت از EdCAAD ، دانشگاه ادینبورگ است.


14. زبان های مرتبط

Datalog که در واقع یک زیر مجموعه از Prolog است و شرایط ترکیب را بخوبی اجازه نمی‌دهد و در مقابل به Prolog ، Datalog تورینگ نشده است. ویژوال پرلوگ که بیشتر به عنوان PDC prolog شناخته می‌شود و شی گرا می‌باشد و با ایجاد محیطی شی گرا فهم را در هنگام کدزنی بالا می‌برد. InterProlog که یک کتابخانه برنامه نویسی شده بین جاوا و پرلوگ است. JPL که پلی بین جاوا و پرلوگ است. Prova یک زبان اسکریپ نویسی بر اساس پرلوگ است .

15. Prolog Gnu چیست؟

gnu Prolog (همچنین به نام gprolog) یک کامپایلرکد باز توسط دانیل دیاز با یک اشکال زدایی محیط تعاملی برای Prolog در دسترس در یونیکس و ویندوزمی باشد. همچنین پشتیبانی از برخی از الحاقات را به Prolog از جمله محدودیت های برنامه نویسی بیش از یک دامنه محدود ، با استفاده از تجزیه grammars بند تصریح شده ، و یک سیستم عامل و رابط را داراست. کامپایلر تبدیل کد منبع را تبدیل به بایت کد می‌کند که می‌تواند توسط یک دستگاه مترجم و یا مفسر وارون انتزاعی آن را به کد اجرایی رایج تبدیل کند.

زمانی که به پایان رسیدی بدان شروعی دوباره در کام تولد است.Wink
۱۷-آبان-۱۳۸۸, ۰۱:۴۷:۲۱
ارسال‌ها
پاسخ
تشکر شده توسط : t3r!p3000, lord_viper, salehjg, The.Ghost
اشک آفلاین
كاربر دو ستاره
**

ارسال‌ها: 108
موضوع‌ها: 14
تاریخ عضویت: آبان ۱۳۸۸

تشکرها : 758
( 532 تشکر در 136 ارسال )
ارسال: #6
RE: هوش مصنوعی
می تونید جزوه ی آموزشی پرولوگ رو از این لینک دانلود کنید.

http://www.behzad-k.blogfa.com

زمانی که به پایان رسیدی بدان شروعی دوباره در کام تولد است.Wink
۱۷-آبان-۱۳۸۸, ۱۴:۲۴:۱۸
ارسال‌ها
پاسخ
تشکر شده توسط : t3r!p3000, HoseinVig, salehjg, The.Ghost
mmasood آفلاین
تازه وارد

ارسال‌ها: 2
موضوع‌ها: 0
تاریخ عضویت: اسفند ۱۳۸۸

تشکرها : 0
( 4 تشکر در 1 ارسال )
ارسال: #7
RE: هوش مصنوعی
واقعا جالب و زیبا بود .
لطفا کمی بیشتر در این رابطه توضیح دهید.
ممنون میشم.
۱۰-اسفند-۱۳۸۸, ۲۲:۱۹:۱۶
ارسال‌ها
پاسخ
تشکر شده توسط : اشک, HoseinVig, salehjg, The.Ghost
اشک آفلاین
كاربر دو ستاره
**

ارسال‌ها: 108
موضوع‌ها: 14
تاریخ عضویت: آبان ۱۳۸۸

تشکرها : 758
( 532 تشکر در 136 ارسال )
ارسال: #8
RE: هوش مصنوعی
درمورد کدوم قسمت توضیح می خواید؟این مبحث،خیلی گستردست.

زمانی که به پایان رسیدی بدان شروعی دوباره در کام تولد است.Wink
۱۰-اسفند-۱۳۸۸, ۲۲:۳۸:۱۸
ارسال‌ها
پاسخ
تشکر شده توسط : t3r!p3000, HoseinVig, The.Ghost
اشک آفلاین
كاربر دو ستاره
**

ارسال‌ها: 108
موضوع‌ها: 14
تاریخ عضویت: آبان ۱۳۸۸

تشکرها : 758
( 532 تشکر در 136 ارسال )
ارسال: #9
RE: هوش مصنوعی
عناوين متن

زبانهاي برنامه‌نويسي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 بنا نهاده شده است.

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
isp اولين زبان برنامه نويسي تابعي است: آن براي پشتيباني محاسبات نمادين با استفاده از ليستهاي پيوندي بعنوان ساختار مركزي داده ها ابداع شده بود ( 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 توابع مي‌توانند بعنوان آرگومان استفاده شود تابعي كه بتواند توابع را بعنوان آرگومانهايش بپذيرد تابع مرتبه بالا ناميده مي‌شود. مشكلات فراواني وجود دارند كه يكي پيمايش يك ليست(يا يك درخت يا يك گراف) است كه بايد براي هر ليست عنصر تابع معيني استفاده شود. براي مثالfliter تابعي است كه تستي براي عناصر ليست به‌كار مي‌برد و آنهايي كه شكست مي‌خورند را حذف مي‌كند. نگاشتها توابعي هستند كه همان تابع را روي هر عنصر ليست به كار مي‌برند تا ليستي از نتايج را برگردانند. تعاربف توابع مرتبه بالا مي‌تواند براي تعريف توابع عمومي پيمايش ليست استفاده شود كه آنها از توابع خاصي كه براي پردازش عناصر ليست بكار مي‌روند خلاصه مي‌شوند (چكيده مي‌شوند). به منظور پشتيباني تعاريف مرتبه بالا يك تابع خاص است كه يك تابع و دنباله‌اي از آرگومانها را به عنوان آرگومان مي‌پذيرد و آن تابع را در آرگومانهاي آنها به كار مي‌برد. بعنوان مثال با استفاده ازfuncall، تابع عموميfliter را تعريف خواهيم كرد كه مي‌تواند به اين صورت فراخواني شود:
(fliter ’(1 3 -9 -5 6 -3) #’plusp) ==>(1 3 6)
plusp يك تابع پيش ساخته است كه كنترل مي‌كند آيا يك عدد داده شده مثبت است يا نه؟ اگر باشد آن عدد را بر‌مي‌گرداند در غير اين صورتnil بر‌مي‌گرداند نماد خاص# بكار مي‌رود تا به مفسرLisp بگويد كه مقدار آرگومان يك شي تابعي است . تعريف به صورت زير است:

(defun fliter (list test)

(cond ((null list) list)

((funcall test (car list))

(cons (car list) (fliter (cdr list) test)))

(T (fliter (cdr list) test))))

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


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

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


به عنوان مثال ديگري از تعريفfliter تابع مرتبه بالا، مامي‌خواهيم يك تابع نگاشت ساده تعريف كنيم كه يك تابع روي همه عناصر يك ليست بكاررفته، ليستي از همه مقادير بر‌مي‌گرداند. اگر تابع 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:xs) = 1 + length xs


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

IV.ساير روشهاي برنامه‌نويسي
در اين مقاله قبلاً زبانهاي AI را با روشهاي برنامه‌نويسي دستوري مقايسه كرديم. زبانهاي شيء گرا به الگوي برنامه‌نويسي مشهور ديگري تعلق دارند. در اين جور زبانها اولين وسيله براي تعيين مسئله‌ها، تعيين خلاصه ساختارهاي داده است كه كلاس‌ها، اشياء‌نام دارند. يك كلاس شامل يك ساختار

زمانی که به پایان رسیدی بدان شروعی دوباره در کام تولد است.Wink
(آخرین ویرایش در این ارسال: ۲۴-شهریور-۱۳۸۹, ۰۱:۳۰:۰۶، توسط اشک.)
۲۴-شهریور-۱۳۸۹, ۰۱:۲۵:۴۶
ارسال‌ها
پاسخ
تشکر شده توسط : lord_viper, salehjg, iris, The.Ghost, godvb
eyar آفلاین
تازه وارد

ارسال‌ها: 3
موضوع‌ها: 0
تاریخ عضویت: دى ۱۳۸۸

تشکرها : 0
( 0 تشکر در 0 ارسال )
ارسال: #10
RE: هوش مصنوعی
باسلام لطفا كمك كنيد.
كسي مدل آماده مثال زير را دارد؟؟
ماشین تورینگ در مدل DFA
برنامه ای بنویسید که ماشین اسلاید پیش را طراحی کند که رشته هایی را می پذیرد که نمایش دودویی آنها بر 5 بخش پذیر است
1-اگر داده ی ورودی به ماشین در مبناع دودویی نباشد پیغام زیر را چک کند

the give number is not bainery sistem
2-اگر رشته باینری داده شده به ماشین بر 5 بخش پذیر نباشد قسمت ارایه مسیرهای طی شده عدم بخش پذیری عدد داده شده بر 5 را اعلام کند.
3-اگر عدد باینری داده شده بر 5 بخش پذیر باشد ضمن ارایه مسیر طی شده بخش پذیر عدد داده شده بر 5 را نیز اعلام کند.
۰۳-دى-۱۳۹۰, ۲۲:۲۵:۳۱
ارسال‌ها
پاسخ
b.jafari آفلاین
تازه وارد

ارسال‌ها: 2
موضوع‌ها: 0
تاریخ عضویت: اردیبهشت ۱۳۹۱

تشکرها : 0
( 0 تشکر در 0 ارسال )
ارسال: #11
RE: هوش مصنوعی
سلام میتونید تو شبیه سازی مدیریت یه چهارراه بهم کمک کنید باید تا آخر امتحانا ارائه بدم
۳۰-اردیبهشت-۱۳۹۱, ۱۱:۵۱:۰۲
ارسال‌ها
پاسخ


پرش به انجمن:


کاربرانِ درحال بازدید از این موضوع: 1 مهمان

صفحه‌ی تماس | IranVig | بازگشت به بالا | | بایگانی | پیوند سایتی RSS