সরাসরি পর্বে যান
পর্ব ১৮ · ৮৩-এর মধ্যে · মডিউল ৩

Cardinality — countable, uncountable আর Cantor-এর diagonal

Cardinality — Bijections, Countable Sets, Cantor's Diagonal Argument, Cantor's Theorem and Uncomputable Problems

Taught in Bangla, this lesson compares infinite sets by bijection, shows that ℤ, ℕ × ℕ (via the Cantor pairing function) and ℚ are countable, and proves (0, 1) uncountable by Cantor's diagonal argument and |S| < |P(S)| by Cantor's theorem. It covers Schröder–Bernstein, the continuum hypothesis, and why uncomputable problems must exist. In-page Python checks the pairing function on a 200 × 200 grid, lists rationals by Calkin–Wilf, and builds a diagonal string.

এই পর্বে যা শিখবেন

  • Bijection আর injection দিয়ে |A| = |B| আর |A| ≤ |B|-এর নিখুঁত সংজ্ঞা; finite, countably infinite, countable আর uncountable
  • ℤ, ℕ×ℕ আর ℚ countable, স্পষ্ট bijection বা তালিকা দিয়ে প্রমাণ; Cantor pairing function আর তার inverse
  • Cantor-এর diagonal argument দিয়ে (0, 1) আর ℝ uncountable, পূর্ণ প্রমাণ
  • Cantor-এর উপপাদ্য |S| < |P(S)|, Schröder–Bernstein-এর ব্যবহার, আর continuum hypothesis-এর অর্থ
  • কেন প্রোগ্রামের চেয়ে সমস্যা বেশি, আর তাই কিছু সমস্যা computable নয়

১ · না গুনে মেলানো — bijection দিয়ে “সমান আকার”

বাজারঘরের ঈদ মেলায় একটি স্টলে প্রত্যেক ক্রেতা একটি করে টোকেন পান, আর প্রতিটি টোকেন দিয়ে একটি উপহার নেওয়া যায়। দিনের শেষে ম্যানেজার দেখলেন: প্রতিটি উপহার ঠিক একটি টোকেনের বদলে গেছে, কোনো টোকেন ফেরত আসেনি, কোনো উপহারও বাকি নেই। তাহলে টোকেন আর উপহার কয়টি ছিল, তা না গুনেই তিনি বলতে পারেন: দুটির সংখ্যা সমান। কারণ দুই দলের মধ্যে একটি নিখুঁত জোড়া মিলেছে।

এই সরল ধারণাটিই এই পর্বের মূল হাতিয়ার। সসীম সেটে আমরা অভ্যাসবশত গুনি: পর্ব ১৪ “সেট — সংজ্ঞা, subset, power set আর Cartesian product”-এ |A| লিখে বোঝানো হয়েছিল A-এর উপাদান-সংখ্যা। কিন্তু অসীম সেটে “গুনে শেষ করা” যায় না। তখন একমাত্র উপায় হলো জোড়া মেলানো। আর এই উপায়ে এমন সব ফল বেরোয়, যা প্রথমে অবিশ্বাস্য লাগে: জোড় সংখ্যা আর সব স্বাভাবিক সংখ্যা “সমান সংখ্যক”, অথচ বাস্তব সংখ্যা তাদের চেয়ে “বেশি”।

সংজ্ঞা ১.১

একটি ফাংশন f : A → B হলো injection (one-to-one), যদি আলাদা উপাদান আলাদা জায়গায় যায়: f(a) = f(a′) হলে a = a′. f হলো surjection (onto), যদি B-এর প্রতিটি উপাদান কারও না কারও ছবি। দুটিই হলে f একটি bijection.

দুটি সেট A আর B-এর cardinality সমান, লেখা হয় |A| = |B|, যদি A থেকে B-তে একটি bijection থাকে। আর |A| ≤ |B| মানে A থেকে B-তে একটি injection আছে; |A| < |B| মানে |A| ≤ |B| কিন্তু |A| ≠ |B|.

ফাংশনের পুরো তত্ত্ব পর্ব ১৬ “ফাংশন — one-to-one, onto, inverse আর composition”-এর বিষয়; এখানে শুধু সংজ্ঞাগুলো লাগবে। খেয়াল করুন, সংজ্ঞায় কোথাও গোনা নেই; শুধু “|A| = |B|” বাক্যটির অর্থ ঠিক করা হয়েছে। সসীম সেটে এটি সাধারণ গোনার সঙ্গেই মেলে।

“সমান cardinality” সম্পর্কটি তিনটি স্বাভাবিক ধর্ম মানে, যা পরে বারবার লাগবে:

  1. Reflexive: |A| = |A|, কারণ identity ফাংশন x ↦ x একটি bijection.
  2. Symmetric: f : A → B bijection হলে তার inverse f−1 : B → A-ও bijection, তাই |B| = |A|.
  3. Transitive: f : A → B আর g : B → C bijection হলে g ∘ f : A → C-ও bijection (দুটি injection-এর composition injection, দুটি surjection-এর composition surjection), তাই |A| = |C|.

এই কারণে আমরা একটি “মান-সেট” বেছে নিয়ে বাকি সেটকে তার সঙ্গে তুলনা করি, যেমন সব স্বাভাবিক সংখ্যার সেট।

সংজ্ঞা ১.২

এই পর্বে ℕ = {0, 1, 2, …} (০-সহ; কিছু বই ০ বাদ দিয়ে ℤ⁺ = {1, 2, …} নেয়, তাতে কোনো ফল বদলায় না)। একটি সেট A countably infinite, যদি |A| = |ℕ|; এর cardinality-কে বলে ℵ0 (aleph-null). A countable, যদি A সসীম অথবা countably infinite. আর A uncountable, যদি countable না হয়।

Countably infinite হওয়ার মানে দাঁড়ায়: A-এর উপাদানগুলোকে a0, a1, a2, … এমন একটি অসীম তালিকায় সাজানো যায়, যেখানে প্রতিটি উপাদান ঠিক একবার আসে। কারণ bijection f : ℕ → A দিলে an = f(n) লিখলেই তালিকা, আর তালিকা দিলে n ↦ an লিখলেই bijection. তাই “countable” প্রমাণ মানে প্রায়ই একটি চতুর তালিকা বানানো, যাতে কোনো উপাদান “অসীম দূরে” আটকে না থাকে।

পরীক্ষার হলে রোল নম্বর দেওয়ার কথা ভাবুন। সসীম হলে সমস্যা নেই। কিন্তু যদি পরীক্ষার্থী অসীম হয়? শর্ত একটাই: প্রত্যেকে একটি সসীম রোল নম্বর পাবেন, আর দুজন একই নম্বর পাবেন না। যে দলকে এভাবে রোল দেওয়া যায়, সেটি countable. এই পর্বের বড় খবর হলো: কিছু দলকে কোনো উপায়েই এভাবে রোল দেওয়া যায় না।

প্রথম চমক: অংশ আর সমগ্র সমান

জোড় স্বাভাবিক সংখ্যার সেট E = {0, 2, 4, …}. f(n) = 2n একটি bijection ℕ → E: 2n = 2m হলে n = m (injection), আর প্রতিটি জোড় সংখ্যা 2k = f(k) (surjection). তাই |E| = |ℕ|, যদিও E হলো ℕ-এর একটি proper subset, আর ℕ-এর “অর্ধেক” সংখ্যা E-তে নেই। একইভাবে বর্গসংখ্যা {0, 1, 4, 9, …} আর ℕ-এর মধ্যে n ↦ n² একটি bijection.

বর্গসংখ্যার এই ধাঁধাটি Galileo Galilei তাঁর ১৬৩৮ সালের বই “Two New Sciences”-এ আলোচনা করেন, আর সিদ্ধান্ত টানেন যে অসীম রাশিতে “সমান”, “বেশি”, “কম” কথাগুলো খাটে না। Georg Cantor ১৮৭০-এর দশক থেকে উল্টো পথ নেন: bijection-কেই মাপকাঠি ধরে অসীম সেটের তুলনার পুরো তত্ত্ব গড়ে তোলেন।

অসীম সেটে “A ⊂ B, তাই |A| < |B|” যুক্তিটি ভুল। Proper subset হলে |A| ≤ |B| ঠিকই (inclusion ফাংশন x ↦ x একটি injection), কিন্তু কঠোর অসমতা আসে না। এটি পরীক্ষার খাতার আর AI-এর লেখা “প্রমাণ”-এর খুব সাধারণ ভুল।

২ · Countable সেট — ℤ আর Hilbert-এর হোটেল

ℤ = {…, −2, −1, 0, 1, 2, …} দেখে মনে হয় এতে ℕ-এর প্রায় দ্বিগুণ উপাদান। তবু ℤ countable. চাবি হলো তালিকার ক্রম: “আগে সব ধনাত্মক, তারপর ঋণাত্মক” লিখলে ঋণাত্মক সংখ্যা কখনো আসে না, কারণ ধনাত্মক সংখ্যাই শেষ হয় না। তার বদলে দুই দিক থেকে পালা করে নিলে প্রতিটি পূর্ণসংখ্যা একটি সসীম জায়গায় পৌঁছে যায়: 0, 1, −1, 2, −2, 3, −3, …

উপপাদ্য ২.১

g : ℕ → ℤ, g(n) = (n + 1)/2 যদি n বিজোড়, আর g(n) = −n/2 যদি n জোড়। g একটি bijection, তাই ℤ countably infinite.

প্রমাণ:

  1. g-এর মান সবসময় পূর্ণসংখ্যা: n বিজোড় হলে n + 1 জোড়, আর n জোড় হলে n/2 পূর্ণসংখ্যা। — জোড়-বিজোড়ের সংজ্ঞা
  2. বিজোড় n-এর ছবি ধনাত্মক ((n + 1)/2 ≥ 1), আর জোড় n-এর ছবি ≤ 0. তাই একটি বিজোড় আর একটি জোড় সংখ্যা কখনো একই ছবি পায় না। — case বিশ্লেষণ
  3. দুটি বিজোড় n, m-এ (n + 1)/2 = (m + 1)/2 হলে n = m; দুটি জোড়-এ −n/2 = −m/2 হলে n = m. ধাপ ২ মিলিয়ে g একটি injection. — বীজগণিত
  4. যেকোনো k ∈ ℤ নিন। k ≥ 1 হলে n = 2k − 1 বিজোড় আর g(n) = k. k ≤ 0 হলে n = −2k জোড়, n ≥ 0, আর g(n) = k. তাই g একটি surjection. ∎ — সাক্ষী বানানো

ℕ থেকে ℤ-এ bijection g

ওপরে ℕ-এর তালিকা, নিচে ছবি: বিজোড় n ধনাত্মক দিকে, জোড় n শূন্য বা ঋণাত্মক দিকে

Bijection g from N onto Z ℕ ℤ 0123456 01−12−23−3
ছবি ২.১ — g(n) = (n + 1)/2 (n বিজোড়, নীল) বা −n/2 (n জোড়, কমলা)। যেকোনো k ∈ ℤ কোন n থেকে আসে, তা উপপাদ্য ২.১-এর ধাপ ৪ সরাসরি বলে দেয়: k = −3 আসে n = 6 থেকে।

Hilbert-এর হোটেল

একটি হোটেলের কথা ভাবুন, যার ঘর নম্বর 0, 1, 2, … অসীম পর্যন্ত, আর সব ঘর ভর্তি। একজন নতুন অতিথি এলেন। ম্যানেজার ঘোষণা দিলেন: “ঘর n-এর অতিথি ঘর n + 1-এ যান।” সবাই একটি করে ঘর পেলেন, আর ঘর 0 খালি হলো। অসীম সংখ্যক নতুন অতিথি এলে? “ঘর n-এর অতিথি ঘর 2n-এ যান”: সব বিজোড় ঘর খালি হয়। এই ভাবনা-পরীক্ষাটি Hilbert-এর হোটেল নামে পরিচিত; David Hilbert ১৯২০-এর দশকের এক বক্তৃতায় এটি ব্যবহার করেছিলেন বলে প্রচলিত। গাণিতিকভাবে এটি শুধু তিনটি bijection: n ↦ n + 1 (ℕ থেকে ℕ∖{0}), n ↦ 2n (ℕ থেকে জোড় সংখ্যা), আর k ↦ 2k + 1 (ℕ থেকে বিজোড় সংখ্যা)।

