إعلان: يُوجد عندي دروس تعليمية باللغة العربية حول لغة البرمجة PROLOG مدّتها 80 ساعة بصيغة فيديو MP4 مع بعض الكتب الإلكترونية المُختصّة, وأنا أعرضها للبيع على طريقة المزَاد, مع العلم أنّ هذه الدروس جمعتها من الأنترنت لِنفسي منذ سنوات, والمهتم يتواصل معي.

مقدمة إلى لغة البرولوك Prolog


لغة البرولوج ( PROLOG ) هي اختصار (programming in LOGIC ) أي البرمجة المنطقية .وصمم هذه اللغة أستاذ بجامعة مرسيليا بفرنسا يدعى ألن كولمرير (Alan Colmeraur) وظل استخدام لغة البرولوج محصورا في معامل أبحاث الذكاء الاصطناعي بقارة أوروبا حتى أكتوبر 1981 عندما أعلن اليابانيون أن لغة برولوج ستكون اللغة الرئيسية لحاسبات الجيل الخامس .

وإلى الآن لم تكتسب لغة البرولوج قبولا وانتشارا تجاريا واسعا في أمريكا , ويرجع ذلك لسببين : الأول هو صعوبة اتصالها باللغات التقليدية مثل لغة فورترون (FORTRAN ) , والثاني هو بطء برامج البرولوج في طور الإنتاج . وعلى الرغم من تغلب البرولوج السريع (turbo PROLOG) على مثل هذه المشاكل إلا انه حقق ذلك على حساب خصائص أخرى للبرولوج مثل التوحيد (Unification).

وتعتمد لغة البرولوج على مفهوم البرمجة المنطقية (Logic Programming ), والتي تتعامل مع جمل ( Statement) تحتوي على أشياء ( Objects ) والعلاقات ( Relationships )التي تربط بينها وبين الجملة:


Professor (Mohammad, Ali)


في هذه الجملة تسمى كلمة (Professor) بالمسند أو المحمول ( Predicate) وتمثل العلاقة بين المعاملات (Mohammad) هو أستاذ (Ali).

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

والبرمجة بلغة البرولوج تنقسم إلى ثلاثة مراحل هي:

1- إعلان الحقائق عن الأشياء ( Objects )والعلاقات التي تربط بينها.

2- تعريف القواعد ( Rules ) التي تحكم كلا من الأشياء والعلاقات التي تربط بينها .

3- السؤال عن الأشياء والعلاقات التي تربطها.


والمرحلة الثالثة يمكن أن تأتي بعد المرحلة الأولي مباشرة حيث يمكن السؤال عن الأشياء دون تطبيق أي قواعد.

وهناك عدة إصدارات للغة البرولوج ولكن إصدار جامعة أد نبرة (Edenburgh University) يعتبر هو الإصدار القياسي وسوف يتم التعرف عليه في الأجزاء التالية .



كيفية الإعلان عن الحقائق والسؤال عنها :

الإعلان عن الحقائق في برنامج البرولوج يجب أولا تحديد الأشياء (Objects) والعلاقات التي تمثل تلك الحقائق .فمثلا إذا كانت هناك حقيقة تقول أن ( Ali Likes Mohammad ) فالأشياء في هذه الحقيقة هي الأسماء (Ali , Mohammad )أما العلاقة بينهما فهي (Linkes) وتسمى بالمسند (Predicate) أي الصفة التي تتعلق بشيء ما أو العلاقة التي تربط بين شيئين أو اكثر. ولتمثيل هذه الحقيقة في برنامج البرولوج تكتب كالآتي :



Likes ( ali , mohammad).


لاحظ كتابة أسماء الأشياء والعلاقات بالحروف الصغيرة (Small Letters) وذلك لأن الأسماء التي تبدأ بالحروف الكبيرة (Capital Letters) أو بالحرف (Underscore (_) ) يعتبرها البرولوج متغيرات (Variable). وتختلف الحقيقة باختلاف ترتيب أسماء الأشياء بمعنى أن (ali , mohammad) likes تختلف عن (mohammad , ali)likes وينتهي الإعلان عن الحقيقة بوضع نقطة (.) في آخرها.

ويطلق على التعبير (Ali , Mohammad ) likes ) في لغة البرولوج لفظ العبارة ( Clause) ويمكن ترجمة اللغة المكتوبة بإحدى اللغات الطبيعية (الإنجليزية أو العربية ) إلى عبارة أو اكثر من عبارات البرولوج. ويتم ذلك بتحديد الأشياء التي يدور حولها موضوع الجملة وتحديد الصفات أو العلاقات التي تميزها, أو محمول الجملة.

