منطق محاسباتی

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

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

امروزه بشر علاقه زیادی دارد که تمام کارها از جمله فکر کردن را به ماشین واگذار کند. اما واگذار کردن فکر کردن به یک ماشین کار ساده ای نیست. ما دید عمیقی درباره اینکه فکر کردن چیست و چگونه انجام میشود نداریم. ازینرو تلاشهای اولیه برای این کار با شکست مواجه شدند یا با سختی زیادی همراه بودند. اما اگر بخواهیم تنها قسمت منطقی فکر کردن را به ماشین واگذار کنیم کار ساده تر است چون برای این کار از منطق ریاضی استفاده میکنیم و منطق یک زیر شاخه قوی از ریاضی است که به سوالات زیادی در مورد آن جواب داده شده است. گرچه ما هنوز واقعا نمیدانیم که چه مقدار از روند تفکر ما منطقی است. به این مطلب در قسمت نتیجه گیری بیشتر خواهیم پرداخت.

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

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

چرچ در ۱۹۳۶ ثابت کرد که منطق مرتبه اول برای زبانی که فقط یک نماد رابطه‌ای دو موضعی داشته باشد تصمیم ناپذیر است. بنا بر قضیه چرچ روشی متناهی برای پاسخ به این سوال که آیا جمله A در منطق مرتبه اول معتبر است، به صورت “آری” یا “نه” نداریم، اما نیمه ای از پاسخ را میتوان مهیا کرد. به عبارت بهتر روشی متناهی وجود دارد که اگر A معتبر باشد،

پاسخ روش “آری” است. به عبارت دیگر مجموعه جملات معتبر در منطق مرتبه اول لیست پذیر هستند. از طرف دیگر با توجه به قضیه تمامیت (در صورتی که در مورد دستگاه استنتاجی ما درست باشد) با استفاده از فرضها و اصول استنتاج میتوان جملات درست را لیست کرد. این قسمت در حقیقت قلب تپنده‌ی منطق محاسباتی است. در صورت پیدا شدن روشهای جدید و سریعتر برای چک کردن درستی یک جمله تحت چند فرض، شاهد تحول بزرگی در دیگر شاخه های مرتبط با این موضوع خواهیم بود.
تحقیقات در بخش پایه‌ی منطق محاسباتی به طور گسترده‌ای بر دیگر بخشهای این علم تاثیر دارند. این تحقیقات عموما به دو بخش تقسیم میشوند:
• تحقیقات در زمینه‌های روشهای استنتاج از قبیل Resolution و …

• تحقیقات در زمینه‌ی پیدا کردن پایه های مناسب ریاضی برای انجام به صرفه‌ی (از نظر زمانی و حافظه) محاسبات مربوط به منطق محاسباتی.
۲-۱ پایه‌های منطق محاسباتی:

روش کلی برای فهمیدن درستی یک جمله این است که از فرضها شروع کرده و در هر مرحله یک جمله درست جدید را با توجه به جملات قبلی و استفاده از قواعد استنتاج تولید کنیم. (یعنی جملات درست را لیست میکنیم.) این کار ادامه پیدا میکند تا وقتی که به جمله مورد سوال یا نقیض آن برسیم.

قسمت دیگری که مورد توجه است، یکی سازی است. به طور مثال دو جمله x:f(x) و y:f(y) را در نظر بگیرید. واضح است که درستی این دو جمله یکسان است. به طور کلی هر جمله را به طریقه های ظاهرا متفاوت بسیار زیادی میتوان نوشت که همگی یک معنای واحد داشته باشند. (در همین مثال به جای x از تمام متغیرها میتوان استفاده کرد. به صورت معمولی لااقل ¬۰N متغیر داریم.) بدین منظور تحقیقات زیادی بر روی روشهای کارا برای یکی سازی جملات منطقی انجام شده است.

برای تولید جملات جدید با توجه به قواعد استنتاج راههای زیادی پیشنهاد شده اند. یکی از محبوبترین راههای پیشنهاد شده به Resolution موسوم است. این روش برای منطق مرتبه اول کمی پیچیدگی دارد اما با بررسی آن برای منطق گزاره ها کلیت آن آشکار میشود.
Resolution Propositional