কয়েকটি ছোট কিন্তু কাজের ফল, যা পরের প্রমাণে লাগবে:

উপপাদ্য ২.২

(ক) Countable সেটের প্রতিটি subset countable. (খ) A countable ⇔ A থেকে ℕ-এ একটি injection আছে. (গ) A আর B countable হলে A ∪ B countable.

প্রমাণ (খসড়া, কিন্তু সম্পূর্ণ):

  1. (খ, ⇐) h : A → ℕ injection হলে A আর h(A) ⊆ ℕ-এর মধ্যে bijection আছে। h(A) সসীম হলে A সসীম। অসীম হলে h(A)-র উপাদান ছোট থেকে বড় সাজান: well-ordering (পর্ব ১১) বলে প্রতিটি অশূন্য subset-এর ক্ষুদ্রতম উপাদান আছে, তাই “বাকিদের মধ্যে ক্ষুদ্রতম” বারবার নিয়ে একটি তালিকা পাওয়া যায়, যাতে প্রতিটি উপাদান সসীম ধাপে আসে (k-এর আগে আছে বড়জোর k-টি সংখ্যা)। — well-ordering
  2. (খ, ⇒) A সসীম হলে {0, …, n − 1}-এ, আর countably infinite হলে ℕ-এ সরাসরি bijection আছে; bijection নিজেই injection. — সংজ্ঞা
  3. (ক) B countable আর A ⊆ B হলে, B থেকে ℕ-এর injection-কে A-তে সীমিত করলেও injection থাকে; (খ) প্রয়োগ। — restriction
  4. (গ) hA, hB injection হলে, A-এর x-কে 2hA(x)-এ আর B∖A-এর x-কে 2hB(x) + 1-এ পাঠান; জোড় আর বিজোড় কখনো মেলে না, তাই এটি A ∪ B থেকে ℕ-এ injection. ∎ — Hilbert-এর হোটেলের কৌশল

(খ) একটি দরকারি সরলীকরণ: countable প্রমাণ করতে bijection লাগে না; একটি injection A → ℕ, বা পুনরাবৃত্তিসহ একটি তালিকা (surjection ℕ → A) যথেষ্ট।

৩ · ℕ×ℕ countable — Cantor pairing function

বাজারঘরের অর্ডার নম্বর দুই অংশে: (দোকান নম্বর x, সেই দোকানের অর্ডার নম্বর y), দুটিই 0 থেকে শুরু। দোকান আর অর্ডার দুটিই ভবিষ্যতে যত খুশি বাড়তে পারে। প্রশ্ন: প্রতিটি জোড়া (x, y)-কে একটিমাত্র স্বাভাবিক সংখ্যা দেওয়া যায় কি, যাতে দুটি জোড়া কখনো একই সংখ্যা না পায়, আর কোনো সংখ্যা ফাঁকা না থাকে? অর্থাৎ ℕ×ℕ থেকে ℕ-এ একটি bijection?

সারি ধরে গোনা চলবে না: প্রথম সারি (0, 0), (1, 0), (2, 0), … কখনো শেষ হয় না, তাই (0, 1)-এর পালা আসে না। উপায় হলো তির্যক রেখা (diagonal) ধরে হাঁটা। d = x + y একই এমন জোড়াগুলো একটি তির্যক রেখায় থাকে, আর প্রতিটি রেখায় সসীম, ঠিক d + 1-টি জোড়া। রেখা d = 0, 1, 2, … একটির পর একটি শেষ করলে প্রতিটি জোড়া সসীম সময়ে আসে।

ℕ×ℕ-এর তির্যক হাঁটা

বৃত্তের ভেতরের সংখ্যা π(x, y); একই রঙ একই diagonal d = x + y

Diagonal walk through N x N with Cantor pairing numbers x → 0123 y ↓ 0123 0136 24711 581217 9131824
ছবি ৩.১ — রেখা d = 0, 1, 2, 3 সম্পূর্ণ দেখানো (ধূসর, নীল, সবুজ, কমলা); বেগুনি ড্যাশ বৃত্তগুলো পরের রেখার অংশ। প্রতিটি রেখা (d, 0) থেকে শুরু হয়ে (0, d)-এ শেষ, তারপর লাফ দিয়ে পরের রেখার শুরু।

এখন সূত্রটি বের করি। রেখা d-এর আগে আছে রেখা 0, 1, …, d − 1, যাদের মোট জোড়া 1 + 2 + ⋯ + d = d(d + 1)/2. এই সংখ্যাকে বলে d-তম triangular number, T(d) = d(d + 1)/2 (পর্ব ১৭ “Sequence আর summation — closed form আর বিখ্যাত যোগফল”-এ এর Gauss-এর যোগফল)। রেখা d-এর ভেতরে (x, y)-এর জায়গা y (0 থেকে d). তাই:

π(x, y) = T(x + y) + y = (x + y)(x + y + 1)/2 + y

এটি Cantor pairing function.

1d=0: (0,0)2d=1: (1,0) (0,1)3d=2: (2,0)…(0,2)4d=3: (3,0)…(0,3)5π = T(x+y) + y
T(d) = d(d+1)/2
এই রেখার জোড়া
পাওয়া নম্বর
রেখার শুরু T(d)
এ পর্যন্ত গোনা
  1. রেখা d = 0. শুধু (0, 0), নম্বর 0. এ পর্যন্ত ১টি জোড়া গোনা হলো, আর T(1) = 1 হলো পরের রেখার শুরুর নম্বর।
  2. রেখা d = 1. (1, 0) পায় 1, (0, 1) পায় 2. নম্বর = T(1) + y = 1 + y. মোট ৩টি জোড়া; পরের রেখা শুরু T(2) = 3 থেকে।
  3. রেখা d = 2. (2, 0), (1, 1), (0, 2) পায় 3, 4, 5. প্রতিটি রেখায় সসীম সংখ্যক জোড়া, তাই রেখাটি শেষ হয় আর পরের রেখায় যাওয়া যায়।
  4. রেখা d = 3. (3, 0), (2, 1), (1, 2), (0, 3) পায় 6, 7, 8, 9. নম্বরগুলো ফাঁক ছাড়া পরপর: 0 থেকে 9, দশটি জোড়া, দশটি নম্বর।
  5. যেকোনো জোড়া। (3, 5)-এর রেখা d = 8; তার আগে T(8) = 36টি জোড়া, আর রেখার ভেতরে জায়গা y = 5. তাই π(3, 5) = 36 + 5 = 41. রেখা 8 শেষ হয় 36 + 8 = 44-এ, আর রেখা 9 শুরু T(9) = 45 থেকে।
উপপাদ্য ৩.১

π : ℕ×ℕ → ℕ, π(x, y) = T(x + y) + y একটি bijection. তাই |ℕ×ℕ| = |ℕ| = ℵ0.

প্রমাণ:

  1. রেখা d-এর জোড়াগুলোর নম্বর T(d), T(d) + 1, …, T(d) + d, কারণ y চলে 0 থেকে d পর্যন্ত। — সংজ্ঞা
  2. T(d + 1) = T(d) + d + 1, তাই রেখা d-এর নম্বর ঠিক ব্যবধি Bd = {T(d), …, T(d + 1) − 1}. — বীজগণিত
  3. B0, B1, B2, … পরস্পর বিচ্ছিন্ন আর পাশাপাশি; T(0) = 0 আর T(d) সীমাহীনভাবে বাড়ে, তাই এরা মিলে পুরো ℕ ঢাকে, প্রতিটি সংখ্যা ঠিক একটি Bd-তে। — ধাপ ২ বারবার
  4. Injection: π(x, y) = π(x′, y′) = z হলে z একটিমাত্র Bd-তে, তাই x + y = x′ + y′ = d. তখন y = z − T(d) = y′, আর x = d − y = x′. — ধাপ ৩
  5. Surjection: যেকোনো z ∈ ℕ নিন। ধাপ ৩ অনুযায়ী এমন d আছে যে z ∈ Bd. y = z − T(d) আর x = d − y নিন; 0 ≤ y ≤ d বলে x ≥ 0, আর π(x, y) = T(d) + y = z. ∎ — সাক্ষী বানানো

ধাপ ৫ আসলে inverse-এর রেসিপি। d হলো সবচেয়ে বড় সংখ্যা যাতে T(d) ≤ z, অর্থাৎ d(d + 1)/2 ≤ z; দ্বিঘাত সমীকরণ থেকে d = ⌊(√(8z + 1) − 1)/2⌋. যেমন z = 100: √801 ≈ 28.3, তাই d = ⌊13.65⌋ = 13, T(13) = 91, y = 9, x = 4. যাচাই: π(4, 9) = 91 + 9 = 100.

অনুসিদ্ধান্ত ৩.২

প্রতিটি k ≥ 1-এর জন্য ℕk (k-টি স্বাভাবিক সংখ্যার tuple-এর সেট) countable. প্রমাণ: k-এর ওপর induction (পর্ব ১০); ℕk+1 = ℕk × ℕ, আর ℕk-এর bijection h দিয়ে (t, n) ↦ π(h(t), n) একটি bijection. ∎ আর A, B countable হলে A × B countable (injection দুটিকে π দিয়ে জুড়ে).

নিচের ব্লকে π আর তার inverse লেখা আছে। প্রথমবার চালালে ব্রাউজারে Python (Pyodide) নামতে কয়েক সেকেন্ড লাগে। ব্লকটি ২০০ × ২০০ গ্রিডে দেখে π কোনো দুটি জোড়াকে একই নম্বর দেয় না, আর এক লাখ নম্বরের প্রতিটি ঠিক একটি জোড়া থেকে আসে। খেয়াল করুন, inverse-এ math.isqrt (পূর্ণসংখ্যার বর্গমূল) ব্যবহার করা হয়েছে; float-এর sqrt খুব বড় z-এ গোলমাল করত।

from math import isqrt

def pair(x, y):                        # Cantor pairing: N x N -> N
    d = x + y                          # which diagonal
    return d * (d + 1) // 2 + y        # T(d) + place on that diagonal

def unpair(z):                         # inverse: N -> N x N
    d = (isqrt(8 * z + 1) - 1) // 2    # largest d with T(d) <= z
    y = z - d * (d + 1) // 2
    return d - y, y

print("z = 0..9 :", [unpair(z) for z in range(10)])
print("pair(3, 5) =", pair(3, 5), "| unpair(100) =", unpair(100))

N = 200
grid = [(x, y) for x in range(N) for y in range(N)]
codes = {pair(x, y) for x, y in grid}
print("pairs on 200 x 200 grid:", len(grid), "| distinct codes:", len(codes))

ok1 = all(unpair(pair(x, y)) == (x, y) for x, y in grid)
ok2 = all(pair(*unpair(z)) == z for z in range(100_000))
print("unpair(pair(x, y)) == (x, y) on the grid:", ok1)
print("pair(unpair(z)) == z for every z < 100000:", ok2)

tri = sorted(pair(x, y) for x, y in grid if x + y < N)
print("triangle x + y < 200 gives exactly 0 ..", tri[-1], ":", tri == list(range(len(tri))))

big = (10**30, 7)
print("pair of a 31-digit number, inverted back:", unpair(pair(*big)) == big)

আসল আউটপুট (ব্রাউজারের Python):

z = 0..9 : [(0, 0), (1, 0), (0, 1), (2, 0), (1, 1), (0, 2), (3, 0), (2, 1), (1, 2), (0, 3)]
pair(3, 5) = 41 | unpair(100) = (4, 9)
pairs on 200 x 200 grid: 40000 | distinct codes: 40000
unpair(pair(x, y)) == (x, y) on the grid: True
pair(unpair(z)) == z for every z < 100000: True
triangle x + y < 200 gives exactly 0 .. 20099 : True
pair of a 31-digit number, inverted back: True

