این Goal سعی می کند ، ماشینی را که توصیف شده است ،در Clauses بیابد.یعنی ماشینهایی را که دقیقا قیمت آنها 25000 دلار است.
جوابی که باز گردانده خواهد شد بصورت زیر است:
کد:
البته شاید ما فقط چنین جوابی را نخواهیم ،بلکه بخواهیم لیست کلیه ماشینهایی را که قیمتشان کمتر از 25000 دلار است را نشان بده که در اینصورت باید کد goal مورد نظر بصورت زیر باشد.
کد:
car(Make, Odometer, Years_on_road, Body, Cost),/*subgoal A and*/
Cost < 25000. /*subgoal B */
در واقع ما می دانیم که فقط از طریق عملگر و منطقی می توان به چنین نتیجه ای رسید.
برای حل این مثال ابتدا باید Subgoal اولی به جواب برسد
کد:
car(Make, Odometer, Years_on_road, Body, Cost).
و بعد از آن Subgoal دومی باید مقدار صحیحی ره به ما ارائه دهد.
Cost < 25000.
زبان طبیعی که در واقع سوال مورد نظر ما ست بصورت زیر است:
کد:
Is there a car listed that costs less than $25000?, or is there a
truck listed that costs less than $20000?
برای نوشتن goal های ترکیبی عبارتهای بالا ، در زبان پرولوگ،از دستورات زیر نیز می توان استفاده کرد:
کد:
car(Make,Odometer,Years_on_road,Body,Cost), Cost<25000
; /* subgoal A or */
truck(Make,Odometer,Years_on_road,Body,Cost), Cost < 20000.
/* subgoal B */
در این Goal می توان این استنباط را داشت که ، اگر یک Car با شرایط ذکر شده وجود داشت آن را نمایش بده(عملیات موفقیت آمیز بوده است) و در غیر این صورت یک Truckرا با شرایطی که ذکر شده بیاب.
Comment ها(توضیحات):
در هر زبان برنامه نویسی این قابلیت به نحوی گنجانده شده است. می توان توضیحاتی را که یک دستور نیاز دارد به آن اضافه کرد تا خوانایی برنامه بالا برود.در واقع توضیحات،اجرا نمی شود و فقط به خوانایی برنامه کمک می کند و یا زمانی که نیاز به اجرا شدن یک دستور نداشته باشیم ،از توضیحات استفاده می کنیم.
برای توضیحات چند خطی می توان از /* comments*/ استفاده نمود و برای تک استفاده از comment های تک خطی می توان از % استفاده نمود.
همانند هم خانواده های زبان C
مثال:
کد:
/* This is an example of a comment */
% This is also a comment
/***************************************/
/* and so are these three lines */
/***************************************/
/*You can also nest a Visual Prolog comment /*within a comment*/ like this */
در زبان پرولوگ می توان بعد از هر Sub Domain از توضیحات استفاده نمود.
کد:
از کلمات title, author, name, uppercase و lowercaseدر اجرای برنامه صرفنظر می شود و فقط برای خوانایی بیشتر نوشته شده اند.
Match چیست؟
در بخشهای قبلی از Match چند بار استفاده شد.پیدا کردن یک match،شرایط Match با Fact و ... .در این بخش این مطلب را مورد بررسی قرار می دهیم.
پرولوگ از چندین راه برای Match کردن یک چیز با چیزهای دیگر استفاده می کند.
بدیهی است که چیزهای همسان با هم match می شوند.برای مثال:
کد:
parent(joe,tammy) matches parent(joe,tammy).
بهرحال یک match از یک یا چند متغیر آزاد تشکیل شده است. برای مثال:
کد:
parent(joe,X) matches parent(joe,tammy)
و متغیر X با مقدار tammy مقید خواهد شد.
نکته:
کد:
parent(joe,X) matches parent(joe,tammy) but
parent(joe,X) would not match parent(joe,millie)
در این مثال همانطور که نوشته شده است،X با tammy ،match خواهد شد ولی X با millie ، Match نخواهد شد.دلیل این است که X یک بار مقید شده است و برای بار دوم امکان مقید سازی وجود ندارد.در واقع اگر X مقید شده باشد همانند یک ثابت عمل می کند و مقدار نمی گیرد.
مرور:
1- زبان پرولوگ بر اساس دو مفهوم اصلی fact و rule بنا نهاده شده است:
• Fact : یک رابطه یا یک خاصیت که شما می دانید صحیح است و یا به عبارت ساده تر چیزی که شما از وجودش مطمعن هستید.برای مثال bill بازی baseball را دوست دارد . در واقع دانش شما از مساله همین fact است.
• Rule : قوانین ارتباطی هستند که به پرولوگ اجازه می دهند بوسیله یک قسمت از اطلاعات ،اطلاعات دیگر را استنباط کنند.شما ازطریق این قوانین میتوانید از دانش های موجود ،اطلاعات دیگری را استنباط نمایید.
2- فاکت ها عموما بصورت زیر نوشته می شوند:
کد:
property(object1, object2, ..., objectN)
یا
کد:
relation(object1, object2, ..., objectN)
property یک خصوصیت از آبجکته می تواند باشد و relation هم می تواند ارتباط بین آبجکتها باشد.
3-هر فاکت در برنامه از یک ارتباط دهنده و یک یا بیشتر آبجکت تشکیل شده است و یا از یک خصوصیت و یک یا بیشتر خصوصیت تشکیل شده است برای مثال:
کد:
likes(tom, baseball).
like یک ارتباط دهنده بین دو آبجکت tom و baseball است.
عبارت زیر هم یک فاکت است
کد:
left_handed(benjamin)
left_handed یک خصوصیت و Benjamin یک آبجکت است. به عبارت ساده تر و به زبان طبیعی، بنجامین چپ دست است.
5- شما در انتخاب نام های ارتباطی و آبجکتها اختیار عمل دارید.موارد محدود کننده عبارت اند از:
• نام آبجکت باید با حروف کوچک شروع شود و بدنبال آن هر عدد و حرف کوچک و یا بزرگ و یا under score می تواند بیاید.
• خصوصیت ارتباطی باید با حروف کوچک آغاز شود و بدنبال آن هر عدد و حرف کوچک و یا بزرگ و یا under score می تواند بیاید.
6- پریدیکیت نام سمبلیکی از ارتباط های بین آرگومانها است.
7- متغیر ها شما را قادر می سازند که پرسش ها و فاکت ها و رولهای عمومی بسازید.
• نام یک متغیر باید با حروف بزرگ ایجاد گردد و یا فقط یک under Score باشد و بدنبال آن هر عدد و حرف کوچک و یا بزرگ و یا under score می تواند بیاید.
• متغیرها مقدار خود را با تطبیق در فاکت ها و رولها می گیرند.تا زمانی که متغیر ،مقداری را نپذیرفته است اصلاحا گفته می شود که آزاد است و با گرفتن مقدار گفته می شود که مقید شده است.
• شما نمی توانید اطلاعات سراسری خود را در متغیر در هنگام ایجاد متغیر ،ذخیره نمایید.متغیر در روند اجرایی برنامه مقید خواهد شد.
8- اگر شما به اطلاعات معینی از پرسش هانیاز داشته باشید می توانید از متغیر های بی نام استفاده نمایید.در پرولوگ متغیر بی نام با یک under score تکی نمایش داده می شود.
متغیر بی نام هر گز مقدار نمی پذیرد.
9-جهت حرکت پرولوگ در حل مسایل همیشه از بالا به پایین است.وقتی پرولوگ می خواهد یک برنامه را اجرا نماید همیشه از بالاترین و اولین فاکت برنامه شروع به حل برنامه می نماید.
10- goal های مرکب از دو یا بیشتر بخش تشکیل شده اند.هر بخش یک goal مرکب را subgoal می گویند.goal های مرکب می توانند از ترکیب عطفی و یا ترکیب فصلی استفاده نمایند.
11- توضیحات برنامه شما را خواناتر می کنند.شما می توانید با در میان قراردادن عبارات توضیحی خود در بین /* */ و یا // به خونایی هرچه بیشتر برنامه خود کمک کنید.
برنامه نویسی در پرولوگ:
عموماً برنامه نویسی ویژوال پرولوگ از چهار بخش برنامه نویسی تشکیل یافته است.این بخشها عبارت اند از :بخش Clauses،بخش Predicates،بخش Domains و بخش Goal.
بخش Clauses قلب برنامه نویسی پرولوگ است،در این بخش Fact ها و Rule ها را وارد می نماییم.در واقع نتیجه گیری های داخل Goal به این قسمت وابسته است.
Predicates: در این بخش predicate هایی را که می خواهیم ،در این قسمت وارد می کنیم.این قسمت می تواند به domain ها هم وابسته باشد.
Domains: در این قسمت می توان دامنه های را تعریف کرد که در استاندارد ویژوال پرولوگ نمی باشند.
Goal: در این قسمت اهداف ما،یا در واقع سولاتی را که از سیستم داریم و نتیجه اش را می خواهیم بدانیم،می پرسیم.
بخش Clauses:
در این بخش فاکت های ها و رول های که در برنامه می خواهید داشته باشید،وارد می نمایید.
اگر شما بفهمید که فاکت و رول چیست و در واقع مفهوم آنها را درک کنید،ضرورت استفاده از Clauses نیز برای شما قابل فهم خواهد شد.
یک رشته از پریدیکیت ها که در Clauses تعریف می شود را پروسیجر می گویند.
وقتی ما در برنامه سعی در حل برنامه از طریق Goal می کنیم،در این موقع ویژوال پرولوگ شروع به نگاه کردن فاکت هاا و رولهای های داخل Clauses ،از بالا به پایین می کند.در واقع به دنبال چیزی می گردد که بتواند با محتویات Goal آن را تطبیق دهد(match).اگر چیزی که در حال حاضر با آن کار می کند جزء جواب ما نباشد ، در واقع با آن کاری نداریم و در این حالت اشاره گر به قسمت بعدی فرستاده می شود.به این عمل Backtracking یا بازگشت به عقب می گویند که در بخشهای بعدی مورد بررسی قرار می گیرد.
بخش Predicates:
چیزهایی را که در Clauses استفاده می کنیم به این بخش وابستگی دارند.اگر بدون تعریف در Predicate ،سعی به استفاده از فاکت ها و رولها ها کنیم،در این حالت برنامه نمی فهمد که در باره چه چیزی داریم سوال می کنیم.در این قسمت تعریف نوع انجام می شود.این تعریف نوع جزء اساسی برنامه نویسی پرولوگ می باشد.
چگونگی تعریف داده های کاربر
(user-defined) در Predicates:
تعریف یک پریدیکیت با نام پریدیکیت شروع می شود و در ادامه یک پرانتز باز و سپس نام آرگومانها (که از طول صفر تا ... می باشد) و د رآخر پرانتز بسته قرار می گیرد.مابین هر دو آرگومان(حد فاصل دو آرگومان)یک (،) قرار می گیرد.
نام یک آرگومان باید با حروف کوچک شروع شود و دنباله آن می تواند حروف کوچک،اعدادو یا Underscore باشد.
نام یک پریدیکیت می تواند تا 250 کارکتر طول داشته باشد.امکان استفاده از Space،-،/ و یا حروفی که جزء کارکتر های الفبایی اصلی نیستند ، وجود ندارد.
کارکتر های که می توان از آنها در تعریف پریدیکیت استفاده نمود عبارت اند از:
کد:
حروف بزرگ انگلیسی A,B,C,D,…,Z
حروف کوچک انگلیسی a,b,c,d,…,z
اعداد 0,1,2,…,9
زیرخط Underscore(_)
در زیر مثالی از نامهای پریدیکیت معتبر و نا معتبر آورده شده است.
کد:
آرگومانهای موجود در پریدیکیت باید در دامنه ویژوال پرولوگ شناخته شده باشند.این دامنه می تواند یک دامنه استاندارد باشد و یا یک دامنه تعریف شده توسط کاربر باشد.
کد:
PREDICATES
my_predicate(symbol,integer)
در تعریف بالا یک نوع تعریف سیستمی می باشد.نیازی به تعریف Domain در بالا ندارید.اگر تعریف پریدیکیت از نوع کاربری باشد آنگاه باید Domain را برای آن تعریف کرد.مثال زیر از تعریف نوع کاربر است:
کد:
مثال زیر برای درک مفاهیم ذکر شده در بالا مناسب می باشد:
کد:
DOMAINS
person, activity = symbol
car, make, color = symbol
mileage, years_on_road, cost = integer
PREDICATES
likes(person, activity)
parent(person, person)
can_buy(person, car)
car(make, mileage, years_on_road, color, cost)
green(symbol)
ranking(symbol, integer)
در مثال بالا پریدیکیت likes دارای دو آرگومان است،که هر دو در domain تعریف شده اند و با symbol ،تعریف نوع شده اند.
پریدیکیت parent با دو آرگومان person تعریف شده است که نوع ارگومان person از نوع symbol است.
پردیکیت can_buy نیز دارای دو آرگومان است که هر دو از نوع symbol هستند و در domain تعریف شده اند.
پردیکیت car از پنج آرگومان تشکیل شده است که این آرگومانها، color از نوع symbol و mileage ،years_on_road،cost وmake از نوع integer می باشند.
پردیکیت green از یک آرگومان تعریف شده است که آن هم از نوع symbol است و نیازی به تعریف آن در Domain نیست چون بصورت استاندارد تعریف شده است.
در پردیکیت ranking از دونوع آرگومان استفاده شده است که باز در اینجا نیاز به تعریف در Domain نیست چون بصورت استاندارد تعریف شده است.نوع آرگومانهای بکار رفته در این پریدیکیت از نوع symbol و integer است.
بخش Domains:
در این بخش دو قصد مهم داریم:
اول:برای دادن نام ها می توان از اسمهای با معنی بجای اسمهای بی معنی استفاده کرد.حتی اگر چند نام ذاتا یکی باشند.این کار کمک بسیاری به خوانایی بر نامه می کند.
دوم:برای تعریف domain های خاص که در دامنه استاندارد تعریف نکرده ایم.
به مثالی برای تعریف domain، برای عبارت زبان طبیعی زیر نگاه کنید:
Frank is a male who is 45 years old.
که domain این زبان طبیعی بصورت زیر است:
کد:
person(symbol, symbol, integer)
حال فرض کنید می خواهیم از این تعریف استاندارد یک تعریف نوع کاربر داشته باشیم که برای این کار می توانیم بصورت زیر عمل کنیم:
کد:
DOMAINS
name, sex = symbol
age = integer
PREDICATES
person(name, sex, age)
یکی از مزایای استفاده از تعاریف در Domains این است که می توان نوع خطا ها را بهتر تشخیص داد .
برای مثال :
کد:
same_sex(X, Y) :-
person(X, Sex, _),
person(Sex, Y, _).
با اینکه Name و Sex از یک نوع اند ولی نمی توان بجای یکدیگر استفاده نمود.
در صورت اشتباه و استفاده از این سبک،زبان پرولوگ خطا را تشخیص داده و به ما اعلام می کند.وقتی برنامه بسیار بزرگ یا پیچیده باشد ،استفاده از سبک گفته شده می تواند مفید واقع شود.
کد:
در این برنامه دو عمل انجام می شود،ضرب و مجموع.
اگر
کد:
Goal
add_em_up(32,54,Sum).
به برنامه اضافه شود نتیجه ای بصورت زیر مشاهده خواهد شد.
کد:
Sum=86
1 Solution
که نتیجه ،مجموع دو مقدار از نوع integer می باشد.از طرف دیگر می خواهیم حاصلضرب دو آرگومان را که در پریدیکیت multiply_em است،را بدست آوریم،که در اینجا هم اگر goal ما بصورت multiply_em(31,13,Product) باشد نتیجه بصورت زیر خواهد بود.
کد:
Product=403
1 Solution
اگر شما چنین goal که در زیر آمده است را امتحان کنید
کد:
شاید فکر کنید که چنین جوابی بعنوان خروجی نمایش داده خواهد شد.
کد:
Sum=527, Answer=1054
1 Solution
ولی در واقع این حالت استفاده یک type error با خود بهمراه خواهد داشت.دامنه Product و Sum از هم متفاوت اند،حتی با اینکه هر دو از نوع integer هستند ولی با این حال چون دامنه هاشان از هم جدا است پس دو ماهیت جدا در نظر گرفته می شوند.
کد:
DOMAINS
brand,color = symbol
age = byte
price, mileage = ulong
PREDICATES
car(brand,mileage,age,color,price)
CLAUSES
car(chrysler,130000,3,red,12000).
car(ford,90000,4,gray,25000).
car(datsun,8000,1,black,30000).
اگر goal های زیر را به برنامه اضافه کنیم، دستور خطایی را با خود به همراه خواهد داشت.
کد:
محصول اجرای هر دستور بالا یک error است .برای مثال در اولی مقدار age بایداز نوع byte با شد بنابر این جای mileage و age باید تغییر کند.در دومی، جای age و color باید عوض شود.
سعی کنید که خطاهای سومین goal را خودتان بیابید.
بخش Goal:
اساساً بخش Goal شباهت زیادی به body یک رول دارد،که لیست ساده ای از subgoal ها است.
دو تفاوت ما بین رول و Goal وجود دارد.
1.کلمه کلیدی goal بعد از :- نمی آید
2.وقتی شروع به اجرای برنامه می کنیم،بصورت اتوماتیک،ویژوال پرولوگ اجرای Goal را بدست می گیرد.
دامنه های استاندارد ویژوال پرولوگ:
ویژوال پرولوگ از چندین دامنه استاندارد تشکیل شده است. وقتی شما آرگومانهای پریدیکیت ها را تعریف می کنید ، می توانید از این دامنه های استاندارد، بهره ببرید.
دامنه های استاندارد در ویژوال پرولوگ به را حتی شناخته می شوند و نیازی به تعریف آنها در بخشDomain نیست.
short : در همه پلت فرمها 16 بیت - ارزش-32768 .. 32767
ushort : در همه پلت فرمها 16 بیت –ارزش 0 .. 65535
Long : در همه پلت فرمها 32 بیت-ارزش -2147483648 ..2147483647
ulong : در همه پلت فرمها 32 بیت – ارزش 0 .. 4294967295
دیگر دامنه های اصلی در زیر آورده شده است.
char:
یک حرف که با کوتیشن های تکی محاصره شده است مانند 'a'.
Real:
یک عدد ممیز شناور که با استانداردIEEE مطابقت داشته باشد،که می تواند به همراه علامت +،- باشد.برای نمایش اعداد اعشاری باید از کارکتر . استفاده شود.برای نمایش اعدادی که در محدوده نمی گنجند از حرف e استفاده می شود.
مثالی از اعداد این نوع:
42705 9999 86.72
9111.929437521e238 79.83e+21
در اینجا معنی 79.83e+21 این است که داشته باشیم:
79.83 x 10^21
اعداد مجاز در این محدوده 1e-307 تا 1e+308 می باشد.
String:
به رشته ای از کارکتر ها می گویند.
دو قاعده برای نوشتن آن وجود دارد:
1.رشته ای از حروف کوچک،اعداد یا Underscore باشد.
2.مابین کوتیشن های جفتی واقع شده باشد.
مثال:
کد:
"railway ticket" "Dorid Inc"
telephone_number
رشته ها تا 255 کارکتر می توانند طول داشته باشند.رشته های درون فایلی سیستم های 16 بیتی، میتوانند تا K64 طول داشته باشندو طول رشته های که در platform های 32 بیتی هستند میتوانند تا 4 گیگ طول داشته باشند.
Symbol:
رشته ای از کارکتر ها که در جدول نماد ها ذخیره می شود(Symbol-table).
در برنامه نویسی تا اندازه زیادی می توان از symbol و string ،بجای هم استفاده کرد.با این وجود اساسا ماهیتی جدا از هم دارند.در symbol ها جدول اشاره گری وجود دارد که به مقادیر اشاره می کند ،برای همین سرعت کارکردن با symbol از string خیلی بالا تر است.رشته ها در این جداول ذخیره نمی شوند و برای match شدن عبارات ،در رشته کارکتر ها تکی تکی مقایسه می شود که سرعت انجام پردازش را پایین می آورد.
چند نمونه از آبجکت های ساده در زیر آمده است:
کد:
نوع آرگومان در تعریف Predicate ها:
برای شروع این قسمت را با یک مثال آغاز می کنیم.
کد:
Frank is a male who is 45 years old.
ابتدا می خواهیم fact مربوط به این عبارت زبان طبیعی را بیابیم،که نتیجه زیر را خواهد داشت:
کد:
person(frank, male, 45).
برای اینکه بتوانیم از این fact استفاده نماییم باید ابتدا در قسمت PREDICATES آن را تعریف کنیم و نوع داده اش را به آن بدهیم،برای این منظور می توانیم نوع داده ای مانند زیر را به آن اختصاص دهیم:
کد:
person(symbol, symbol, unsigned)
در فرم بالا از روش تعریف دامنه استاندارد استفاده نموده ایم.که دو آرگومان ابتدایی آن از نوع symbol و نوع داده آخری از نوع unsigned است.
مثال دیگر:فرض کنید می خواهیم که موقعیت حروف کوچک را بترتیب حروف الفبا داشته باشیم،برای این منظور ،a در موقعیت 1 به سر می برد و b در موقعیت 2 و ... تا z در موقعیت 26.
کد:
حال با نوشتن goal های زیر سعی کنید جواب را ببینید:
کد:
a. phone_number("Carol", Number).
b. phone_number(Who, "438-8400").
c. phone_number("Albert", Number).
d. phone_number(Who, Number).
حال بخش Clauses را به این صورت بروز رسانی کنید،فرض بگیرید شخصی به نام Kim با Dorothy دارای یک شماره تماس مشترک هستند.فاکت مورد نظر را به Clausus اضافه نمایید و سعی کنید جواب زیر را در بخش Goal مشاهده نمایید.
کد:
phone_number(Who, "438-8400").
جوابی که به شما ارائه خواهد شد بصورت زیر خواهد بود:
کد:
Who=Dorothy
Who=Kim
2 Solutions
اگر بغیر از کارکتر هایی که فاکت آنها وجود دارد ،بخواهد جستجوی را انجام دهید،در این صورت با جواب no مواجه خواهید شد.
کد:
PREDICATES
isletter(char)
CLAUSES
/* When applied to characters, '<=' means */
/* "alphabetically precedes or is the same as" */
isletter(Ch):-
'a' <= Ch,
Ch <= 'z'.
isletter(Ch):-
'A' <= Ch,
Ch <= 'Z'.
حال سعی کنید که goal های زیر را به برنامه اضافه کنید و جواب را مشاهده نمایید:
کد:
a. isletter('x').
b. isletter('2').
c. isletter("hello").
d. isletter(a).
e. isletter(X).
در اجرای بخش c و d با یک خطا مواجه خواهید شد،در اجرای بخش e نیز با خطای متغیر آزاد مواجه خواهید .
Arity چندگانه:
Arity در پریدیکیت یعنی تعداد آرگومانهای متفاوت در یک پریدیکیت . برای مثال شما می توانید یک پریدیکیت داشته باشید اما با تعداد آرگومانهای متفاوت.
مثال زیر می تواند نمونه خوبی برای این مفهوم باشد:
کد:
DOMAINS
person = symbol
PREDICATES
father(person) % This person is a father
father(person, person)%One person is the father of the other person
CLAUSES
father(Man):-
father(Man,_).
father(adam,seth).
father(abraham,isaac).
سلام دوستان.
من تصمیم دارم در رشته هوش مصنوعی ادامه تحصیل بدم اطلاعاتم در زمینه زبان های برنامه نویسی خیلی کمه می خواستم بدون برای یادگیری زبان های برنامه نویسی بهتر از چه زبانی شروع کنم؟
ممنون
سلام
تو پرولوگ دو تا تمرين داريم ميدونم كه تو امتحان پايان ترم مياد خواهش ميكنم كمكم كنيد
برنامه اي بنويسيد كه عنصر آخر و اول ليست رو برگرداند.
برنامه اي بنويسيد تشخيص دهد كه ليست خود معكوس است يا نه (همون آيينه اي مثال:abba )
خواهشش ميكنم كمكم كنيد