كما يجب ملاحظة أن الاسم الذي يعبر عن صنف (Class ) معين من الأشياء يجب أن يختلف الاسم الذي يعبر عن عنصر محدد من ذلك الصنف ( Instance of the class) على سبيل المثال إذا أردنا كتابة برنامج خبير بواسطة لغة البرولوج ليستطيع تمييز سمكة معينة من أسماك القط ( Catfish ) وهي سمكة نشطة (Active) يجب إعلان حقيقتين هما:



A catfish resembles an eal.

The catfish is extremely active.

ففي هذه الحالة يجب إعطاء ( Catfish ) في الحقيقة الثانية إسما مختلفا عن الحقيقة الأولى أي كتابتها بالصورة التالية :




resemble ( catfish , eal).

active ( catfish 1).

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

وبمجرد تخزين الحقائق في قاعدة بيانات يمكن بعد ذلك الاستفسار ( Query ) عن أي أشياء والعلاقات التي تربط بينها فعلى سبيل المثال إذا أخذنا قاعدة المعرفة التي تمثل العلاقة بين ( Mohammad , Ali ) في المثال الأول فيمكن السؤال عن العلاقة بينهما بإحدى الطريقتين التاليتين :



? – likes( ali, mohammad )

likes ( ali , mohammad)?


وبناء على هذا السؤال يقوم البرولوج بالبحث في قاعدة المعرفة(Knowledgebase ) عن عبارة (Clause) تطابق العبارة الموجودة في السؤال ويحدث الاتفاق عندما يتفق كل من المسند في عبارة السؤال مثل (Like ) مع المسند في الحقيقة الموجودة في قاعدة المعرفة وأيضا عندما تتفق معاملات السؤال مع مثيلاتها من المعاملات الحقيقة.

وبما أن السؤال يتفق مع الحقيقة يقوم البرولوج بالرد بالإيجاب (Yes) على ذلك السؤال ولكن إذا تغير ترتيب المعاملات, مثل



Likes ( mohammad , ali) ?

يكون الرد بالنفي (No).

وهذا يعني أن الحاسب (أو برنامج البرولوج) لا يعلم حقيقة تتفق مع هذا السؤال , أو بمعنى أدق لا توجد عبارة تمثل هذه الحقيقة في قاعدة المعرفة.




الثوابت والمتغيرات

يمكن أن تحتوي العبارة في لغة البرولوج على نوعين من البيانات ثوابت (Constants) ومتغيرات (Variables) .والثابت (Constant ) هو أي أسم يقوم بوصف شئ محدد (Specific Object) ,مثل (mohammad) , (ali) , أو وصف أي علاقة محددة ( Specific Relation) , مثل (Likes)وهناك نوعان من الثوابت في لغة البرولوج وهما الأعداد الصحيحة (Integers) والعناصر (Atoms).



أ_ الأعداد الصحيحة (Integers)

وهي مجموعة الأعداد الصحيحة الموجبة أو السالبة المحصورة بين العددين (-32,765) و (32,765) , مثل:



-15.7,32,1011,-3200


ب_العنـــاصـــر ( Atoms)

العنصر (Atom) هو عبارة عن سلسلة من الحروف أو الأعداد أو الحروف الخاصة والتي تصف اسم أي شئ (Object) أو علاقة (Relationship)كما يجب أن يتحقق فيه الشروط الثلاثة التالية :

1- ألا يبدأ بعدد صحيح أو حرف كبير (Capital) أو العلامة (_)(underscore).

2- ألا يحتوي على علامة (-)(hyphen).