প্রথম লাইন stepper-এর তির্যক ক্রম হুবহু দেখায়। ৪০,০০০টি জোড়া ৪০,০০০টি আলাদা নম্বর পেল: injection-এর পরীক্ষা। দুই দিকের inverse পরীক্ষাই True. “Triangle” লাইন: রেখা 0 থেকে 199-এর জোড়া ঠিক 0 থেকে 20099 পর্যন্ত সব নম্বর ফাঁক ছাড়া নেয়, আর 20100 = T(200); এটি প্রমাণের ধাপ ৩। বর্গাকার গ্রিডে ফাঁক থাকত, কারণ কিছু নম্বর গ্রিডের বাইরের জোড়ার। শেষ লাইন দেখায়, Python-এর int সীমাহীন নির্ভুল, তাই ৩১ অঙ্কের সংখ্যাতেও inverse ঠিক থাকে। তবে মনে রাখুন, এটি যাচাই, প্রমাণ নয়; প্রমাণ উপপাদ্য ৩.১-এর পাঁচ ধাপ।

৪ · ℚ countable — আর countable অনেক সেটের union

মূলদ সংখ্যা ℚ “ঘন”: যেকোনো দুটি আলাদা মূলদ সংখ্যার মাঝে আরও একটি আছে ((a + b)/2). তবু ℚ countable. কারণ ঘনত্ব হলো ক্রম-এর ধর্ম, আর cardinality ক্রমের তোয়াক্কা করে না: তালিকায় আমরা সংখ্যাগুলোকে ছোট থেকে বড় সাজাতে বাধ্য নই।

উপপাদ্য ৪.১

ℚ countable.

প্রমাণ:

  1. প্রতিটি ধনাত্মক মূলদ সংখ্যা r-কে ঠিক একভাবে lowest terms-এ লেখা যায়: r = p/q, যেখানে p, q ∈ ℤ⁺ আর gcd(p, q) = 1. — পর্ব ০৮-এর lowest terms-এর যুক্তি
  2. h(r) = π(p, q) সংজ্ঞায়িত করুন। দুটি আলাদা r আলাদা (p, q) দেয় (lowest terms অনন্য), আর π injection, তাই h : ℚ⁺ → ℕ একটি injection. — composition-এ injection টেকে
  3. উপপাদ্য ২.২ (খ) অনুযায়ী ℚ⁺ countable. একইভাবে ঋণাত্মক মূলদ সংখ্যার সেট ℚ⁻ (r ↦ −r একটি bijection ℚ⁺ → ℚ⁻)। — উপপাদ্য ২.২
  4. ℚ = ℚ⁻ ∪ {0} ∪ ℚ⁺; উপপাদ্য ২.২ (গ) দুবার প্রয়োগে ℚ countable. ∎

এই প্রমাণ অস্তিত্ব দেখায়, কিন্তু ℚ⁺-এর একটি সুন্দর তালিকা নিজেই দেখার মতো। দুটি পরিচিত তালিকা আছে। তির্যক হাঁটা: p + q = 2, 3, 4, … ক্রমে, প্রতিটি যোগফলে p = 1, 2, … নিয়ে p/q লেখা, আর lowest terms-এ নয় এমন ভগ্নাংশ (যেমন 2/2, 2/4) বাদ দেওয়া। Calkin–Wilf ক্রম: 1 থেকে শুরু করে প্রতিবার x-এর পরের পদ 1/(2⌊x⌋ − x + 1). Neil Calkin আর Herbert Wilf ২০০০ সালের একটি প্রবন্ধে একটি binary tree দিয়ে দেখান যে এই ক্রমে প্রতিটি ধনাত্মক মূলদ সংখ্যা ঠিক একবার আসে, আর তা-ও lowest terms-এ; পরের পদের এই এক লাইনের সূত্রটি সাধারণত Moshe Newman-এর নামে উল্লেখ করা হয়। এর প্রমাণ এই পর্বের সীমার বাইরে; নিচে আমরা শুধু প্রথম কয়েক হাজার পদ যাচাই করব।

from fractions import Fraction
from math import floor, gcd

def calkin_wilf(n):                    # Newman's formula for the next term
    x, out = Fraction(1), []
    for _ in range(n):
        out.append(x)
        x = 1 / (2 * floor(x) - x + 1)
    return out

def diagonal_walk(n):                  # p + q = 2, 3, 4, ... ; skip p/q not in lowest terms
    out, s = [], 2
    while len(out) < n:
        out += [Fraction(p, s - p) for p in range(1, s) if gcd(p, s - p) == 1]
        s += 1
    return out[:n]

show = lambda xs: " ".join(str(x) for x in xs)
print("Calkin-Wilf  :", show(calkin_wilf(14)))
print("diagonal walk:", show(diagonal_walk(14)))

M = 5000
for name, seq in [("Calkin-Wilf", calkin_wilf(M)), ("diagonal walk", diagonal_walk(M))]:
    pos = {x: i + 1 for i, x in enumerate(seq)}
    where = [pos.get(Fraction(a, b), "not yet") for a, b in [(3, 4), (2, 3), (1, 12), (12, 1)]]
    print(f"{name}: {M} terms, repeats = {M - len(pos)}, "
          f"place of 3/4, 2/3, 1/12, 12 = {where}")

আসল আউটপুট (ব্রাউজারের Python):

Calkin-Wilf  : 1 1/2 2 1/3 3/2 2/3 3 1/4 4/3 3/5 5/2 2/5 5/3 3/4
diagonal walk: 1 1/2 2 1/3 3 1/4 2/3 3/2 4 1/5 5 1/6 2/5 3/4
Calkin-Wilf: 5000 terms, repeats = 0, place of 3/4, 2/3, 1/12, 12 = [14, 6, 2048, 4095]
diagonal walk: 5000 terms, repeats = 0, place of 3/4, 2/3, 1/12, 12 = [14, 7, 46, 57]

দুটি তালিকাই প্রথম ৫,০০০ পদে কোনো পুনরাবৃত্তি দেখায় না। কিন্তু ক্রম খুব আলাদা। Calkin–Wilf-এ 1/12 আসে 2048-তম জায়গায় (= 211) আর 12 আসে 4095-তম জায়গায় (= 212 − 1); সাধারণভাবে 1/n থাকে 2n−1-তম জায়গায়, তাই 1/30 প্রায় ৫৩ কোটিতম পদে। তির্যক হাঁটায় একই সংখ্যা আসে অনেক আগে (46 আর 57). দুটিই বৈধ তালিকা, কারণ countable হওয়ার শর্ত শুধু “প্রতিটি সংখ্যা কোনো এক সসীম জায়গায়”, কত তাড়াতাড়ি তা নয়। মজার কাকতাল: 3/4 দুই তালিকাতেই ১৪তম।

Countable অনেক countable সেটের union

উপপাদ্য ৪.২ (countable union)

A0, A1, A2, … প্রতিটি countable হলে তাদের union A0 ∪ A1 ∪ A2 ∪ ⋯ countable.

প্রমাণের খসড়া: ফাঁকা Ai বাদ দিন। প্রতিটি বাকি Ai-এর জন্য একটি surjection fi : ℕ → Ai বেছে নিন (উপপাদ্য ২.২)। তাহলে F(i, j) = fi(j) হলো ℕ×ℕ থেকে union-এ একটি surjection, আর π−1-এর সঙ্গে জুড়লে ℕ থেকে union-এ surjection. তাই union countable. ∎ একটি সূক্ষ্ম কথা: অসীম সংখ্যক Ai-এর প্রত্যেকের জন্য একসঙ্গে একটি তালিকা “বেছে নেওয়া” সেট তত্ত্বের axiom of choice-এর একটি দুর্বল রূপ (countable choice) ব্যবহার করে। তালিকাগুলো আগে থেকেই স্পষ্ট দেওয়া থাকলে (যেমন নিচের উদাহরণে) এর দরকার পড়ে না।

সবচেয়ে গুরুত্বপূর্ণ প্রয়োগ কম্পিউটার বিজ্ঞানে। একটি সসীম alphabet Σ-এর ওপর সব সসীম string-এর সেট Σ* (পর্ব ১২-এর Kleene star) হলো Σ0 ∪ Σ1 ∪ Σ2 ∪ ⋯, যেখানে Σn হলো n দৈর্ঘ্যের string-এর সসীম সেট (|Σ|n-টি)। তাই Σ* countable. এখানে choice-ও লাগে না: “আগে দৈর্ঘ্য, তারপর অভিধানের ক্রম” (shortlex) একটি স্পষ্ট তালিকা দেয়: ε, 0, 1, 00, 01, 10, 11, 000, … {0, 1}-এর ওপর n বা তার কম দৈর্ঘ্যের string আছে 2n+1 − 1-টি; n = 5-এ 63টি।

উদাহরণ (পরীক্ষার ধাঁচে): “সব বহুপদীর সেট, যাদের সহগ পূর্ণসংখ্যা, countable কি না প্রমাণ করুন।” সমাধান: ডিগ্রি n-এর বহুপদীকে তার সহগের tuple (a0, …, an) ∈ ℤn+1 দিয়ে চেনা যায়, যা countable (অনুসিদ্ধান্ত ৩.২)। সব বহুপদী = n = 0, 1, 2, …-এর এই সেটগুলোর countable union, তাই countable (উপপাদ্য ৪.২)। অশূন্য বহুপদীর মূল সসীম সংখ্যক, তাই সব algebraic number-ও countable.

৫ · Cantor-এর diagonal — (0, 1) uncountable

তাহলে কি সব অসীম সেট countable? না। ১৮৯১ সালে Georg Cantor একটি আশ্চর্য রকম ছোট যুক্তি প্রকাশ করেন, যা আজ Cantor-এর diagonal argument নামে পরিচিত। (তিনি ১৮৭৪ সালেই বাস্তব সংখ্যার uncountability অন্য একটি পদ্ধতিতে প্রমাণ করেছিলেন; diagonal পদ্ধতিটি পরে আসে, আর সেটিই সবচেয়ে বিখ্যাত হয়।) কৌশলটি এই: আপনি যেকোনো তালিকা দিন, আমি তালিকার বাইরের একটি সংখ্যা বানিয়ে দেব।

উপপাদ্য ৫.১

খোলা ব্যবধি (0, 1) = {x ∈ ℝ : 0 < x < 1} uncountable.

একটি প্রযুক্তিগত সতর্কতা আগে। কিছু বাস্তব সংখ্যার দুটি দশমিক রূপ আছে: 0.5000… = 0.4999…. দ্বিতীয় রূপের সমস্যা এড়াতে আমরা প্রতিটি সংখ্যার যে রূপটি অসীম সংখ্যক 9-এ শেষ হয় না, সেটিই নেব; এই রূপ অনন্য। আর নতুন সংখ্যার অঙ্ক হিসেবে শুধু 4 আর 5 ব্যবহার করব, যাতে নতুন সংখ্যার নিজেরও দ্বৈত রূপ না থাকে।

প্রমাণ (contradiction):

  1. ধরি (0, 1) countable. সেটটি অসীম (1/2, 1/3, 1/4, … সবাই এতে আছে), তাই countably infinite, আর একটি তালিকা r1, r2, r3, … আছে যাতে (0, 1)-এর প্রতিটি সংখ্যা আসে। — বিরোধের অনুমান
  2. প্রতিটি ri-কে তার অনন্য দশমিক রূপে লিখুন (অসীম 9-এ শেষ হয় না এমন): ri = 0.di1di2di3…, যেখানে dij হলো ri-এর j-তম অঙ্ক। — দশমিক রূপ
  3. নতুন সংখ্যা x = 0.e1e2e3… বানান, যেখানে en = 5 যদি dnn ≠ 5, আর en = 4 যদি dnn = 5. — diagonal নির্মাণ
  4. x-এর সব অঙ্ক 4 বা 5, তাই 0.444… ≤ x ≤ 0.555…, অর্থাৎ x ∈ (0, 1); আর x-এর রূপে কোনো 9 নেই, তাই এটিই x-এর অনন্য রূপ। — অঙ্কের সীমা
  5. যেকোনো n-এর জন্য x-এর n-তম অঙ্ক en ≠ dnn, অর্থাৎ x আর rn-এর অনন্য রূপ n-তম অঙ্কে আলাদা। অনন্য রূপ আলাদা মানে সংখ্যাও আলাদা, তাই x ≠ rn. — অনন্যতা
  6. তাহলে x ∈ (0, 1), অথচ x তালিকার কোনো rn-এর সমান নয়; এটি ধাপ ১-এর “প্রতিটি সংখ্যা আসে”-এর বিরোধী। তাই (0, 1) uncountable. ∎