در این روش تمام جمله ها به صورت clausal form هستند. برای تبدیل یک جمله به این فرم ابتدا جمله را به صورت نرمال عطفی CNF تبدیل میکنیم.
¬(g  ( r → f)) ──CNF (¬g  r)  (¬g  ¬f)
و سپس نتیجه را به تعدادی مجموعه تبدیل میکنیم، مجموعه ای از مجموعه ها که هر عضو آن اعضای یکی از پرانتزهاست:
(¬g  r)  (¬g  ¬f) ──Clausal Form {¬g, r}, {¬g, ¬f}

این کار یک روش نسبتا خوب برای Unification است. برای انجام استنتاج بر اساس این قاعده عمل میکنیم:
میدانیم که
(p  q)  (¬p  r)  (q  r)

میتوان نشان داد که استفاده از این رابطه به عنوان تنها قاعده استنتاج برای استنتاج کافی است. این رابطه در
clausal form به این شکل تبدیل میشود:

{p, q}
{¬p, r}
————
{q, r}

این تعریف برای مجموعه های بیش از دو عضو نیز قابل گسترش است. به موارد جالب زیر توجه کنید:

{¬p, q}
{p}
————
{q}
(این معادل با قاعده Modus Ponens است.)

{p}
{¬p}
————
{}
(تناقض!)
۲-۲ پایه‌ی ریاضی

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

 

۳ کاربردهای منطق محاسباتی
منطق محاسباتی امروزه به طور گسترده‌ای جهت حل مسایل مهندسی در حال استفاده است و این استفاده با سرعت زیادی در حال گسترش است. زمینه‌های مهمی که امروزه از منطق محاسباتی در آنها استفاده میشود عبارتند از:
• Database Systems

با استفاده از سیستمهای مبتنی بر منطق محاسباتی میتوان Database ها را از محل ذخیره‌ی اطلاعات خام به پایگاههای هوشمند داده‌ها تبدیل نمود، به این ترتیب شاهد منابع هوشمندی از اطلاعات خواهیم بود که استفاده از آنها به مراتب ساده‌تر از موارد مشابه فعلی است. با توجه به اینکه جهان امروزی به شدت مبتنی بر استفاده از پایگاه‌های داده است، به نظر میرسد که در این قسمت سرمایه گذاری زیادی انجام شود و لذا پیشرفت در این زمینه بسیار سریع خواهد بود که این امر منجر به پیشرفت سریعتر دیگر موارد مربوط به منطق محاسباتی خواهد شد.
• Software Analysis

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

• Hardware Engineering
امروزه در طراحی سخت‌افزار هم به مانند طراحی نرم‌افزار پیشرفتهای عمده‌ای به وجود آمده است، قانون مور بیان میکند که تعداد ترانزیستورهای یک تراشه در هر سال دو برابر خواهد شد (از نظر تکنولوژی ساخت). این قانون تاکنون نقض نشده است و اگر این روند ادامه پیدا کند در طی مدتی کوتاه شاهد تراشه‌های کامپیوتری‌ای خواهیم بود که حاوی صدها میلیار ترانزیستور هستند، وضوحا تست کردن درستی عملکرد این تراشه‌های عظیم از طریق روشهای کلاسیک موجود امکان‌پذیر نخواهد بود و سیستمهای مبتنی بر منطق محاسباتی به طور عمده‌ای برای این کار استفاده خواهند شد.
• Automated Theorem Proving