3- إذا احتوى العنصر على أي علامة من العلامات السابقة يجب أن ينحصر بيم علامتي التنصيص(").


ومن أمثلة العناصر ما يلي:



abc mahammad

chapter_10 ‘ This is an atom.’

و الأمثلة التالية ليست عناصر:



456 Vector

Street5 _Tax


Large_Number

أما المتغير (Variable)فهو أي سلسلة من الحروف تبدأ إما بحرف كبير (Capital) وأما بالعلامة (_)(Underscore), وهو اسم خاص يمكن أن يتفق مع أي شئ (Object) موجود بقاعدة المعرفة , والأسماء الآتية تعتبر متغيرات:



Abc _Ten Like

X Xaxis Move

Yz Ali X_Y_Z



وتستخدم المتغيرات عادة في للتعبير عن أي شخص أو عن أي شئ ,فعلى سبيل المثال إذا أردنا أن نعبر عن الجملة (Every one Likes Mohammad)نكتب:



Likes( X , mohammad(.

وفي هذه الحالة إذا سألنا عن أي شخص هل هو يحب محمد فسيكون رد البرولوج بالإيجاب , أي إذا سألنا:



Likes(ahmad,mohammad(?

سيكون الرد هو :



Yes




معنى ذلك أن أي عنصر يحل محل المتغير (X ) يجعل البرولوج يرد بالإيجاب.واستخدام المتغيرات في التعبير عن الحقائق يمكن أن يدمر العلاقات التي تربط الأشياء (Objects) في قاعدة المعرفة , وسنرى فيما بعد كيفية التغلب على هذا الاستخدام السيئ للمتغيرات.



التراكيب (Structure)

التركيب (Structures) , ويسمى أيضا بالمسند المركب(Compound Predicate) , هو العبارة التي تأخذ الشكل




predicate ( argument , argument2 , …. ).



حيث المعامل الاول ( Argument1 ) يمكن ان يكون ثابتا ( constant ) او متغيرا (variable)

أو عبارة ( clause ) أو تركيبا ( structure ) . والأمثلة التالية تعتبر تراكيب صحيحة .



Like ( ali , mohamand ).

Point ( x , y , z ).


ownd ( ahmed, book ( X , author ('Mc Craw Hill'))).



ويمكن أن يحتوي التركيب على المعاملات المنطقية ( And ) , ( Or ) حيث تفسير العلامة (,) ( | ) بالمعامل ( Or ) . والمثال التالي يوضح كيفية استخدام المعامل ( , ) اي ( and )





Likes ( ali , mohamad) , like ( omar , mohamad ) ?



وللإجابة على هذا السؤال يقوم البرولوج بالبحث في قاعدة المعرفة عن الشطر الأول من السؤال ، أي العبارة الأولى ، فإذا وجدها لاتتفق مع أي من الحقائق الموجودة رد بالنفي ( no ) واذا وجدها تتفق مع مع حقيقة من الحقائق يبدأ بالبحث عن الشطر الثاني، أي العبارة الثانية ، فإذا وجدها لا تتفق مع أي من الحقائق رد بالنفي ( NO ) ذلك رد بالإيجاب (yas ).

أما المثالين التاليين فيوضحان كيفية استخدام المعامل ( or ) وكلاهما يؤدي نفس المعنى :





Likes ( ali , mohamad ) ; likes ( ali , adel )? 

Likes ( ali , mohamad ) | likes ( ali, adel )? أو



وفي هذه الحالة يرد البرولوج بالإيجاب ( yas ) اذا وجد اتفاق بين التعبير الأول وحقيقة من الحقائق واذا لم يجد يقوم بالبحث عن التعبير الثاني في الحقائق فإذا تم الاتفاق بينه وبين اي حقيقة رد بالإيجاب ( yas ) واذا لم يجد رد بالنفي ( no ).



البحث الراجع ( Backtracking )

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

اذا زودنا البرولوج بقاعدة المعرفة التالية :




Likes ( ali , mohamad ).

Likes ( ali , ahmad ).

Likes ( ali , omar ).

Likes ( ali , adel ).

Likes ( ahmad , mohamad ).



فإذا اردنا الإستفسار عن الاشخاص الذين يحبهم " علي " نكتب السؤال التالي :



Likes ( ali , People_Ali_Likes )?


في هذه الحالة يبدأ البرولوج بالبحث في قاعدة المعرفة لإيجاد قيم المتغير (People_Ali_Likes) وهذا المتغير يسمى غير محدد ( uninstantiated ) وعندما يجد حقيقة ( أي عبارة ) تتفق مع السؤال ( وهي أول عبارة ) يقوم البرولوج بإسناد الإسم ( اي الشئ) المناظر لذلك المتغير اليه اي وضع ( People_Ali_Likes=Mohamad) . وفي هذه الحالة يقال ان المتغير تم تحديده ( instantiated ) بالعنصر ( أو الشئ او الثابت ) ( Mohamad )


والان دعنا نرى الإجابة على هذا السؤال وبعد ذلك نرى كيف توصل البرولوج الى هذه الاجابة . فالإجابة على السؤال السابق ستكون على الشكل التالي :





People_Ali_Like = mohamad

People_Ali_Like = ahmad

People_Ali_Like = omar


People_Ali_Like = adel


والذي حدث داخل البرولوج للوصول الى هذه النتيجة هو كالتالي:



يبدأ البرولوج في البحث داخل قاعة المعرفة من اول عبارة وعندما يجد اي توافق بين المسند والمعامل الأول في السؤال والمسند والمعامل الاول في الحقيقة يقوم بوضع علامة عند هذه الحقيقة ويحاول بعد ذلك البحث عن حقيقة اخرى تتفق مع السؤال وهكذا الى ان يتم البحث في قاعدة المعرفة كلها .




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


إضافة القواعد الى قاعدة المعرفة

يمكن إضافة القواعد (Rules) على قاعدة المعرفة بكتابتها بالشكل التالي:



P:-

Q,


R,

.

.

.

Z.



أو كتابتها بالشكل التالي :



P:-Q,R,...Z



وكما نرى تتكون القاعدة من قسمين هما العنوان (head) و الجسم(body) ويفصل كلا منهما العلامة (-).

ففي المثال السابق تمثل (P) العنوان وتمثل (Q,R,..,,Z) جسم القاعدة

وهذه القاعدة تعني أن (P) تتحقق (اى True ) إذا تحقق كل من (R..,..,..,(Z),(Q) ) لاحظ أن الفاصلة هنا تعني (and) ويمكن استخدام ( أى (or) داخل جسم القاعدة أيضا.


وتضاف القاعدة الجديدة إلى قاعدة المعرفة أو تكتب في صورة برنامج للتحكم في عملية البحث و استخراج البيانات المطلوبة ,والمثال التالي يوضح ذلك : 

إذا أردنا البحث عن شخص ما (person 1) والذى يكون أخا لشخص معروف (person 2) نكتب القاعدة التالية :



brother_of (Person1 , Person2):-

parent(X,Person 1),

parent(X,Person 2),


sex(Person 1,male),

diff(Person 1, Person 2).

diff (X , Y):- X /= Y


وهذا معناه أننا نحدد أن الشخص الاول (person 1) يكون أخا للشخص الثاني (person 2) إذا كان والد (parent) الشخص الاول هو نفسه والد الشخص الثاني ، وأن الشخص الاول ذكر (لأنه "أخ"الشخص الثاني)وكذلك الشخص الاول يختلف عن الشخص الثاني (وذلك لكي لا يرد علينا البرولوج بأن محمد أخو نفسه لأن لهم نفس الاب !) والقاعدة التي تفرق بين الشخصين تم كتابتها بعد القاعدة الاولى وهى تقول أن المتغير (X) لا يساوي (=/)المتغير(Y)


ولتوضيح هذه القاعدة نكتب قاعدة المعرفة الخاصة بالأسرة المكونة من (Ali) أب و (Fatma) أم و (Mona, Ahmad, Mohammad , Khalid ) أبناء .

وهي تكتب كالآتي:



Parent (ali,ahmad).

parant (ali , mohammad).

parant (ali , Khalid).


parant (ali , mona).

parant (fatma , mona).

parant (fatma , mohammad).

parant (fatma , Khalid).

parant (fatma , ahmad).

sex (ali , male).


sex (fatma , female).

sex (mona , female).

sex (ahmad , male).

sex (mohammad , male).

sex (Khalid , male).

وهذه التعبيرات أو الحقائق التي تكون قاعدة المعرفة للأسرة تمثل العلاقات التي تربط الأسماء ببعضها وهي أن (Ali) هو والد كل من (ahmad) و (mohammad) و (Khalid) وهو ذكر (male) وهم ذكور وهو أيضا والد (mona) وهي أنثى (female) وان (fatma) هي أم كل من (ahmad)و(Khalid)و(mohammad)و(mona)وهي أنثى (female) وبعد كتابة قاعدة المعرفة كما سبق الإيضاح يمكن أجراء الاستفسارات التالية:


1-هل (Khalid) أخو (mohammad) ويكون السؤال كالتالي :



brother_of( khalid , mohammad)?

وتكون الإجابة بالإيجاب



Yes

وذلك لان البرولوج تتبع الخطوات التي تحقق القاعدة (brother_of) وهي أن الشخص الأول والثاني لهما نفس الأبويين والأول ذكر ويختلف عن الثاني (أي أن Khalid لا يساوي mohammad).

2- من هم أخوة (ahmad), ويكون السؤال كالتالي:




Brother_of( X , ahmad )?

وفي هذه الحالة يكون الرد بأسماء كل إخوة (ahmad) الذين يتفقون مع القاعدة ( brother_of ) ويكون الرد كالتالي



X=mohammad

X=Khalid

أي أن كل من (mohammad) و (Khalid) يتفق مع المتغير (X) والذي يمثل اسم اخوة ( ahmad) ويلاحظ انه لم يذكر (mona) وذلك لان نوعها (sex) يختلف عن النوع الموجود بالقاعدة (brother_of ).




العمليات الرياضية (Arithmetic Operations)

تحتوي معظم إصدارات لغة البرولوج على المعاملات الرياضية (Arithmetic Operation) الموضحة في الجدول التالي , كما أن بعض الإصدارات تحتوي على المعامل (is) والذي يقوم بعمل المعامل (=), أي أن العبارة (x is 10+20) تكافئ (x = 10+20)




المعامل

المعنى

مثال

الناتج
+ الجمع

2+3
5
- الطرح 3-1 2
* الضرب 3*5 15
/
ناتج القسمة الصحيحة
7/4 1

mod

باقي القسمة الصحيحة
mod 7 4 3
=
اختبار التساوي
2=2
true

/=

اختبار عدم التساوي

3=/2
true
< اكبر من 3>5 false
> اقل من 3<5 true
<= اقل من او يساوي x<=y
غير محدد

>=
اكبر من او يساوي
X <=y

غير محدد



القوائم(Lists)

كما في لغة ليسب فإن البرولوج توفر استخدام القوائم (Lists) والقائمة هي إما عنصر Atom)) يمثل قائمة فارغة ([]) وإما تركيب مكون من معاملين (Arguments Two) الرأس (Head) والذيل (Tail) محصورين داخل قوسين مربعين ([]) ويمثل الرأس العنصر الأول (First Element) والذيل باقي العناصر . فمثلا في القائمة [a , b , c , d ,e,]فإن العنصر (a) يمثل رأس القائمة وباقي العناصر تمثل ذيل القائمة .

والمثال التالي يمثل كيفية استخدام القوائم في البرولوج:




وإذا اعتبرنا الحقيقة التالية:



Friends([a ,b , c , d ,e, ])


فإذا أردنا معرفة رأس القائمة و ذيلها نكتب السؤال التالي :






Friends([Head |Tail ])?

Or

Friends([Head |...Tail ])?


فيجب البرولوج بالآتي:



Head =a

Tail=[b,c,d,e]


أي أن ذيل القائمة هو أيضا قائمة فرعية



وبهذه الإمكانية يمكننا بناء الدوال الذاتية الموجودة في لغة ليسب ، مثل (car) و(cdr) و(member) في لغة البرولوج .فعلى سبيل المثال يمكن كتابة الدالة (member) في لغة البرولوج ، بتعريفها بالقاعدتين التاليتين :

1- العنصر (A) عضو(member) في القائمة (P) إذا كان (A) هو أول عنصر في (P).


2- إذا لم يكن (A) هو أول عنصر في (P) فإن (A) يكون عنصرا في(P) فقط إذا كان عنصر في ذيل القائمة (P) .



وتكتب هاتان القاعدتان في لغة البرولوج كالتالي :



member(A ,[A|_ ])

member(A ,[_ |Y]):- member(A ,Y)



ففي القاعدة (أو الحقيقة ) الأولى نعرف أن المسند (member) يتحقق إذا كان العنصر (A) هو أول عنصر في القائمة بغض النظر عن ذيل القائمة ( وتعرف هذه بوضع العلامة (_) وتسمى (Underscore) مكان ذيل القائمة )



اما في القاعدة الثانية فإن المسند (member) يتحقق إذا كان عنصرا في ذيل القائمة بغض النظر عن رأس القائمة وهذه القاعدة تسمى بالقاعدة التكرارية (Recursive) .



معامل القطع للبحث الراجع

معامل القطع (Cut Operator)هو من أهم المعاملات في لغة البرولوج والذي يتحكم في عملية البحث الراجع(Backtracking) ويمثل هذا المعامل بعلامة التعجب ( !). و استخدام هذا المعامل يعني للبرولوج تخطي الاختبارات السابقة للاختبار الذي يوجد به معامل القطع ( !) وذلك عندما تبدأ البرولوج في عملية البحث الراجع وهذا المعامل يستخدم لزيادة سرعة البرنامج وتقليل المساحة المستخدمة من الذاكرة وكذلك منع البرولوج من أعطاء عدد كبير أو لا نهائي من الحلول




ولتوضيح تأثير هذا المعامل نأخذ المثال التالي :



باستخدام القاعدتين السابقتين للدالة (member) ولاستفسار بالسؤال التالي :




member(X ,[a ,b ,c , d, e ,])?

يرد البرولوج بالتالي:




X=a

X=b

X=c

X=d

X=e



وللحد من هذا العدد الكبير من الحلول نستخدم معامل القطع في قاعدتي تعريف الدالة (member) كالتالي:





member(X ,[X |_ ]) :-!.

member(X ,[_ |Y]):- member(X ,Y)

في هذه الحالة عند الاستفسار بالسؤال



member(X ,[a ,b ,c , d, e ,])?



يكون الرد كالآتي :



X=a

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