1r1 = 0.[3]141592…2r2 = 0.5[0]00000…3r3 = 0.71[8]2818…4r4 = 0.141[5]926…5r5 = 0.5555[5]55…6x  = 0.55544…
নিয়ম: d(n,n) ≠ 5 হলে 5, নইলে 4
diagonal অঙ্ক
x-এর নতুন অঙ্ক
x এ পর্যন্ত
  1. দাবি করা তালিকা। কেউ বলছেন (0, 1)-এর সব সংখ্যা একটি তালিকায় আছে; প্রথম পাঁচটি r1 থেকে r5. বন্ধনীর অঙ্কগুলো diagonal: rn-এর n-তম অঙ্ক।
  2. ১ম অঙ্ক। r1-এর ১ম অঙ্ক 3, যা 5 নয়, তাই x-এর ১ম অঙ্ক 5. এখন যা-ই হোক, x আর r1 প্রথম অঙ্কেই আলাদা।
  3. ২য় অঙ্ক। r2-এর ২য় অঙ্ক 0, তাই x-এর ২য় অঙ্ক 5. x = 0.55…, আর r2 = 0.50…: আলাদা।
  4. ৩য় অঙ্ক। r3-এর ৩য় অঙ্ক 8, তাই x-এর ৩য় অঙ্ক 5. x = 0.555…
  5. ৪র্থ অঙ্ক। r4-এর ৪র্থ অঙ্ক 5, তাই নিয়ম অনুযায়ী x-এর ৪র্থ অঙ্ক 4. এই একটি জায়গাতেই x আর r4 আলাদা হওয়া নিশ্চিত।
  6. ৫ম অঙ্ক আর উপসংহার। r5-এর ৫ম অঙ্ক 5, তাই x-এর ৫ম অঙ্ক 4: x = 0.55544… তালিকা অসীম হলেও একই কাজ প্রতিটি n-এ চলে, তাই x কোনো rn-এর সমান নয়। অথচ x ∈ (0, 1). তালিকাটি সম্পূর্ণ ছিল না। ∎

যুক্তিটি প্রতিটি তালিকার বিরুদ্ধে কাজ করে: x-কে তালিকার শুরুতে বসালেও নতুন তালিকায় আবার diagonal চালিয়ে আরেকটি বাদ পড়া সংখ্যা পাওয়া যায়। নিচের ব্লকে একই কৌশল সসীম আকারে: ৮টি binary string (প্রতিটি ৮ bit)-এর তালিকা থেকে diagonal উল্টে একটি নতুন string. পর্ব ০২-এর bit string-এর ভাষায়, এটি diagonal-এর প্রতিটি bit-এ NOT.

import random
random.seed(18)

n = 8                                    # a "complete" list of n binary strings
rows = ["".join(random.choice("01") for _ in range(n)) for _ in range(n)]

for i, r in enumerate(rows):             # [ ] marks the diagonal bit
    print(f"s{i + 1} = {r[:i]}[{r[i]}]{r[i + 1:]}")

diag = "".join(rows[i][i] for i in range(n))
new = "".join("1" if b == "0" else "0" for b in diag)
print("diagonal     :", diag)
print("flip each bit:", new)
print("new string in the list?", new in rows)
print("differs from s_i at bit i for every i:",
      all(new[i] != rows[i][i] for i in range(n)))

# the same trick against ANY list: try 10000 random lists
misses = 0
for _ in range(10_000):
    L = ["".join(random.choice("01") for _ in range(n)) for _ in range(n)]
    d = "".join("1" if L[i][i] == "0" else "0" for i in range(n))
    misses += d not in L
print("random lists tried: 10000 | diagonal string missing from:", misses)

আসল আউটপুট (ব্রাউজারের Python):

s1 = [0]0110011
s2 = 0[1]111010
s3 = 10[0]00010
s4 = 101[1]0110
s5 = 1111[1]011
s6 = 01000[1]01
s7 = 100111[0]1
s8 = 0101000[1]
diagonal     : 01011101
flip each bit: 10100010
new string in the list? False
differs from s_i at bit i for every i: True
random lists tried: 10000 | diagonal string missing from: 10000

বন্ধনীর bit-গুলো diagonal: 01011101. উল্টালে 10100010, যা s1 থেকে প্রথম bit-এ, s2 থেকে দ্বিতীয় bit-এ, … s8 থেকে অষ্টম bit-এ আলাদা। দশ হাজার এলোমেলো তালিকার প্রতিটিতে diagonal-উল্টানো string তালিকার বাইরে ছিল: এটি ভাগ্য নয়, নির্মাণের ফল, আর প্রমাণের ধাপ ৫ ঠিক এটিই বলে। একটি সতর্কতা: সসীম ক্ষেত্রে এটি শুধু বলে “৮ bit-এর ২৫৬টি string-এর মধ্যে ৮টির তালিকা অসম্পূর্ণ”, যা গুনেও জানা যায়। Diagonal-এর আসল জোর অসীম ক্ষেত্রে, যেখানে গোনা অসম্ভব আর তালিকার প্রতিটি সারি অসীম লম্বা।

ℝ আর (0, 1)-এর cardinality সমান

(0, 1) ⊆ ℝ, তাই ℝ countable হলে উপপাদ্য ২.২ (ক) অনুযায়ী (0, 1)-ও countable হতো; অতএব ℝ uncountable. আরও বলা যায়: |ℝ| = |(0, 1)|. একটি স্পষ্ট bijection হলো h(x) = 1/(1 + 2x), ℝ → (0, 1): 2x কঠোরভাবে বাড়ে আর (0, ∞)-এর প্রতিটি মান নেয়, আর t ↦ 1/(1 + t) কঠোরভাবে কমে, (0, ∞)-কে (0, 1)-এ এক-এক মিলায়। Inverse: y ↦ log2(1/y − 1). এই cardinality-কে বলে continuum-এর cardinality, লেখা হয় 𝔠. সংক্ষেপে: ℵ0 < 𝔠. অসীমেরও আকার আছে, আর অন্তত দুটি আলাদা আকার।

৬ · Cantor-এর উপপাদ্য — |S| < |P(S)|

Diagonal argument একটি সাধারণ উপপাদ্যের বিশেষ রূপ, যা Cantor একই ১৮৯১ সালের প্রবন্ধের ধারণা থেকে আসে। পর্ব ১৪-এ দেখা power set P(S) হলো S-এর সব subset-এর সেট; সসীম S-এ |P(S)| = 2|S|, আর n < 2n সব n ≥ 0-এ সত্য (পর্ব ১০-এর induction). Cantor দেখান, এই অসমতা অসীম সেটেও টেকে।

উপপাদ্য ৬.১ (Cantor-এর উপপাদ্য)

যেকোনো সেট S-এর জন্য (সসীম বা অসীম) |S| < |P(S)|. অর্থাৎ S থেকে P(S)-এ injection আছে, কিন্তু কোনো surjection (তাই কোনো bijection) নেই।

প্রমাণ:

  1. x ↦ {x} একটি injection S → P(S): {x} = {y} হলে x = y. তাই |S| ≤ |P(S)|. — সংজ্ঞা
  2. এখন যেকোনো ফাংশন f : S → P(S) নিন। প্রতিটি x-এর জন্য f(x) হলো S-এর একটি subset, তাই প্রশ্ন “x ∈ f(x)?”-এর উত্তর হ্যাঁ বা না। — f-এর ধরন
  3. D = {x ∈ S : x ∉ f(x)} সংজ্ঞায়িত করুন। D ⊆ S, তাই D ∈ P(S). — set-builder notation
  4. ধরি D কোনো d ∈ S-এর ছবি: f(d) = D. প্রশ্ন: d ∈ D? — বিরোধের অনুমান
  5. যদি d ∈ D, তাহলে D-এর সংজ্ঞায় d ∉ f(d) = D, বিরোধ। যদি d ∉ D, অর্থাৎ d ∉ f(d), তাহলে সংজ্ঞায় d ∈ D, আবার বিরোধ। — proof by cases
  6. দুই ক্ষেত্রেই বিরোধ, তাই এমন d নেই: D কোনো উপাদানের ছবি নয়, f surjection নয়। f ছিল যেকোনো ফাংশন, তাই কোনো surjection, অতএব কোনো bijection নেই, আর |S| ≠ |P(S)|. ধাপ ১ মিলিয়ে |S| < |P(S)|. ∎
1f(a) = {a, b}2f(b) = {c}3f(c) = {a, c}4D = {x : x ∉ f(x)}
S = {a, b, c}, |P(S)| = 8
প্রশ্ন
উত্তর
D এ পর্যন্ত
  1. একটি ফাংশন। S = {a, b, c} থেকে P(S)-এ f: প্রতিটি উপাদান একটি subset পায়। P(S)-এ ৮টি subset, f-এর ছবি মাত্র ৩টি; সসীম ক্ষেত্রে গুনেই বোঝা যায় f onto নয়। কিন্তু D-এর নির্মাণ গোনা ছাড়াই একটি বাদ পড়া subset দেখায়, যা অসীম সেটেও চলে।
  2. a-কে জিজ্ঞাসা। a ∈ f(a) = {a, b}? হ্যাঁ। তাই D-এর সংজ্ঞায় a ∉ D. ফলে D আর f(a) সদস্য a-তে আলাদা: একটিতে a আছে, অন্যটিতে নেই।
  3. b-কে জিজ্ঞাসা। b ∈ f(b) = {c}? না। তাই b ∈ D. D আর f(b) সদস্য b-তে আলাদা।
  4. c-কে জিজ্ঞাসা। c ∈ f(c) = {a, c}? হ্যাঁ। তাই c ∉ D. D আর f(c) সদস্য c-তে আলাদা।
  5. উপসংহার। D = {b}. এটি f(a) = {a, b}, f(b) = {c}, f(c) = {a, c} কোনোটির সমান নয়, কারণ প্রতিটির সঙ্গে “নিজের” উপাদানে অমিল। এটিই diagonal: সারি x, কলাম x-এর হ্যাঁ/না উল্টে D. ∎

Diagonal-এর সঙ্গে মিলটি স্পষ্ট করা যাক। S-এর উপাদান দিয়ে সারি আর কলাম সাজিয়ে একটি ছক কল্পনা করুন: সারি x, কলাম y-তে 1 যদি y ∈ f(x), নইলে 0. প্রতিটি সারি একটি subset-এর “bit string”. D হলো diagonal (x, x)-এর bit উল্টে পাওয়া string. S = ℕ হলে প্রতিটি subset একটি অসীম bit string, আর এটি হুবহু §৫-এর যুক্তি, দশমিকের বদলে binary-তে।

from itertools import combinations, product

def subsets(S):
    return [frozenset(c) for k in range(len(S) + 1) for c in combinations(S, k)]

def show(A):
    return "{" + ",".join(sorted(A)) + "}"

for n in range(5):
    S = "abcd"[:n]
    P = subsets(S)
    total = missed = 0
    for images in product(P, repeat=n):            # every f: S -> P(S)
        f = dict(zip(S, images))
        D = frozenset(x for x in S if x not in f[x])
        total += 1
        missed += D not in images
    print(f"|S| = {n}: |P(S)| = {len(P):2}, functions = {total:5}, "
          f"D missed by every f: {missed == total}")

S = "abc"
f = {"a": frozenset("ab"), "b": frozenset("c"), "c": frozenset("ac")}
D = frozenset(x for x in S if x not in f[x])
print("f:", {x: show(f[x]) for x in S}, "-> D =", show(D))

