تعريف الحوسبة {#compchap }
تعريف الحوسبة
- أن ترى كيف يمكن نمذجة الحوسبة بدقّة. \
- أن تتعلّم النموذج الحوسب للدوائر المنطقية (Boolean circuits) / البرامج المستقيمة.
- تكافؤ الدوائر مع البرامج المستقيمة.
- تكافؤ AND/OR/NOT مع NAND.
- أمثلة على الحساب في العالم الفيزيائي. \
"لا يوجد سبب يمنع من الاقتصاد في العمل العقلي كما في العمل البدني بمعاونة الآلات"، تشارلز بابيج، 1852
"إن لم ينبّهه مثالُي، وشرع أي رجل في بناء مُحرّك يجسّد في ذاته كامل القسم التنفيذي من التحليل الرياضي على مبادئ مختلفة أو بوسائل ميكانيكية أبسط، فلا أخشى أن أترك سمعتي في عهده، إذ هو وحده القادر تمامًا على تقدير طبيعة جهدي وقيمة نتائجه."، تشارلز بابيج، 1864
"لفهم برنامج لا بدّ أن تصير في آن واحد الماكينة والبرنامج"، آلان بيرليس، 1982


لقد كان الناس يحسبون لآلاف السنين، بمعونات لا تقتصر على القلم والورق، بل تشمل العدّاد (abacus) والمسطرةَ الحسابية (slide rules) والأجهزةَ الميكانيكيةَ المتنوعة، والحواسيبَ الإلكترونيةَ الحديثة. من حيث المبدأ، تبدو فكرة الحوسبة مرتبطة بالأداة التي تستخدمها بعينها. قد تظنّ أن الخوارزمية «الأفضل» لضرب الأعداد ستكون مختلفة إن نفّذتها في Python على حاسوب محمول حديث عمّا لو استخدمت القلم والورق. غير أننا، كما رأينا في المقدمة (مقدمة)، فإن الخوارزمية الأفضل من حيث السلوك التصاعدي (asymptotically better) كانت لتتفوّق في النهاية على خوارزمية أضعف مهما كانت التقنية الكامنة. وهذا يمنحنا أملًا في طريقة مستقلة عن التقنية (technology independent) لتعريف الحوسبة. وهذا هو ما نفعله في هذا الفصل. سنعرّف فكرة حساب مُخرَج من مُدخَل عبر تطبيق تسلسل من العمليات الأساسية (انظر الشكل التوضيحي). وباستخدام هذا، سنتمكن من تعريف عبارات مثل «الدالة يمكن حسابها بالنموذج » أو «الدالة يمكن حسابها بالنموذج باستخدام عمليات» بدقّة.

أبرز ما نستفيده من هذا الفصل هو ما يلي:
-
يمكننا استخدام العمليات المنطقية (logical operations) مثل و و لحساب مُخرج من مُدخل (انظر الحساب باستخدام AND وOR وNOT.).
-
الدائرة المنطقية (Boolean circuit) هي طريقة لتركيب العمليات المنطقية الأساسية معًا لتحسب دالةً أعقد (انظر الدوائر المنطقية). ويمكننا أن نرى الدوائر المنطقية بوصفها نموذجًا رياضيًا (قائمًا على الرسوم البيانية الموجَّهة غير الدورية) فضلًا عن كونها أجهزة فيزيائية يمكننا بناؤها في العالم الحقيقي بطرق متنوّعة، لا تقتصر على أشباه الموصلات السيليكونية فحسب بل تشمل أيضًا الآليات الميكانيكية وحتى الحيوية (انظر التنفيذات الفيزيائية لأجهزة الحوسبة (استطراد)).
-
يمكننا أيضًا وصف الدوائر المنطقية بوصفها برامج مستقيمة (straight-line programs)، أي برامج لا تحتوي على أي بِنَى تكرارية (أي لا
whileولاforولاdo .. untilإلخ)، انظر البرامج المستقيمة. -
من الممكن تنفيذ عمليات و و باستخدام العملية (وكذلك العكس). وهذا يعني أن الدوائر ذات البوابات // تستطيع حساب الدوال نفسها (أي أنها متكافئة في القدرة) التي تحسبها الدوائر ذات بوابات ، ويمكننا استخدام أيّ النموذجين لوصف الحوسبة بحسب ما يريحنا، انظر دالة NAND. ولكي نكشف جانبًا من الجواب مبكرًا، سنرى في السكر النحوي، وحساب كل دالة أن مثل هذه الدوائر تستطيع حساب كل الدوال المتناهية.
إحدى «الفكرة الكبرى» في هذا الفصل هي فكرة التكافؤ (equivalence) بين النماذج (equivalencemodels). ويكون نموذجان حوسبان متكافئين إذا استطاعا حساب المجموعة نفسها من الدوال. والدوائر المنطقية ذات البوابات // تكافئ الدوائر ذات بوابات ، لكن هذا مجرد مثال على ظاهرة أعمّ سنلتقي بها مرارًا في هذا الكتاب.
تعريف الحوسبة
اسم «الخوارزمية» مشتق من النقل اللاتيني لاسم محمد بن موسى الخوارزمي. كان الخوارزمي عالمًا فارسيًا في القرن التاسع الميلادي، عرّض كتبه العالمَ الغربي على نظام الأرقام العشري الموضعي، فضلًا عن حلول المعادلات من الدرجة الأولى والثانية (انظر الشكل التوضيحي). غير أن أوصاف الخوارزميات عند الخوارزمي كانت غير رسمية إلى حدٍّ كبير بمقاييس اليوم. فهو لم يستخدم «متغيّرات» مثل ، بل استخدم أعدادًا بعينها مثل 10 و39، ووثق في القارئ أن يكون قادرًا على التعميم انطلاقًا من هذه الأمثلة، تمامًا كما لا يزال تُعلَّم الخوارزميات للأطفال اليوم.
إليك كيف وصف الخوارزمي خوارزمية حل معادلة من الشكل :
[كيف تحلّ معادلة من الشكل ] «الجذور والمربعات تساوي أعدادًا»: على سبيل المثال «مربع واحد، وعشرة جذور منه، مجموعها تسعة وثلاثون درهمًا»، أي ما هو المربع الذي إذا زيد إليه عشرة من جذره بلغ تسعة وثلاثين؟ الحل هو هذا: أنصِف عدد الجذور، فيصير في هذه الحالة خمسة. اضرب هذا في نفسه، فيكون الناتج خمسة وعشرين. أضِف هذا إلى تسعة وثلاثين، فيكون المجموع أربعة وستين. خُذ الآن جذر هذا المجموع، وهو ثمانية، واطرح منه نصف عدد الجذور، وهو خمسة، فيبقى ثلاثة. هذا هو جذر المربع الذي كنت تبحث عنه؛ وأما المربع نفسه فتسعة.


ولأغراض هذا الكتاب، سنحتاج إلى طريقة أدقّ بكثير لوصف الخوارزميات. ولحسن الحظ (أو لسوء الحظ؟)، على الأقل في الوقت الحالي، تتأخر الحواسيب كثيرًا في التعلّم من الأمثلة مقارنةً بأطفال سنّ المدرسة. ولهذا، في القرن العشرين، ابتكر الناس صيغًا رسمية دقيقة لوصف الخوارزميات، وهي لغات البرمجة. إليك خوارزمية الخوارزمي لحل المعادلات من الدرجة الثانية مصوغةً بلغة البرمجة Python:
from math import sqrt
#Pythonspeak to enable use of the sqrt function to compute square roots.
def solve_eq(b,c):
# return solution of x^2 + bx = c following Al Khwarizmi's instructions
# Al Kwarizmi demonstrates this for the case b=10 and c= 39
val1 = b / 2.0 # "halve the number of the roots"
val2 = val1 * val1 # "this you multiply by itself"
val3 = val2 + c # "Add this to thirty-nine"
val4 = sqrt(val3) # "take the root of this"
val5 = val4 - val1 # "subtract from it half the number of roots"
return val5 # "This is the root of the square which you sought for"
# Test: solve x^2 + 10*x = 39
print(solve_eq(10,39))
# 3.0
يمكننا تعريف الخوارزميات إجرائيًا على النحو التالي:
اقتباس
تعريف إجرائي للخوارزمية: الخوارزمية (algorithm) مجموعة تعليمات تصف كيفية حساب مُخرج من مُدخل عبر اتباع تسلسل من «الخطوات الأولية».
تقول الخوارزمية إنها تحسب الدالة إذا كان لكل مُدخل ، حين نتبع تعليمات على المُدخل ، ينتج عن ذلك المُخرج .
في هذا الفصل سنجعل هذا التعريف الإجرائي دقيقًا باستخدام نموذج الدوائر المنطقية (Boolean Circuits). وسنبيّن أن الدوائر المنطقية متكافئة في القدرة مع البرامج المستقيمة (straight line programs) المكتوبة بلغات برمجة «فائقة البساطة» لا تحوي حتى حلقات تكرار. وسنرى أيضًا أن الاختيار بعينه للعمليات الأولية (elementary operations) لا أهمية له، وأن اختيارات كثيرة مختلفة تُنتج نماذج متكافئة القدرة (انظر الشكل التوضيحي). غير أننا سنحتاج إلى بعض الوقت حتى نصل إلى ذلك. وسنبدأ بمناقشة ما هي «العمليات الأولية»، وكيف نحوّل وصفًا لخوارزمية إلى عملية فيزيائية فعلية تُنتج مُخرجًا من مُدخل في العالم الحقيقي.

الحساب باستخدام AND وOR وNOT.
تفكّك الخوارزمية الحسابَ المعقّد إلى سلسلة من خطوات أبسط. وتنفيذ هذه الخطوات ممكن بطرق متنوّعة مختلفة، منها:
-
كتابة الرموز على ورقة.
-
تعديل التيار الكهربائي الذي يجري في الأسلاك.
-
ربط بروتينٍ بخيط من الحمض النووي.
-
الاستجابة لمنبّه من جانب عنصر في مجموعة (مثل نحلة في مستعمرة، أو تاجر في سوق).
ولكي نعرّف الخوارزميات تعريفًا رسميًا، فلنحاول أن «نميل إلى جهة البساطة» وأن نمذجة «خطواتنا الأساسية» بوصفها بالغة الدقّة. فمثلًا، إليك بعض الدوال البسيطة جدًا:
- المعرَّفة بما يلي:
- المعرَّفة بما يلي:
- المعرَّفة بما يلي:
الدوال و و هي المشغّلات المنطقية الأساسية المستخدمة في المنطق وفي أنظمة حواسوب كثيرة. وفي سياق المنطق، من الشائع استعمال التدوين للدالة ، و للدالة ، و و للدالة ، وسنستعمل هذا التدوين أيضًا.
كل واحدة من الدوال تأخذ إمّا بتًّا واحدًا أو اثنين كمدخل، وتُنتج بتًّا واحدًا كمخرج. ومن البديهي أنها لا يمكن أن تكون أكثر أولية من ذلك. غير أن القدرة الحوسبية مصدرها تركيب هذه القوالب الأولية البسيطة معًا.
مثال — الأغلبية من و و
لتُعتبر الدالة المعرَّفة بما يلي:
بمعنى آخر، لكل ، لدينا إذا ونحو فقط إذا كانت أكثرية عناصر (أي اثنين على الأقل من الثلاثة) مساوية لـ . هل تستطيع أن تجد صيغة تتضمّن و و لحساب ؟ (من المفيد لك أن تتوقف هنا وتستنتج الصيغة بنفسك. وكإرشاد، فرغم أن المشغّل لازم لحساب بعض الدوال، فإنك لن تحتاج إليه لحساب .)
لنحاول أولًا أن نعيد صياغة بالكلمات: « إذا ونحو فقط إذا وُجد زوجٌ ما من العناصر المتمايزة بحيث يكون و كلاهما مساويًا لـ ». وبعبارة أخرى، يعني ذلك أن إذا ونحو فقط إذا كان إمّا و كلاهما، أو و كلاهما، أو و كلاهما. ولأن لثلاثة شروط يمكن كتابتها ، يمكننا الآن ترجمة ذلك إلى صيغة كالتالي:
تذكّر أننا يمكننا أيضًا كتابة للدالة و للدالة . وبهذا التدوين، يمكن كتابة المعادلة أيضًا على الصورة
كما يمكننا كتابة المعادلة بصورة «لغة برمجة»، أي التعبير عنها كمجموعة تعليمات لحساب انطلاقًا من العمليات الأساسية :
def MAJ(X[0],X[1],X[2]):
firstpair = AND(X[0],X[1])
secondpair = AND(X[1],X[2])
thirdpair = AND(X[0],X[2])
temp = OR(secondpair,thirdpair)
return OR(firstpair,temp)
بعض خواص AND وOR
كما في الجمع والضرب المعياريَّين، فإن الدالتين و تستوفيان خاصيتي التبديل (commutativity): و، وخاصية التجميع (associativity): و. وكما في حالة الجمع والضرب، فإننا نُسقط الأقواس غالبًا ونكتب بدلًا من ، وكذلك في حالات OR وAND لأكثر من حدّ. كما أنهما تستوفيان صيغةً من صيغ قانون التوزيع:
تمرين محلول — قانون التوزيع لـ AND و OR
أثبِت أن لكل ، لدينا .
الحل
يمكننا إثبات ذلك بحصر جميع القيم الثمانية الممكنة لـ ، لكنه أيضًا يتبع قانون التوزيع المعياري. لنفترض أن نُطابق أي عدد صحيح موجب مع «صحيح» والقيمة صفر مع «خطأ». عندئذٍ لكل عددين ، يكون موجبًا إذا ونحو فقط إذا كانت صحيحة، ويكون موجبًا إذا ونحو فقط إذا كانت صحيحة. وهذا يعني أن لكل ، يكون التعبير صحيحًا إذا ونحو فقط إذا كان موجبًا، ويكون التعبير صحيحًا إذا ونحو فقط إذا كان موجبًا، ولكن بقانون التوزيع المعياري فإن ، وبالتالي فالتعبير الأول صحيح إذا ونحو فقط إذا كان التعبير الثاني كذلك.
مثال موسّع: حساب من و و
لِنَرَ كيف يمكننا الحصول على دالة مختلفة من القوالب البناءية نفسها. لنُعرِّف لتكون الدالة . أي أن و. ونحن ندّعي أنه يمكننا بناء باستخدام و و لا غير.
توقّف وتأمّل
وكالمعتاد، من التمارين المفيدة أن تحاول استنتاج خوارزمية باستخدام و و بنفسك قبل أن تقرأ ما يلي.
تحسب الخوارزمية التالية باستخدام و و:
خوارزمية — من //
Input: $a,b \in \{0,1\}$.
Output: $XOR(a,b)$
$w1 \leftarrow AND(a,b)$
$w2 \leftarrow NOT(w1)$
$w3 \leftarrow OR(a,b)$
return $AND(w2,w3)$
لمّة
لكل ، عند المدخلين ، تُنتج الخوارزمية خوارزمية — XOR من AND/OR/NOT القيمة .
برهان
لكل ، لدينا إذا ونحو فقط إذا كان مختلفًا عن . وعند المدخلين ، تُنتج الخوارزمية خوارزمية — XOR من AND/OR/NOT القيمة حيث و.
-
إذا كان فإن ، وبالتالي سيكون المُخرج .
-
إذا كان فإن ، وبالتالي يكون ، وسيكون المُخرج .
-
إذا كان و (أو العكس) فإن كلًّا من و، وفي هذه الحالة ستُنتج الخوارزمية .
كما يمكننا التعبير عن الخوارزمية خوارزمية — XOR من AND/OR/NOT بلغة برمجة. وعلى وجه التحديد، إليك برنامج Python يحسب الدالة :
def AND(a,b): return a*b
def OR(a,b): return 1-(1-a)*(1-b)
def NOT(a): return 1-a
def XOR(a,b):
w1 = AND(a,b)
w2 = NOT(w1)
w3 = OR(a,b)
return AND(w2,w3)
# Test out the code
print([f"XOR({a},{b})={XOR(a,b)}" for a in [0,1] for b in [0,1]])
# ['XOR(0,0)=0', 'XOR(0,1)=1', 'XOR(1,0)=1', 'XOR(1,1)=0']
تمرين محلول — حساب على ثلاثة بتات مُدخلة
لتكن الدالة المعرَّفة بـ . أي أن إذا كان فرديًا، و في غير ذلك. أثبِت أنه بإمكانك حساب باستخدام AND وOR وNOT. يمكنك التعبير عنها بصيغة، أو استخدام لغة برمجة مثل Python، أو استخدام دائرة منطقية.
الحل
الجمع على مقياس اثنين يستوفي خصيتي التجميع () و_التبديل_ () نفسها التي يستوفيها الجمع المعياري. وهذا يعني أنه إذا عرّفنا بأنه يساوي ، فإن أو بمعنى آخر
ولأننا نعرف كيف نحسب باستخدام AND وOR وNOT، يمكننا تركيب ذلك لحساب بالقوالب البناءية نفسها. وفي Python يقابل ذلك البرنامج التالي:
def XOR3(a,b,c):
w1 = AND(a,b)
w2 = NOT(w1)
w3 = OR(a,b)
w4 = AND(w2,w3)
w5 = AND(w4,c)
w6 = NOT(w5)
w7 = OR(w4,c)
return AND(w6,w7)
# Let's test this out
print([f"XOR3({a},{b},{c})={XOR3(a,b,c)}" for a in [0,1] for b in [0,1] for c in [0,1]])
# ['XOR3(0,0,0)=0', 'XOR3(0,0,1)=1', 'XOR3(0,1,0)=1', 'XOR3(0,1,1)=0', 'XOR3(1,0,0)=1', 'XOR3(1,0,1)=0', 'XOR3(1,1,0)=0', 'XOR3(1,1,1)=1']
توقّف وتأمّل
حاول تعميم الأمثلة أعلاه للحصول على طريقة لحساب لكل باستخدام خطوة أساسية على الأكثر، وتكون تطبيقات لدالة من على مُخرجات أو على قيم حُسبت سابقًا.
تعريف «العمليات الأساسية» و«الخوارزميات» إجرائيًا
لقد رأينا أننا يمكننا الحصول على بعض الأمثلة على الأقل من الدوال المهمة، عبر تركيب و و معًا. وهذا يوحي إلينا باستعمال و و بوصفها «عملياتنا الأساسية»، فنحصل على التعريف التالي لـ«الخوارزمية»:
اقتباس
تعريف شبه رسمي للخوارزمية: تتألف الخوارزمية (algorithm) من تسلسل خطوات من الشكل «احسب قيمة جديدة بتطبيق أو أو على قيم حُسبت سابقًا (مع الافتراض بأن المُدخل قد حُسب بدوره سابقًا)».
تقول الخوارزمية إنها تحسب الدالة إذا كان لكل مُدخل للدالة ، حين نُدخل كمدخل إلى الخوارزمية، كانت القيمة المحسوبة في خطوتها الأخيرة هي .
يثير هذا التعريف عدة مخاوف:
-
أولًا وقبل كل شيء، هذا التعريف غير رسمي فعلًا. فنحن لا نحدّد بدقّة ما الذي تفعله كل خطوة، ولا ما الذي يعنيه «إدخال كمدخل».
-
ثانيًا، يبدو اختيار أو أو عشوائيًا إلى حدٍّ كبير. ولماذا لا و؟ ولماذا لا نسمح بعمليات مثل الجمع والضرب؟ وماذا عن أي بِنَى منطقية أخرى مثل
if/thenأوwhile؟ -
ثالثًا، هل نعرف أصلًا أن لهذا التعريف علاقة بأي حساب فعلي؟ فلو أعطى أحدهم لنا وصفًا لخوارزمية كهذه، فهل يمكننا استعمالها فعلًا لحساب الدالة في العالم الحقيقي؟
توقّف وتأمّل
ستوجّه هذه المخاوف مسيرتنا إلى حدٍّ كبير في الفصول القادمة. ومن ثمّ فإن من الحكمة أن تعيد قراءة التعريف الإجرائي أعلاه وتنظر فيما تعبّر عنه من رأي في هذه المسائل.
سيُخصَّص جزء كبير من هذا الكتاب لمعالجة المسائل أعلاه. وسنرى أن:
-
يمكننا أن نجعل تعريف الخوارزمية رسميًا تمامًا، وبالتالي منح معنى رياضيًا دقيقًا لعبارات مثل «الخوارزمية تحسب الدالة ».
-
ورغم أن اختيار // عشوائي، وأن كان بإمكاننا أن نختار دوال أخرى بالقدر نفسه، فسنرى أيضًا أن هذا الاختيار لا أهمية كبيرة له. وسنرى أننا لو استخدمنا بدلًا منه الجمع والضرب، بل وكل عملية أخرى يمكن اعتبارها بصورة معقولة خطوةً أساسية، لَحَصّلنا على القدرة الحوسبية نفسها.
-
ويبيّن الأمر في الواقع أننا يمكننا أن نحسب هذه «الخوارزميات المعتمدة على //» في العالم الحقيقي، بل إننا نفعل ذلك فعلًا. أولًا، مثل هذه الخوارزمية محدَّدة بدقّة واضح، ولذلك يمكن تنفيذها من إنسان بقلم وورقة. وثانيًا، هناك طرائق متنوّعة لآلية (mechanize) هذا الحساب. لقد رأينا بالفعل أننا نستطيع كتابة شيفرة Python تقابل اتباع قائمة التعليمات هذه. لكننا في الواقع نستطيع تنفيذ عمليات مثل و و مباشرةً عبر إشارات إلكترونية باستخدام مكوّنات تُعرف بالـ_ترانزستورات_ (transistors). هكذا تعمل الحواسيب الإلكترونية الحديثة.
وفي بقية هذا الفصل، وفي بقية هذا الكتاب، سنبدأ في الإجابة عن بعض هذه الأسئلة. وسنرى أمثلة أكثر على قوة العمليات البسيطة في حساب عمليات أعقد، منها الجمع والضرب والترتيب وغيرها. وسنناقش أيضًا كيف نُنفّذ فيزيائيًا عمليات بسيطة مثل و و باستخدام تقنيات متنوّعة.
الدوائر المنطقية


توفّر الدوائر المنطقية (Boolean circuits) مفهومًا دقيقًا لـ«تركيب العمليات الأساسية معًا». تتألف الدائرة المنطقية (انظر الشكل التوضيحي) من بوابات و_مُدخلات_ متّصلة بواسطة أسلاك. تحمل الأسلاك إشارة تمثّل إمّا القيمة وإمّا القيمة . تقابل كل بوابة إمّا عملية OR أو AND أو NOT. وللبوابة OR سلكان داخليان، وسلك خارج واحد أو أكثر. إذا حمل هذان السلكان الداخليان الإشارتين و (من أجل )، فإن الإشارة على الأسلاك الخارجية ستكون . وتُعرَّف بوابتا AND و_NOT_ بالمثل. أما المُدخلات فليس لها إلا أسلاك خارجة. إذا عيّننا مُدخلًا معيّنًا على القيمة ، فإن هذه القيمة تنتشر على كل الأسلاك الخارجة منه. كما نُعيّن بعض البوابات لتكون بوابات مُخرَج، وتُقابل قيمتها نتيجة تقييم الدائرة. على سبيل المثال، يقدّم الشكل التوضيحي دائرة كهذه للدالة ، وفق مثال موسّع: حساب XOR من AND وOR وNOT. نُقيّم دائرة منطقية ذات مُدخلًا على مُدخل بوضع بتات على المُدخلات، ثم نشر القيم على الأسلاك حتى نصل إلى مُخرج، انظر الشكل التوضيحي.
ملاحظة — التجسيد الفيزيائي للدوائر المنطقية
الدوائر المنطقية هي نموذج رياضي لا يقابل بالضرورة جسماً ماديًا، لكنها قابلة للتنفيذ فيزيائيًا. في التنفيذات الفيزيائية للدوائر، تُنفَّذ الإشارة غالبًا بواسطة فرق الجهد الكهربائي، أو الجهد الكهربائي (voltage)، على سلك، حيث يُفسَّر، مثلًا، الجهد الأعلى من مستوى معيّن على أنه قيمة منطقية ، والأدنى من مستوى معيّن على أنه قيمة منطقية . يناقش التنفيذات الفيزيائية لأجهزة الحوسبة (استطراد) التنفيذات الفيزيائية للدوائر المنطقية (مع أمثلة تشمل استعمال الإشارات الكهربائية كما في الدوائر السيليكونية، وكذلك التنفيذات الحيوية والميكانيكية).

تمرين محلول — دالة التساوي التام
عرِّف لتكون الدالة التي على المُدخل تُنتج إذا ونحو فقط إذا كان . أعطِ دائرة منطقية لحساب .
الحل
هناك طريقة أخرى لوصف الدالة : أنها تُنتج على مُدخل إذا ونحو فقط إذا كان أو . ويمكننا صياغة الشرط على صورة ، ويمكن حسابه باستعمال ثلاث بوابات AND. وبالمثل يمكننا صياغة الشرط على صورة ، ويمكن حسابه باستعمال أربع بوابات NOT وثلاث بوابات AND. ومُخرج هو OR لهذين الشرطين، أي الدائرة ذات 4 بوابات NOT و6 بوابات AND وبوابة OR واحدة المعروضة في الشكل التوضيحي.

الدوائر المنطقية: تعريف رسمي
عرّفنا الدوائر المنطقية إجرائيًا بأنها ما يُحصل عليه بوصل بوابات AND و_OR_ و_NOT_ بواسطة أسلاك لإنتاج مُخرج من مُدخل. غير أنه، لكي نتمكّن من إثبات مبرهنات حول وجود دوائر منطقية تحسب دوالّ متنوّعة أو عدم وجودها، نحتاج إلى:
-
أن نعرّف الدائرة المنطقية رسميًا بوصفها كائنًا رياضيًا.
-
أن نعرّف رسميًا معنى قول الدائرة إنها تحسب الدالة .
وسنقوم الآن بذلك. سنعرّف الدائرة المنطقية بأنها رسم بياني موجَّه غير دوري (Directed Acyclic Graph) مُوسَم. وتُقابل رؤوس (vertices) الرسم البياني بوابات الدائرة ومُدخلاتها، بينما تُقابل حواف (edges) الرسم البياني الأسلاك. السلك الذي ينتقل من مُدخل أو بوابة إلى بوابة في الدائرة يقابل حافة موجَّهة بين الرأسين المقابلين. أما المُدخلات فهي رؤوس لا حواف داخلية لها، بينما لكل بوابة العدد المناسب من الحواف الداخلية بحسب الدالة التي تحسبها. (أي أن بوابتَي AND و_OR_ لهما جيران داخليان اثنان، بينما لبوابة NOT جار داخلي واحد.) والتعريف الرسمي هو ما يلي (انظر أيضًا الشكل التوضيحي):

تعريف — الدوائر المنطقية
لتكن أعدادًا صحيحة موجبة بحيث . الدائرة المنطقية (Boolean circuit) ذات مُدخلًا و مُخرجًا و بوابة هي رسم بياني موجَّه غير دوري (DAG) مُوسَم له رأسًا، يستوفي الخصائص التالية:
-
بالضبط من الرؤوس ليس لها جيران داخلية. وتُعرف هذه الرؤوس بـ_المُدخلات_ وتُوسَم بـ من الوسوم
X[], ,X[]. ولكل مُدخل جار خارج واحد على الأقل. -
الرؤوس الـ الأخرى تُعرف بـ_البوابات_. وتُوسَم كل بوابة بـ أو أو . والبوابات الموسومة بـ (AND) أو (OR) لها جيران داخليان اثنان. والبوابات الموسومة بـ (NOT) لها جار داخلي واحد. وسنسمح بالحواف الموازية.[1]
-
بالضبط من البوابات تُوسَم أيضًا بـ من الوسوم
Y[], ,Y[](بالإضافة إلى وسمها //). وتُعرف هذه بـ_المُخرجات_.
و_حجم_ الدائرة المنطقية هو العدد من البوابات التي تحتوي عليها.
توقّف وتأمّل
هذا تعريف رياضي غير تافه، ومن ثمّ من المفيد أن تقرأه ببطء وتدقيق. فكما في كل التعريفات الرياضية، فإننا نستعمل كائنًا رياضيًا معروفًا --- رسمًا بيانيًا موجَّهًا غير دوري (DAG) --- لتعريف كائن جديد، هو الدائرة المنطقية. قد يكون هذا وقتًا مناسبًا لمراجعة بعض الخصائص الأساسية للرسوم البيانية غير الدورية، وخصوصية أنها يمكن أن تُرتَّب طوبولوجيًّا، انظر مثال موسّع: الفرز الطوبولوجي.
إذا كانت دائرة ذات مُدخلًا و مُخرجًا، و، فيمكننا حساب مُخرج على المُدخل بالطريقة الطبيعية: نُسند إلى رؤوس المُدخلات X[], , X[] القيم ، ونطبّق كل بوابة على قيم جيرانها الداخلة، ثم نُخرج القيم المقابلة لرؤوس الخرج.
ويُعرَّف ذلك رسميًا على النحو التالي:
تعريف — حساب دالة بواسطة دائرة منطقية
لتكن دائرة منطقية ذات مُدخلًا و مُخرجًا. لكل ، يُعرَّف مُخرج على المُدخل ، ويُرمز له بـ، بأنه نتيجة العملية التالية:
لتكن هي التوزيع الطبقي الأدنى (minimal layering) لـ (أي الفرز الطوبولوجي، انظر مبرهنة — الطبقيّة الأصغرية متفرّدة). ولتكن أكبر طبقة في ، ولكل نفعل ما يلي:
-
لكل في الطبقة (أي بحيث ) نفعل:
-
إذا كان رأس مُدخل موسومًا بـ
X[]لمُدخل ما ، فإننا نُسند إلى القيمة . -
إذا كان رأس بوابة موسومًا بـ وله جيران داخليان ، فإننا نُسند إلى ناتج AND للقيمتين المُسندتين إلى و. (وبما أن و جيران داخليان لـ، فإنهما في طبقة أدنى من ، وبذلك تكون قيمتُهما قد سُندت بالفعل.)
-
إذا كان رأس بوابة موسومًا بـ وله جيران داخليان ، فإننا نُسند إلى ناتج OR للقيمتين المُسندتين إلى و.
-
إذا كان رأس بوابة موسومًا بـ وله جار داخلي واحد ، فإننا نُسند إلى نفي القيمة المُسندة إلى .
-
-
نتيجة هذه العملية هي القيمة بحيث إن كان فإن هي القيمة المُسندة إلى الرأس الموسوم بـ
Y[].
ولتكن . نقول إن الدائرة تحسب إذا كان لكل ، لدينا .
ملاحظة — تفاصيل دقيقة في الدوائر المنطقية (اختياري)
في صياغة تعريف — الدوائر المنطقية، اتخذنا بعض الخيارات التقنية التي ليست بالغة الأهمية، لكنها ستكون مريحة لنا لاحقًا. معنى وجود حواف موازية أن بوابة AND أو OR المعنونة يمكن أن يكون كلا جيريها الداخلي هو البوابة نفسها. وبما أن لكل ، فإن هذه الحواف الموازية لا تساعد في حساب قيم جديدة في الدوائر ذات بوابات AND/OR/NOT. غير أننا سنرى لاحقًا دوائر بمجموعات بوابات أكثر عمومية. وشرط أن يكون لكل رأس مُدخل جار خارج واحد على الأقل ليس بالغة الأهمية أيضًا، لأن يمكننا دائمًا إضافة «بوابات وهمية» تلامس هذه المُدخلات. لكنه مريح لأنها تضمن أن عدد المُدخلات في الدائرة (بما أن لكل بوابة جيران داخليان على الأكثر) لا يتجاوز أبدًا ضعف حجمها.
البرامج المستقيمة
لقد رأينا طريقتين لوصف كيفية حساب دالة باستخدام AND و_OR_ و_NOT_:
-
الدائرة المنطقية (Boolean circuit)، المعرَّفة في تعريف — الدوائر المنطقية، تحسب بوصل بوابات AND و_OR_ و_NOT_ بالمُدخلات بواسطة الأسلاك.
-
ويمكننا أيضًا وصف حساب كهذا باستخدام برنامج مستقيم (straight-line program) تتكون أسطره من الشكل
foo = AND(bar,blah)وfoo = OR(bar,blah)وfoo = NOT(bar)، حيثfooوbarوblahأسماء متغيّرات. (ونسمّيه برنامجًا مستقيمًا لأنه لا يحتوي على حلقات تكرار ولا على تعليمات تفرّع (مثل if/then).)
ولجعل التعريف الثاني أدقّ، سنعرّف الآن لغة برمجة تكافئ الدوائر المنطقية. ونسميّ لغة البرمجة هذه لغة البرمجة AON-CIRC (يرمز "AON" إلى AND/OR/NOT، ويرمز "CIRC" إلى الدائرة).
على سبيل المثال، إليك برنامج AON-CIRC يُخرج، على مُدخل ، القيمة (أي عملية المطبَّقة على :
temp = AND(X[0],X[1])
Y[0] = NOT(temp)
لغة AON-CIRC ليست لغة برمجة عملية: فقد صُمِّمت لأغراض تعليمية فحسب، بوصفها وسيلة لنمذجة الحوسبة بوصفها تركيبًا لدوال و و. غير أنها مع ذلك يمكن تنفيذها بسهولة على الحاسوب.
وبناءً على هذا المثال، لعلك تستطيع بالفعل أن تخمّن كيف تكتب برنامجًا لحساب (مثلًا) ، وعمومًا كيف تترجم دائرة منطقية إلى برنامج AON-CIRC. غير أننا، لأننا نريد إثبات عبارات رياضية عن برامج AON-CIRC، سنحتاج إلى تعريف دقيق للغة البرمجة AON-CIRC. وقد تكون المواصفات الدقيقة للّغات البرمجة طويلة ومملّة في أحيانٍ كثيرة،[2] لكنها بالغة الأهمية للتنفيذات الآمنة والموثوقة. ولحسن الحظ، فإن لغة البرمجة AON-CIRC بسيطة بما يكفي لنعرّفها رسميًا بألمٍ قليل.
مواصفة لغة البرمجة AON-CIRC
برنامج AON-CIRC هو تسلسل من النصوص، نسمّيها «أسطرًا»، يستوفي الشروط التالية:
-
لكل سطر إحدى الصور التالية:
foo = AND(bar,baz)أوfoo = OR(bar,baz)أوfoo = NOT(bar)، حيثfooوbarوbazمعرِّفات متغيّرات. (ونتبع عرف لغات البرمجة الشائع في استعمال أسماء مثلfooوbarوbazبديلًا عن معرِّفات عامة.) ويقابل السطرfoo = AND(bar,baz)عملية إسناد القيمة المنطقية لـ AND إلى المتغيّرfooمن قيم المتغيّرينbarوbaz. ومثلًا، يقابلfoo = OR(bar,baz)وfoo = NOT(bar)عمليتي OR المنطقية وNOT المنطقية. -
يمكن أن يكون معرِّف المتغيّر في لغة البرمجة AON-CIRC أي تركيبة من الحروف والأرقام والشرطات السفلية والأقواس. وهناك نوعان خاصان من المتغيّرات:
- المتغيّرات من الشكل
X[], مع تُعرف بـ_متغيّرات المُدخل_. - المتغيّرات من الشكل
Y[]تُعرف بـ_متغيّرات الخرج_.
- المتغيّرات من الشكل
-
برنامج AON-CIRC الصحيح يتضمّن متغيّرات مُدخل من الشكل
X[],,X[]ومتغيّرات خرج من الشكلY[],,Y[]حيث عددان طبيعيان. ونقول إن هو عدد مُدخلات البرنامج و هو عدد مُخرجاته. -
في برنامج AON-CIRC الصحيح، يجب أن تكون المتغيّرات الموجودة في الطرف الأيمن من معامل الإسناد في كل سطر إمّا متغيّرات مُدخل وإمّا متغيّرات فُسندت لها قيمة في سطر سابق.
-
إذا كان برنامج AON-CIRC صحيحًا ذو مُدخلًا و مُخرجًا، فإن مُخرج على المُدخل لكل هو النص المعرَّف على النحو التالي:
- نهيّئ متغيّرات المُدخل
X[],,X[]على القيم - ننفّذ أسطر العمليات في واحدًا تلو الآخر بالترتيب، وفي كل سطر نُسند إلى المتغيّر في الطرف الأيسر من معاملات الإسناد قيمة العملية الموجودة في الطرف الأيمن.
- لتكن هي قيم متغيّرات الخرج
Y[],,Y[]في نهاية التنفيذ.
- نهيّئ متغيّرات المُدخل
-
نرمز لمُخرج على المُدخل بـ.
-
حجم برنامج AON circ هو عدد الأسطر التي يحتوي عليها. (ولعلّ القارئ يلاحظ أن هذا يوافق تعريفنا لحجم الدائرة بعدد البوابات التي تحتوي عليها.)
والآن وقد وصفنا برامج AON-CIRC رسميًا، يمكننا أن نعرّف معنى قول برنامج AON-CIRC إنه يحسب دالة :
تعريف — حساب دالة بواسطة برامج AON-CIRC
لتكن ، وليكن برنامج AON-CIRC صحيحًا ذو مُدخلًا و مُخرجًا. نقول إن يحسب إذا كان لكل .
يعطي التمرين المحلول التالي مثالًا على برنامج AON-CIRC.
تمرين محلول
لتُعتبر الدالة التالية التي، على أربعة بتات مُدخلة ، تُنتج إذا ونحو فقط إذا كان العدد الذي تمثّله أكبر من العدد الذي تمثّله . أي أن إذا ونحو فقط إذا كان .
اكتب برنامج AON-CIRC يحسب .
الحل
كتابة برنامج كهذا مملّة لكنها ليست صعبة حقًا. لمقارنة عددين نقارن أولًا أكثر خانتين أهمية فيهما، ثم ننتقل إلى الخانة التالية وهكذا دواليك. وفي حالتنا هنا حيث للأرقام خانتان ثنائيتان فقط، تكون هذه المقارنات بسيطة إلى حدٍّ خاص. يكون العدد الذي تمثّله أكبر من العدد الذي تمثّله إذا ونحو فقط إذا وقع أحد الشرطين التاليين:
- البت الأكثر أهمية في أكبر من البت الأكثر أهمية في .
أو
- البتان الأكثر أهمية و متساويتان، لكن .
وهناك طريقة أخرى للتعبير عن الشرط نفسه وهي التالية: العدد أكبر من إذا ونحو فقط إذا كان OR ( AND ).
بالنسبة للخانات الثنائية ، فإن الشرط هو ببساطة و، أي ، والشرط هو ببساطة . ويمكن استعمال هذه الملاحظات مجتمعةً للحصول على برنامج AON-CIRC التالي الذي يحسب :
# Compute CMP:{0,1}^4-->{0,1}
# CMP(X)=1 iff 2X[0]+X[1] > 2X[2] + X[3]
temp_1 = NOT(X[2])
temp_2 = AND(X[0],temp_1)
temp_3 = OR(X[0],temp_1)
temp_4 = NOT(X[3])
temp_5 = AND(X[1],temp_4)
temp_6 = AND(temp_5,temp_3)
Y[0] = OR(temp_2,temp_6)
ويمكننا أيضًا تقديم هذا البرنامج المكوَّن من 8 أسطر بوصفه دائرة ذات 8 بوابات، انظر الشكل التوضيحي.

إثبات تكافؤ برامج AON-CIRC والدوائر المنطقية
وسنثبت الآن رسميًا أن برامج AON-CIRC والدوائر المنطقية لهما القدرة نفسها تمامًا:
مبرهنة — تكافؤ الدوائر والبرامج المستقيمة
لتكن و عددًا ما. حينئذٍ يكون قابلًا للحساب بواسطة دائرة منطقية ذات بوابة إذا ونحو فقط كان قابلًا للحساب بواسطة برنامج AON-CIRC من سطرًا.
الفكرة بسيطة — برامج AON-CIRC والدوائر المنطقية ليست سوى طريقتين مختلفتين لوصف العملية الحسابية نفسها تمامًا.
على سبيل المثال، تقابل بوابة AND في دائرة منطقية حساب AND لقيمتين حُسبتا سابقًا.
وفي برنامج AON-CIRC سيقابل ذلك السطر الذي يخزّن في متغيّر ناتج AND لمتغيّرين حُسبا سابقًا.
توقّف وتأمّل
هذا البرهان لـمبرهنة — تكافؤ الدوائر والبرامج المستقيمة بسيط في جوهره، لكن كل التفاصيل التي يحتويها تجعل قراءته أثقل قليلًا. غالبًا ما يكون من الأفضل لك أن تحاول استنتاجه بنفسك قبل قراءته.
ويحتوي مستودعنا على GitHub على «برهان بـ Python» لـمبرهنة — تكافؤ الدوائر والبرامج المستقيمة: تنفيذ الدالتين circuit2prog وprog2circuits اللتين تربطان الدوائر المنطقية ببرامج AON-CIRC
وبالعكس.
برهان
لتكن . وبما أن المبرهنة عبارة عن «إذا وفقط إذا»، فإثباتها يتطلب بيان الاتجاهين: ترجمة برنامج AON-CIRC يحسب إلى دائرة تحسب ، وترجمة دائرة تحسب إلى برنامج AON-CIRC يفعل ذلك.
نبدأ بالاتجاه الأول. وليكن برنامج AON-CIRC يحسب . نعرّف دائرة على النحو التالي: يكون للدائرة مُدخلًا و بوابة. ولكل ، إذا كان سطر العمليات رقم على الصورة foo = AND(bar,blah)، فإن البوابة رقم في الدائرة ستكون بوابة AND موصولة بالبوابتين و حيث تقابل و آخر سطرين قبل كُتب فيهما المتغيّران bar وblah (على التوالي). (فمثلًا، إذا كان وكان آخر سطر كُتب فيه bar هو وآخر سطر كُتب فيه blah هو ، فإن الجارين الداخليين للبوابة هما البوابتان و.)
وإذا كان أحد bar أو blah متغيّر مُدخل، فإننا نوصل البوابة برأس المُدخل المقابل بدلًا من ذلك.
وإذا كان foo متغيّر خرج من الشكل Y[], فإننا نضيف الوسم نفسه إلى البوابة المقابل لنُعلّمها بوابة خرج.
ونجري العمليات المماثلة إذا تضمّن السطر رقم عملية OR أو عملية NOT (مع أننا نستعمل في الحالة الثانية بوابة NOT المقابل، ولها عندها جار داخلي واحد بدل اثنين).
ولكل مُدخل ، إذا نفّذنا البرنامج على ، فإن القيمة المحسوبة في السطر رقم هي بالضبط القيمة التي ستُسنَد إلى البوابة رقم إذا قيّمنا الدائرة على . وبذلك يكون لكل .
وفي الاتجاه الآخر، لتكن دائرة ذات بوابة و مُدخلًا تحسب الدالة . نرتّب البوابات وفق ترتيب طوبولوجي ونكتبها .
ويمكننا الآن إنشاء برنامج من سطر عمليات كالتالي.
لكل ، إذا كانت بوابة AND بجارين داخليين ، فإننا نضيف إلى سطرًا على الصورة temp_ = AND(temp_,temp_), إلا إذا كان أحد الرأسين رأس مُدخل أو بوابة خرج، وعندئذٍ نغيّر ذلك إلى الصورة X[.] أو Y[.] بحسب ما يلائم.
ولأننا نعمل بترتيب طوبولوجي، فإننا نضمن أن الجيران الداخليين و يقابلان متغيّرات فُسندت لها قيمة بالفعل.
ونفعل الشيء نفسه مع بوابتَي OR وNOT.
ومرة أخرى، يمكن التحقق أن القيمة ستساوي لكل مُدخل ، وبذلك يحسب البرنامج الدالة نفسها التي تحسبها الدائرة.
(ولاحظ أن دائرة صحيحة، وفقًا لـتعريف — الدوائر المنطقية، فإن لكل رأس مُدخل في جارًا خارجًا واحدًا على الأقل، وهناك بالضبط بوابة خرج موسومة بـ؛
وبالتالي فإن جميع المتغيّرات X[0] و وX[] وY[0] و وY[] ستظهر في البرنامج .)

التنفيذات الفيزيائية لأجهزة الحوسبة (استطراد)
الحوسبة مفهوم مجرد يختلف عن تنفيذاته الفيزيائية. ورغم أن معظم أجهزة الحوسبة الحديثة تُحصل بوَصْل البوابات المنطقية على ترانزستورات قائمة على أشباه الموصلات، إلا أن الناس على مدى التاريخ قد حسبوا باستخدام تشكيلة ضخمة من الآليات، منها الأنظمة الميكانيكية، والغازات والسوائل (المعروفة بـ_التحكّم الموائع_ (fluidics))، والعمليات الحيوية والكيميائية، بل وحتى الكائنات الحيّة (مثلًا، انظر الشكل التوضيحي أو هذا الفيديو لتعرف كيف يمكن استعمال السرطان أو العفن المخاطي في إجراء حسابات).
في هذا القسم سنستعرض بعض هذه التنفيذات، وذلك أولًا لتقدير كيف يمكن ترجمة الدوائر المنطقية مباشرةً إلى العالم الفيزيائي دون المرور بمنظومة العمارة وأنظمة التشغيل والمترجِمات كاملةً، وثانيًا للتأكيد على أن المعالجات القائمة على السيليكون ليست بأي حال الطريقة الوحيدة لإجراء الحوسبة. وفعلًا، كما سنرى في الحساب الكمّي، فإن خطًّا بحثيًا ممتعًا جدًا في الآونة الأخيرة يتطلّب استعمال وسائل مختلفة للحوسبة تتيح لنا الاستفادة من الآثار الميكانيكية الكمّية (quantum mechanical effects) لتفعيل أنواع مختلفة من الخوارزميات.

طريقة باردة جدًا لشرح البوابات المنطقية. pic.twitter.com/6Wgu2ZKFCx
— Lionel Page (\@page_eco) October 28, 2019
الترانزستورات
يمكن تصوّر الـ_ترانزستور_ (transistor) على أنه دائرة كهربائية لها مُدخلان يُعرفان بـ_المصدر_ (source) و_البوابة_ (gate)، ومُخرج يُعرف بـ_المصبّ_ (sink). تتحكّم البوابة في ما إذا كان التيار يفيض من المصدر إلى المصبّ. وفي الـ_ترانزستور القياسي_، إذا كانت البوابة «مُفعَّلة» (ON) أمكن للتيار أن يفيض من المصدر إلى المصبّ، وإذا كانت «معطَّلة» (OFF) لم يستطع. وفي الـ_ترانزستور التكاملي_ (complementary transistor) يكون هذا معكوسًا: إذا كانت البوابة «معطَّلة» أمكن للتيار أن يفيض من المصدر إلى المصبّ، وإذا كانت «مُفعَّلة» لم يستطع.

هناك عدة طرق لتنفيذ منطق الترانزستور. فمثلًا، يمكننا استعمال الصنابير لتنفيذه بواسطة ضغط الماء (انظر الشكل التوضيحي). وقد يبدو هذا مجرد فضول، لكن هناك مجال يُعرف بـالتحكّم الموائع (fluidics) يعنى بتنفيذ العمليات المنطقية باستعمال السوائل أو الغازات. ومن بين دوافعه العمل في ظروف بيئية قاسية مثل الفضاء أو أرض المعركة، حيث لن تصمد المعدات الإلكترونية القياسية.
تستخدم التنفيذات القياسية للترانزستورات تيارًا كهربائيًا. ومن أقدم التنفيذات ما استخدم أنابيب التفريغ (vacuum tubes). وكما يدل اسمها، فإن أنبوب التفريغ أنبوب لا يحتوي على شيء (أي فراغ)، حيث يمكن للإلكترونات مبدئيًا أن تفيض بحرية من المصدر (سلك) إلى المصبّ (لوح). غير أنه توجد بين الاثنين بوابة (شبكة)، وتعديل جهدها يمكن أن يعوق فيض الإلكترونات.
كانت أنابيب التفريغ المبكّرة بحجم لمبات المصابيح تقريبًا، وكانت تتشابه معها إلى حدٍّ كبير. وفي الخمسينيات حلّت محلّها الترانزستورات، التي تنفّذ المنطق نفسه باستعمال أشباه الموصلات (semiconductors)، وهي مواد لا توصّل الكهرباء عادةً ولكن يمكن تعديل ناقليتها والتحكم بها بإدخال شوائب (وتُسمّى «التخليق» (doping)) وتطبيق مجال كهربائي خارجي (ويُعرف ذلك بـ_أثر المجال_ (field effect)). وفي الستينيات بدأت تُنفَّذ الحواسيب باستعمال الدوائر المتكاملة (integrated circuits) التي سمحت بكثافة أعلى بكثير. وفي عام 1965 تنبّأ جوردون مور بأن عدد الترانزستورات في كل دائرة متكاملة سيتضاعف كل عام (انظر الشكل التوضيحي)، وأن هذا سيؤدي إلى «عجائب مثل الحواسيب المنزلية —أو على الأقلّ أطراف طرفية موصولة بحاسوب مركزي— وضوابط آلية للسيارات، ومعدّات اتصالات شخصية محمولة». ومنذ ذلك الحين، ظلّت هذه «قانون مور» المزعوم (في نسخ معدَّلة منه) يسير بقوة، وإن كان النمو الأُسّي لا يمكن أن يستمر إلى الأبد، فبعض القيود الفيزيائية بدأت بالفعل تظهر للعلن.



البوابات المنطقية من الترانزستورات
يمكننا استعمال الترانزستورات لتنفيذ دوال منطقية متنوّعة مثل و و. ولكل بوابة ذات مُدخلين ، يكون هذا التنفيذ نظامًا فيه سلكا مُدخل وسلك مُخرج واحد ، بحيث إذا طابقنا الجهد العالي بـ«» والجهد المنخفض بـ«»، فإن السلك يساوي «» إذا ونحو فقط كان تطبيق على قيمتي السلكين و يساوي (انظر الشكل التوضيحي والشكل التوضيحي). وهذا يعني أن ما دام هناك دائرة من نوع AND/OR/NOT تحسب الدالة ، فيمكننا حساب في العالم الفيزيائي باستعمال الترانزستورات أيضًا.


الحوسبة البيولوجية
يمكن أن تستند الحوسبة إلى الأنظمة البيولوجية أو الكيميائية. فمثلًا، ينتج lac operon_ الأنزيمات اللازمة لهضم اللاكتوز فقط إذا تحقّقت الشروط ، حيث تعني «اللاكتوز موجود» و تعني «الغلوكوز موجود». تمكن الباحثون من إنشاء ترانزستورات، ومنها بوابات منطقية، قائمة على جزيئات الحمض النووي (انظر أيضًا الشكل التوضيحي). وتتيح مشاريع مثل لغة برمجة Cello تحويل الدوائر المنطقية إلى تسلسلات حمض نووي ترمّز عمليات يمكن تنفيذها في الخلايا البكتيرية، انظر هذا الفيديو. وأحد دوافع حوسبة الحمض النووي هو تحقيق توازٍ أو كثافة تخزين أعلى؛ وآخر هو إنشاء «وكلاء بيولوجيين أذكياء» يمكن حقنهم في الأجساد فيتكاثرون ويصلحون الخلايا التالفة أو يقتلونها، والتي أضرّها مرضٌ مثل السرطان. وهي بالطبع لا تقتصر الحوسبة في الأنظمة البيولوجية على الحمض النووي: فحتى الأنظمة الأكبر مثل أسراب الطيور يمكن اعتبارها عمليات حسابية.

الأوتوماتا الخلوية ولعبة الحياة
الأوتوماتا الخلوية (cellular automata) نموذج لنظام مؤلَّف من تسلسل من الخلايا، لكل منها حالة متناهية محتملة. وفي كل خطوة تحدّث الخلية حالتها بناءً على حالات خلاياها المجاورة وعلى قواعد بسيطة. وكما سنناقش لاحقًا في هذا الكتاب (انظر الآليات الخلوية)، فإن الأوتوماتا الخلوية مثل «لعبة الحياة» لكونيواي يمكن استعمالها لمحاكاة البوابات الحسابية.

الشبكات العصبية
أحد أجهزة الحوسبة التي نحملها جميعًا هو دماغنا نفسه. وقد خدمت الأدمغة البشرية البشرية على مدى التاريخ، فأنجزت حسابات تمتدّ من التمييز بين الفرائس والمفترسات، مرورًا بالاكتشافات العلمية والتحفّرات الفنية، وصولًا إلى تأليف رسائل ذكية من 280 حرفًا. ولا يزال العمل الدقيق للدماغ غير مفهوم تمامًا، لكن أحد النماذج الرياضية الشائعة له هو شبكة عصبية (neural network) كبيرة جدًا.
يمكن تصوّر الشبكة العصبية على أنها دائرة منطقية تستعمل بوابات أخرى غير // بوصفها الأساس. فمثلًا، أحد الأسس التي يمكننا استعمالها هي بوابات العتبة (threshold gates). ولكل متجه من الأعداد الصحيحة ولكل عدد صحيح (قد يكون بعضها أو كلها سالبة)، تكون دالة العتبة المقابلة لـ هي الدالة التي تُسقط على إذا ونحو فقط إذا كان . فمثلًا، دالة العتبة المقابلة لـ و هي ببساطة دالة الأغلبية على . ويمكن تصوّر بوابات العتبة على أنها تقريب لـ_خلايا العصبونات_ التي تشكّل جوهر أدمغة البشر والحيوانات. وفي التقريب الأول، للعصبون مُدخلات ومُخرج واحد، وينطلق العصبون «ناريًا» أي يُشغّل مُخرجه حين تتجاوز تلك الإشارات عتبةً ما.
تستعمل كثير من خوارزميات التعلّم الآلي الشبكات العصبية الاصطناعية التي لا يقصد منها محاكاة الأحياء بل تنفيذ مهمة حسابية ما، ولذلك فهي غير مقيّدة ببوابة عتبة أو ببوابات أخرى مستوحاة من الأحياء. وبوجه عام، تُوصف الشبكة العصبية بأنها تعمل على إشارات هي أعداد حقيقية لا قيم ، حيث يُحصل مُخرج بوابة على مُدخلات بتطبيق ، حيث هي دالة تنشيط (activation function) كوحدة الخطية المصحَّحة (ReLU) أو السيغمويد (Sigmoid) أو غيرها كثير (انظر الشكل التوضيحي). غير أنه، لأغراض مناقشتنا، كل ما سبق متكافئ (انظر أيضًا تمرين — NAND من دوال التنشيط). ويسرّنا أن نلاحظ أننا نستطيع اختصار حالة المُدخلات الحقيقية إلى مُدخلات ثنائية بتمثيل العدد الحقيقي في الأساس الثنائي، ثم ضرب وزن البت المقابل لرتبة الخانة في .

حاسوب مصنوع من الكرات والأنابيب
يمكننا تنفيذ الحوسبة بوسائط فيزيائية كثيرة أخرى، دون أي مكوّنات إلكترونية أو حيوية أو كيميائية. وقد تقدُّمت مقترحات كثيرة لحاسوبات ميكانيكية، يعود أقدمها على الأقل إلى آلات الحوسبة لغوتفريد لايبنتس في سبعينيات القرن السابع عشر، وإلى خطة تشارلز بابيج عام 1837 المحرك التحليلي الميكانيكي. ومن الأمثلة، يوضّح الشكل التوضيحي تنفيذًا مبسّطًا لبوابة NAND (نفي AND، انظر دالة NAND) باستعمال كرات تمرّ في أنابيب. ونمثّل قيمة منطقية في بزوج من الأنابيب بحيث يمرّ في أحدهما كرة بالضبط. ونسمّي أحد الأنابيب «أنبوب » والآخر «أنبوب »، وبذلك تحدّد هوية الأنبوب الذي توجد فيه الكرة القيمة المنطقية. وتقابل بوابة NAND جسمًا ميكانيكيًا له زوجان من الأنابيب الداخلة وزوج من الأنابيب الخارجة، بحيث لكل ، إذا كانت كرتان تتدحرجان نحو الجسم في أنبوب من الزوج الأول وأنبوب من الزوج الثاني، فإن كرة ستتدحرج خارج الجسم في أنبوب من الزوج الخرج. وفعلًا، هناك حتى لعبة تعليمية متوفّرة تجاريًا تستعمل الكرات أساسًا للحوسبة، انظر الشكل التوضيحي.



دالة NAND
دالة هي دالة أخرى بسيطة بالغة النفع لتعريف الحوسبة. وهي الدالة التي تُسقط على والمعرَّفة بما يلي:
وكما يدل اسمها، فإن هي نفي AND (أي )، ولذلك يمكننا بوضوح حساب باستعمال و. ومن اللافت أن الاتجاه المعاكس يصمد أيضًا:
مبرهنة — NAND تحسب AND وOR وNOT
يمكننا حساب و و بتركيب دالة وحدها.
برهان
نبدأ بالملاحظة التالية. لكل لدينا . وبذلك . وهذا يعني أن تستطيع حساب . وبمبدأ «النفي المزدوج»، لدينا ، ولذلك يمكننا استعمال لحساب أيضًا. ومتى استطعنا حساب و، استطعنا حساب باستعمال «قانون دو مورغان»: (ويمكن أيضًا كتابتها ) لكل .
توقّف وتأمّل
برهان مبرهنة — NAND تحسب AND وOR وNOT بسيط جدًا، غير أنك ينبغي أن تتأكد أنك (i) تفهم نص المبرهنة، و__(ii)__ تتابع برهانها. وعلى وجه الخصوص، ينبغي أن تتأكد أنك تفهم لماذا يكون قانون دو مورغان صحيحًا.
ويمكننا استعمال لحساب دوال أخرى كثيرة، كما يوضّح التمرين التالي.
تمرين محلول — حساب الأغلبية بـNAND
لتكن الدالة التي على المُدخل تُنتج إذا ونحو فقط إذا كان . بيّن كيف تحسب بتركيب من عمليات .
الحل
تذكّر أن المعادلة تنص على أن
ويمكننا استعمال مبرهنة — NAND تحسب AND وOR وNOT لاستبدال كل مواضع و بـ. على وجه التحديد، يمكننا استعمال التكافؤات و و لاستبدال الطرف الأيمن من المعادلة بتعبير يتضمّن وحدها، مما ينتج أن تكافئ التعبير (الذي هو بعض الشيء مُعقّد)
ويمكن التعبير عن الصيغة نفسها أيضًا بدائرة ببوابات NAND، انظر الشكل التوضيحي.

دوائر NAND
نعرّف دوائر NAND بأنها الدوائر التي كل بوابات فيها عمليات NAND. وتقابل هذه الدائرة أيضًا رسمًا بيانيًا موجَّهًا غير دوري (DAG)، إذ إن كل البوابات تقابل الدالة نفسها (أي NAND)، ولذلك لا نحتاج حتى إلى وسمها، وكل البوابات درجتها الداخلة اثنان بالضبط. ورغم بساطتها، فإن دوائر NAND قد تكون بالغة القوة.
مثال — دائرة للدالة
تذكّر الدالة التي تُسقط على . لقد رأينا في مثال موسّع: حساب XOR من AND وOR وNOT أننا نستطيع حساب باستعمال و و، وبذلك وبموجب مبرهنة — NAND تحسب AND وOR وNOT نستطيع حسابها بعمليات وحدها. غير أن التالي بناء مباشر لحساب عبر تسلسل من عمليات NAND:
- ليكن .
- ليكن
- ليكن .
- تكون لـ و هي .
ويمكن التحقق من أن هذه الخوارزمية تحسب فعلًا بحصر الاحتمالات الأربعة الممكنة لـ. ويمكننا أيضًا تمثيل هذه الخوارزمية بيانيًا بدائرة، انظر الشكل التوضيحي.

وفعلًا، يمكننا إثبات المبرهنة التالية:
مبرهنة — NAND عملية شاملة
لكل دائرة منطقية ذات بوابة، توجد دائرة NAND ذات بوابة على الأكثر تحسب الدالة نفسها التي تحسبها .
فكرة البرهان هي مجرد استبدال كل بوابة و و بتنفيذها المعتمد على NAND، على النحو المبيَّن في برهان مبرهنة — NAND تحسب AND وOR وNOT.
برهان
إذا كانت دائرة منطقية، فإن بما أننا، كما رأينا في برهان مبرهنة — NAND تحسب AND وOR وNOT، لدينا لكل
نستطيع استبدال كل بوابة في بثلاث بوابات على الأكثر للحصول على دائرة مكافئة . وستكون الدائرة الناتجة ذات بوابة على الأكثر.
النموذجان متكافئان في القدرة إذا أمكِن استعمالهما لحساب المجموعة نفسها من الدوال.
أمثلة أخرى على دوائر NAND (اختياري)
إليك بعض الأمثلة الأكثر تعقيدًا على دوائر NAND:
_زيادة الأعداد الصحيحة. لنُعتبر مهمة حساب، انطلاقًا من مُدخل نصي يمثّل عددًا طبيعيًا ، التمثيلَ الخاص بـ. أي أننا نريد حساب الدالة بحيث لكل ، يكون الذي يستوفي . (لتبسيط التدوين، نستخدم في هذا المثال التمثيل الذي تكون فيه الخانة الأقل أهمية أولًا لا آخرًا.)
يمكن وصف عملية الزيادة بإيجاز شديد على النحو التالي: «أضِف إلى البت الأقل أهمية وانقل الحمل (carry)». وبشكل أدق قليلًا، في حالة التمثيل الثنائي، للحصول على زيادة ، نفحص بدءًا من البت الأقل أهمية، ونقلب كل البتات إلى حتى نلاقي بتًّا مساويًا لـ، وعندئذٍ نقلبه إلى ونتوقف.
ويمكننا بذلك حساب زيادة بفعل ما يلي:
خوارزمية — حساب دالة الزيادة
INPUT: $x_0,x_1,\ldots,x_{n-1}$ representing the number $\sum_{i=0}^{n-1} x_i\cdot 2^i$ # we use LSB-first representation
OUTPUT:$y \in \{0,1\}^{n+1}$ such that $\sum_{i=0}^n y_i \cdot 2^i = \sum_{i=0}^{n-1} x_i\cdot 2^i + 1$
Let $c_0 \leftarrow 1$ # we pretend we have a "carry" of $1$ initially
For{$i=0,\ldots, n-1$}
Let $y_i \leftarrow XOR(x_i,c_i)$.
If{$c_i=x_i=1$}
$c_{i+1}=1$
else
$c_{i+1}=0$
endif
Endfor
Let $y_n \leftarrow c_n$.
تصف خوارزمية — حساب دالة الزيادة بدقة كيفية حساب عملية الزيادة، ويمكن بسهولة تحويلها إلى شيفرة Python تؤدّي الحساب نفسه، لكنها لا تبدو وكأنها تعطي مباشرةً دائرة NAND لحسابها. غير أننا نستطيع تحويل هذه الخوارزمية سطرًا بسطر إلى دائرة NAND. فمثلًا، بما أن لكل ، يمكننا استبدال التصريح الأول بـ. ونحن نعرف بالفعل كيف نحسب باستعمال NAND، وبذلك يمكننا استعمال ذلك لتنفيذ العملية . وبالمثل، يمكننا كتابة تعليمات «if» على صورة ، أو بمعنى آخر . وأخيرًا، يمكن كتابة الإسناد على صورة . ويجمع هذه الملاحظات معًا لتُعطي لكل دائرة تحسب . فعلى سبيل المثال، يوضّح الشكل التوضيحي كيف تبدو هذه الدائرة عند .

من الزيادة إلى الجمع. ومتى توفرت لدينا عملية الزيادة، يمكننا بالتأكيد حساب الجمع بالتكرار المتواصل للزيادة (أي حساب بتنفيذ مرة). غير أن ذلك سيكون غير فعّال تمامًا وغير ضروري. وبفكرة تتبّع الحمل نفسها، يمكننا تنفيذ خوارزمية الجمع «المدرسية» وحساب الدالة التي على مُدخل تُخرج التمثيل الثنائي لمجموع العددين الممثَّلين بـ و:
خوارزمية — الجمع باستعمال NAND
INPUT: $u \in \{0,1\}^n$, $v\in \{0,1\}^n$ representing numbers in LSB-first binary representation.
OUTPUT: LSB-first binary representation of $x+y$.
Let $c_0 \leftarrow 0$
For{$i=0,\ldots,n-1$}
Let $y_i \leftarrow u_i + v_i \mod 2$
If{$u_i + v_i + c_i \geq 2$}
$c_{i+1}\leftarrow 1$
else
$c_{i+1} \leftarrow 0$
endif
Endfor
Let $y_n \leftarrow c_n$
ومرة أخرى، يمكن ترجمة خوارزمية — الجمع باستعمال NAND إلى دائرة NAND. والملاحظة الجوهرية هي أن تعليمات «if/then» تقابل ببساطة ، وقد رأينا في تمرين محلول — حساب الأغلبية بـNAND أن الدالة يمكن حسابها باستعمال .
لغة البرمجة NAND-CIRC
تمامًا كما فعلنا مع الدوائر المنطقية، يمكننا تعريف نسخة بلغة برمجة تكافئ دوائر NAND. وهي أبسط حتى من لغة AON-CIRC لأن لدينا عملية واحدة فقط. ونعرّف لغة برمجة NAND-CIRC بأنها لغة برمجة كل سطر فيها (باستثناء تصريح المُدخل/المُخرج) على الصورة التالية:
foo = NAND(bar,blah)
حيث foo وbar وblah معرِّفات متغيّرات.
مثال — أول برنامج NAND-CIRC لنا
إليك مثالًا على برنامج NAND-CIRC:
u = NAND(X[0],X[1])
v = NAND(X[0],u)
w = NAND(X[1],u)
Y[0] = NAND(v,w)
توقّف وتأمّل
هل تعرف الدالة التي يحسبها هذا البرنامج؟ إرشاد: لقد رأيتها من قبل.
ورسميًا، تمامًا كما فعلنا في تعريف — حساب دالة بواسطة برامج AON-CIRC بالنسبة إلى AON-CIRC، يمكننا تعريف فكرة الحساب ببرنامج NAND-CIRC بالطريقة الطبيعية:
تعريف — الحساب ببرنامج NAND-CIRC
لتكن دالة ما، وليكن برنامج NAND-CIRC. نقول إن تحسب الدالة إذا:
-
كان للبرنامج متغيّر مُدخل
X[]X[]و متغيّر خرجY[],,Y[]. -
لكل ، إذا نفّذنا مع إسناد القيم إلى
X[]X[]، فإن متغيّرات الخرجY[],,Y[]تكون في نهاية التنفيذ لها القيم حيث .
وكما من قبل، يمكننا أن نبيّن أن دوائر NAND تكافئ برامج NAND-CIRC (انظر الشكل التوضيحي):
مبرهنة — تكافؤ دوائر NAND والبرامج المستقيمة
لكل و، يكون قابلًا للحساب ببرنامج NAND-CIRC من سطرًا إذا ونحو فقط كان قابلًا للحساب بدائرة NAND ذات بوابة.

نُغفل برهان مبرهنة — تكافؤ دوائر NAND والبرامج المستقيمة لأنه يسير على الخطوط نفسها تمامًا كتكافؤ الدوائر المنطقية مع برنامج AON-CIRC (مبرهنة — تكافؤ الدوائر والبرامج المستقيمة).
وبناءً على مبرهنة — تكافؤ دوائر NAND والبرامج المستقيمة ومبرهنة — NAND عملية شاملة، نعرف أننا نستطيع ترجمة كل برنامج AON-CIRC من سطرًا إلى برنامج NAND-CIRC مكافئ من سطرًا على الأكثر.
وفعلًا، يمكن إجراء هذه الترجمة بسهولة باستبدال كل سطر على الصورة foo = AND(bar,blah) أو foo = OR(bar,blah) أو foo = NOT(bar) بالأسطر المكافئة من 1 إلى 3 التي تستعمل العملية NAND.
ويحتوي مستودعنا على GitHub على «برهان بالشيفرة»: برنامج Python بسيط اسمه AON2NAND يحوّل برنامج AON-CIRC إلى برنامج NAND-CIRC مكافئ.
ملاحظة — هل لغة البرمجة NAND-CIRC تامّة تورينج؟ (ملاحظة اختيارية)
ربما سمعت مصطلحًا يُعرف بـ«تامّة تورينج» (Turing Complete) يُستعمل أحيانًا لوصف لغات البرمجة. (وإن لم تكن سمعت به، فلا بأس من تجاهل بقية هذه الملاحظة: فنحن نعرّف هذا المصطلح بدقّة في نماذج حوسبة مكافئة.) وإن كنت سمعت به، فقد تتساءل إن كانت لغة البرمجة NAND-CIRC تملك هذه الخاصية. والجواب لا، أو على نحو أدقّ أن مصطلح «اكتمال تورينج» لا ينطبق أصلًا على لغة البرمجة NAND-CIRC. والسبب أن لغة البرمجة NAND-CIRC، بحسب تصميمها، تستطيع حساب الدوال المتناهية فقط، وهي دوال تأخذ عددًا ثابتًا من بتات المُدخل وتُنتج عددًا ثابتًا من بتات الخرج. أما مصطلح «تامّة تورينج» فلا ينطبق إلا على لغات البرمجة الخاصة بالدوال اللامتناهية التي تقبل مُدخلات بطول اعتباطي. وسنعود إلى هذا التمييز لاحقًا في هذا الكتاب.
تكافؤ كل هذه النماذج
إذا جمعنا بين مبرهنة — تكافؤ الدوائر والبرامج المستقيمة ومبرهنة — NAND عملية شاملة ومبرهنة — تكافؤ دوائر NAND والبرامج المستقيمة، نحصل على النتيجة التالية:
مبرهنة — التكافؤ بين نماذج الحوسبة المتناهية
لكل كبيرة بما يكفي ولكل ، الشروط التالية كلها متكافئة فيما بينها:
-
يمكن حسابها بدائرة منطقية (ذات بوابات ) عدد بواباتها على الأكثر.
-
يمكن حسابها ببرنامج AON-CIRC مستقيم عدد أسطره على الأكثر.
-
يمكن حسابها بدائرة NAND عدد بواباتها على الأكثر.
-
يمكن حسابها ببرنامج NAND-CIRC مستقيم عدد أسطره على الأكثر.
بـ«» نعني أن الحد هو على الأكثر حيث ثابت مستقل عن . فمثلًا، إذا كانت قابلة للحساب بدائرة منطقية ذات بوابة، فإنها قابلة للحساب ببرنامج NAND-CIRC من سطرًا على الأكثر، وإذا كانت قابلة للحساب بدائرة NAND ذات بوابة، فإنها قابلة للحساب ببرنامج AON-CIRC من سطرًا على الأكثر.
نُغفل البرهان الرسمي، إذ يُحصل عليه بدمج مبرهنة — تكافؤ الدوائر والبرامج المستقيمة ومبرهنة — NAND عملية شاملة ومبرهنة — تكافؤ دوائر NAND والبرامج المستقيمة. والملاحظة الأساسية هي أن النتائج التي رأيناها تتيح لنا ترجمة برنامج/دائرة يحسب في أحد النماذج أعلاه إلى برنامج/دائرة يحسب في نموذج آخر، بزيادة عدد الأسطر/البوابات بمعامل ثابت على الأكثر (وهذا المعامل الثابت هو على الأكثر في الواقع).
ويعد مبرهنة — تكافؤ الدوائر والبرامج المستقيمة حالة خاصة من نتيجة أكثر عمومية. فقد نُفكّر في نماذج حوسبة أكثر عمومية، حيث نستعمل بدلًا من AND/OR/NOT أو NAND عمليات أخرى (انظر الدوائر بمجموعات بوابات أخرى أدناه). ويبيّن الأمر أن الدوائر المنطقية تكافئ هذه النماذج أيضًا في القدرة. وأن كون كل هذه الطرق المختلفة لتعريف الحوسبة يقود إلى نماذج متكافئة يدلّ على أننا «على الطريق الصحيح». وهذا يبرّر الخيارات التي تبدو عشوائية والمتمثلة في استعمال AND/OR/NOT أو NAND بوصفهما عملياتنا الأساسية، لأن هذه الخيارات لا تؤثر في قدرة نموذجنا الحوسب. وتعني نتائج التكافؤ مثل مبرهنة — التكافؤ بين نماذج الحوسبة المتناهية أننا نستطيع بسهولة الترجمة بين الدوائر المنطقية ودوائر NAND وبرامج NAND-CIRC وما شابه. وسنستعمل هذه القدرة لاحقًا في هذا الكتاب، منتقلين كثيرًا إلى الصياغة الأكثر ملاءمة دون أن نُوليها عناية بالغة. ولذلك لن نقلق كثيرًا من التمييز بين، مثلًا، الدوائر المنطقية وبرامج NAND-CIRC.
وفي المقابل، سنواصلة الحرص على التمييز بين الدوائر/البرامج و_الدوال_ (تذكّر functionprogramidea). فتقابل الدالةُ مواصفةَ مهمة حسابية، وهي كائن مختلف جوهريًا عن البرنامج أو الدائرة التي تقابل تنفيذَ تلك المهمة.
الدوائر بمجموعات بوابات أخرى
لا شيء خاص بـAND/OR/NOT أو NAND. فلكل مجموعة دوال يمكننا تعريف فكرة الدوائر التي تستعمل عناصر بوصفها بوابات، وفكرة «لغة برمجة » التي يكون فيها كل سطر إسنادًا إلى متغيّر foo نتيجة تطبيق ما على متغيّرات مُعرَّفة سابقًا أو على مُدخلات.
وبالتحديد، يمكننا تقديم التعريف التالي:
تعريف — البرامج المستقيمة العامة
لتكن مجموعة متناهية من الدوال المنطقية، بحيث
لمُدخل ما .
برنامج هو تسلسل من الأسطر، يُسند كلٌّ منها إلى متغيّر ما نتيجة تطبيق ما على متغيّرات أخرى. وكما سبق، نستعمل X[] وY[] للدلالة على متغيّرات المُدخل والمُخرج.
ونقول إن هي مجموعة عمليات شاملة (وتُعرف أيضًا بمجموعة بوابات شاملة) إذا وُجد برنامج يحسب الدالة .
تقابل برامج AON-CIRC برامج ، وتقابل برامج NAND-CIRC برامج للمجموعة التي لا تحتوي إلّا على الدالة ، ولكن يمكننا أيضًا تعريف برامج (انظر أدناه)، أو استعمال أي مجموعة أخرى.
ويمكننا أيضًا تعريف دوائر ، وهي رسوم بيانية موجَّهة تكون فيها كل بوابة مقابلة لتطبيق دالة ، ولكل بوابة سلكًا داخليًا وسلكًا خارجيًا واحدًا. (وإذا كانت الدالة غير متماثلة، بمعنى أن ترتيب مُدخلاتها مهم، فيلزم أن نوسم كل سلك يدخل البوابة بمُعامل الدالة الذي يقابله.) وكما في مبرهنة — تكافؤ الدوائر والبرامج المستقيمة، يمكننا أن نبيّن أن دوائر وبرامج متكافئة. لقد رأينا أن الدوائر/البرامج الناتجة عن تكافئ في القدرة لغة البرمجة NAND-CIRC، لأننا نستطيع حساب باستعمال // وبالعكس. ويبيّن الأمر أن هذه حالة خاصة من ظاهرة أعمّ — عمومية (universality) ومجموعات البوابات الأخرى — سنستكشفها بمزيد من التفصيل لاحقًا في هذا الكتاب.
مثال — دوائر IF وZERO وONE
لتكن حيث و هما دالتا الصفر والواحد الثابتتان،[3] و هي الدالة التي على المُدخل تُخرج إذا كان و في غير ذلك. عندئذٍ تكون شاملة.
وفعلًا، يمكننا أن نبيّن أن شاملة باستعمال الصيغة التالية لـ:
وهناك أيضًا بعض المجموعات المقيّدة أكثر في القدرة. فمثلًا يمكن إثبات أن استعملنا بوابات AND أو OR وحدها (من دون NOT) فإننا لا نحصل على نموذج حوسبة مكافئ. وتغطي التمارين عدة أمثلة على مجموعات بوابات شاملة وغير شاملة.
المواصفة مقابل التنفيذ (مرة أخرى)

كما ناقشنا في ميّزوا الدوال عن البرامج!، فإن أحد أهم التمييزات في هذا الكتاب هو تمييز المواصفة عن التنفيذ، أي فصل «ماذا» عن «كيف» (انظر الشكل التوضيحي). فتقابل الدالةُ مواصفةَ مهمة حسابية، أي ما الذي ينبغي أن يُنتج كمُخرج لكل مُدخل بعينه. وتقابل البرنامج (أو الدائرة، أو أي طريقة أخرى لتحديد الخوارزميات) تنفيذَ كيفية حساب المُخرج المطلوب من المُدخل. أي أن البرنامج مجموعة تعليمات حول كيفية حساب المُخرج من المُدخل. وحتى في النموذج الحوسب نفسه، قد توجد طرق كثيرة مختلفة لحساب الدالة نفسها. فمثلًا، يوجد أكثر من برنامج NAND-CIRC واحد يحسب دالة الأغلبية، وأكثر من دائرة منطقية واحدة تحسب دالة الجمع، وهكذا دواليك.
والخلط بين المواصفة والتنفيذ (أو بما يكافئهما من الدوال و_البرامج_) خطأ شائع، وللأسف تشجّعه المصطلحات الشائعة في لغات البرمجة التي تسمّي أجزاء من البرنامج «دوالًا». غير أنه، في نظرية علم الحاسوب وممارسته معًا، من المهم الإبقاء على هذا التمييز، وهو مهم بشكل خاص لنا في هذا الكتاب.
خلاصة
- الخوارزمية وصفةٌ لتنفيذ حسابٍ، وهي تسلسل من عمليات «أولية» أو «بسيطة».
- أحد التعريفات المرشَّحة للعمليات «الأولية» هو المجموعة و و.
- تعريف مرشَّح آخر لعملية «أولية» هو عملية . وهي عملية يسهل تنفيذها في العالم الفيزيائي بطرق متنوّعة، منها الترانزستورات الإلكترونية.
- يمكننا استعمال لحساب دوال أخرى كثيرة، منها الأغلبية والزيادة وغيرها.
- وهناك اختيارات أخرى متكافئة، منها المجموعتان و.
- يمكننا تعريف رسميًا فكرة أن الدالة قابلة للحساب باستعمال لغة البرمجة NAND-CIRC.
- ولكل مجموعة عمليات أساسية، تتكافؤ فكرة القابلية للحساب بدائرة وفكرة القابلية للحساب ببرنامج مستقيم.
التمارين
تمرين — مقارنة أعداد من بتات
أعطِ دائرة منطقية (ببوابات AND/OR/NOT) تحسب الدالة بحيث إذا ونحو فقط إذا كان العدد الذي تمثّله أكبر من العدد الذي تمثّله .
تمرين — مقارنة أعداد من بتًا
أثبِت أن هناك ثابتًا بحيث إن لكل توجد دائرة منطقية (ببوابات AND/OR/NOT) عدد بواباتها على الأكثر تحسب الدالة بحيث إذا ونحو فقط إذا كان العدد الذي تمثّله أكبر من العدد الذي تمثّله .
تمرين — OR وNOT شاملتان
أثبِت أن المجموعة شاملة، بمعنى أنه يمكن حساب NAND باستعمال هاتين البوابتين.
تمرين — AND وOR ليستا شاملتين
أثبِت أن لكل دائرة ذات مُدخل من بتات تحتوي بوابات AND وOR وحدها، وكذلك بوابات تحسب الدالتين الثابتتين و، تكون مُحكَمة الترتيب (monotone)، بمعنى أنه إذا كان و لكل ، فإن .
استنتج أن المجموعة ليست شاملة.
تمرين — XOR ليست شاملة
أثبِت أن لكل دائرة ذات مُدخل من بتات تحتوي بوابات XOR وحدها، وكذلك بوابات تحسب الدالتين الثابتتين و، تكون تآلفية أو خطّية على مقياس اثنين، بمعنى أنه يوجد و بحيث لكل ، لدينا .
استنتج أن المجموعة ليست شاملة.
تمرين — MAJ وNOT و1 شاملة
لتكن دالة الأغلبية. أثبِت أن مجموعة بوابات شاملة.
تمرين — MAJ وNOT ليستا شاملتين
أثبِت أن ليست مجموعة شاملة. انظر الحاشية للإرشاد.[4]
تمرين — NOR شاملة
لتكن المعرَّفة بـ. أثبِت أن مجموعة بوابات شاملة.
تمرين — LOOKUP شاملة
أثبِت أن مجموعة بوابات شاملة، حيث و دالتان ثابتتان و تحقق أن تساوي إذا كان وتساوي إذا كان .
تمرين — حدّ على حجم الأساس الشامل (تحدٍّ)
أثبِت أن لكل مجموعة جزئية من الدوال من إلى ، إذا كانت شاملة، فهناك دائرة عدد بواباتها على الأكثر تحسب الدالة (يمكنك البدء بإثبات وجود دائرة عدد بواباتها على الأكثر).[5]
تمرين — الحجم والمُدخلات / المُخرجات
أثبِت أن لكل دائرة NAND ذات حجم و مُدخلًا و مُخرجًا، لدينا . انظر الحاشية للإرشاد.[6]
تمرين — العتبة باستعمال NAND
أثبِت أن هناك ثابتًا بحيث إن لكل ، ولكل أعداد صحيحة ، توجد دائرة NAND عدد بواباتها على الأكثر تحسب دالة العتبة التي على مُدخل تُخرج إذا ونحو فقط إذا كان .
تمرين — NAND من دوال التنشيط
نقول إن الدالة هي مُقارِب NAND (NAND approximator) إذا كانت لها الخاصية التالية: لكل ، إذا كان و، حينئذٍ ، حيث نرمز بـ إلى أقرب عدد صحيح إلى . أي أنه إذا كان على مسافة من ، فنريد أن يساوي قيمة للقيم في الأقرب إلى و على التوالي. وفي غير ذلك، لا يهمّنا ما يكونه مُخرج عند و.
في هذا التمرين ستبيّن أنه يمكن بناء مُقارِب NAND من دوال تنشيط شائعة كثيرة المستعملة في الشبكات العصبية العميقة. ونتيجةً لذلك ستحصل على أن الشبكات العصبية العميقة تستطيع محاكاة دوائر NAND. وبما أن دوائر NAND تستطيع أيضًا محاكاة الشبكات العصبية العميقة، فإن هذين النموذجين الحوسبين متكافئان فيما بينهما.
-
بيّن أن هناك مُقارِب NAND المعرَّف بـ حيث دالة تآلفية (affine) (من الشكل لمُعاملات ما )، و دالة تآلفية (من الشكل لمُعاملات )، و دالة معرَّفة بـ. ولاحظ أن حيث هي دالة تنشيط الوحدة الخطية المصحَّحة.
-
بيّن أن هناك مُقارِب NAND المعرَّف بـ حيث تآلفية كما سبق و دالة معرَّفة بـ.
-
بيّن أن هناك مُقارِب NAND المعرَّف بـ حيث تآلفية كما سبق و دالة معرَّفة بـ.
-
أثبِت أن لكل دائرة NAND ذات مُدخلًا ومُخرج واحد تحسب دالة ، إذا استبدلنا كل بوابة في بمُقارِب NAND ثم استدعينا الدائرة الناتجة على ما، فإن المُخرج سيكون عددًا بحيث .
تمرين — الأغلبية بكفاءة باستعمال NAND
أثبِت أن هناك ثابتًا بحيث إن لكل توجد دائرة NAND عدد بواباتها على الأكثر تحسب دالة الأغلبية على بت مُدخل . أي أن إذا ونحو فقط إذا كان . انظر الحاشية للإرشاد.[7]
تمرين — المُخرج في الطبقة الأخيرة
أثبِت أن لكل ، إذا كانت هناك دائرة منطقية ذات بوابة تحسب ، فهناك دائرة منطقية ذات بوابة على التوالي بحيث في التوزيع الطبقي الأدنى لـ، تكون بوابة خرج موضوعة في الطبقة الأخيرة. انظر الحاشية للإرشاد.[8]
ملاحظات سردية
المقتطف من كتاب الخوارزمي مأخوذ من «جبر ابن موسى» لفريدريك روزن، 1831.
كان تشارلز بابيج (1791-1871) عالمًا ومخترعًا وباحثًا رؤيويًا (انظر [@swade2002the, @collier2000charles]). وقبل أكثر من قرن من اختراع الحواسيب الإلكترونية الحديثة، أدرك بابيج أن الحساب يمكن أن يُآلَف من حيث المبدأ. وكان تصميمه الأول لحاسوب ميكانيكي هو محرك الفروق المصمَّم لإجراء الاستيفاء متعددة الحدود. ثم صمّم بعد ذلك المحرك التحليلي، وهو آلة أكثر عمومية بكثير وأول نموذج أوّلي لحاسوب عام قابل للبرمجة. وللأسف لم يستطع بابيج يومًا إتمام تصميم نماذجه الأوّلية. ومن أوائل من أدركوا إمكانات المحرك وآثاره البعيدة آدا لوفلايس (انظر ملاحظات الحلقات وما لا نهاية).
جرى أول البحث في جبر البولياني على يد بولي ودي مورغان في الأربعينيات من القرن التاسع عشر [@Boole1847mathematical, @DeMorgan1847]. وأُعطيت تعريف الدوائر المنطقية وصلتها بدوائر المرحِّلات الكهربائية في رسالة الماجستير لشانون [@Shannon1938]. (وقد وصف هوارد غاردنر رسالة شانون بأنها «ربما أهم رسالة ماجستير، وأيضًا أشهرها، في القرن العشرين».) كتاب سافيج [@Savage1998models]، مثل هذا الكتاب، يقدّم نظرية الحوسبة بدءًا بالدوائر المنطقية بوصفها النموذج الأول. ويحتوي كتاب جوكنا [@Jukna12] على عرض حديث ومتعمّق للدوائر المنطقية، انظر أيضًا [@wegener1987complexity].
أُثبت أن دالة NAND شاملة على يد شيفر [@Sheffer1913]، مع أن هذا يظهر أيضًا في عمل بيرس الأسبق، انظر [@Burks1978charles]. واستعمل وايتهد وروسيل NAND أساسًا لمنطقهما في عملهما العظيم مبادئ الرياضيات (Principia Mathematica) [@WhiteheadRussell1912]. وتبحث أطروحة إرنست للدكتوراه [@Ernst2009phd] تجريبيًا في أصغر دوائر NAND لدوال متنوّعة. ويبني كتاب نيسان وشوكن [@NisanShocken2005] نظام حوسبة يبدأ من بوابات NAND وينتهي عند البرامج والألعاب عالية المستوى («من NAND إلى تيتريس»)؛ انظر أيضًا الموقع nandtotetris.org.
عرّفنا في تعريف — الدوائر المنطقية حجم الدائرة المنطقية بأنه عدد البوابات التي تحتوي عليها. وهذه إحدى عريفتين مستعملتين في الأدبيات. أما العريفة الأخرى فتُعرّف الحجم بأنه عدد الأسلاك (وهو مكافئ لعدد البوابات مضافًا إليه عدد المُدخلات). وهذا لا يصنع فارقًا يُذكر في كل السياقات تقريبًا، لكنه قد يؤثّر في تعقيد حجم الدائرة لبعض «الأمثلة المرضية» لدوال مثل دالة الصفر الثابت التي لا تعتمد على كثير من مُدخلاتها.
معنى وجود حواف موازية أن بوابة AND أو OR المعنونة يمكن أن يكون كلا جيريها الداخلي هو البوابة نفسها. وبما أن لكل ، فإن هذه الحواف الموازية لا تساعد في حساب قيم جديدة في الدوائر ذات بوابات AND/OR/NOT. غير أننا سنرى لاحقًا دوائر بمجموعات بوابات أكثر عمومية. ↩︎
فمثلًا مواصفة لغة البرمجة C تتجاوز 500 صفحة. ↩︎
يمكن أيضًا تعريف هاتين الدالتين بأنهما تأخذان مُدخلًا طوله صفر. وهذا لا يحدث أي فرق في قدرة النموذج الحوسبية. ↩︎
إرشاد: استعمل الحقيقة لإثبات أن كل يمكن حسابها بدائرة فيها بوابتا و فقط تستوفي . شكرًا لناثان برونيل وديفيد إيفانز على اقتراح هذا التمرين. ↩︎
شكرًا لأليك صن وسيمون فيشر على ملاحظاتهما على هذه المسألة. ↩︎
إرشاد: استعمل شرطَي تعريف — الدوائر المنطقية اللذين ينصّان على أن لكل رأس مُدخل جارًا خارجًا واحدًا على الأقل، وأن هناك بالضبط بوابة خرج. وانظر أيضًا ملاحظة — تفاصيل دقيقة في الدوائر المنطقية (اختياري). ↩︎
أحد أساليب حل هذه المسألة هو استعمال التعاود وتحليله باستعمال ما يُعرف بـ«مبرهنة سيجر» (Master Theorem). ↩︎
إرشاد: يمكن إزالة الرؤوس الواقعة في طبقات بعد الخرج بأمان دون تغيير وظيفة الدائرة. ↩︎