এই পর্বে যা শিখবেন
- দুই চলকের quantifier-এর সব রূপ, কোনটি কোনটিকে নিশ্চিত করে, আর তার প্রমাণ
- বাংলা বা ইংরেজি বাক্যকে nested quantifier-এ লেখা, আর সূত্র পড়ে বাংলায় বলা
- যত গভীরই হোক, nested বাক্যের negation ধাপে ধাপে বের করা, ε-δ সংজ্ঞাসহ
- Witness function-এর ধারণা, আর continuity বনাম uniform continuity-তে quantifier-এর ক্রমের ভূমিকা
- Nested loop, Python-এর
all()/any()আর SQL-এর NOT EXISTS-কে quantifier হিসেবে পড়া
১ · এক বাক্য, দুই অর্থ — quantifier-এর ক্রম কেন গুরুত্বপূর্ণ
বাজারঘরের ঢাকা অফিসে দুজন ম্যানেজার কথা বলছেন। প্রথমজন বললেন, “প্রতিটি এলাকায় কোনো না কোনো রাইডার যান।” দ্বিতীয়জন বললেন, “একজন রাইডার আছেন যিনি প্রতিটি এলাকায় যান।” দুটি বাক্যে শব্দ প্রায় একই: “প্রতিটি”, “কোনো একজন”, “এলাকা”, “রাইডার”। কিন্তু অর্থ একেবারে আলাদা। প্রথম বাক্য সত্য হতে মিরপুরে রাজু আর উত্তরায় শিলা গেলেই চলে। দ্বিতীয়টি সত্য হতে একজন মানুষকেই সব এলাকা সামলাতে হবে। সেই রাইডার অসুস্থ হলে পুরো শহরের ডেলিভারি বন্ধ, তাই দ্বিতীয় বাক্যটি ব্যবসার জন্য একটি ঝুঁকির কথাও বলে।
পর্ব ০৪-এ (Predicate logic আর quantifier) আপনি একটি চলকের predicate আর দুটি quantifier দেখেছেন: ∀ (“প্রতিটির জন্য”) আর ∃ (“অন্তত একটির জন্য”)। এই পর্বে দুই বা তার বেশি চলক আসবে, আর একটি quantifier আরেকটির ভেতরে বসবে। একে বলে nested quantifier. ধরুন:
- X = বাজারঘরের এলাকার সেট, Y = রাইডারের সেট;
- S(x, y) = “রাইডার y এলাকা x-এ ডেলিভারি দেন”।
তাহলে প্রথম ম্যানেজারের কথা ∀x∃y S(x, y), আর দ্বিতীয়জনের কথা ∃y∀x S(x, y). দুটিতে একই তিনটি জিনিস আছে, শুধু quantifier-এর ক্রম উল্টো। এই পর্বের পুরো গল্প এই এক ছোট পরিবর্তনকে ঘিরে।
একটি quantifier-এর scope (প্রভাবের এলাকা) হলো তার পরের অংশ, যেখানে তার চলক বাঁধা থাকে। একটি quantifier আরেকটির scope-এর ভেতরে থাকলে তাকে nested quantifier বলে। ∀x∃y P(x, y) পড়তে হয় বাঁ থেকে ডানে, বাইরে থেকে ভেতরে: ∀x (∃y P(x, y)). অর্থাৎ প্রথমে একটি x ধরা হয়, তারপর সেই x-এর জন্য একটি y খোঁজা হয়। তাই ভেতরের y বাইরের x-এর ওপর নির্ভর করতে পারে। ∃y∀x-এ y আগে বাছাই হয়, তখনো কোনো x ঠিক হয়নি, তাই y-কে সব x-এর জন্য একই থাকতে হয়।
একটি খেলা হিসেবে ভাবুন। ∀ হলো আপনার প্রতিপক্ষ, যিনি আপনাকে হারাতে চান; ∃ হলেন আপনি। ∀x∃y-তে প্রতিপক্ষ আগে একটি এলাকা বেছে দেন, তারপর আপনি সেই এলাকা দেখে একজন রাইডার বাছেন। ∃y∀x-এ আপনাকে আগে রাইডার বলতে হয়, তারপর প্রতিপক্ষ জেনেশুনে এমন এলাকা বাছবেন যেখানে সেই রাইডার যান না। ক্রিকেটে টস জিতে পরে সিদ্ধান্ত নেওয়া আর আগেই সিদ্ধান্ত জানিয়ে দেওয়ার পার্থক্য এটাই: যে পরে চাল দেয়, সে বেশি তথ্য পায়।
এই “খেলা” শুধু উপমা নয়। যুক্তিবিদ্যায় এটিকে game semantics বলা হয়, আর পরে দেখবেন জটিলতা তত্ত্বেও (complexity theory) এই খেলার ধারণা সরাসরি কাজে লাগে। এখন একটি কথা মনে রাখুন: ∃ যত ডানে থাকে, তার witness তত বেশি তথ্য দেখে বাছা যায়, তাই বাক্যটি তত সহজে সত্য হয়।
Quantifier-এর আধুনিক ধারণা আসে Gottlob Frege-এর ১৮৭৯ সালের Begriffsschrift থেকে; প্রায় একই সময়ে আলাদাভাবে Charles S. Peirce আর তাঁর ছাত্ররাও (১৮৮৩–১৮৮৫ সালের লেখায়) quantifier ব্যবহার করেন। Frege-ই প্রথম দেখান যে “প্রত্যেকের একজন মা আছে” ধরনের বাক্যে quantifier-এর ক্রম যুক্তির ফলাফল বদলে দেয়, যা অ্যারিস্টটলের পুরোনো syllogism-এর কাঠামোয় ঠিকমতো ধরা যেত না। ∃ চিহ্নটি সাধারণত Peano-র (১৮৯৭ সালের দিকে) উল্টো E-র সঙ্গে আর ∀ চিহ্নটি Gentzen-এর ১৯৩৫ সালের লেখার সঙ্গে যুক্ত করা হয়; চিহ্নের ইতিহাসে বর্ণনায় কিছু ভিন্নতা আছে।
২ · দুই চলকের বাক্যগুলো আর তাদের সম্পর্ক
প্রথমে একটি ছোট টেবিলে দুটি বাক্যের মান হাতে বের করি। বাজারঘরের চারটি এলাকা আর চারজন রাইডার; ✓ মানে S(x, y) সত্য, · মানে মিথ্যা। Domain সসীম হলে ∀ আসলে একটি বড় ∧ (এবং), আর ∃ একটি বড় ∨ (অথবা)। তাই ∀x∃y S(x, y) মানে “প্রতিটি সারিতে অন্তত একটি ✓”, আর ∃y∀x S(x, y) মানে “অন্তত একটি কলাম পুরোটা ✓”।
| x \ y | রা | শি | তা | মি |
| মিরপুর | ✓ | · | ✓ | · |
| উত্তরা | · | ✓ | · | · |
| ধানমন্ডি | · | · | ✓ | ✓ |
| মতিঝিল | ✓ | · | · | ✓ |
| পুরো ✓? |
| এখন যাচাই | |
| দেখা ঘর | |
| f (witness y) | |
| g (বাদ পড়া x) | |
| সিদ্ধান্ত |
- টেবিল পড়া। সারি x = এলাকা, কলাম y = রাইডার। প্রথম কাজ ∀x∃y S(x, y): প্রতিটি সারিতে বাঁ থেকে ডানে একটি ✓ খুঁজতে হবে। ✓ পেলেই সেই সারির কাজ শেষ, কারণ ∃-এর জন্য একটি witness-ই যথেষ্ট।
- মিরপুর। প্রথম ঘর (রাজু) ✓, তাই একটি ঘর দেখেই witness পাওয়া গেল: y = রাজু।
- উত্তরা। রাজুর ঘর ·, শিলার ঘর ✓। দুটি ঘর দেখে witness শিলা; এ পর্যন্ত মোট ৩টি ঘর দেখা হলো।
- ধানমন্ডি। রাজু ·, শিলা ·, তানভীর ✓। তিনটি ঘর লাগল, মোট ৬।
- মতিঝিল। রাজু ✓, এক ঘরেই witness. চারটি সারিতেই witness পাওয়া গেছে, তাই ∀x∃y S(x, y) সত্য, মোট ৭টি ঘর দেখে। খেয়াল করুন, witness সারি অনুযায়ী বদলেছে: মিরপুরে রাজু, উত্তরায় শিলা।
- এবার ∃y∀x S(x, y). এখন খুঁজতে হবে এমন একটি কলাম, যার সব ঘর ✓। রাজুর কলামে মিরপুর ✓ কিন্তু উত্তরা ·, তাই রাজু বাদ (২টি ঘর)। শিলার কলামে প্রথম ঘর মিরপুরই ·, তাই শিলা বাদ (১টি ঘর)।
- তানভীর আর মিতু। তানভীরের কলামে মিরপুর ✓, উত্তরা ·, বাদ (২টি ঘর)। মিতুর কলামে মিরপুরই ·, বাদ (১টি ঘর)। কোনো কলাম পুরো ✓ নয়, তাই ∃y∀x S(x, y) মিথ্যা, ৬টি ঘর দেখে।
- সারাংশ: দুটি function. ∀x∃y-এর সত্যতার প্রমাণ একটি witness function f: প্রতিটি x-কে একটি কাজের y দেয়। ∃y∀x-এর মিথ্যাত্বের প্রমাণ আরেকটি function g: প্রতিটি রাইডার y-কে এমন একটি এলাকা দেয় যেখানে তিনি যান না। g হলো ∀y∃x ¬S(x, y)-এর witness, অর্থাৎ ¬∃y∀x S-এর প্রমাণ।
দুই চলক আর দুই quantifier মিলিয়ে বাক্য হয় আটটি (চলকের দুটি ক্রম × প্রতিটি জায়গায় ∀ বা ∃)। কিন্তু এর মধ্যে কয়েকটি জোড়া সমতুল্য, তাই আলাদা বাক্য থাকে ছয়টি। নিচের উপপাদ্য বলে কোনটি কোনটিকে নিশ্চিত করে।
Domain খালি নয় এমন যেকোনো X, Y আর যেকোনো predicate P(x, y)-এর জন্য:
(ক) ∀x∀y P(x, y) ≡ ∀y∀x P(x, y) (খ) ∃x∃y P(x, y) ≡ ∃y∃x P(x, y)
(গ) ∃y∀x P(x, y) → ∀x∃y P(x, y) সবসময় সত্য (ঘ) ∀x∃y P(x, y) → ∃y∀x P(x, y) সবসময় সত্য নয়
(ক) আর (খ) সহজ: ∀∀ মানে “সব জোড়ায় সত্য”, জোড়াগুলো কোন ক্রমে দেখছেন তাতে কিছু যায় আসে না; ∃∃ মানে “অন্তত একটি জোড়ায় সত্য”, সেটিও ক্রমের ওপর নির্ভর করে না। আসল কথা (গ) আর (ঘ)।
(গ)-এর প্রমাণ। এখানে পর্ব ০৬-এর (অনুমানের নিয়ম) চারটি নিয়ম আগে থেকেই সাধারণ ভাষায় ব্যবহার করছি; সেখানে এদের আনুষ্ঠানিক নাম দেখবেন।
- ধরি ∃y∀x P(x, y) সত্য। (অনুমান)
- তাহলে Y-তে একটি নির্দিষ্ট উপাদান b আছে, যার জন্য ∀x P(x, b) সত্য। (∃-এর সংজ্ঞা; b-কে একটি নাম দিলাম)
- X থেকে ইচ্ছামতো একটি উপাদান c নিন। ধাপ ২ থেকে P(c, b) সত্য। (∀-এর সংজ্ঞা: সব x-এ সত্য, তাই c-তেও)
- অতএব y = b নিলে P(c, y) সত্য হয়, অর্থাৎ ∃y P(c, y) সত্য। (b হলো witness)
- c-কে কোনো বিশেষ শর্ত ছাড়া ইচ্ছামতো নেওয়া হয়েছিল, তাই প্রতিটি x-এর জন্য ∃y P(x, y) সত্য, অর্থাৎ ∀x∃y P(x, y). ∎
(ঘ)-এর প্রমাণ (একটি counterexample). Domain X = Y = ℤ (সব পূর্ণসংখ্যা), P(x, y): x + y = 0. ∀x∃y সত্য: যেকোনো x-এর জন্য y = −x নিলে চলে। কিন্তু ∃y∀x মিথ্যা: যেকোনো b নিন, তাহলে x = 1 − b-তে x + b = 1 ≠ 0, অর্থাৎ কোনো একটি b সব x-এর জন্য কাজ করে না। একটি উদাহরণে implication ভাঙল, তাই সেটি সাধারণভাবে সত্য নয়। ∎
ছয়টি আলাদা বাক্যের পুরো সম্পর্ক নিচের চিত্রে। তীর মানে “ওপরেরটি সত্য হলে নিচেরটিও অবশ্যই সত্য”। কোনো তীর উল্টো দিকে খাটে না, আর বাঁ আর ডানের শিকলের মধ্যে কোনো সরাসরি তীর নেই।
দুই চলকের quantifier-বাক্যের implication-চিত্র
Arrows show which statements imply which (non-empty domains)
চিত্রটি বিশ্বাস না করে যাচাই করুন। ৩টি x আর ৩টি y থাকলে P-এর মোট সম্ভাব্য রূপ (relation) 29 = 512টি, কারণ নয়টি ঘরের প্রতিটি ✓ বা · হতে পারে। নিচের brute force ব্লক সবগুলো তৈরি করে, ছয়টি বাক্যের মান হিসাব করে, আর প্রতিটি জোড়া (A, B)-র জন্য গোনে কতগুলো relation-এ A সত্য কিন্তু B মিথ্যা। শূন্য মানে সেই ৫১২টির কোনোটিতেই A → B ভাঙেনি। (এই কোর্সের Python ব্লকগুলো আপনার ব্রাউজারেই চলে; প্রথমবার চালাতে Python লোড হতে কয়েক সেকেন্ড লাগে।)
from itertools import product
n = 3
R = range(n)
stmts = { # ছয়টি আলাদা বাক্য; P[x][y] = 1 মানে P(x, y) সত্য
"∀x∀y": lambda P: all(P[x][y] for x in R for y in R),
"∃x∀y": lambda P: any(all(P[x][y] for y in R) for x in R),
"∃y∀x": lambda P: any(all(P[x][y] for x in R) for y in R),
"∀x∃y": lambda P: all(any(P[x][y] for y in R) for x in R),
"∀y∃x": lambda P: all(any(P[x][y] for x in R) for y in R),
"∃x∃y": lambda P: any(P[x][y] for x in R for y in R),
}
rels = [[bits[i * n:(i + 1) * n] for i in R]
for bits in product((0, 1), repeat=n * n)]
print("3×3 relation মোট:", len(rels))
truth = {s: [f(P) for P in rels] for s, f in stmts.items()}
for s in stmts:
print(f"{s} সত্য {sum(truth[s]):3d}টিতে")
print("সূত্র: ∀x∃y =", (2**n - 1)**n, " ∃y∀x =", 2**(n * n) - (2**n - 1)**n)
names = list(stmts)
print("\nসারি A, কলাম B: A সত্য কিন্তু B মিথ্যা — এমন relation কয়টি")
print(" " + " ".join(f"{b:>5}" for b in names))
for a in names:
row = [sum(ta and not tb for ta, tb in zip(truth[a], truth[b]))
for b in names]
print(f"{a} " + " ".join(f"{c:5d}" for c in row))আসল আউটপুট (ব্রাউজারের Python):
3×3 relation মোট: 512
∀x∀y সত্য 1টিতে
∃x∀y সত্য 169টিতে
∃y∀x সত্য 169টিতে
∀x∃y সত্য 343টিতে
∀y∃x সত্য 343টিতে
∃x∃y সত্য 511টিতে
সূত্র: ∀x∃y = 343 ∃y∀x = 169
সারি A, কলাম B: A সত্য কিন্তু B মিথ্যা — এমন relation কয়টি
∀x∀y ∃x∀y ∃y∀x ∀x∃y ∀y∃x ∃x∃y
∀x∀y 0 0 0 0 0 0
∃x∀y 168 0 78 42 0 0
∃y∀x 168 78 0 0 42 0
∀x∃y 342 216 174 0 78 0
∀y∃x 342 174 216 78 0 0
∃x∃y 510 342 342 168 168 0
শূন্যগুলো ঠিক চিত্রের তীরগুলো: ∃y∀x সারিতে ∀x∃y কলামে ০, অর্থাৎ ৫১২টির একটিতেও (গ) ভাঙেনি। উল্টো দিকে, ∀x∃y সারির ∃y∀x কলামে ১৭৪: এতগুলো relation-এ প্রতিটি সারিতে ✓ আছে, কিন্তু কোনো কলাম পুরো ✓ নয়। সংখ্যাগুলোও সূত্রের সঙ্গে মেলে। প্রতিটি সারিতে অন্তত একটি ✓ থাকার উপায় 23 − 1 = 7, তিনটি সারি স্বাধীন, তাই ∀x∃y সত্য 73 = 343টিতে। ∃y∀x মিথ্যা মানে প্রতিটি কলামে অন্তত একটি ·, সেটিও 73 = 343 ভাবে হয়, তাই ∃y∀x সত্য 512 − 343 = 169টিতে। ∀x∀y সত্য শুধু সব-✓ relation-এ (১টি), আর ∃x∃y মিথ্যা শুধু সব-· relation-এ (তাই ৫১১)। তবে মনে রাখুন, ৩×৩-এ টেকা মানেই প্রমাণ নয়; প্রমাণ উপরের পাঁচ ধাপ। Brute force শুধু আত্মবিশ্বাস বাড়ায় আর ভুল দাবিকে দ্রুত ধরে।
৩ · অনুবাদ — বাংলা বাক্য থেকে nested quantifier, আর ফিরতি পথে
বাস্তবের নিয়ম, যেমন বাজারঘরের ডেলিভারি নীতি, সাধারণত লম্বা বাংলা বাক্যে লেখা থাকে। সেটিকে সূত্রে আনতে পারলে তিনটি লাভ: অস্পষ্টতা ধরা পড়ে, negation বের করা যায়, আর কোডে বা database-এ যাচাই করা যায়। কাজটি করার একটি নির্ভরযোগ্য কৌশল আছে: বাইরে থেকে ভেতরে, এক একটি quantifier করে।
| ধাপ | |
| লেখা | |
| কেন |
- উপাদান আর সম্পর্ক। বাক্যে তিন ধরনের বস্তু: জেলা, গুদাম, থানা। এখানে domain সবকিছুর মিলিত সেট, তাই “d একটি জেলা” বোঝাতে আলাদা predicate J(d) লাগে। সম্পর্ক তিনটি: কোন গুদাম কোন জেলায় (G), কোন থানা কোন জেলায় (T), কোন গুদাম থেকে কোন থানায় ডেলিভারি যায় (R).
- সবচেয়ে বাইরে “প্রতিটি জেলা”। এটি ∀d. Domain-এ জেলা ছাড়াও জিনিস আছে, তাই শর্তটি → দিয়ে জুড়তে হয়: “d যদি জেলা হয়, তবে …”। ∀-এর সঙ্গে সীমিত domain সবসময় → দিয়ে লেখা হয়।
- তারপর “একটি গুদাম আছে, সেই জেলায়”। এটি ∃w, আর শর্তটি এবার ∧ দিয়ে: “এমন w আছে যা d-তে আছে এবং …”। ∃-এর সঙ্গে → লিখলে ভুল হয়, কারণ জেলার বাইরের যেকোনো w-এর জন্য G(w, d) মিথ্যা হলে পুরো implication আপনাআপনি সত্য হয়ে যেত।
- সবশেষে “সেই জেলার সব থানায়”। এটি ∀t, আবার → দিয়ে। এটি ∃w-এর ভেতরে বসেছে, তাই একবার w বাছা হলে সেই একই w-কে জেলার প্রতিটি থানায় পৌঁছাতে হবে। বাক্যের “যা” শব্দটিই এই nesting-এর সংকেত।
- পুরো সূত্র। quantifier-এর ক্রম ∀d ∃w ∀t. w বাইরের d-এর ওপর নির্ভর করতে পারে (প্রতিটি জেলার নিজস্ব গুদাম), কিন্তু ভেতরের t-এর ওপর নয়। বাংলায় ফিরিয়ে পড়লে আসল বাক্যটিই পাওয়া যায়, তাই অনুবাদ ঠিক।
- দুটি সাধারণ ভুল রূপ। (১) ∀d∀t∃w মানে “প্রতিটি থানায় সেই জেলার কোনো না কোনো গুদাম পৌঁছায়”, থানাভেদে গুদাম আলাদা হতে পারে; এটি দুর্বল দাবি। (২) ∃w∀d মানে “একটিই গুদাম সব জেলার সব থানায় পৌঁছায়”; এটি অনেক শক্ত, আর সেই গুদামকে আবার প্রতিটি জেলার ভেতরে থাকতে হতো, যা প্রায় অসম্ভব।
গণিতের কয়েকটি পরিচিত বাক্যে একই কৌশল খাটান। প্রতিটির ক্ষেত্রে domain বদলালে কী হয়, সেটিও খেয়াল করুন:
| বাংলা বাক্য | সূত্র | কোথায় সত্য, কোথায় মিথ্যা |
|---|---|---|
| প্রতিটি সংখ্যার একটি যোগের বিপরীত আছে | ∀x∃y (x + y = 0) | ℤ-এ সত্য (y = −x); ℕ = {0, 1, 2, …}-এ মিথ্যা (x = 1-এর বিপরীত নেই) |
| সবচেয়ে ছোট একটি সংখ্যা আছে | ∃x∀y (x ≤ y) | ℕ-এ সত্য (x = 0); ℤ-এ মিথ্যা |
| যেকোনো সংখ্যার চেয়ে বড় সংখ্যা আছে | ∀x∃y (y > x) | ℕ, ℤ, ℝ-এ সত্য (y = x + 1); {1, …, 10}-এ মিথ্যা (x = 10) |
| যেকোনো দুটি আলাদা বাস্তব সংখ্যার মাঝে আরেকটি আছে | ∀x∀y (x < y → ∃z (x < z ∧ z < y)) | ℚ আর ℝ-এ সত্য (z = (x + y)/2); ℤ-এ মিথ্যা (x = 1, y = 2) |
| প্রতিটি গ্রাহকের ঠিক একটি গ্রাহক নম্বর | ∀c∃!n N(c, n) | ∃! মানে “ঠিক একটি”: ∃n (N(c, n) ∧ ∀m (N(c, m) → m = n)) |
ফিরতি পথটিও অনুশীলন করুন: সূত্র পড়ে স্বাভাবিক বাংলায় বলা। ∀x∀y ((x > 0 ∧ y > 0) → xy > 0)-কে “x-এর জন্য, y-এর জন্য …” না বলে বলুন “দুটি ধনাত্মক সংখ্যার গুণফল ধনাত্মক”। আক্ষরিক অনুবাদ প্রথম ধাপ; স্বাভাবিক বাক্যে আনা দ্বিতীয় ধাপ, আর সেটিই প্রমাণ করে আপনি অর্থ বুঝেছেন। চলকের নামও খেয়াল করুন: ∀x∃y P(x, y)-তে x আর y দুটিই bound variable, তাই এদের নাম বদলে ∀a∃b P(a, b) লিখলে অর্থ একই থাকে। কিন্তু ∃y P(x, y)-তে x একটি free variable, তাই x-এর মান না জানা পর্যন্ত বাক্যটি সত্য বা মিথ্যা কোনোটিই নয়।
“কোনো” আর “any” শব্দে সাবধান। “কোনো রাইডার সব এলাকায় যান না” মানে ¬∃y∀x S(x, y), অর্থাৎ “এমন কেউ নেই যিনি সব এলাকায় যান”। কিন্তু “কোনো এলাকায় যদি রাইডার না যান, অভিযোগ করুন” বাক্যের “কোনো” আসলে ∀: “প্রতিটি এলাকার জন্য, সেখানে কেউ না গেলে অভিযোগ”। ইংরেজির “any”-ও একইভাবে কখনো ∀, কখনো ∃। অনুবাদের আগে নিজেকে জিজ্ঞেস করুন: এটি কি “প্রতিটি”, না “অন্তত একটি”?
৪ · Nested quantifier-এর negation
পর্ব ০৪-এ quantifier-এর De Morgan নিয়ম দেখেছেন: ¬∀x Q(x) ≡ ∃x ¬Q(x) আর ¬∃x Q(x) ≡ ∀x ¬Q(x). Nested বাক্যে এই নিয়মটিই বারবার লাগাতে হয়, প্রতিবার একটি quantifier পেরিয়ে।
¬∀x∃y P(x, y) ≡ ∃x∀y ¬P(x, y) এবং ¬∃x∀y P(x, y) ≡ ∀x∃y ¬P(x, y). সাধারণভাবে, quantifier-এর যেকোনো সারির সামনের ¬ ভেতরে নিলে প্রতিটি ∀ হয় ∃, প্রতিটি ∃ হয় ∀, আর ¬ গিয়ে বসে শেষের quantifier-ছাড়া অংশের সামনে।
প্রমাণ (প্রথম সমতুল্যতা)।
- Q(x) দিয়ে ∃y P(x, y) বোঝাই। তাহলে ¬∀x∃y P(x, y) হলো ¬∀x Q(x). (শুধু নাম দেওয়া)
- ¬∀x Q(x) ≡ ∃x ¬Q(x). (quantifier-এর De Morgan, পর্ব ০৪)
- প্রতিটি x-এর জন্য ¬Q(x) = ¬∃y P(x, y) ≡ ∀y ¬P(x, y). (আবার De Morgan, এবার y-এর ওপর)
- দুটি সমতুল্য সূত্র প্রতিটি x-এ একই মান দেয়, তাই ∃x-এর ভেতরে একটির জায়গায় আরেকটি বসানো যায়: ∃x ¬Q(x) ≡ ∃x∀y ¬P(x, y). ∎
দ্বিতীয়টির প্রমাণ একইভাবে, শুধু ∃ আর ∀ উল্টো। আর সাধারণ ক্ষেত্রে quantifier-এর সংখ্যা ধরে induction করা যায় (পর্ব ১০-এ induction শিখবেন)।
প্রথম স্টেপারের টেবিলে মিলিয়ে দেখুন। ∃y∀x S(x, y) মিথ্যা ছিল, তাই তার negation ∀y∃x ¬S(x, y) সত্য, আর সেটির witness ছিল function g: প্রতিটি রাইডারের একটি বাদ পড়া এলাকা। উপপাদ্য শুধু চিহ্নের খেলা নয়; negation-এর প্রতিটি quantifier বলে দেয় প্রমাণে কী হাজির করতে হবে।
বাজারঘরের অনুবাদ করা নিয়মটির negation:
¬∀d (J(d) → ∃w (G(w, d) ∧ ∀t (T(t, d) → R(w, t))))
≡ ∃d (J(d) ∧ ∀w (G(w, d) → ∃t (T(t, d) ∧ ¬R(w, t))))
বাংলায়: “এমন একটি জেলা আছে, যার প্রতিটি গুদামের জন্য সেই জেলার অন্তত একটি থানা আছে যেখানে ওই গুদাম পৌঁছায় না।” খেয়াল করুন, restricted quantifier-এর রূপও বদলায়: ∀d (J(d) → …)-এর negation ∃d (J(d) ∧ ¬…), কারণ ¬(p → q) ≡ p ∧ ¬q; আর ∃w (G ∧ …)-এর negation ∀w (G → ¬…)। নিয়ম দাঁড়ায়: ∀-এর সঙ্গী →, ∃-এর সঙ্গী ∧; negation-এ quantifier উল্টালে সঙ্গীও বদলায়। নিয়ম ভঙ্গের একটি প্রমাণ দিতে তাই দরকার একটি জেলা আর একটি function: প্রতিটি গুদামকে একটি না-পৌঁছানো থানা।
এবার সবচেয়ে বিখ্যাত nested বাক্যটি, যা বহু শিক্ষার্থীকে প্রথমবার হোঁচট খাওয়ায়। নিচের stepper-টি একটু উন্নত স্তরের; Calculus-এর limit না দেখে থাকলে শুধু quantifier-এর নড়াচড়া খেয়াল করুন, বাকিটা পরের অংশে ব্যাখ্যা আছে।
| এখনকার রূপ | |
| নিয়ম |
- পুরো রূপে লেখা আর সামনে ¬। “ε > 0”-এর মতো সীমিত quantifier খুলে লিখলে ∀ε (ε > 0 → …) আর ∃δ (δ > 0 ∧ …)। ভেতরের লম্বা দুটি শর্তকে আপাতত A(x) আর B(x) নাম দিলাম, যাতে quantifier-গুলো চোখে পড়ে।
- প্রথম quantifier পেরোনো। ¬∀ε হলো ∃ε ¬, আর ¬(ε > 0 → …) হলো ε > 0 ∧ ¬(…)। অর্থাৎ “এমন একটি ধনাত্মক ε আছে যার জন্য …”।
- দ্বিতীয় quantifier. ¬∃δ হলো ∀δ ¬, আর ¬(δ > 0 ∧ …) হলো δ > 0 → ¬(…)। সীমিত রূপে আবার সংক্ষেপে লিখলে: ∃ε > 0 ∀δ > 0 ¬∀x (A → B).
- তৃতীয় quantifier. ¬∀x হলো ∃x ¬। তিনটি quantifier-ই উল্টে গেছে: ∀∃∀ হয়েছে ∃∀∃।
- ভেতরের implication. ¬(A → B) ≡ A ∧ ¬B. এখানেই সবচেয়ে বেশি ভুল হয়: অনেকে লেখেন A → ¬B, যা ভুল। Implication-এর negation কখনো implication নয়।
- চূড়ান্ত রূপ আর অর্থ। “এমন একটি ε > 0 আছে যে, δ যত ছোটই নিন, a-এর δ-দূরত্বের ভেতরে এমন x পাওয়া যাবে যেখানে f(x), L থেকে অন্তত ε দূরে।” উদাহরণ: f(x) = 1 যখন x > 0, নইলে 0; a = 0, L = 0. ε = ½ নিন; যেকোনো δ-এর জন্য x = δ/2-তে f(x) = 1, আর │1 − 0│ = 1 ≥ ½। তাই lim f(x) = 0 নয়।
৫ · গণিতে quantifier — witness function, limit আর continuity
∀x∃y P(x, y) সত্য হলে প্রতিটি x-এর জন্য অন্তত একটি কাজের y আছে। প্রতিটি x-এর জন্য এমন একটি y বেছে রাখলে একটি function পাই: f(x) = বাছাই করা y. তখন ∀x P(x, f(x)) সত্য। এই function-কে বলে witness function, যুক্তিবিদ্যায় Skolem function (নরওয়েজীয় গণিতবিদ Thoralf Skolem-এর নামে, যিনি ১৯২০-এর দশকে এটি ব্যবহার করেন)। এটিই nested quantifier-এর সবচেয়ে কাজের দৃষ্টিভঙ্গি:
∃y∀x P(x, y) সত্য ⇔ এমন একটি ধ্রুবক y আছে যা সব x-এ খাটে
অর্থাৎ ∃y∀x মানে witness function-টি ধ্রুবক হতে পারে। এই দৃষ্টিতে উপপাদ্য ৫.১-এর (গ) প্রায় স্পষ্ট: ধ্রুবক function-ও তো একটি function. সসীম domain-এ “প্রতিটি x-এর জন্য একটি বাছাই” সোজা কাজ; অসীম domain-এ সাধারণভাবে এমন বাছাইয়ের অস্তিত্বের জন্য গণিতের একটি স্বতঃসিদ্ধ, axiom of choice, ব্যবহার করা হয়। আমাদের উদাহরণগুলোতে বাছাইয়ের নিয়ম স্পষ্ট লেখা যায়, তাই সে প্রশ্ন ওঠে না।
নিচের ব্লক প্রথম stepper-এর টেবিল থেকে f আর g দুটি function বানায়, তারপর একটি সংখ্যার উদাহরণ দেখায়: ∀n∃p (p > n ∧ p মৌলিক)। এটি Euclid-এর সেই প্রাচীন উপপাদ্য, “মৌলিক সংখ্যা অসীম”, quantifier-এর ভাষায়; এর প্রমাণ পর্ব ২০-এ (বিভাজ্যতা আর মৌলিক সংখ্যা) আসবে। এখানে witness function হলো “n-এর পরের মৌলিক সংখ্যা”।
areas = ["মিরপুর", "উত্তরা", "ধানমন্ডি", "মতিঝিল"]
riders = ["রাজু", "শিলা", "তানভীর", "মিতু"]
P = [[1, 0, 1, 0], # P[x][y] = 1: রাইডার y এলাকা x-এ যান
[0, 1, 0, 0],
[0, 0, 1, 1],
[1, 0, 0, 1]]
# ∀x∃y P(x, y)-এর witness function: প্রতিটি x-এর জন্য প্রথম যে y কাজ করে
f = {}
for i, x in enumerate(areas):
ys = [riders[j] for j in range(4) if P[i][j]]
f[x] = ys[0] if ys else None
print("f =", f)
print("∀x∃y সত্য?", all(v is not None for v in f.values()))
# ∃y∀x মিথ্যা, অর্থাৎ ∀y∃x ¬P: প্রতিটি রাইডারের একটি 'বাদ পড়া' এলাকা g(y)
g = {riders[j]: next(areas[i] for i in range(4) if not P[i][j])
for j in range(4)}
print("g =", g)
# সংখ্যার উদাহরণ: ∀n∃p (p > n এবং p মৌলিক); witness = পরের মৌলিক সংখ্যা
def is_prime(m):
return m > 1 and all(m % d for d in range(2, int(m ** 0.5) + 1))
def next_prime(n):
p = n + 1
while not is_prime(p):
p += 1
return p
print([(n, next_prime(n)) for n in (1, 10, 24, 89, 113, 1000)])
# ∃p∀n (p > n)-এর জন্য যেকোনো p-এর বিপক্ষে n = p-ই counterexample
print([(p, p > p) for p in (2, 97, 7919)])আসল আউটপুট (ব্রাউজারের Python):
f = {'মিরপুর': 'রাজু', 'উত্তরা': 'শিলা', 'ধানমন্ডি': 'তানভীর', 'মতিঝিল': 'রাজু'}
∀x∃y সত্য? True
g = {'রাজু': 'উত্তরা', 'শিলা': 'মিরপুর', 'তানভীর': 'উত্তরা', 'মিতু': 'মিরপুর'}
[(1, 2), (10, 11), (24, 29), (89, 97), (113, 127), (1000, 1009)]
[(2, False), (97, False), (7919, False)]
f আর g ঠিক stepper-এর শেষ ধাপের দুটি function. f ধ্রুবক নয় (মিরপুরে রাজু, উত্তরায় শিলা), আর অন্য কোনো বাছাইও ধ্রুবক হতে পারে না, কারণ g দেখাচ্ছে প্রতিটি রাইডারের অন্তত একটি বাদ পড়া এলাকা আছে। মৌলিক সংখ্যার তালিকায় witness n-এর ওপর জোরালোভাবে নির্ভর করে: ১১৩-এর পরের মৌলিক ১২৭, ফাঁক ১৪। শেষ লাইনটি ∃p∀n (p > n)-এর বিপক্ষে যুক্তি: যে p-ই প্রস্তাব করুন, n = p নিলে p > p মিথ্যা। তবে সাবধান: কয়েকটি n-এ next_prime কাজ করেছে বলে ∀n-এর প্রমাণ হয় না; প্রমাণের জন্য দেখাতে হয় যে while loop প্রতিটি n-এর জন্য থামে, আর সেটিই Euclid-এর উপপাদ্য।
Limit আর continuity: quantifier-এর ক্রমের সবচেয়ে বিখ্যাত উদাহরণ (উন্নত)
এই অংশটি Calculus বা real analysis-এর বিষয়; এখানে শুধু quantifier-এর গঠনটুকু দেখছি, পুরো তত্ত্ব নয়। বাস্তব ফাংশন f-এর ক্ষেত্রে “x যখন a-এর দিকে যায়, f(x)-এর limit L” কথাটির নিখুঁত সংজ্ঞা:
∀ε > 0 ∃δ > 0 ∀x (0 < |x − a| < δ → |f(x) − L| < ε)
এখানে ε (এপসাইলন) হলো “L থেকে কতটা দূরে থাকা চলবে”, আর δ (ডেল্টা) হলো “a-এর কতটা কাছে আসতে হবে”; |x − a| মানে x আর a-এর দূরত্ব। খেলার ভাষায়: প্রতিপক্ষ একটি সহনশীলতা ε দেন, আপনি সেটি দেখে δ বাছেন, তারপর প্রতিপক্ষ δ-এর ভেতরের যেকোনো x বাছেন। f(x) ε-এর ভেতরে থাকলে আপনি জেতেন। δ বাছার সময় আপনি ε জানেন, কিন্তু x জানেন না।
a বিন্দুতে continuity হলো একই গঠন, L-এর জায়গায় f(a). এখন f পুরো ℝ-এ continuous মানে প্রতিটি a-তে continuous: ∀a ∀ε ∃δ ∀x. এখানে δ নির্ভর করতে পারে ε আর a দুটোর ওপরই। কিন্তু যদি দাবি করি একটিই δ সব a-তে খাটে, তাহলে ∃δ-কে ∀a-র বাঁয়ে সরাতে হয়: ∀ε ∃δ ∀a ∀x. এটির নাম uniform continuity. দুটি সংজ্ঞায় শব্দ এক, শুধু ∃δ আর ∀a-র ক্রম আলাদা, আর উপপাদ্য ৫.১-এর (গ) অনুযায়ী uniform continuity থেকে সাধারণ continuity আসে, কিন্তু উল্টোটা নয়।
উদাহরণ: f(x) = x², a = 3-এ continuous. ε > 0 দেওয়া আছে। δ = min(1, ε/7) নিন। তাহলে |x − 3| < δ হলে:
- |x − 3| < 1, তাই 2 < x < 4, আর 5 < x + 3 < 7, অর্থাৎ |x + 3| < 7. (δ ≤ 1)
- |x² − 9| = |x − 3| · |x + 3|। (বীজগণিত: x² − 9 = (x − 3)(x + 3))
- |x − 3| · |x + 3| < δ · 7 ≤ (ε/7) · 7 = ε। (ধাপ ১ আর δ ≤ ε/7) ∎
এখানে δ = min(1, ε/7) হলো ∀ε∃δ-এর witness function: ε থেকে δ বানানোর নিয়ম। কিন্তু ৭ সংখ্যাটি এসেছে a = 3 থেকে (|x + 3| < 7). a বড় হলে δ-কে আরও ছোট হতে হয়।
উদাহরণ: x² ℝ-এ uniformly continuous নয়। Uniform continuity-র negation (উপপাদ্য ৫.২ খাটিয়ে): ∃ε > 0 ∀δ > 0 ∃x∃y (|x − y| < δ ∧ |x² − y²| ≥ ε)। ε = 1 নিন। যেকোনো δ > 0-এর জন্য x = 1/δ আর y = x + δ/2 নিন। তাহলে |x − y| = δ/2 < δ, আর y² − x² = (y − x)(y + x) = (δ/2)(2/δ + δ/2) = 1 + δ²/4 ≥ 1. ∎ নিচের ব্লক দুটি দাবিই সঠিক ভগ্নাংশে (Fraction, কোনো rounding ছাড়া) যাচাই করে।
from fractions import Fraction as F
def f(x):
return x * x
a, L = F(3), F(9)
def delta(eps): # প্রমাণ থেকে পাওয়া witness: δ = min(1, ε/7)
return min(F(1), eps / 7)
print("x = 3-এ continuity: প্রতিটি ε-এর জন্য δ(ε)")
for eps in (F(1), F(1, 10), F(1, 1000)):
d = delta(eps)
xs = [a + d * k / 1000 for k in range(-999, 1000) if k != 0]
worst = max(abs(f(x) - L) for x in xs)
print(f" ε={str(eps):6} δ={str(d):6} সবচেয়ে বড় |x²-9| = "
f"{float(worst):.6f} < ε? {worst < eps}")
print("ε = 1 ধরে uniform continuity যাচাই: কোনো একটি δ কি সব x-এ চলে?")
for d in (F(1, 2), F(1, 10), F(1, 100)):
x = 1 / d # δ যত ছোট, x তত দূরে নিতে হয়
y = x + d / 2 # |y - x| = δ/2 < δ
print(f" δ={str(d):5} x={str(x):4} |y-x|={str(y - x):6} "
f"|y²-x²| = {y * y - x * x} ≥ 1? {y * y - x * x >= 1}")আসল আউটপুট (ব্রাউজারের Python):
x = 3-এ continuity: প্রতিটি ε-এর জন্য δ(ε)
ε=1 δ=1/7 সবচেয়ে বড় |x²-9| = 0.876653 < ε? True
ε=1/10 δ=1/70 সবচেয়ে বড় |x²-9| = 0.085832 < ε? True
ε=1/1000 δ=1/7000 সবচেয়ে বড় |x²-9| = 0.000856 < ε? True
ε = 1 ধরে uniform continuity যাচাই: কোনো একটি δ কি সব x-এ চলে?
δ=1/2 x=2 |y-x|=1/4 |y²-x²| = 17/16 ≥ 1? True
δ=1/10 x=10 |y-x|=1/20 |y²-x²| = 401/400 ≥ 1? True
δ=1/100 x=100 |y-x|=1/200 |y²-x²| = 40001/40000 ≥ 1? True
প্রথম অংশে প্রতিটি ε-এর জন্য δ-এর ভেতরের ১,৯৯৮টি বিন্দুতে সবচেয়ে বড় ফারাক ε-এর নিচে থেকেছে; ε = 1-এ ০.৮৭৭, অর্থাৎ ৭ গুণকটি একটু রক্ষণশীল, কিন্তু প্রমাণের জন্য রক্ষণশীল হওয়াই যথেষ্ট। দ্বিতীয় অংশে প্রতিটি δ-এর বিপক্ষে একটি x পাওয়া গেছে যেখানে ফারাক ১-এর বেশি: ১৭/১৬ = ১ + (১/২)²/৪, ঠিক সূত্রের মতো। δ যত ছোট, x তত বড় (২, ১০, ১০০)। এটিই ∀δ∃x-এর witness function: x = 1/δ। তবে কয়েকটি বিন্দু দেখা প্রমাণ নয়; প্রমাণ উপরের তিন ধাপ। কম্পিউটার এখানে প্রমাণের প্রতিটি দাবি আলাদা করে পরীক্ষা করছে।
৬ · Programming-এ quantifier — nested loop, all/any আর SQL
সসীম domain-এ quantifier আসলে loop. ∀x Q(x) মানে সব x একে একে দেখা, আর একটিতেও Q মিথ্যা হলে সেখানেই থেমে False ফেরত দেওয়া; ∃x Q(x) মানে একটিতে Q সত্য হলেই থেমে True ফেরত দেওয়া। তাই ∀x∃y P(x, y) হয় দুই স্তরের loop: বাইরে x, ভেতরে y. Quantifier-এর ক্রম আর loop-এর ক্রম এক। নিচের trace-এ একটি ৩×৩ relation-এ ∀x∃y যাচাই হচ্ছে, যার শেষ সারিতে কোনো ✓ নেই।
1def forall_exists(P):2 for x in range(3): # ∀x3 found = False4 for y in range(3): # ∃y5 if P[x][y]:6 found = True7 break8 if not found:9 return False10 return True
| x | |
| y | |
| found | |
| দেখা ঘর |
- বাইরের loop = ∀x. x = 0 দিয়ে শুরু। প্রতিটি নতুন x-এর জন্য found আবার False করা হয়, কারণ ∃y-এর খোঁজ প্রতিটি x-এর জন্য নতুন করে শুরু হয়।
- ভেতরের loop = ∃y. P[0][0] = 0, witness নয়; পরের y দেখতে হবে। মোট দেখা ঘর ১।
- Witness পাওয়া গেল। P[0][1] = 1, তাই found = True আর
break: ∃-এর জন্য একটি witness-ই যথেষ্ট, বাকি y দেখার দরকার নেই। - x = 0-এর কাজ শেষ। found সত্য, তাই লাইন ৯-এর return হয়নি। বাইরের loop পরের x = 1-এ গেল, found আবার False.
- x = 1-এ প্রথম ঘরেই witness. P[1][0] = 1, found = True, break. মোট দেখা ঘর ৩।
- x = 2. found = False দিয়ে নতুন খোঁজ শুরু।
- খোঁজ চলছে। P[2][0] = 0. ভেতরের loop থামে না, কারণ এখনো কোনো witness নেই।
- পুরো সারি শেষ। P[2][1] = 0, P[2][2] = 0. ভেতরের loop break ছাড়াই শেষ হলো, অর্থাৎ ∃y P(2, y) মিথ্যা। মোট দেখা ঘর ৬।
- Counterexample পাওয়া গেল। found মিথ্যা, তাই
return False: x = 2 হলো ∀x∃y-এর counterexample. ∀-এর জন্য একটি counterexample-ই যথেষ্ট, তাই বাইরের loop-এর বাকি অংশ আর চলার দরকার নেই (এখানে বাকি ছিলও না)।
Python-এ একই কাজ এক লাইনে: all(any(P[x][y] for y in Y) for x in X). all() হলো ∀, any() হলো ∃, আর লেখার ক্রমই quantifier-এর ক্রম। দুটিই short-circuit করে: all() প্রথম False পেলে থামে, any() প্রথম True পেলে, ঠিক উপরের break আর return-এর মতো। (loop আর comprehension-এর Python দিক Python প্রোগ্রামিং কোর্সের পর্ব ১২ আর পর্ব ১৮-এ আছে।) ∃y∀x লিখতে হলে loop-এর ক্রম বদলাতে হয়: any(all(P[x][y] for x in X) for y in Y). দুই ক্ষেত্রেই সবচেয়ে খারাপ অবস্থায় |X| · |Y|টি ঘর দেখতে হয়; প্রতিটি অতিরিক্ত quantifier আরেকটি গুণক যোগ করে, তাই তিন স্তরের quantifier-এ n চলকের domain-এ n³ পর্যন্ত কাজ।
বাস্তবের ডেটায় দুটি বাক্য কত ঘন ঘন সত্য হয়? ধরুন প্রতিটি (এলাকা, রাইডার) জোড়ায় ডেলিভারি ব্যবস্থা থাকার সম্ভাবনা p = 0.6, স্বাধীনভাবে। একটি সারিতে কোনো ✓ না থাকার সম্ভাবনা (1 − p)n, তাই ∀x∃y-এর সম্ভাবনা (1 − (1 − p)n)n. একটি কলাম পুরো ✓ হওয়ার সম্ভাবনা pn, তাই ∃y∀x-এর সম্ভাবনা 1 − (1 − pn)n. নিচের ব্লক seed-সহ এলোমেলো relation বানিয়ে সূত্রের সঙ্গে মেলায়।
import random
random.seed(2026)
p = 0.6 # প্রতিটি (এলাকা, রাইডার) জোড়ায় P সত্য হওয়ার সম্ভাবনা
trials = 3000
def one(n):
P = [[random.random() < p for _ in range(n)] for _ in range(n)]
ae = all(any(row) for row in P) # ∀x∃y
ea = any(all(P[x][y] for x in range(n)) for y in range(n)) # ∃y∀x
return ae, ea
print(" n ∀x∃y(sim) সূত্র ∃y∀x(sim) সূত্র ∃y∀x সত্য কিন্তু ∀x∃y মিথ্যা")
for n in (2, 4, 6, 8, 12):
ae = ea = bad = 0
for _ in range(trials):
a, e = one(n)
ae += a; ea += e; bad += e and not a
f_ae = (1 - (1 - p) ** n) ** n
f_ea = 1 - (1 - p ** n) ** n
print(f"{n:2d} {ae / trials:.3f} {f_ae:.3f} "
f"{ea / trials:.3f} {f_ea:.3f} {bad}")আসল আউটপুট (ব্রাউজারের Python):
n ∀x∃y(sim) সূত্র ∃y∀x(sim) সূত্র ∃y∀x সত্য কিন্তু ∀x∃y মিথ্যা
2 0.715 0.706 0.604 0.590 0
4 0.898 0.901 0.427 0.426 0
6 0.976 0.976 0.263 0.249 0
8 0.991 0.995 0.121 0.127 0
12 0.999 1.000 0.024 0.026 0
দুটি কলাম উল্টো দিকে চলে। n বাড়লে ∀x∃y প্রায় নিশ্চিত হয়ে ওঠে (n = 12-এ ০.৯৯৯), কারণ ১২টি রাইডারের মধ্যে একজনও কোনো এলাকায় না যাওয়ার সম্ভাবনা খুব কম। কিন্তু ∃y∀x দ্রুত ভেঙে পড়ে (০.০২৪), কারণ একজন রাইডারকে ১২টি এলাকাই সামলাতে হবে, যার সম্ভাবনা 0.612 ≈ ০.০০২। Simulation আর সূত্রের ফারাক সর্বোচ্চ প্রায় ০.০১৪, ৩,০০০টি নমুনায় এমন এলোমেলো ফারাক স্বাভাবিক। শেষ কলামে ১৫,০০০টি এলোমেলো relation-এর একটিতেও ∃y∀x সত্য অথচ ∀x∃y মিথ্যা হয়নি, উপপাদ্য ৫.১(গ) যা বলে। এখান থেকে একটি ব্যবহারিক শিক্ষা: “প্রতিটি এলাকায় কেউ না কেউ যান” সহজে পূরণ হয়, কিন্তু “একজন সবখানে যান” এমন নিয়ম বড় শহরে প্রায় অসম্ভব।
SQL-এ “সবার জন্য”: দুটি NOT EXISTS
SQL-এ EXISTS আছে (এটি ∃), কিন্তু FOR ALL বলে কোনো শব্দ নেই। তাই ∀ লিখতে উপপাদ্য ৫.২-এর কৌশল লাগে: ∀x Q(x) ≡ ¬∃x ¬Q(x). “যে রাইডার সব এলাকায় যান” মানে ∃y∀x S(x, y)-এর witness খোঁজা, অর্থাৎ এমন y যার জন্য ¬∃x ¬S(x, y): “এমন কোনো এলাকা নেই যেখানে তিনি যান না।” এই ধরনের প্রশ্নকে database-এর ভাষায় relational division বলে (DBMS ও SQL কোর্সের পর্ব ৩৩), আর EXISTS-এর বিস্তারিত সেই কোর্সের পর্ব ২১-এ।
-- ∀x∃y: কোনো এলাকা কি রাইডারহীন? (ফাঁকা ফল = প্রতিটি এলাকায় কেউ যান)
SELECT a.name FROM area a
WHERE NOT EXISTS (SELECT 1 FROM serves s WHERE s.area = a.name);
-- ∃y∀x: কোন রাইডারের জন্য "যেখানে তিনি যান না এমন এলাকা" নেই?
SELECT r.name FROM rider r
WHERE NOT EXISTS (
SELECT 1 FROM area a
WHERE NOT EXISTS (
SELECT 1 FROM serves s
WHERE s.rider = r.name AND s.area = a.name));সত্যিকারের run: Python 3.14.4-এর ভেতরের SQLite 3.50.4-এ, প্রথম stepper-এর টেবিলটিই serves টেবিলে বসিয়ে (প্রশ্ন দুটিকে Q1, Q2 নামে), পরে মিতুর জন্য মিরপুর আর উত্তরা যোগ করে:
$ python sql_demo.py
sqlite 3.50.4
Q1 rows: []
Q2 rows: []
after adding Mitu->Mirpur, Mitu->Uttara
Q2 rows: [('Mitu',)]
Q1 ফাঁকা, অর্থাৎ রাইডারহীন কোনো এলাকা নেই: ∀x∃y সত্য। Q2-ও ফাঁকা: ∃y∀x মিথ্যা, stepper-এর সঙ্গে মিলে গেল। মিতুর দুটি নতুন এলাকা যোগ করার পর মিতুর কলাম পুরো ✓ হলো, আর Q2 তাঁকেই witness হিসেবে ফেরত দিল। দুই স্তরের NOT EXISTS পড়ার সহজ উপায়: “এমন কোনো এলাকা নেই, যেখানে এমন কোনো ডেলিভারি নেই” = ¬∃x ¬∃ = ∀x∃।
৭ · সাধারণ ভুল, গভীরতর দিক আর পরীক্ষার প্রস্তুতি
Nested quantifier-এ ভুলগুলো বারবার একই ছাঁচে আসে। নিচের তালিকাটি নিজের লেখা মেলানোর জন্য রেখে দিন।
| ভুল | ভুল রূপ | ঠিক রূপ |
|---|---|---|
| ক্রম উল্টে ফেলা | “প্রতিটি গ্রাহকের একটি পাসওয়ার্ড আছে” → ∃p∀c H(c, p), অর্থাৎ সবার একই পাসওয়ার্ড | ∀c∃p H(c, p) |
| শুধু বাইরের quantifier উল্টানো | ¬∀x∃y P ≡ ∃x∃y ¬P | ¬∀x∃y P ≡ ∃x∀y ¬P |
| ∀-এর সঙ্গে ∧ | ∀x (Order(x) ∧ Paid(x)): domain-এর সবকিছুই অর্ডার | ∀x (Order(x) → Paid(x)) |
| ∃-এর সঙ্গে → | ∃x (Order(x) → Late(x)): একটি অ-অর্ডার থাকলেই সত্য | ∃x (Order(x) ∧ Late(x)) |
| Implication-এর ভুল negation | ¬(A → B) ≡ A → ¬B | ¬(A → B) ≡ A ∧ ¬B |
| একই চলকের নাম দুবার | ∀x (P(x) → ∃x Q(x, x)): কোন x কোনটি? | ∀x (P(x) → ∃y Q(x, y)) |
| কোডে found আবার False না করা | found = False বাইরের loop-এর আগে: আসলে ∃x∃y যাচাই | প্রতিটি x-এর শুরুতে found = False |
আরেকটি সূক্ষ্ম ভুল খালি domain নিয়ে। পর্ব ০৪-এ দেখেছেন, খালি domain-এ ∀x Q(x) আপনাআপনি সত্য (vacuous truth) আর ∃x Q(x) মিথ্যা। তাই ছবি ৫.১-এর ∀x∀y → ∃x∀y তীরটি খালি X-এ ভাঙে: ∀x∀y সত্য, কিন্তু ∃x∀y মিথ্যা। কোডেও একই ঘটনা: খালি list-এ all([]) হলো True আর any([]) হলো False. বাজারঘরে নতুন খোলা একটি শহরে এখনো কোনো এলাকা না থাকলে “প্রতিটি এলাকায় রাইডার আছে” পরীক্ষা পাস করবে; আপনার রিপোর্ট যেন সেটিকে “সব ঠিক আছে” না বলে।
আরও গভীরে: প্রতিটি first-order বাক্যকে এমন রূপে আনা যায় যেখানে সব quantifier সামনে সারি বেঁধে থাকে, একে বলে prenex normal form; তখন ∀ আর ∃ কতবার পালা বদল করে (quantifier alternation) সেটিই বাক্যের “জটিলতা” মাপার একটি প্রধান উপায়, আর সংখ্যাতত্ত্বের বাক্যগুলোকে এভাবে সাজানো স্তরকে arithmetical hierarchy বলে (Kleene আর Mostowski-র ১৯৪০-এর দশকের কাজ)। Boolean চলকের ওপর এমন সারিবদ্ধ বাক্য, অর্থাৎ QBF, সত্য কি না বের করার সমস্যাটি PSPACE-complete বলে Stockmeyer আর Meyer ১৯৭৩ সালে দেখান। আর resolution-ভিত্তিক theorem prover প্রতিটি ∃-কে Skolem function দিয়ে বদলে quantifier সরিয়ে ফেলে (Skolemization); resolution-এর মূল ধারণা পর্ব ০৬-এ আসবে।
পরীক্ষা ও ইন্টারভিউতে:
- ℤ-এ ∀x∃y (x + y = 0) আর ∃y∀x (x + y = 0)-এর মান? প্রথমটি সত্য (y = −x), দ্বিতীয়টি মিথ্যা (যেকোনো b-এর জন্য x = 1 − b).
- ¬∀x∃y (x < y)-কে ¬ ছাড়া লিখুন। ∃x∀y (x ≥ y).
- ∃y∀x P → ∀x∃y P কি সবসময় সত্য? উল্টোটা? প্রথমটি হ্যাঁ (b-কে সব x-এর witness ধরুন), উল্টোটা না (ℤ-এ x + y = 0).
- “প্রতিটি ছাত্রের একজন বন্ধু আছে যে সব কোর্সে পাস করেছে” লিখুন। ∀s∃f (F(s, f) ∧ ∀c P(f, c)).
- ৩টি x আর ৩টি y-তে কয়টি relation-এ ∀x∃y P সত্য? (23 − 1)3 = ৩৪৩, মোট ৫১২-এর মধ্যে।
৮ · AI-এর যুগে nested quantifier — AI-কে কীভাবে যাচাই করবেন
AI সহকারীকে “এই বাক্যটি predicate logic-এ লিখে দাও” বা “এর negation কী” জিজ্ঞেস করলে সাধারণত দ্রুত, আত্মবিশ্বাসী আর পরিপাটি উত্তর আসে। কিন্তু nested quantifier ঠিক সেই জায়গা, যেখানে একটি চিহ্ন এদিক-ওদিক হলে পুরো অর্থ বদলে যায়, অথচ লেখা দেখতে প্রায় একই থাকে। সাধারণত যে ধরনের ভুল দেখা যায়, সেগুলোও বলা হয় একই আত্মবিশ্বাস নিয়ে:
| AI-এর ভুল | কীভাবে ধরবেন |
|---|---|
| অনুবাদে ∀ আর ∃-এর ক্রম উল্টে দেয়, বিশেষ করে “যা”, “যে” দিয়ে জোড়া বাক্যে | সূত্রটি আবার বাংলায় পড়ুন; ছোট টেবিলে দুটি রূপের মান মিলিয়ে দেখুন |
| Negation-এ একটি quantifier উল্টাতে ভুলে যায়, বা ¬(A → B)-কে A → ¬B লেখে | সব relation-এ brute force: মূল আর negation কি সবসময় উল্টো মান দেয়? |
| ভুল দিকের implication “প্রমাণ” করে, যেমন ∀x∃y → ∃y∀x | উপপাদ্য ৫.১(ঘ)-এর মতো ছোট counterexample খুঁজুন |
| Continuity আর uniform continuity গুলিয়ে ফেলে; δ যে x-এর ওপর নির্ভর করছে তা চেপে যায় | প্রমাণে δ-এর সূত্রে x বা a আছে কি না দেখুন, আর quantifier-এর ক্রম মেলান |
| উপপাদ্যের শর্ত বাদ দেয় (যেমন domain খালি না হওয়া), বা বানানো বইয়ের রেফারেন্স দেয় | প্রতিটি উপপাদ্যের শর্ত জিজ্ঞেস করুন; রেফারেন্স নিজে খুঁজে মিলিয়ে নিন |
AI-কে কাজে লাগানোর সবচেয়ে নিরাপদ পথ হলো তাকে দিয়ে উত্তরের সঙ্গে একটি যাচাইযোগ্য জিনিসও বানিয়ে নেওয়া: একটি ছোট counterexample বা একটি brute-force কোড, যা আপনি নিজে চালাতে পারবেন।
AI-এর গণিত হাতে পেলে — যাচাইয়ের চেকলিস্ট
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন, তারপর “→ উত্তর” চাপুন।
প্র ০১উনিশ শতকের বড় গণিতবিদেরাও quantifier-এর ক্রম নিয়ে ভুল করেছিলেন বলে শোনা যায়। ঘটনাটি কী, আর এর থেকে কী শেখার আছে?
সবচেয়ে বেশি আলোচিত ঘটনাটি Augustin-Louis Cauchy-র। ১৮২১ সালের বিখ্যাত পাঠ্যবই Cours d'analyse-এ তিনি একটি ফল দেন, যা আজকের ভাষায় দাঁড়ায়: “continuous ফাংশনের একটি অসীম ধারা (series) যদি প্রতিটি বিন্দুতে converge করে, তবে যোগফলটিও continuous.” ১৮২৬ সালে Niels Henrik Abel একটি লেখায় মন্তব্য করেন যে এই ফলের ব্যতিক্রম আছে, আর উদাহরণ হিসেবে sin x − (sin 2x)/2 + (sin 3x)/3 − … ধারাটির কথা বলেন: প্রতিটি পদ continuous, কিন্তু যোগফলে লাফ (jump) আছে।
সমস্যাটি ঠিক quantifier-এর ক্রমে। “প্রতিটি বিন্দুতে converge করে” মানে ∀x ∀ε ∃N (n ≥ N হলে ভুল < ε), যেখানে N নির্ভর করতে পারে x-এর ওপর। Continuity টিকিয়ে রাখার জন্য আসলে দরকার শক্ত দাবিটি: ∀ε ∃N ∀x, অর্থাৎ একটিই N সব x-এ খাটে। একে আজ uniform convergence বলা হয়। ১৮৪০-এর দশকের শেষে Philipp Ludwig von Seidel আর George Gabriel Stokes আলাদাভাবে এই পার্থক্য ধরেন, আর Karl Weierstrass তাঁর বক্তৃতায় পুরো ε-δ ভাষা আর uniform convergence-কে আজকের রূপে দাঁড় করান। Cauchy নিজে ঠিক কী বোঝাতে চেয়েছিলেন, সে নিয়ে ইতিহাসবিদদের মধ্যে আজও বিতর্ক আছে; কেউ কেউ মনে করেন তাঁর “অসীম ক্ষুদ্র” ধারণায় শর্তটি লুকানো ছিল।
শিক্ষাটি দুই রকম। প্রথমত, স্বাভাবিক ভাষায় “যথেষ্ট বড় n নিলে ভুল ছোট হয়” কথাটি দুটি ভিন্ন quantifier-ক্রম লুকিয়ে রাখে, আর প্রতিভাবান মানুষও সেখানে পিছলে যেতে পারেন। দ্বিতীয়ত, গণিত এগিয়েছে ঠিক এই অস্পষ্টতা দূর করে: ε, δ, N-এর quantifier স্পষ্ট লিখে কোনটি কার ওপর নির্ভর করে তা চোখের সামনে আনা। আজ আমরা AI-এর লেখা প্রমাণ পড়ার সময় একই প্রশ্ন করি: এই δ কি x-এর ওপর নির্ভর করছে, আর সেটি কি অনুমোদিত?
মূল উপলব্ধি: “প্রতিটি x-এর জন্য একটি N” আর “একটি N সব x-এর জন্য” এক নয়। বড় ভুল প্রায়ই আসে এমন দুটি বাক্য থেকে, যা স্বাভাবিক ভাষায় প্রায় একই শোনায়।
প্র ০২∀x∃y P(x, y) সত্য হলেই কি কম্পিউটার দিয়ে প্রতিটি x-এর y বের করা যায়?
না, আর এর উত্তর কম্পিউটার বিজ্ঞানের সবচেয়ে গভীর ফলগুলোর একটির সঙ্গে জড়িত। ধরুন x হলো যেকোনো Python প্রোগ্রাম, আর y একটি bit (0 বা 1). P(x, y): “y = 1 ঠিক তখন, যখন প্রোগ্রাম x খালি input-এ শেষ পর্যন্ত থামে”। প্রতিটি প্রোগ্রাম হয় থামে, নয়তো থামে না, তাই প্রতিটি x-এর জন্য ঠিক একটি y কাজ করে: ∀x∃y P(x, y) সত্য, আর witness function f-ও অস্তিত্বশীল, গাণিতিক অর্থে।
কিন্তু Alan Turing ১৯৩৬ সালে দেখান, এমন কোনো algorithm নেই যা প্রতিটি প্রোগ্রামের জন্য এই f(x) সঠিকভাবে হিসাব করে। এটি halting problem, যার প্রমাণ পর্ব ৭৫-এ (Turing machine-এর পরিচয়) আসবে, আর পরের Theory of Computation কোর্সে আরও গভীরে। অর্থাৎ “witness আছে” আর “witness হিসাব করা যায়” দুটি আলাদা কথা। ক্লাসিক্যাল গণিত প্রথমটিতেই সন্তুষ্ট। Constructive mathematics নামের একটি ধারা (L. E. J. Brouwer-এর intuitionism থেকে উৎসারিত) দাবি করে, ∃-এর প্রমাণ মানে witness বানানোর একটি পদ্ধতি দেওয়া। এই ধারণাই আধুনিক কিছু proof assistant-এর ভিত্তি, যেখানে ∀x∃y-এর একটি constructive প্রমাণ থেকে সরাসরি একটি চালানো যায় এমন প্রোগ্রাম বের করা যায়।
বাস্তব প্রোগ্রামিংয়েও এর ছায়া দেখবেন। “প্রতিটি অর্ডারের জন্য একটি বৈধ ডেলিভারি সময় আছে” প্রমাণ করা এক কথা; সেই সময়টি দ্রুত খুঁজে বের করার algorithm লেখা আরেক কথা। কখনো witness খোঁজা সহজ (পরের মৌলিক সংখ্যা), কখনো খুব ধীর (বড় সংখ্যার উৎপাদক খোঁজা, যা পর্ব ২৫-এ আসবে), আর কখনো অসম্ভব (halting). উপরের next_prime-এর while loop ঠিক এই প্রশ্নের মুখোমুখি: loop প্রতিটি n-এ থামবে, এ নিশ্চয়তা আসে Euclid-এর উপপাদ্য থেকে, কোড থেকে নয়।
মূল উপলব্ধি: ∀x∃y-এর সত্যতা, witness-এর অস্তিত্ব, আর witness-এর হিসাবযোগ্যতা তিনটি আলাদা স্তর। প্রমাণ পড়ার সময় জিজ্ঞেস করুন, এটি কোন স্তরের দাবি।
প্র ০৩শুধু ∃ থাকলে সমস্যা NP, আর ∀ ও ∃ পালা করে এলে আরও কঠিন — এর পেছনের যুক্তি কী?
Propositional logic-এর SAT সমস্যা আসলে একটি বড় ∃: “চলকগুলোর এমন একটি মান আছে কি, যাতে সূত্রটি সত্য?” একটি witness (মানের সেট) দেওয়া থাকলে সেটি দ্রুত যাচাই করা যায়, আর এটিই NP শ্রেণির মূল ধর্ম। Stephen Cook ১৯৭১ সালে দেখান SAT NP-complete (Leonid Levin স্বাধীনভাবে প্রায় একই সময়ে); বিস্তারিত DSA কোর্সের পর্ব ৬৪-এ। উল্টো দিকে “সূত্রটি কি সব মানে সত্য” (tautology) হলো একটি বড় ∀; এর বিপক্ষে একটি counterexample সহজে যাচাই করা যায়, কিন্তু পক্ষে ছোট প্রমাণ আছে কি না জানা নেই। এটি coNP শ্রেণি।
এখন ∀ আর ∃ মেশান: ∃x1∀x2∃x3… φ। এটি ঠিক দুই খেলোয়াড়ের একটি খেলা। ∃ খেলোয়াড় একটি চাল দেন, ∀ খেলোয়াড় জবাব দেন, আবার ∃, এভাবে। বাক্যটি সত্য মানে ∃ খেলোয়াড়ের একটি জয়ের কৌশল (winning strategy) আছে। দাবা, Go বা লুডুর মতো খেলায় “আমার এমন চাল আছে যে আপনার যেকোনো জবাবের পরে আমার এমন চাল আছে …” ঠিক এই গঠন। এমন Boolean সূত্রের সত্যতার সমস্যাকে QBF বলে, আর Larry Stockmeyer ও Albert Meyer ১৯৭৩ সালে দেখান এটি PSPACE-complete. এখানে witness একটি মান নয়, একটি পুরো কৌশল, অর্থাৎ প্রতিটি ∀-চালের জন্য একটি জবাব, যা Skolem function-এরই আরেক রূপ। এমন কৌশল লিখতেই সূচকীয় পরিমাণ জায়গা লাগতে পারে।
এই শ্রেণিগুলো আসলে আলাদা কি না, যেমন P ≠ NP বা NP ≠ PSPACE, তা এখনো প্রমাণিত নয়। কিন্তু অনুভবটি পরিষ্কার: প্রতিটি নতুন quantifier-পালাবদল খোঁজার কাজে আরেকটি স্তর যোগ করে। এই পর্বের brute force ব্লকেও সেটি দেখেছেন: প্রতিটি quantifier একটি loop.
মূল উপলব্ধি: quantifier-এর পালাবদল মানে খেলায় পালাবদল। কত বার পালা বদলায়, সেটিই প্রায়ই বলে দেয় একটি সমস্যা কত কঠিন।
প্র ০৪SQL-এ FOR ALL নেই কেন, আর দুটি NOT EXISTS লেখার সময় কী সাবধানতা দরকার?
Edgar F. Codd ১৯৭০ সালে relational model প্রস্তাব করেন, আর ১৯৭২ সালের একটি লেখায় relational calculus-কে query ভাষার মাপকাঠি হিসেবে দাঁড় করান। সেই calculus মূলত first-order logic: সেখানে ∃ আর ∀ দুটিই আছে। পরে বাস্তব query ভাষা হিসেবে SQL (শুরুতে SEQUEL, ১৯৭০-এর দশকে IBM-এ) জনপ্রিয় হলো, আর তাতে EXISTS রাখা হলো, কিন্তু সাধারণ FOR ALL নয়। উপপাদ্য ৫.২ অনুযায়ী ∀ = ¬∃¬, তাই প্রকাশের ক্ষমতা হারায়নি, শুধু লেখাটা একটু ঘোরানো হয়েছে। (কেন এই নকশা বেছে নেওয়া হয়েছিল, তার পুরো ইতিহাস নিয়ে নিশ্চিত সূত্র আমাদের জানা নেই।)
দুটি NOT EXISTS লেখার সময় তিনটি সাবধানতা:
- খালি domain: area টেবিল খালি হলে ভেতরের NOT EXISTS সবসময় সত্য, তাই প্রতিটি রাইডারকেই “সব এলাকায় যান” বলে ফেরত দেবে। এটি vacuous truth, গণিতে সঠিক, কিন্তু রিপোর্টে বিভ্রান্তিকর।
- NULL: NOT EXISTS-এর বদলে NOT IN লিখলে আর subquery-তে একটি NULL থাকলে পুরো ফল ফাঁকা হয়ে যেতে পারে, কারণ SQL তিন-মানের যুক্তি (TRUE, FALSE, UNKNOWN) ব্যবহার করে। এ কারণে “সবার জন্য” ধরনের প্রশ্নে NOT EXISTS নিরাপদ পছন্দ; বিস্তারিত DBMS ও SQL কোর্সের পর্ব ২১-এ।
- Correlation ঠিক রাখা: সবচেয়ে ভেতরের শর্তে r.name আর a.name দুটিই লাগবে। একটি বাদ পড়লে সেটি অন্য quantifier-এর সঙ্গে আর বাঁধা থাকে না, আর query নীরবে অন্য বাক্য যাচাই করে, যেমন ∃y∀x-এর বদলে ∀x∃y.
অন্য একটি পথও আছে: প্রতিটি রাইডারের আলাদা এলাকা গুনে (COUNT DISTINCT) মোট এলাকার সংখ্যার সঙ্গে মেলানো। এটি সহজ পড়া যায়, কিন্তু ডুপ্লিকেট সারি বা area টেবিলে নেই এমন এলাকা থাকলে ভুল দেয়। Logic-এর রূপটি মাথায় থাকলে দুটি query-র অর্থ মিলিয়ে দেখা সহজ হয়।
মূল উপলব্ধি: database query আসলে quantifier-সহ যুক্তিবাক্য। ∀-কে ¬∃¬ হিসেবে লেখার অভ্যাস থাকলে কঠিন রিপোর্টও নির্ভুলভাবে লেখা যায়।
প্র ০৫টেস্ট দিয়ে কোন ধরনের দাবি প্রমাণ করা যায় আর কোনটি যায় না? Quantifier-এর চোখে software testing
একটি ∃-দাবি (“এমন একটি input আছে যাতে প্রোগ্রাম crash করে”) একটি witness দেখালেই প্রমাণিত: ওই input-টি চালিয়ে দেখান। একটি ∀-দাবি (“প্রতিটি input-এ ফল সঠিক”) টেস্ট দিয়ে কখনো প্রমাণ হয় না, শুধু খণ্ডন হয়, কারণ একটি counterexample-ই তাকে ভাঙতে যথেষ্ট, আর সব input চালানো অসম্ভব। Edsger Dijkstra-র বহুল উদ্ধৃত কথাটি এরকম: টেস্ট বাগের উপস্থিতি দেখাতে পারে, অনুপস্থিতি নয়। পর্ব ০১-এ দেখেছেন, n² + n + 41 সূত্রটি n = 0 থেকে 39 পর্যন্ত মৌলিক দেয়, কিন্তু n = 40-এ ভাঙে; চল্লিশটি সফল টেস্টও ∀-এর প্রমাণ ছিল না।
∀∃ দাবি আরও সূক্ষ্ম। “প্রতিটি অর্ডারের জন্য একটি বৈধ ডেলিভারি স্লট আছে” যাচাই করতে টেস্টকে প্রতিটি নমুনা অর্ডারের জন্য একটি স্লট খুঁজে দেখাতে হয়। কোনো অর্ডারের স্লট না পেলে দুটি সম্ভাবনা: দাবিটি সত্যিই মিথ্যা, নয়তো খোঁজার কোড দুর্বল। তাই ∀∃-এর ব্যর্থ টেস্টকে counterexample বলার আগে প্রমাণ করতে হয় যে ভেতরের ∃-খোঁজটি সম্পূর্ণ ছিল, যেমন উপরের nested loop সব y দেখেছিল।
Property-based testing এই চিন্তাকে টুলে পরিণত করেছে। Koen Claessen আর John Hughes ২০০০ সালে Haskell-এর জন্য QuickCheck প্রকাশ করেন; Python-এ একই ধারণার একটি জনপ্রিয় লাইব্রেরি Hypothesis. আপনি একটি ∀-নিয়ম লেখেন (“যেকোনো list উল্টে আবার উল্টালে আগের list ফেরে”), টুলটি শত শত এলোমেলো input বানায়, আর ভাঙলে সবচেয়ে ছোট counterexample খুঁজে দেখায়। এটি এই পর্বের brute force-এরই বড় রূপ। তবে এটিও প্রমাণ নয়; পুরো নিশ্চয়তার জন্য লাগে প্রমাণ বা formal verification, যা পর্ব ১৩ (program-এর সঠিকতা) আর পর্ব ৭৭-এ (SAT আর SMT solver) আসবে।
মূল উপলব্ধি: ∃-কে witness দিয়ে প্রমাণ করুন, ∀-কে প্রমাণ দিয়ে, আর টেস্টকে ব্যবহার করুন counterexample খোঁজার যন্ত্র হিসেবে।
অনুশীলন
আগে নিজে খাতায় করুন, তারপর উত্তর মিলিয়ে নিন। সংখ্যার উত্তরগুলো Python দিয়ে যাচাই করা।
-
প্রমাণ: Domain ℤ। প্রমাণ করুন (ক) ∀x∃y (y > x) সত্য, (খ) ∃y∀x (y > x) মিথ্যা। (গ) Domain {1, 2, …, 10} হলে (ক)-এর বাক্যটির মান কী?
(ক) ১. ইচ্ছামতো একটি পূর্ণসংখ্যা x নিন। ২. y = x + 1 নিন; এটিও পূর্ণসংখ্যা। ৩. y − x = 1 > 0, তাই y > x. ৪. x ইচ্ছামতো ছিল, তাই ∀x∃y (y > x). Witness function f(x) = x + 1. ∎
(খ) Negation দেখাই: ∀y∃x (x ≥ y). ১. ইচ্ছামতো y নিন। ২. x = y নিন; তাহলে x ≥ y সত্য। ৩. তাই প্রতিটি y-এর বিপক্ষে counterexample আছে, ∃y∀x (y > x) মিথ্যা। (সহজ ভাষায়: সবচেয়ে বড় পূর্ণসংখ্যা নেই, আর y নিজের চেয়ে বড় নয়।) ∎
(গ) মিথ্যা: x = 10-এর জন্য domain-এ এর চেয়ে বড় কোনো y নেই। একই বাক্য, domain বদলালে মান বদলায়।
-
গণনা: বাজারঘরের ৩টি এলাকা আর ৪জন রাইডার। S(x, y) “রাইডার y এলাকা x-এ যান” এর সম্ভাব্য রূপ কয়টি? কয়টিতে ∀x∃y S(x, y) সত্য, আর কয়টিতে ∃y∀x S(x, y) সত্য? সূত্র দিয়ে বের করে brute force দিয়ে মিলিয়ে দেখুন।
টেবিলে ৩ × ৪ = ১২টি ঘর, প্রতিটি ✓ বা ·, তাই মোট 212 = ৪,০৯৬টি relation.
∀x∃y: প্রতিটি সারিতে (৪টি ঘর) অন্তত একটি ✓: 24 − 1 = ১৫ উপায়; ৩টি সারি স্বাধীন, তাই 153 = ৩,৩৭৫।
∃y∀x: মিথ্যা হয় যখন প্রতিটি কলামে (৩টি ঘর) অন্তত একটি ·: 23 − 1 = ৭ উপায়, ৪টি কলামে 74 = ২,৪০১। তাই সত্য 4096 − 2401 = ১,৬৯৫টিতে।
Brute force (itertools.product দিয়ে সব ৪,০৯৬টি) একই সংখ্যা দেয়: 3375 আর 1695. আরও লক্ষ্য করুন, যে ১,৬৯৫টিতে ∃y∀x সত্য, তার প্রতিটিতে ∀x∃y-ও সত্য, উপপাদ্য ৫.১(গ) অনুযায়ী।
-
আউটপুট অনুমান করুন: একজন ডেভেলপার ∀x∃y P(x, y) যাচাই করতে নিচের কোড লিখলেন। কোডটি কী print করবে, সঠিক উত্তর কী হওয়া উচিত, আর ভুলটি কোথায়?
P = [[1, 0], [0, 0]] found = False for x in range(2): for y in range(2): if P[x][y]: found = True print(found)কোডটি
Trueprint করবে। কিন্তু x = 1-এর সারি [0, 0], সেখানে কোনো y নেই, তাই ∀x∃y P আসলে মিথ্যা (all(any(row) for row in P)চালালেFalseআসে, যাচাই করা)।ভুল:
foundএকবারই, দুই loop-এর বাইরে False করা হয়েছে, আর কোনো x-এর জন্য found মিথ্যা কি না তা কখনো পরীক্ষা হয়নি। ফলে কোডটি আসলে ∃x∃y P যাচাই করছে: কোথাও একটি ✓ থাকলেই True. সংশোধন: প্রতিটি x-এর শুরুতেfound = False, ভেতরের loop-এর পরেif not found: return False, ঠিক অংশ ৬-এর trace-এর মতো। -
প্রমাণের ভুল ধরুন: দাবি: “ℝ-এ continuous প্রতিটি ফাংশন uniformly continuous.” ‘প্রমাণ’: ε > 0 নিন। f প্রতিটি বিন্দু a-তে continuous, তাই প্রতিটি a-এর জন্য একটি δ > 0 আছে যাতে |x − a| < δ হলে |f(x) − f(a)| < ε। এই δ নিলেই সব a আর x-এর জন্য শর্তটি খাটে। অতএব f uniformly continuous. ∎ — ভুলটি কোথায়, আর দাবিটি যে মিথ্যা তার একটি উদাহরণ দিন।
ভুলটি “এই δ নিলেই সব a-এর জন্য” বাক্যে। Continuity দেয় ∀a ∀ε ∃δ: δ নির্ভর করে a-এর ওপর, তাই একে δ(a) লেখা উচিত। “এই δ” বলে একটিই δ সব a-এর জন্য ধরে নেওয়া মানে ∃δ-কে ∀a-র বাঁয়ে সরানো, অর্থাৎ ∀a∃δ থেকে ∃δ∀a-তে লাফ, যা উপপাদ্য ৫.১(ঘ) অনুযায়ী বৈধ নয়। (অসীম অনেক ধনাত্মক δ(a)-র কোনো ক্ষুদ্রতম মানও থাকতে পারে না, তাদের infimum 0 হতে পারে।)
Counterexample: f(x) = x²। অংশ ৫-এ দেখেছেন, ε = 1-এর জন্য যেকোনো δ-এর বিপক্ষে x = 1/δ আর y = x + δ/2-তে |y² − x²| = 1 + δ²/4 ≥ 1. তাই x² continuous কিন্তু ℝ-এ uniformly continuous নয়। (সীমাবদ্ধ বন্ধ ব্যবধান [a, b]-এ অবশ্য continuous মানেই uniformly continuous; এটি Heine–Cantor উপপাদ্য, যার প্রমাণ real analysis-এর বিষয়।)
নিজেকে যাচাই করুন
ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।
ক্রমএকটি nested quantifier-বাক্যের negation বের করার ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)
- বাক্যটি সব quantifier আর সীমিত domain-এর শর্তসহ পুরো সূত্রে লিখুন
- পুরো সূত্রের সামনে ¬ বসান
- বাঁ থেকে ডানে একটি একটি quantifier পেরিয়ে ¬ ভেতরে নিন, প্রতিটি ∀ ↔ ∃ উল্টে
- ভেতরের শর্তে ¬ খাটান, যেমন ¬(A → B) ≡ A ∧ ¬B
- ছোট একটি উদাহরণে দেখুন মূল বাক্য আর negation সবসময় উল্টো মান দেয়
Domain হলো সব পূর্ণসংখ্যা ℤ। নিচের কোন বাক্যটি সত্য?
- ∃y∀x (x + y = 0)
- ∀x∃y (x + y = 0)
- ∃x∀y (x ≤ y)
- ∀x∀y (x + y = 0)
¬∀x∃y P(x, y)-এর সমতুল্য কোনটি?
- ∃x∃y ¬P(x, y)
- ∀x∃y ¬P(x, y)
- ∃x∀y ¬P(x, y)
- ∃y∀x ¬P(x, y)
খালি নয় এমন domain আর যেকোনো predicate P(x, y)-এর জন্য কোন implication সবসময় সত্য?
- ∃y∀x P(x, y) → ∀x∃y P(x, y)
- ∀x∃y P(x, y) → ∃y∀x P(x, y)
- ∃x∃y P(x, y) → ∀x∃y P(x, y)
- ∀x∃y P(x, y) → ∃x∀y P(x, y)
Python-এ all(any(P[x][y] for y in Y) for x in X) কোন বাক্যটি যাচাই করে?
- ∃y∀x P(x, y)
- ∀x∀y P(x, y)
- ∃x∃y P(x, y)
- ∀x∃y P(x, y)
f: ℝ → ℝ-এর জন্য ∀ε > 0 ∃δ > 0 ∀a ∀x (|x − a| < δ → |f(x) − f(a)| < ε) বাক্যটি কী বোঝায়?
- f প্রতিটি বিন্দুতে continuous, এর বেশি কিছু নয়
- f uniformly continuous: প্রতিটি ε-এর জন্য একটিই δ সব বিন্দুতে কাজ করে
- f-এর কোনো একটি বিন্দুতে limit আছে
- f একটি ধ্রুবক ফাংশন
Domain ℕ = {0, 1, 2, …} হলে ∃x∀y (x ≤ y) বাক্যটির মান কী?
- মিথ্যা, কারণ ℕ অসীম
- মান ঠিক করা যায় না, কারণ x free variable
- সত্য, witness x = 0
- মিথ্যা, কারণ y = 0-এ শর্ত ভাঙে
শব্দকোষ
লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন, অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:
মনে রাখুন
- Nested quantifier পড়ুন বাঁ থেকে ডানে; প্রতিটি ∃-এর witness তার বাঁয়ের ∀-চলকগুলোর ওপর নির্ভর করতে পারে।
- ∀∀ আর ∃∃ অদলবদল করা যায়; ∃y∀x → ∀x∃y সবসময় সত্য, কিন্তু উল্টোটি নয় (ℤ-এ x + y = 0).
- Negation: ¬ ভেতরে নিন, প্রতিটি ∀ ↔ ∃ উল্টান, শেষে শর্তটি উল্টান; ¬(A → B) ≡ A ∧ ¬B.
- ∀-এর সঙ্গী →, ∃-এর সঙ্গী ∧; continuity (∀a∀ε∃δ) আর uniform continuity (∀ε∃δ∀a) পার্থক্য শুধু ক্রমে।
- কোডে quantifier = loop:
all= ∀,any= ∃; SQL-এ ∀ = দুটি NOT EXISTS; ছোট domain-এ brute force দিয়ে যাচাই করুন, প্রমাণ দিয়ে নিশ্চিত হোন।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পর্ব ০৬ · অনুমানের নিয়ম — modus ponens থেকে resolutionপরবর্তী পর্ববৈধ যুক্তির রূপ, fallacy আর quantifier-সহ অনুমানের চারটি নিয়ম।
- ডিসক্রিট ম্যাথমেটিক্স · কোর্স হোম৮৩টি পর্বপুরো কোর্সের মানচিত্র — কোন মডিউলে কী।
- AI-এর ভিত্তি · পর্ব ৪৬ — First-order logicপাশের ট্র্যাকQuantifier আর nested quantifier কীভাবে AI-এর knowledge base আর inference-এ কাজে লাগে।
- DBMS ও SQL · পর্ব ২১ — Subquery আর EXISTSপ্রয়োগEXISTS, NOT EXISTS আর correlated subquery-র বিস্তারিত।
- DSA · পর্ব ৩ — অ্যালগরিদম ঠিক কি নাপ্রয়োগLoop invariant আর induction দিয়ে ∀-দাবির প্রমাণ অ্যালগরিদমে।