আসল আউটপুট (ব্রাউজারের Python):

|S| = 0: |P(S)| =  1, functions =     1, D missed by every f: True
|S| = 1: |P(S)| =  2, functions =     2, D missed by every f: True
|S| = 2: |P(S)| =  4, functions =    16, D missed by every f: True
|S| = 3: |P(S)| =  8, functions =   512, D missed by every f: True
|S| = 4: |P(S)| = 16, functions = 65536, D missed by every f: True
f: {'a': '{a,b}', 'b': '{c}', 'c': '{a,c}'} -> D = {b}

|S| = n হলে S থেকে P(S)-এ ফাংশন আছে (2n)n-টি: 1, 2, 16, 512, 65536. প্রতিটির ক্ষেত্রে D ছবির তালিকার বাইরে; |S| = 0-তেও, যেখানে একমাত্র ফাংশনটি ফাঁকা আর D = ∅ ∉ (ফাঁকা ছবির সেট)। শেষ লাইন stepper-এর D = {b} মিলিয়ে দেয়। n = 5-এ ফাংশন হবে 325 = 33,554,432টি: brute force এখানেই থামে, আর অসীম S-এ পৌঁছায় শুধু প্রমাণ।

অসীমের সিঁড়ি আর Russell

Cantor-এর উপপাদ্য বারবার প্রয়োগ করলে পাই |ℕ| < |P(ℕ)| < |P(P(ℕ))| < ⋯: শেষ নেই এমন একটি সিঁড়ি, প্রতিটি ধাপে আরও বড় অসীম। প্রথম ধাপটি চেনা: |P(ℕ)| = 𝔠 = |ℝ|. খসড়া কারণ: ℕ-এর প্রতিটি subset A একটি অসীম bit string (n-তম bit 1 যদি n ∈ A), আর bit string-কে binary ভগ্নাংশ ধরলে [0, 1]-এর সংখ্যা পাওয়া যায়; দ্বৈত রূপের (0.0111… = 0.1000…) সামান্য ঝামেলা §৭-এর Schröder–Bernstein মিটিয়ে দেয়।

D-এর গঠন চেনা লাগতে পারে। পর্ব ১৪-এ দেখা Russell-এর paradox (প্রচলিত বিবরণে ১৯০১ সাল) ঠিক এই রূপ: R = {x : x ∉ x}. “সব সেটের সেট” U থাকলে P(U) ⊆ U হতো, যা Cantor-এর উপপাদ্যের সঙ্গে খাপ খায় না। সেই কারণে আধুনিক সেট তত্ত্ব (ZFC) এমন “সব কিছুর সেট” বানাতে দেয় না।

৭ · Schröder–Bernstein আর continuum hypothesis

প্রায়ই একটি সরাসরি bijection লেখা কঠিন, কিন্তু দুই দিকের injection সহজ। যেমন [0, 1] আর (0, 1): “প্রান্তের দুটি বিন্দু কোথায় পাঠাব” ভেবে bijection লেখা যায়, কিন্তু ঝামেলার। নিচের উপপাদ্য সেই কাজ বাঁচায়।

উপপাদ্য ৭.১ (Schröder–Bernstein)

A থেকে B-তে একটি injection আর B থেকে A-তে একটি injection থাকলে A আর B-এর মধ্যে একটি bijection আছে। অর্থাৎ |A| ≤ |B| আর |B| ≤ |A| হলে |A| = |B|.

এখানে ≤ injection দিয়ে সংজ্ঞায়িত, তাই সংখ্যার মতো স্বতঃস্পষ্ট নয়; প্রমাণ লাগে। প্রমাণের খসড়া: f : A → B আর g : B → A injection. A-এর প্রতিটি উপাদান থেকে পেছন দিকে হাঁটুন: x, তারপর g−1(x) (থাকলে), তারপর f−1 তার, … এভাবে প্রতিটি উপাদান একটি “শিকল”-এ পড়ে: শিকলটি A-তে থামে, B-তে থামে, বা কখনো থামে না। A-তে থামা শিকলের উপাদানে f, আর বাকি দুই ধরনে g−1 ব্যবহার করলে একটি bijection পাওয়া যায়। প্রতিটি খুঁটিনাটি যাচাই সেট তত্ত্বের বইয়ের কাজ; এখানে খসড়াটুকুই রাখছি।

নামকরণের পেছনের ইতিহাস জটিল, আর উৎসভেদে বিবরণ কিছুটা আলাদা। প্রচলিত বিবরণ অনুযায়ী Cantor উপপাদ্যটি বলেছিলেন, কিন্তু তাঁর প্রমাণ অন্য একটি অনুমানের ওপর নির্ভর করত; Dedekind ১৮৮৭ সালে একটি প্রমাণ লিখেছিলেন যা তখন প্রকাশিত হয়নি; Ernst Schröder ১৮৯০-এর দশকে একটি প্রমাণ প্রকাশ করেন যাতে পরে ত্রুটি পাওয়া যায়; আর তরুণ Felix Bernstein ১৮৯৭ সালের দিকে একটি সঠিক প্রমাণ দেন। তাই কিছু বইয়ে নামটি Cantor–Schröder–Bernstein.

ব্যবহার ১: |[0, 1]| = |(0, 1)|. (0, 1) → [0, 1]: x ↦ x (inclusion), injection. [0, 1] → (0, 1): x ↦ 1/4 + x/2, যা [0, 1]-কে [1/4, 3/4]-এ পাঠায়, injection. উপপাদ্য ৭.১ শেষ করে দিল; কোনো চতুর bijection লাগল না।

ব্যবহার ২: |ℕ×ℕ| = |ℕ|, π ছাড়াই। n ↦ (n, 0) একটি injection ℕ → ℕ×ℕ. আর (x, y) ↦ 2x3y একটি injection ℕ×ℕ → ℕ, কারণ মৌলিক উৎপাদকে বিশ্লেষণ অনন্য (fundamental theorem of arithmetic; পর্ব ১১-এ এর অস্তিত্বের অংশ, আর পর্ব ২০ “বিভাজ্যতা আর মৌলিক সংখ্যা — division algorithm আর unique factorization”-এ পুরোটা)। যেমন (3, 5) ↦ 8 · 243 = 1944. এই injection onto নয় (5-এর কোনো উৎস নেই), তবু Schröder–Bernstein bijection-এর অস্তিত্ব নিশ্চিত করে।

Continuum hypothesis — প্রমাণও হয় না, খণ্ডনও না

ℵ0 < 𝔠 জানলাম। মাঝে কিছু আছে কি? অর্থাৎ ℝ-এর এমন কোনো subset, যা countable নয়, আবার ℝ-এর সমান আকারেরও নয়? Cantor বিশ্বাস করতেন, নেই। এই দাবিই continuum hypothesis (CH): এমন কোনো সেট A নেই যাতে ℵ0 < |A| < 𝔠. ১৯০০ সালে Hilbert তাঁর বিখ্যাত ২৩টি সমস্যার তালিকায় এটিকে প্রথম স্থান দেন।

উত্তরটি এল অপ্রত্যাশিত রূপে। Kurt Gödel ১৯৪০ সালে দেখান যে সেট তত্ত্বের প্রচলিত স্বতঃসিদ্ধ ZFC (Zermelo–Fraenkel, axiom of choice-সহ) থেকে CH-এর অস্বীকার প্রমাণ করা যায় না (ZFC নিজে সঙ্গতিপূর্ণ ধরে)। Paul Cohen ১৯৬৩ সালে “forcing” নামের নতুন পদ্ধতিতে দেখান যে CH-ও ZFC থেকে প্রমাণ করা যায় না। অর্থাৎ CH, ZFC থেকে স্বাধীন: এটি “এখনো জানি না” নয়, বরং প্রমাণিত যে প্রচলিত নিয়মে উত্তর আসবে না।

৮ · কম্পিউটার বিজ্ঞানে — প্রোগ্রামের চেয়ে সমস্যা বেশি

একটি সিদ্ধান্ত-সমস্যা (decision problem), যেমন “এই বাজারঘর অর্ডার নম্বরটি কি বৈধ?”, আসলে একটি সেট: যে ইনপুট string-গুলোর উত্তর “হ্যাঁ”, তাদের সেট। {0, 1}*-এর এমন যেকোনো subset-কে বলে একটি formal language. একটি প্রোগ্রাম language L-কে decide করে, যদি প্রতিটি ইনপুটে থেমে ঠিক বলে দেয় ইনপুটটি L-এ আছে কি না।

উপপাদ্য ৮.১

{0, 1}-এর ওপর এমন language আছে, যা কোনো প্রোগ্রাম decide করে না।

প্রমাণ:

  1. যেকোনো প্রোগ্রাম (Python, C, বা যেকোনো নির্দিষ্ট ভাষায়) একটি সসীম string, একটি সসীম alphabet-এর ওপর (যেমন সব Unicode অক্ষর, যা সংখ্যায় সসীম)। — প্রোগ্রামের প্রকৃতি
  2. সসীম alphabet-এর ওপর সব string-এর সেট countable (§৪), আর প্রোগ্রামগুলো তার subset; তাই প্রোগ্রাম countable. — উপপাদ্য ৪.২, ২.২ (ক)
  3. প্রতিটি প্রোগ্রাম বড়জোর একটি language decide করে (যে ইনপুটে সে “হ্যাঁ” বলে, তাদের সেট)। তাই decide করা যায় এমন language-এর সেট countable. — প্রোগ্রাম থেকে language-এ surjection
  4. সব language-এর সেট হলো P({0, 1}*). {0, 1}* countably infinite, তাই Cantor-এর উপপাদ্যে |P({0, 1}*)| > ℵ0: language uncountable. — উপপাদ্য ৬.১
  5. Uncountable সেট একটি countable subset-এর সমান হতে পারে না, তাই কিছু language decide করা যায় না। ∎

প্রমাণটি একটি অস্তিত্বের প্রমাণ: এটি কোনো নির্দিষ্ট অসমাধানযোগ্য সমস্যা দেখায় না, শুধু বলে যে আছে। আসলে আরও বলে: decide করা যায় এমন language countable, বাকিরা uncountable, তাই “বেশিরভাগ” language-ই অসমাধানযোগ্য। একটি নির্দিষ্ট, স্বাভাবিক উদাহরণ হলো halting problem: প্রোগ্রাম আর ইনপুট দেখে বলা, প্রোগ্রামটি থামবে কি না। Alan Turing ১৯৩৬ সালে দেখান এটি undecidable, আর তাঁর প্রমাণও একটি diagonal: “নিজের কোড ইনপুট পেলে যে প্রোগ্রাম উল্টো কাজ করে”, ঠিক D = {x : x ∉ f(x)}-এর মতো। এর পূর্ণ আলোচনা পর্ব ৭৫ “Turing machine-এর পরিচয় — computability আর halting problem”-এ; আর পরে একটি আলাদা Theory of Computation কোর্স automata, grammar আর computability-তে গভীরে যাবে।

আরেকটি ব্যবহারিক সংযোগ: কম্পিউটারের float বাস্তব সংখ্যা নয়। 64-bit float-এর মান বড়জোর 264-টি, সসীম; অথচ (0, 1)-এ uncountable সংখ্যা। তাই প্রায় কোনো বাস্তব সংখ্যাই হুবহু রাখা যায় না (Python কোর্সের পর্ব ৭-এ float-এর ফাঁদ)। অথচ Fraction যেকোনো মূলদ সংখ্যা হুবহু রাখে, কারণ প্রতিটি মূলদ সংখ্যা একটি সসীম তথ্য (p, q).

পরীক্ষার ধাঁচে হিসাব (সমাধানসহ)