از منطق محاسباتی میتوان به صورت گسترده‌ای جهت اثبات خودکار قضایای ریاضی استفتده کرد.
۳-۱ STRIPS :
یکی از مهمترین مسایل در علم روباتیک برنامه ریزی حرکت روبات است. روباتی را در نظر بگیرید که دارای توانایی‌های متعارف حرکتی است و قادر است با دستهای خود اقدام به جابجا کردن اشیا نماید، همچنین به وسیله چشم الکترونیکی خود میتواند اطلاعات تصویری از جهان پیرامون خود دریافت کند و آنها را تجزیه و تحلیل کند. این ویژگیها برای یک روبات همگی ویژگیهایی مکانیکی محسوب میشوند. روباتی با این ویژگیها مهمترین کاری که باید بتواند انجام دهد این است که بتواند به طریقه‌ای مفید از قابلیتهای مکانیکی خود استفاده کند.

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

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

این چارچوب برای حل مسایل در مورد بسیاری از مسایل هوش‌مصنوعی قابل اعمال است، اما هدف ما در اینجا حل مسایلی که یک ربات با آنها مواجه میشود است. مدل جهان این گونه از مسایل بسیار گسترده و پیچیده است. برای مقایسه مسایل مرتبط با حل پازل را در نظر بگیرید. مدل یک پازل را میتوان به سادگی در یک لیست یا ماتریس نگه داشت. اما در مورد یک ربات مدل ما از جهان شامل حجم بزرگی از اطلاعات مثل مکان ربات، مکان و خصوصیات اشیا، فضاهای باز و دیوارها و … میباشد. بدین ترتیب یکی از بزرگترین مسایل دراین مورد نحوه نگه داری مدل جهان است. در STRIPS مدل جهان در یک مجموعه از فرمولهای خوش شکل ریخت(wff) در زبان منطق مرتبه اول، نگه داری میشود.

عملگر ها عناصر اصلی برای پیدا کردن جواب هستند. هر عملگر متناظر با یک روال کاری است. فرق این دو این است که عملگرها هنگام برنامه ریزی استفاده میشوند ولی روالهای کاری وقتی استفاده میشوند که ربات میخواهد جواب پیدا شده را به صورت فیزیکی انجام دهد. (یعنی یک عملگر در جهان منطقی معادل با یک روال کلری در جهان واقعی است.)
سوال بعدی این است که یک عملگر مدل جهان را چگونه تغییر میدهد؟ در STRIPS این کار از طریق یک لیست اضافه و یک لیست حذف انجام میشود. همچنین هر عملگر تعدادی شرط مقدماتی برای انجام شدن دارد.

مثلا عملگر push(k,m,n) را برای هل دادن شی k از مکان m به n به صورت زیر تعریف میشود:
push(k, m, n)
precondition:
ATR (m)
At(k, m)
delete list:
ATR(m)
AT(k, m)
add list:
ATR(n)
AT(k, n)

پس برای بدست آوردن جهان جدید از جهان قبلی تحت تاثیر یک عملگر تنها کافی است که ابتدا با چک کردن شرطهای مقدماتی بفهمیم که آیا عملگر قابل اعمال به جهان هست یا نه؟ اگر بود، جملات لیست حذف را از جهان حذف کرده و جملات مربوط به لیست اضافه را به جهان اضافه کنیم.
مثال
مثال زیر را در نظر بگیرید:

فرض کنید که این شکل نقشه‌ی یک ساختمان است که روبات در آن قرار دارد و همچنین تعداد جعبه و … در این ساختمان است.
جهان و عملگرها به این شکل تعریف میشوند:
Initial World Model
CONNECTS(x,y,z)=~ C C N N E CTS(x,z,y)
CONNECTS(DOOR1, ROOM1, ROOM5)
CONNECTS(DOOR2, ROOM2, ROOM5)
CONNECTS(DOOR3, ROOM3, ROOM5)

CONNECTS(DOOR4,ROOM4,ROOM5)
LOCINROOM(f, ROOM4)
AT(BOXl,a) INROOM(BOXI,ROOM1)
AT(BOX2,b) INROOM(BOX2,ROOM1)
AT(BOX3,c) INROOM(BOX3,ROOM1)
AT(LIGHTSWlTCH l,d) INROOM(ROBOT, ROOM1)
ATROBOT(e) INROOM(LIGHTSWITCH1,ROOM1)