প্রশ্নসমাধান
π(3, 5) কত?d = 8, T(8) = 36, তাই 36 + 5 = 41
π(x, y) = 100 হলে (x, y)?T(13) = 91 ≤ 100 < 105 = T(14); y = 9, x = 13 − 9 = 4
তির্যক হাঁটায় (lowest terms) 2/3 কততম?p + q = 2: 1; 3: 1/2, 2; 4: 1/3, 3; 5: 1/4, 2/3 → ৭ম
|S| = 3 হলে S → P(S) ফাংশন কয়টি?প্রতিটি উপাদানের ৮টি পছন্দ: 83 = 512
{0, 1}-এর ওপর দৈর্ঘ্য ≤ 5 string কয়টি?1 + 2 + 4 + 8 + 16 + 32 = 26 − 1 = 63
ℤ×ℚ countable? ℝ∖ℚ countable?প্রথমটি হ্যাঁ (countable × countable). দ্বিতীয়টি না: হলে ℝ = ℚ ∪ (ℝ∖ℚ) countable হতো

শেষ সারিটি একটি দরকারি কৌশল: “X uncountable” প্রমাণ করতে প্রায়ই দেখান যে X countable হলে কোনো জানা uncountable সেট countable হয়ে যেত। একই যুক্তিতে অমূলদ সংখ্যা (আর transcendental সংখ্যা, যারা algebraic নয়) uncountable, অর্থাৎ “বেশিরভাগ” বাস্তব সংখ্যা।

আরও গভীরে: Cardinal সংখ্যার পাশাপাশি সেট তত্ত্বে আছে ordinal সংখ্যা, যা “কততম” প্রশ্নের অসীম রূপ; transfinite induction পর্ব ১০-এর induction-কে ordinal-এর ওপর বাড়ায়। Diagonal পদ্ধতি গণিত আর কম্পিউটার বিজ্ঞানের বহু মৌলিক সীমার প্রমাণে ফিরে আসে: Gödel-এর অসম্পূর্ণতা উপপাদ্য (১৯৩১), halting problem (১৯৩৬), আর complexity তত্ত্বের time hierarchy theorem (Hartmanis আর Stearns, ১৯৬৫), যা বলে বেশি সময় দিলে কঠোরভাবে বেশি সমস্যা সমাধান করা যায়। আবার এটাও জানা যে শুধু diagonal-ধাঁচের যুক্তি দিয়ে P বনাম NP মীমাংসা করা যাবে না (Baker, Gill আর Solovay-এর ১৯৭৫ সালের “relativization” ফল); DSA কোর্সের পর্ব ৬৪-এ P বনাম NP-এর পরিচয় আছে।

পরীক্ষা ও ইন্টারভিউতে: বিশ্ববিদ্যালয়, চাকরি বা ইন্টারভিউর পরীক্ষায় এই ধরনের প্রশ্ন প্রায়ই আসে:

  • ℤ countable দেখান। 0, 1, −1, 2, −2, …; g(n) = (n + 1)/2 (বিজোড়), −n/2 (জোড়), bijection-এর দুই অংশ প্রমাণসহ।
  • ℚ countable কেন? Lowest terms p/q ↦ π(p, q) একটি injection ℚ⁺ → ℕ; তারপর তিনটি countable সেটের union.
  • ℝ countable নয় কেন? Diagonal: যেকোনো তালিকা থেকে n-তম অঙ্ক বদলে নতুন সংখ্যা; 0.4999… সমস্যা এড়াতে অঙ্ক 4/5.
  • |S| < |P(S)| প্রমাণ করুন। x ↦ {x} injection; f onto হলে D = {x : x ∉ f(x)} = f(d) থেকে d ∈ D ⇔ d ∉ D.
  • অসমাধানযোগ্য সমস্যা কেন থাকতেই হবে? প্রোগ্রাম countable, language uncountable.

৯ · AI-এর যুগে — অসীম নিয়ে AI-এর আত্মবিশ্বাসী ভুল

অসীম সেট নিয়ে স্বজ্ঞা সহজে ভুল পথে যায়, আর AI সহকারী সেই ভুলগুলো সাবলীল ভাষায় লিখে দেয়। Diagonal আর countability-র প্রমাণ দেখতে ছোট, তাই একটি ভুল ধাপ সহজে চোখ এড়ায়। নিচে সাধারণ ভুলগুলো:

AI-এর ভুলকীভাবে ধরবেন
“A ⊂ B, তাই |A| < |B|” (অসীম সেটে)জোড় সংখ্যা আর ℕ-এর counterexample মনে রাখুন; কঠোর অসমতার জন্য “কোনো bijection নেই” প্রমাণ চাই
ℚ uncountable “প্রমাণ” করতে diagonal প্রয়োগজিজ্ঞেস করুন নতুন সংখ্যাটি সেটের ভেতরে কি না; ℚ-এর তালিকার diagonal সংখ্যা সাধারণত মূলদ নয়
Diagonal-এ “অঙ্কে 1 যোগ” বা 0/9 ব্যবহার, দ্বৈত রূপ উপেক্ষা0.4999… = 0.5000… উদাহরণ দিয়ে পরীক্ষা করুন; অঙ্ক 4/5-এর মতো নিরাপদ পছন্দ চান
“সারি ধরে” তালিকা (আগে সব (x, 0), তারপর (x, 1)…)জিজ্ঞেস করুন (0, 1) কততম জায়গায়; উত্তর সসীম না হলে তালিকা অবৈধ
Schröder–Bernstein বা countable union-এর শর্ত বাদ; CH “প্রমাণিত” বা “মিথ্যা” বলাপ্রতিটি উপপাদ্যের পূর্ণ hypothesis চান; CH-এর অবস্থা (ZFC থেকে স্বাধীন) বিশ্বস্ত বইয়ে মেলান
Pairing-এর সূত্রে off-by-one, বা বানানো রেফারেন্স ও সালPython-এ ছোট গ্রিডে injection/inverse পরীক্ষা করুন; সাল আর প্রবন্ধ পাঠ্যবইয়ে মেলান

AI-কে cardinality-র প্রমাণ লিখতে দিলে কাঠামো বেঁধে দিন, যাতে প্রতিটি দাবি যাচাই করা যায়:

নিচের দাবিটির প্রমাণ দাও: [যেমন "ℤ × ℕ countable" বা "[0,1] আর (0,1)-এর cardinality সমান"] ১. প্রথমে countable, bijection, injection-এর যে সংজ্ঞা ব্যবহার করবে তা লেখো (ℕ-এ 0 আছে কি না বলো)। ২. সম্ভব হলে একটি স্পষ্ট ফাংশন বা তালিকা দাও, আর প্রথম ১০টি মান ছক আকারে দেখাও। ৩. Injection আর surjection আলাদা আলাদা সংখ্যাযুক্ত ধাপে প্রমাণ করো; প্রতিটি ধাপের যুক্তি লেখো। ৪. কোনো উপপাদ্য (Schröder–Bernstein, countable union, Cantor) ব্যবহার করলে তার পূর্ণ শর্ত লেখো আর দেখাও শর্তগুলো এখানে কেন মেলে। ৫. ফাংশনটি যাচাই করার একটি ছোট Python কোড দাও (ছোট গ্রিডে injection আর inverse পরীক্ষা)। ৬. কোনো ধাপে নিশ্চিত না হলে স্পষ্ট বলো; ইতিহাস বা রেফারেন্স অনুমান করে লিখো না।

AI-এর প্রমাণ হাতে পেলে — যাচাইয়ের চেকলিস্ট

সবচেয়ে কাজের প্রশ্নটি সরল: “এই উপাদানটি তালিকার কততম?” উত্তর সসীম সংখ্যা না হলে প্রমাণটি ভেঙে পড়ে।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন, তারপর “→ উত্তর” চাপুন।

প্র ০১“অংশ সমগ্রের চেয়ে ছোট” কথাটি ইউক্লিডের সময় থেকে স্বতঃসিদ্ধ। অসীম সেটে এটি ভাঙে কেন, আর এতে গণিত কি অসঙ্গত হয়ে যায়?

ইউক্লিডের “Elements”-এ একটি সাধারণ ধারণা হিসেবে বলা আছে যে সমগ্র অংশের চেয়ে বড়। সসীম সংগ্রহে, আর দৈর্ঘ্য বা ক্ষেত্রফলের মতো মাপে, এটি নির্ভুল। Galileo ১৬৩৮ সালে দেখলেন বর্গসংখ্যা ℕ-এর একটি ক্ষুদ্র অংশ, অথচ n ↦ n² তাদের ℕ-এর সঙ্গে এক-এক মেলায়। তিনি সিদ্ধান্ত নিলেন, অসীমে তুলনার শব্দগুলো অর্থহীন। এটি একটি যুক্তিসঙ্গত প্রতিক্রিয়া ছিল, কারণ তখন “আকার” বলতে দুটি ধারণা একসঙ্গে জড়ানো ছিল।

আসলে দুটি আলাদা প্রশ্ন আছে। এক, “A কি B-এর অংশ?” (⊆, একটি ক্রম-সম্পর্ক)। দুই, “A আর B-কে কি এক-এক মেলানো যায়?” (bijection). সসীম সেটে দুটি একসঙ্গে চলে: proper subset মানেই কম উপাদান, পর্ব ৩২ “Pigeonhole principle — সহজ থেকে generalized”-এর মূল যুক্তি অনুযায়ী n + 1টি জিনিস nটি বাক্সে এক-এক বসানো যায় না। অসীম সেটে দুটি আলাদা হয়ে যায়। Dedekind এই বিচ্ছেদকেই অসীমের সংজ্ঞা বানান: একটি সেট “Dedekind-অসীম”, যদি নিজের কোনো proper subset-এর সঙ্গে তার bijection থাকে। Hilbert-এর হোটেলের ম্যানেজার ঠিক এই ধর্মটিই কাজে লাগান।

গণিত অসঙ্গত হয় না, কারণ কোনো বাক্য একসঙ্গে সত্য আর মিথ্যা প্রমাণিত হয়নি। ভেঙেছে শুধু একটি স্বজ্ঞা, যা সসীম অভিজ্ঞতা থেকে এসেছিল। সংজ্ঞা নিখুঁত করলে (|A| = |B| মানে bijection আছে) সব ফল সঙ্গতিপূর্ণ থাকে। ইউক্লিডের নীতি এখনো ⊆-এর ভাষায় সত্য: A ⊊ B হলে B-তে এমন উপাদান আছে যা A-তে নেই। শুধু cardinality-র ভাষায় তা আর কঠোর অসমতা দেয় না। সংখ্যাতত্ত্বে আবার আরেকটি মাপ আছে, natural density: জোড় সংখ্যার “ঘনত্ব” ১/২ (1 থেকে n-এর মধ্যে জোড় সংখ্যার অনুপাত n বাড়লে ১/২-এর দিকে যায়), যা cardinality থেকে আলাদা প্রশ্নের উত্তর দেয়।

মূল উপলব্ধি: “আকার”-এর দুটি ধারণা (অংশ হওয়া আর এক-এক মেলানো) সসীমে মিলে যায়, অসীমে আলাদা হয়। স্পষ্ট সংজ্ঞা স্বজ্ঞার জায়গা নিলে বিরোধ থাকে না।

প্র ০২Cantor-এর অসীম তত্ত্ব তাঁর সময়ে তীব্র বিরোধিতার মুখে পড়েছিল বলে শোনা যায়। গণিতবিদরা আপত্তি করেছিলেন কেন, আর শেষ পর্যন্ত তত্ত্বটি গৃহীত হলো কীভাবে?

প্রচলিত বিবরণ অনুযায়ী সবচেয়ে পরিচিত সমালোচক ছিলেন বার্লিনের প্রভাবশালী গণিতবিদ Leopold Kronecker. তাঁর দৃষ্টিভঙ্গি ছিল, গণিতের বস্তু হতে হবে এমন, যা সসীম ধাপে গঠন করা যায়; “সম্পূর্ণ অসীম সেট” একটি বস্তু হিসেবে ধরা, আর তার ওপর হিসাব করা, তাঁর কাছে গ্রহণযোগ্য ছিল না। Cantor-এর diagonal যুক্তির মতো প্রমাণ, যেখানে “সব তালিকা” বা “সব subset”-এর মতো সামগ্রিকতা নিয়ে কথা হয়, এই অবস্থানের ঠিক বিপরীত। ইতিহাসবিদরা অবশ্য সতর্ক করেন যে ব্যক্তিগত দ্বন্দ্বের কিছু গল্প সম্ভবত অতিরঞ্জিত।

আপত্তিগুলোর একটি গুরুতর ভিত্তিও ছিল। শতাব্দীর শুরুতে “সাদামাটা” সেট তত্ত্বে paradox ধরা পড়ে: Russell-এর paradox (পর্ব ১৪) দেখায় যে “যেকোনো ধর্ম দিয়ে একটি সেট বানানো যায়” নীতিটি অসঙ্গত। Cantor-এর উপপাদ্য নিজেও “সব সেটের সেট” ধারণার সঙ্গে খাপ খায় না। তাই সন্দেহবাদীদের মনে হয়েছিল, অসীম নিয়ে এই খেলা ভিত্তিহীন।

সমাধান এল স্বতঃসিদ্ধ পদ্ধতিতে। Ernst Zermelo ১৯০৮ সালে সেট তত্ত্বের স্বতঃসিদ্ধ প্রস্তাব করেন, আর পরে Abraham Fraenkel ও অন্যদের সংশোধনে আজকের ZFC দাঁড়ায়। এতে সেট বানানোর নিয়ম সীমিত, তাই পরিচিত paradox-গুলো বানানো যায় না, কিন্তু Cantor-এর সব মূল ফল প্রমাণ করা যায়। David Hilbert-এর একটি বহুল-উদ্ধৃত উক্তি (১৯২০-এর দশকের মাঝামাঝি) এই সময়ের মনোভাব ধরে: Cantor যে স্বর্গ তৈরি করেছেন, সেখান থেকে কেউ আমাদের তাড়াতে পারবে না।

অন্যদিকে Kronecker-এর ধারার চিন্তাও হারিয়ে যায়নি। Brouwer-এর intuitionism আর পরে constructive mathematics গঠনযোগ্যতার ওপর জোর দেয়। মজার ব্যাপার, diagonal argument নিজে অনেকটা গঠনমূলক: স্পষ্ট তালিকা দিলে এটি বাদ পড়া সংখ্যাটির প্রতিটি অঙ্ক হিসাব করে দেয়, ঠিক যেমন §৫-এর কোড করল।

মূল উপলব্ধি: নতুন ধারণার বিরোধিতা সবসময় একগুঁয়েমি নয়; Cantor-এর ক্ষেত্রে তা আংশিকভাবে ঠিক জায়গায় আঙুল তুলেছিল, আর সেই চাপ থেকেই সেট তত্ত্বের নিখুঁত স্বতঃসিদ্ধ ভিত্তি এসেছে।

প্র ০৩Continuum hypothesis ZFC থেকে স্বাধীন। একটি গাণিতিক প্রশ্নের “উত্তর নেই” কথাটির অর্থ কী, আর এটি কি প্রোগ্রামারের কাছে কোনো অর্থ বহন করে?

প্রথমে কী প্রমাণিত, তা স্পষ্ট করা যাক। Gödel ১৯৪০ সালে একটি “ছোট” সেট-জগৎ (constructible universe, L) গড়ে দেখান যে ZFC-র সব স্বতঃসিদ্ধ সেখানে সত্য আর CH-ও সত্য; তাই ZFC সঙ্গতিপূর্ণ হলে ZFC + CH-ও সঙ্গতিপূর্ণ, অর্থাৎ ZFC CH-কে খণ্ডন করতে পারে না। Cohen ১৯৬৩ সালে forcing পদ্ধতিতে এমন জগৎ গড়েন যেখানে ZFC সত্য কিন্তু CH মিথ্যা; তাই ZFC CH প্রমাণও করতে পারে না। এই কাজের জন্য Cohen ১৯৬৬ সালে Fields Medal পান। দুটি মিলে: CH, ZFC থেকে স্বাধীন।

“উত্তর নেই” কথাটি তাই সতর্কভাবে বলতে হয়: উত্তর ZFC-এর নিয়মে নির্ধারিত নয়। এর আগের পরিচিত উদাহরণ জ্যামিতিতে: ইউক্লিডের সমান্তরাল স্বীকার্য বাকি স্বীকার্য থেকে স্বাধীন, আর তাই euclidean আর non-euclidean দুই রকম সঙ্গত জ্যামিতি আছে। গণিতবিদদের একটি অংশ মনে করেন, সেটের একটি “সত্যিকারের” জগৎ আছে যেখানে CH সত্য বা মিথ্যা, আর আমাদের সঠিক নতুন স্বতঃসিদ্ধ খুঁজতে হবে; আরেক অংশ মনে করেন, বিভিন্ন সঙ্গত সেট-জগৎ পাশাপাশি থাকতে পারে। প্রশ্নটি এখনো গবেষণা আর দর্শনের আলোচনার বিষয়।

প্রোগ্রামারের কাছে এর একটি সরাসরি অর্থ আছে। পর্ব ০৭-এ SAT solver দেখেছেন: একটি সূত্র satisfiable, unsatisfiable, বা (বড় হলে) solver সময়ে কিছু বলতে পারে না। স্বাধীনতা হলো এর যুক্তিগত রূপ: একটি specification (স্বতঃসিদ্ধের সেট) থেকে কিছু দাবি প্রমাণও হয় না, খণ্ডনও না, কারণ specification-টি দুই রকম “বাস্তবায়ন” অনুমোদন করে। সফটওয়্যারে এটি চেনা: একটি অসম্পূর্ণ API specification-এর দুটি implementation আলাদা আচরণ দেখায়, অথচ দুটিই specification মানে।

মূল উপলব্ধি: স্বাধীনতা মানে অজ্ঞতা নয়, একটি প্রমাণিত সীমা: নিয়মগুলো প্রশ্নটির উত্তর ঠিক করে দেয় না, ঠিক যেমন একটি অসম্পূর্ণ specification একটি আচরণ নির্ধারণ করে না।

প্র ০৪প্রায় সব language অসমাধানযোগ্য, আর প্রায় সব বাস্তব সংখ্যা কোনো প্রোগ্রাম দিয়ে হিসাব করা যায় না। তাহলে দৈনন্দিন কাজে প্রোগ্রাম এত সফল কেন?

গণনাটি নিখুঁত: প্রোগ্রাম countable, language uncountable, তাই সমাধানযোগ্য language একটি countable “ক্ষুদ্র” অংশ। একই কথা বাস্তব সংখ্যায়। Alan Turing তাঁর ১৯৩৬ সালের প্রবন্ধের শিরোনামেই “computable numbers”-এর কথা বলেন: এমন বাস্তব সংখ্যা, যার দশমিক অঙ্কগুলো একটি প্রোগ্রাম একটির পর একটি ছাপতে পারে। π, e, √2 সবাই computable. কিন্তু প্রোগ্রাম countable, তাই computable সংখ্যাও countable, আর বাকি uncountable সংখ্যাগুলো কোনো প্রোগ্রামের নাগালের বাইরে।

তবু বাস্তবে সমস্যা হয় না, কারণ মানুষ যে সমস্যা নিয়ে ভাবে, তা “এলোমেলো” language নয়। একটি সমস্যা বর্ণনা করতে আমরা একটি সসীম বাক্য লিখি, আর সসীম বাক্যও countable. অসমাধানযোগ্য “বেশিরভাগ” language-এর অধিকাংশের কোনো সসীম বর্ণনাই নেই; সেগুলো আমরা কখনো জিজ্ঞেস করতেও পারি না। বাজারঘরের প্রশ্ন (এই অর্ডার বৈধ কি না, সবচেয়ে কম খরচের রুট কোনটি) সসীম নিয়মে বর্ণিত, আর বেশিরভাগই সমাধানযোগ্য।

কিন্তু “বর্ণনা করা যায়” আর “সমাধান করা যায়” এক নয়, আর এখানেই আসল শিক্ষা। Halting problem একটি এক বাক্যের বর্ণনা, তবু undecidable. H. G. Rice-এর ১৯৫০-এর দশকের উপপাদ্য বলে, প্রোগ্রামের আচরণ-সংক্রান্ত প্রায় যেকোনো অ-তুচ্ছ প্রশ্ন (“এই কোড কি কখনো null pointer-এ পড়বে?”) সাধারণভাবে undecidable. তাই static analyzer সবসময় আপস করে: কিছু বাগ মিস করে, বা মিথ্যা সতর্কতা দেয়, বা “জানি না” বলে।

মূল উপলব্ধি: cardinality বলে অসমাধানযোগ্যতা অনিবার্য আর সর্বব্যাপী, কিন্তু আমাদের প্রশ্নগুলো বর্ণনাযোগ্য বলে বেশিরভাগই নাগালে থাকে; যেগুলো থাকে না, তাদের চিনতে পারাই একজন প্রকৌশলীর দক্ষতা।

প্র ০৫Cantor-এর diagonal, Russell-এর paradox, halting problem আর Gödel-এর অসম্পূর্ণতা: এদের মধ্যে একটি সাধারণ কাঠামো আছে বলা হয়। সেটি কী?

চারটির মূলে একটি ছক: বস্তুগুলোকে সারিতে আর “প্রশ্নগুলো”কে কলামে রাখা, যেখানে সারি x আর কলাম y-এর ঘরে লেখা থাকে “x-এর সম্পর্কে y কী বলে”। তারপর diagonal (x, x) ধরে প্রতিটি উত্তর উল্টে একটি নতুন সারি বানানো, যা কোনো বিদ্যমান সারির সমান হতে পারে না, কারণ সারি x-এর সঙ্গে ঘর (x, x)-এ অমিল। এই পর্বে আমরা কাঠামোটি তিনবার দেখেছি: দশমিক অঙ্কে (§৫), binary string-এ (§৫-এর কোড), আর D = {x ∈ S : x ∉ f(x)}-এ (§৬)।

Russell (প্রচলিত বিবরণে ১৯০১): সারি আর কলাম দুটোই “সব সেট”; ঘরে x ∈ y কি না। Diagonal উল্টালে R = {x : x ∉ x}. এখানে বিরোধটি কোনো তালিকার অসম্পূর্ণতা দেখায় না, দেখায় “সব সেটের সেট” ধারণাটিই অসম্ভব। Turing (১৯৩৬): সারিতে প্রোগ্রাম, কলামে ইনপুট (প্রোগ্রামের কোড), ঘরে “থামে কি না”। যদি halting decide করার একটি প্রোগ্রাম H থাকত, তাহলে diagonal উল্টানো প্রোগ্রাম লেখা যেত: “নিজের কোড পেলে H যা বলে তার উল্টো কাজ করো”। এই প্রোগ্রাম নিজের সারির সঙ্গে নিজের ঘরেই অমিল, বিরোধ; তাই H নেই।

Gödel (১৯৩১): সারিতে বাক্য, আর “প্রমাণযোগ্যতা” মূল প্রশ্ন। তিনি সংখ্যা দিয়ে বাক্য এনকোড করে (Gödel numbering, এই পর্বের pairing function-এর মতো একটি কৌশল) এমন একটি বাক্য বানান, যা মোটামুটি বলে “আমি প্রমাণযোগ্য নই”। ব্যবস্থাটি সঙ্গতিপূর্ণ হলে এই বাক্য প্রমাণযোগ্য নয়, অথচ (উপযুক্ত অর্থে) সত্য। এখানে diagonal “মিথ্যাবাদীর paradox”-কে প্রমাণযোগ্যতার ভাষায় নিরাপদে রূপ দেয়।

F. William Lawvere ১৯৬৯ সালে category theory-র ভাষায় এই সব যুক্তির একটি সাধারণ উপপাদ্য দেন বলে পরিচিত। যখনই দাবি দেখবেন “এমন কোনো X নেই যা সব Y-কে তালিকাভুক্ত করে”, প্রথমে diagonal-এর কথা ভাবুন।

মূল উপলব্ধি: diagonal একটি পুনঃব্যবহারযোগ্য কৌশল: প্রতিটি বস্তুকে নিজের সম্পর্কে প্রশ্ন করে উত্তর উল্টে দেওয়া, তারপর দেখানো যে উল্টানো বস্তুটি কারও সমান হতে পারে না। অসীমের আকার থেকে কম্পিউটারের সীমা পর্যন্ত, একই ছক।