TYPE(BOXI,BOX) PUSHABLE(BOXI)
TYPE(BOX2,BOX) PUSHABLE(BOX2)
TYPE(BOX3,BOX) PUSHABLE(BOX3)
TYPE(IM,DOOR) ONFLOOR
TYPE(D3,DOOR) STATUS(LIGHTSWITCH1, OFF)
TYPE(D2,DOOR) TYPE(LIGHTSWITCH1, LIGHTSWITCH)
TYPE(DI,DOOR)

Operators

goto1(m): Robot goes to coordinate location m.
Preconditions:
(ONFLOOR) ^ (x)[INROOM(ROBOT,x)  LOCINROOM(m,x)]
Delete list: ATROBOT($),NEXTTO(ROBOT,$)
Add list: ATROBOT(m)

 

goto2(m): Robot goes next to item m.
Preconditions:
(ONFLOOR)  {(x)[INROOM(ROBOT,x)  INROOM(m,x)]  (x)(y)
[INROOM(ROBOT,x)  CONNECTS(m,x,y)]}
Delete list: ATROBOT($),NEXTTO(ROBOT,$)
Add list: NEXTTO(ROBOT, m)

pushto(m,n): robot pushes object m next[to item n

Precondition:
PUSHABLE(m)  ONFLOOR  NEXTTO(ROBOT,m)  {(x)[INROOM(m,x)
 INROOM(n,x)]  (xy)[INROOM(m,x)  CONNECTS(n,x,y)]}
Delete list:
AT ROBOT ($), NEXTO (ROBOT, $), NEXTI’O ($,m), AT(m, $), NEXTTO(m,$)
Add list: NEXTTO(m,n), NEXTTO(n,m), NEXTTO(ROBOT, m)

 

turnonlight(m): robot turns on lightswitch m.
Precondition:
{(n)[TYPE(n,BOX)  ON(ROBOT, n)  NEXTO(n,m)I}
 TYPE(m, LIGHTSWITCH)
Delete list: STATUS(m,OFF)

Add list: STATUS(m,ON)

climbonbox(m): Robot climbs up on box m.
Preconditions:
ONFLOOR  TYPE(m,BOX)  NEXTTO(ROBOT, m)
Delete list: ATROBOT($),ONFLOOR
Add list: ON(ROBOT,m)

climboffbox(m): Robot climbs off box m.
Preconditions: TYPE(m,BOX)  ON(ROBOT, m)
Delete list: ON(ROBOT, m)
Add list: ONFLOOR

gothrudoor (k, l, m): Robot goes through door k from room l into room m.
Preconditions:
NEXTTO(ROBOT, k)  CONNECTS(k, l, m)  INROOM(ROBOT, l)  ONFLOOR
Delete list:
ATROBOT($), NEXTTO(ROBOT,$), INROOM(ROBOT, $)
Add list: INROOM(ROBOT,m)

با استفاده از STRIPاین راه حلها برای انجام کارهای زیر پیشنهاد شده است:
۱٫ Turn on the lightswitch
Goal wff: STATUS (LIGHTSWITCHI, ON)
STRIPS solution:
{goto2 (BOXl), climbonbox (BOXl), climboffbox (BOXl),
pushto (BOXI, LIGHTSWlTCHl), climbonbox (BOXl),

turnonlight (LIGHTSWITCHI)}
2. Push three boxes together
Goal wff: NEXTTO (BOXI, BOX2)  NEXTTO (BOX2, BOX3)
STRIPS solution:

{goto2 (BOX2), pushto (BOX2, BOXl), goto2 (BOX3), pushto
(BOX3, BOX2)}

۳٫ Go to a location in another room
Goal wff: ATROBOT (f)
STRIPS solution:
{goto2 (DOORl), gothrudoor (DOOR1, ROOM1, ROOMS),
goto2 (DOOR4), gothrudoor (DOOR4, ROOMS, ROOM4),
gotol (f)}

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

۱- چگونه میتوان در مدل یک جهان خاص درستی یک جمله را چک کرد؟
۲- چگونه میتوان با شروع از مدل مبدا، مدل مقصد جهان را یافت؟

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

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