অনুশীলন

আগে খাতায় করুন, তারপর উত্তর খুলে মেলান।

  1. প্রমাণ: ℕ-এর সব সসীম subset-এর সেট F countable, স্পষ্ট bijection দিয়ে প্রমাণ করুন। তারপর ব্যাখ্যা করুন, এটি Cantor-এর উপপাদ্য (|ℕ| < |P(ℕ)|)-এর সঙ্গে বিরোধ করে না কেন।

    ফাংশন b : F → ℕ, b(A) = ∑a ∈ A 2a (ফাঁকা সেটে 0). যেমন b({0, 2, 3}) = 1 + 4 + 8 = 13.

    1. b সংজ্ঞায়িত: A সসীম, তাই যোগফল সসীম, একটি স্বাভাবিক সংখ্যা। — সসীমতা
    2. প্রতিটি n ∈ ℕ-এর একটি অনন্য binary রূপ আছে (পর্ব ১১-এর strong induction দিয়ে প্রমাণযোগ্য); অর্থাৎ n = ∑a ∈ A 2a এমন সসীম A ঠিক একটি। — binary-র অস্তিত্ব আর অনন্যতা
    3. অস্তিত্ব থেকে surjection, অনন্যতা থেকে injection; তাই b একটি bijection, আর F countably infinite. ∎

    বিরোধ নেই, কারণ F ≠ P(ℕ): অসীম subset (যেমন সব জোড় সংখ্যা) F-এ নেই। অসীম subset-গুলো অসীম bit string, আর তারাই uncountable অংশ; সসীম subset শেষে শূন্যের অসীম সারিতে শেষ হওয়া bit string, যা একটি সাধারণ পূর্ণসংখ্যার binary রূপ। যাচাই: scratch-এ Python-এ b({0, 2, 3}) = 13 আর 13-এর bit থেকে {0, 2, 3} ফেরত পাওয়া গেছে।

  2. হিসাব: (ক) π(2, 3), π(5, 0) আর π(0, 5) বের করুন। (খ) π(x, y) = 50 হলে (x, y) কত? (গ) ℚ⁺-এর তির্যক হাঁটায় (p + q ক্রমে, lowest terms) 1/5 কততম? Calkin–Wilf ক্রমে 1/5 কততম, যদি জানা থাকে 1/n আসে 2n−1-তম জায়গায়? (ঘ) |S| = 2 হলে S থেকে P(S)-এ কয়টি ফাংশন, আর তাদের কয়টি onto?

    (ক) π(2, 3) = T(5) + 3 = 15 + 3 = 18; π(5, 0) = T(5) + 0 = 15; π(0, 5) = 15 + 5 = 20. একই রেখা d = 5-এর দুই প্রান্ত: 15 থেকে 20.

    (খ) T(9) = 45 ≤ 50 < 55 = T(10), তাই d = 9, y = 50 − 45 = 5, x = 9 − 5 = 4. যাচাই: π(4, 5) = 45 + 5 = 50.

    (গ) তির্যক হাঁটা: 1, 1/2, 2, 1/3, 3, 1/4, 2/3, 3/2, 4, 1/5: ১০ম। Calkin–Wilf-এ 24 = ১৬তম (scratch-এ দুটিই Python দিয়ে মেলানো)।

    (ঘ) |P(S)| = 4, তাই 42 = 16টি ফাংশন; একটিও onto নয়, কারণ দুটি উপাদান বড়জোর দুটি subset-এ যায়, চারটিতে নয়। Cantor-এর উপপাদ্যের সসীম রূপ: §৬-এর কোডও 16টির প্রতিটিতে D বাদ পড়তে দেখেছে।

  3. আউটপুট অনুমান: কোড না চালিয়ে বলুন কী ছাপা হবে, আর দ্বিতীয় তালিকায় 6 কেন নেই কিন্তু 12 আছে। তারপর যেকোনো Python-এ চালিয়ে মেলান।
    def pair(x, y): return (x + y) * (x + y + 1) // 2 + y
    print([pair(x, 2 - x) for x in range(3)])
    print(sorted({pair(x, y) for x in range(3) for y in range(3)}))
    [5, 4, 3]
    [0, 1, 2, 3, 4, 5, 7, 8, 12]

    প্রথম লাইন রেখা d = 2-এর তিনটি জোড়া (0, 2), (1, 1), (2, 0): নম্বর T(2) + y = 3 + 2, 3 + 1, 3 + 0. দ্বিতীয় লাইন 3 × 3 গ্রিড (x, y ∈ {0, 1, 2}): নয়টি জোড়া, নয়টি আলাদা নম্বর। 6 = π(3, 0), কিন্তু x = 3 গ্রিডে নেই; 12 = π(2, 2), যা রেখা d = 4-এর মাঝখানে। §৩-এর কোডের মতোই: বর্গাকার গ্রিড নয়, ত্রিভুজ x + y < k ঠিক 0 থেকে T(k) − 1 পর্যন্ত সব নম্বর পায়।

  4. প্রমাণের ভুল ধরুন: একজন লিখলেন: “দাবি: (0, 1)-এর মূলদ সংখ্যার সেট uncountable. প্রমাণ: ধরি এগুলো একটি তালিকা q1, q2, … তে আছে। প্রতিটি qn-এর দশমিক রূপ লিখে diagonal-এর n-তম অঙ্ক 5 না হলে 5, নইলে 4 নিয়ে x বানাই। x প্রতিটি qn থেকে আলাদা, তাই তালিকা অসম্পূর্ণ। অতএব সেটটি uncountable. ∎” ভুল কোথায়? দাবিটি সত্য কি?
    • ভুল: বিরোধ পেতে হলে x-কে সেই সেটের সদস্য হতে হবে, অর্থাৎ মূলদ। কিন্তু x-এর দশমিক অঙ্ক (4 আর 5-এর ক্রম) পর্যাবৃত্ত হবে এমন কোনো নিশ্চয়তা নেই, আর মূলদ সংখ্যার দশমিক রূপ শেষ পর্যন্ত পর্যাবৃত্ত। x সাধারণত অমূলদ, তাই “x তালিকায় নেই” কোনো বিরোধ নয়: অমূলদ সংখ্যা তো তালিকায় থাকার কথাই নয়।
    • দাবি: মিথ্যা। (0, 1)-এর মূলদ সংখ্যা ℚ-এর subset, আর ℚ countable (উপপাদ্য ৪.১), তাই উপপাদ্য ২.২ (ক) অনুযায়ী এটি countable.
    • শিক্ষা: Diagonal যুক্তির প্রতিটি প্রয়োগে আলাদা করে দেখাতে হয় যে বানানো বস্তুটি সেটের ভেতরে। (0, 1)-এর ক্ষেত্রে ধাপ ৪ ঠিক এই কাজ করেছিল।

নিজেকে যাচাই করুন

ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।

ক্রম(0, 1) uncountable প্রমাণের diagonal argument-এর ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)

  1. ধরে নেওয়া যে (0, 1)-এর সব সংখ্যা একটি তালিকা r1, r2, …-তে আছে
  2. প্রতিটি rn-কে অনন্য দশমিক রূপে লেখা
  3. n-তম অঙ্ক বদলে (5 না হলে 5, নইলে 4) নতুন সংখ্যা x বানানো
  4. দেখানো যে x ∈ (0, 1) আর x প্রতিটি rn থেকে n-তম অঙ্কে আলাদা
  5. সিদ্ধান্ত: তালিকা অসম্পূর্ণ, অনুমানের সঙ্গে বিরোধ

নিচের কোন সেটটি uncountable?

  • ℚ (সব মূলদ সংখ্যা)
  • ℤ×ℤ
  • {0, 1}-এর ওপর সব সসীম binary string
  • P(ℕ), ℕ-এর সব subset

Cantor pairing function π(x, y) = (x + y)(x + y + 1)/2 + y অনুযায়ী π(2, 2) কত?

  • 10
  • 12
  • 8
  • 14

যেকোনো ফাংশন f : S → P(S)-এর জন্য D = {x ∈ S : x ∉ f(x)}. D কেন f-এর কোনো ছবি হতে পারে না?

  • কারণ D সবসময় ফাঁকা সেট
  • কারণ S সসীম হলে P(S) বড়
  • কারণ f(d) = D হলে d ∈ D হবে ঠিক তখন, যখন d ∉ D
  • কারণ D, S-এর subset নয়

A থেকে B-তে একটি injection আর B থেকে A-তে একটি injection আছে। কোন সিদ্ধান্তটি সঠিক?

  • A আর B-এর মধ্যে একটি bijection আছে
  • দেওয়া injection দুটির অন্তত একটি bijection
  • A = B
  • A আর B দুটিই সসীম

Cantor-এর diagonal argument-এ নতুন সংখ্যার n-তম অঙ্ক হিসেবে “dnn + 1 (9 হলে 0)” না নিয়ে “5 না হলে 5, নইলে 4” নেওয়া হয় কেন?

  • কারণ এতে হিসাব দ্রুত হয়
  • যাতে 0 বা 9-এ শেষ হওয়া দ্বৈত দশমিক রূপের সমস্যা না হয়
  • যাতে নতুন সংখ্যাটি মূলদ হয়
  • যাতে তালিকাটি countable থাকে

Continuum hypothesis (ℵ0 আর 𝔠-এর মাঝে কোনো cardinality নেই) সম্পর্কে কোনটি সঠিক?

  • ZFC থেকে CH প্রমাণিত হয়েছে
  • ZFC থেকে CH মিথ্যা প্রমাণিত হয়েছে
  • ZFC সঙ্গতিপূর্ণ হলে CH সেখান থেকে প্রমাণ বা খণ্ডন কোনোটিই করা যায় না
  • এটি একটি খোলা প্রশ্ন, যা বড় কম্পিউটার হিসাবে মীমাংসা হবে

“কিছু সিদ্ধান্ত-সমস্যা কোনো প্রোগ্রাম দিয়ে সমাধান করা যায় না” — এর cardinality-ভিত্তিক প্রমাণের মূল কথা কোনটি?

  • প্রোগ্রামের সংখ্যা সসীম
  • প্রোগ্রাম আর language দুটিই countable
  • কম্পিউটারের মেমরি সসীম
  • প্রোগ্রাম countable, কিন্তু language uncountable

শব্দকোষ

লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন, অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:

মনে রাখুন

  1. |A| = |B| মানে একটি bijection আছে; |A| ≤ |B| মানে injection. অসীমে proper subset-ও সমান আকারের হতে পারে (জোড় সংখ্যা আর ℕ)।
  2. Countable: সসীম বা ℕ-এর সঙ্গে bijection; প্রমাণে একটি injection A → ℕ বা একটি তালিকা যথেষ্ট, যেখানে প্রতিটি উপাদানের জায়গা সসীম।
  3. ℤ, ℕ×ℕ, ℚ, Σ* countable: 0, 1, −1, 2, …; π(x, y) = T(x + y) + y; lowest terms; countable সেটের countable union.
  4. Diagonal: (0, 1) আর ℝ uncountable (অঙ্ক 4/5 দিয়ে); Cantor-এর উপপাদ্য |S| < |P(S)|, D = {x : x ∉ f(x)}. বানানো বস্তুটি সেটের ভেতরে কি না, সবসময় দেখুন।
  5. Schröder–Bernstein দুই দিকের injection থেকে bijection দেয়; CH ZFC থেকে স্বাধীন; প্রোগ্রাম countable বলে অসমাধানযোগ্য সমস্যা থাকতেই হবে।

পরের পর্বে: মডিউল ৩-এর শেষ পর্ব ১৯ “Discrete math-এ matrix — 0-1 matrix আর Boolean product”: সসীম সেটের ওপর relation আর graph-কে 0-1 matrix দিয়ে লেখা, আর Boolean গুণফল দিয়ে “কয় ধাপে পৌঁছানো যায়” প্রশ্নের উত্তর।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

এই পর্বটি শেয়ার করুন:
এই পর্বে ভুল পেয়েছেন? জানান