এই পর্বে যা শিখবেন
- Tautology, contradiction আর contingency চেনা, আর দুটি রাশি equivalent কি না truth table দিয়ে প্রমাণ করা
- De Morgan সহ প্রায় বিশটি equivalence সূত্র ব্যবহার করে শিকল-প্রমাণ লেখা, প্রতিটি ধাপের কারণসহ
- যেকোনো truth table থেকে DNF আর CNF বানানো, আর DNF কখনো কখনো কেন বিশাল হয়ে যায় তা প্রমাণ করা
- কোন connective-সেট functionally complete, NAND দিয়ে ∧ আর ∨ বানানো, আর {∧, ∨} কেন যথেষ্ট নয়
- Satisfiability (SAT) কী, equivalence যাচাইয়ের সঙ্গে এর সম্পর্ক, আর NP-completeness-এর প্রথম পরিচয়
১ · Tautology, contradiction আর contingency
বাজারঘরের দুই ডেভেলপার, রুমানা আর তানভীর, নতুন গ্রাহকের কুপনের নিয়ম আলাদা আলাদা করে কোডে লিখেছেন। ধরুন a = “গ্রাহক নতুন”, b = “অর্ডার ৫০০ টাকা বা তার বেশি”, c = “অর্ডার app থেকে এসেছে”। রুমানা লিখেছেন: কুপন চলবে, যদি এটি সত্য না হয় যে “গ্রাহক নতুন নয়, অথবা অর্ডার ৫০০ টাকার কম এবং app থেকেও নয়”। তানভীর লিখেছেন: কুপন চলবে, যদি গ্রাহক নতুন হন এবং অর্ডার ৫০০ টাকা বা বেশি হয় অথবা app থেকে আসে।
রুমানা: ¬(¬a ∨ (¬b ∧ ¬c)) তানভীর: a ∧ (b ∨ c)
দুটি নিয়ম কি একই কাজ করে? Code review-তে এই প্রশ্নের উত্তর “মনে হয়” দিয়ে চলে না। একটি গ্রাহকও যদি এক নিয়মে কুপন পান আর অন্য নিয়মে না পান, তাহলে অভিযোগ আসবে। এই পর্বে আপনি দুটি পথে এর নিশ্চিত উত্তর দিতে শিখবেন: truth table-এর প্রতিটি সারি মিলিয়ে, আর সূত্রের শিকল দিয়ে। পর্ব ০২-এ (Propositional logic — proposition, connective আর truth table) যে connective আর truth table শিখেছেন, এখানে সেগুলোকেই হাতিয়ার হিসেবে ব্যবহার করা হবে।
প্রথমে রাশিগুলোকে তিন ভাগে ভাগ করা যাক। চলক বা variable বলতে এখানে p, q, r-এর মতো সাধারণ proposition বোঝায়, যাদের প্রতিটির মান T (সত্য) অথবা F (মিথ্যা)। কয়েকটি চলককে connective দিয়ে জুড়ে যে রাশি হয়, তাকে বলে যৌগিক proposition বা compound proposition.
একটি যৌগিক proposition হলো
- tautology, যদি চলকগুলোর প্রতিটি মান-বিন্যাসে (truth table-এর প্রতিটি সারিতে) এর মান T হয়;
- contradiction, যদি প্রতিটি সারিতে এর মান F হয়;
- contingency, যদি এটি tautology-ও নয়, contradiction-ও নয়, অর্থাৎ অন্তত একটি সারিতে T আর অন্তত একটি সারিতে F.
| p | ¬p | p ∨ ¬p | p ∧ ¬p | p → ¬p |
|---|---|---|---|---|
| T | F | T | F | F |
| F | T | T | F | T |
| ধরন | tautology | contradiction | contingency | |
আবহাওয়ার এক খবরে বলা হলো, “কাল ঢাকায় বৃষ্টি হবে, অথবা হবে না।” কথাটি কখনো ভুল হবে না, কারণ এটি p ∨ ¬p ধরনের tautology. কিন্তু এতে বাইরের পৃথিবী সম্পর্কে কোনো তথ্যও নেই: ছাতা নেবেন কি না, এ কথা থেকে বোঝা যায় না। Tautology-র সত্যতা আসে শুধু বাক্যের গঠন থেকে, বিষয়বস্তু থেকে নয়। এই কারণেই tautology যুক্তির “নিয়ম” হিসেবে কাজে লাগে: চলকের জায়গায় যা-ই বসান, এটি সত্যই থাকে।
শেষ কথাটি একটি ছোট উপপাদ্য, আর এই পর্বে বারবার কাজে লাগবে।
A যদি tautology হয়, আর A-তে কোনো চলক p-এর প্রতিটি জায়গায় একই রাশি B বসানো হয়, তাহলে নতুন রাশিটিও tautology. Contradiction-এর বেলায়ও একই কথা খাটে।
প্রমাণ।
- নতুন রাশির চলকগুলোর যেকোনো একটি মান-বিন্যাস নিন। সেই বিন্যাসে B-এর একটি নির্দিষ্ট মান আছে, ধরুন v (T অথবা F). (B-এর truth table থেকে)
- নতুন রাশির মান তখন ঠিক সেই মান, যা A পায় যখন p = v আর বাকি চলকগুলো আগের মতো। (প্রতিস্থাপনের সংজ্ঞা; p-এর প্রতিটি জায়গায় একই B বসেছে বলে সব জায়গায় একই v আসে)
- A-এর truth table-এর প্রতিটি সারিতে মান T, তাই এই সারিতেও T. (A tautology)
- বিন্যাসটি যেকোনো ছিল, তাই নতুন রাশি প্রতিটি সারিতে T. ∎
উদাহরণ: p ∨ ¬p tautology, তাই p-এর জায়গায় (q ∧ r) বসালে (q ∧ r) ∨ ¬(q ∧ r)-ও tautology, আট সারির টেবিল না বানিয়েই। আরেকটি সহজ পর্যবেক্ষণ: A tautology হলে ¬A contradiction, আর উল্টোটাও সত্য, কারণ ¬ প্রতিটি সারির মান উল্টে দেয়।
২ · Logical equivalence — সংজ্ঞা আর truth table দিয়ে প্রমাণ
দুটি রাশি “একই কথা বলে” কথাটির গাণিতিক রূপ হলো logical equivalence.
দুটি যৌগিক proposition p আর q-কে logically equivalent বলা হয়, যদি p ↔ q একটি tautology হয়। লেখা হয় p ≡ q. সমতুল্যভাবে: দুটি রাশিতে যত চলক আছে, তাদের প্রতিটি মান-বিন্যাসে p আর q-এর মান সমান, অর্থাৎ truth table-এ দুটির কলাম হুবহু এক।
দুটি রূপ যে একই, তা সহজেই দেখা যায়: p ↔ q একটি সারিতে T হয় ঠিক তখনই, যখন সেই সারিতে p আর q-এর মান সমান। তাই “p ↔ q প্রতিটি সারিতে T” আর “প্রতিটি সারিতে p আর q-এর মান সমান” একই কথা। খেয়াল করুন, ≡ কোনো connective নয়। p ∧ q একটি proposition, কিন্তু p ≡ q দুটি রাশি সম্পর্কে একটি দাবি, যা সত্য বা মিথ্যা প্রমাণ করা যায়। কিছু বই ≡-এর বদলে ⇔ লেখে।
প্রথম বড় উদাহরণ সবচেয়ে বিখ্যাত দুটি সূত্র, De Morgan-এর সূত্র। “রাফি ক্রিকেট খেলে এবং গান গায়” কথাটি মিথ্যা হলে কী বোঝায়? দুটির অন্তত একটি সত্য নয়: “রাফি ক্রিকেট খেলে না, অথবা গান গায় না।” অনেকে ভুল করে বলেন “খেলেও না, গায়ও না”, যা অনেক বেশি জোরালো দাবি।
¬(p ∧ q) ≡ ¬p ∨ ¬q ¬(p ∨ q) ≡ ¬p ∧ ¬q
প্রমাণ (truth table দিয়ে)। দুই চলকে চারটি সারি; প্রতিটি সারিতে চারটি রাশির মান হিসাব করা হলো:
| p | q | ¬(p ∧ q) | ¬p ∨ ¬q | ¬(p ∨ q) | ¬p ∧ ¬q |
|---|---|---|---|---|---|
| T | T | F | F | F | F |
| T | F | T | T | F | F |
| F | T | T | T | F | F |
| F | F | T | T | T | T |
তৃতীয় আর চতুর্থ কলাম চার সারিতেই সমান, তাই প্রথম সূত্রটি সত্য; পঞ্চম আর ষষ্ঠ কলামও সমান, তাই দ্বিতীয়টিও। ∎
এভাবে truth table দিয়ে প্রমাণকে কখনো perfect induction বলা হয়: সম্ভাব্য সব ক্ষেত্র একে একে দেখা। পদ্ধতিটি সবসময় কাজ করে, কারণ সারির সংখ্যা সসীম। এবার conditional নিয়ে তিনটি দাবি দেখা যাক, যেগুলো পরীক্ষায় সবচেয়ে বেশি আসে। পর্ব ০২-এ দেখেছেন, p → q-এর converse হলো q → p, inverse হলো ¬p → ¬q, আর contrapositive হলো ¬q → ¬p.
(ক) p → q ≡ ¬p ∨ q. (খ) p → q ≡ ¬q → ¬p, অর্থাৎ conditional আর তার contrapositive equivalent. (গ) p → q আর তার converse q → p equivalent নয়; একইভাবে conditional আর inverse-ও নয়।
প্রমাণ।
- p → q মিথ্যা শুধু একটি সারিতে: p = T, q = F. (conditional-এর সংজ্ঞা)
- ¬p ∨ q-ও মিথ্যা শুধু তখন, যখন ¬p = F আর q = F, অর্থাৎ p = T, q = F. (∨-এর সংজ্ঞা) দুই রাশির মিথ্যা সারি একই, তাই বাকি তিন সারিতে দুটিই T; (ক) প্রমাণিত।
- ¬q → ¬p মিথ্যা শুধু যখন ¬q = T আর ¬p = F, অর্থাৎ q = F, p = T. সেই একই সারি, তাই (খ) প্রমাণিত।
- (গ)-এর জন্য একটি সারিই যথেষ্ট: p = T, q = F হলে p → q = F কিন্তু q → p = T. দুই কলাম অন্তত এক সারিতে আলাদা, তাই equivalent নয়। Inverse ¬p → ¬q আসলে converse-এর contrapositive, তাই (খ) অনুযায়ী converse-এর সঙ্গে equivalent, ফলে সেটিও p → q-এর সঙ্গে equivalent নয়। ∎
লক্ষ করুন, “equivalent নয়” প্রমাণ করতে পুরো টেবিল লাগে না, একটি counterexample সারিই যথেষ্ট। ≡ সম্পর্কটির আরও তিনটি ধর্ম আছে, যেগুলো পরের অংশের শিকল-প্রমাণকে বৈধ করে: যেকোনো A-এর জন্য A ≡ A; A ≡ B হলে B ≡ A; আর A ≡ B ও B ≡ C হলে A ≡ C (দুটি কলাম সমান, তারপর পরের দুটি সমান, তাই প্রথম আর শেষটিও সমান)। এই তিন ধর্মের নাম reflexive, symmetric আর transitive; পর্ব ৫৫-এ (Equivalence relation আর partition) এদের সাধারণ রূপ দেখবেন।
এবার কম্পিউটারকে দিয়ে সব সারি মিলিয়ে নেওয়া যাক। নিচের ব্লকটি আপনার ব্রাউজারেই Python চালায় (Pyodide, অর্থাৎ WebAssembly-তে compile করা আসল CPython). প্রথমবার চালালে Python লোড হতে কয়েক সেকেন্ড লাগে। itertools.product([True, False], repeat=n) n চলকের 2nটি সারি একটি একটি করে দেয়, ঠিক truth table-এর ক্রমে। Python-এর and, or, not যে ∧, ∨, ¬-এর কাজ করে, তার বিস্তারিত Python প্রোগ্রামিং কোর্সের পর্ব ০৮-এ আছে।
from itertools import product
def imp(a, b): # a → b
return (not a) or b
def check(f, g, n):
"""সব 2**n সারিতে f আর g মেলে কি না; না মিললে প্রথম counterexample"""
for row in product([True, False], repeat=n):
if f(*row) != g(*row):
return "≢ counterexample " + str(row)
return f"≡ (সব {2**n} সারিতে মিল)"
tests = [
("¬(p∧q) , ¬p∨¬q", lambda p, q: not (p and q), lambda p, q: not p or not q, 2),
("p→q , ¬p∨q", imp, lambda p, q: not p or q, 2),
("p→q , ¬q→¬p", imp, lambda p, q: imp(not q, not p), 2),
("p→q , q→p", imp, lambda p, q: imp(q, p), 2),
("p∨(q∧r) , (p∨q)∧(p∨r)", lambda p, q, r: p or (q and r),
lambda p, q, r: (p or q) and (p or r), 3),
("(p∧q)→r , (p→r)∧(q→r)", lambda p, q, r: imp(p and q, r),
lambda p, q, r: imp(p, r) and imp(q, r), 3),
]
for name, f, g, n in tests:
print(f"{name:<24} {check(f, g, n)}")
def kind(f, n):
vals = [f(*row) for row in product([True, False], repeat=n)]
if all(vals): return "tautology"
if not any(vals): return "contradiction"
return f"contingency ({sum(vals)}/{len(vals)} সারিতে সত্য)"
print("(p ∧ (p→q)) → q :", kind(lambda p, q: imp(p and imp(p, q), q), 2))
print("p ∧ ¬p :", kind(lambda p: p and not p, 1))
print("(p→q) → p :", kind(lambda p, q: imp(imp(p, q), p), 2))আসল আউটপুট (ব্রাউজারের Python):
¬(p∧q) , ¬p∨¬q ≡ (সব 4 সারিতে মিল)
p→q , ¬p∨q ≡ (সব 4 সারিতে মিল)
p→q , ¬q→¬p ≡ (সব 4 সারিতে মিল)
p→q , q→p ≢ counterexample (True, False)
p∨(q∧r) , (p∨q)∧(p∨r) ≡ (সব 8 সারিতে মিল)
(p∧q)→r , (p→r)∧(q→r) ≢ counterexample (True, False, False)
(p ∧ (p→q)) → q : tautology
p ∧ ¬p : contradiction
(p→q) → p : contingency (2/4 সারিতে সত্য)
প্রথম তিন সারি উপপাদ্য ২ আর ৩-এর (ক), (খ) অংশ নিশ্চিত করে। চতুর্থ সারিতে converse ব্যর্থ, আর counterexample ঠিক সেই সারি, যা প্রমাণের ৪ নম্বর ধাপে দেখেছি: p = T, q = F. পঞ্চম সারি distributive সূত্র, আট সারিতেই মিল। ষষ্ঠটি একটি সাধারণ ভুল ধরে: (p ∧ q) → r আর (p → r) ∧ (q → r) এক নয়; p = T, q = F, r = F হলে বাঁ দিক T (কারণ p ∧ q মিথ্যা), ডান দিক F. সঠিক সূত্রটি হলো (p ∧ q) → r ≡ (p → r) ∨ (q → r), যা অংশ ৩-এর তালিকায় আছে। শেষ তিন লাইন kind দিয়ে রাশির ধরন বলে: (p ∧ (p → q)) → q একটি tautology, যা পর্ব ০৬-এর modus ponens নিয়মের ভিত্তি; p ∧ ¬p contradiction; আর (p → q) → p চার সারির দুটিতে সত্য, তাই contingency. মনে রাখবেন, n বাড়লে এই লুপ 2n বার ঘোরে; সেই সমস্যায় অংশ ৭-এ ফিরব।
৩ · Equivalence-এর সূত্র-তালিকা
প্রতিবার truth table বানানো ক্লান্তিকর, আর চলক বাড়লে অসম্ভব। তাই গণিতবিদরা কিছু মৌলিক equivalence একবার প্রমাণ করে তালিকা বানিয়ে রেখেছেন। প্রতিটি সারি এক বা দুই চলকের ছোট truth table দিয়ে প্রমাণ করা যায় (দুই তালিকার প্রতিটি সূত্র Python দিয়ে সব সারিতে মিলিয়েও দেখা হয়েছে)। এখানে T মানে সবসময়-সত্য রাশি (যেমন p ∨ ¬p), আর F মানে সবসময়-মিথ্যা রাশি।
| নাম | ∧-রূপ | ∨-রূপ |
|---|---|---|
| Identity | p ∧ T ≡ p | p ∨ F ≡ p |
| Domination | p ∧ F ≡ F | p ∨ T ≡ T |
| Idempotent | p ∧ p ≡ p | p ∨ p ≡ p |
| Double negation | ¬(¬p) ≡ p | |
| Commutative | p ∧ q ≡ q ∧ p | p ∨ q ≡ q ∨ p |
| Associative | (p ∧ q) ∧ r ≡ p ∧ (q ∧ r) | (p ∨ q) ∨ r ≡ p ∨ (q ∨ r) |
| Distributive | p ∧ (q ∨ r) ≡ (p ∧ q) ∨ (p ∧ r) | p ∨ (q ∧ r) ≡ (p ∨ q) ∧ (p ∨ r) |
| De Morgan | ¬(p ∧ q) ≡ ¬p ∨ ¬q | ¬(p ∨ q) ≡ ¬p ∧ ¬q |
| Absorption | p ∧ (p ∨ q) ≡ p | p ∨ (p ∧ q) ≡ p |
| Negation | p ∧ ¬p ≡ F | p ∨ ¬p ≡ T |
দুটি কলাম পাশাপাশি রাখার একটি কারণ আছে। যে equivalence-এ শুধু ¬, ∧, ∨, T আর F আছে, তাতে ∧ আর ∨ অদলবদল করে এবং T আর F অদলবদল করলে আরেকটি সঠিক equivalence পাওয়া যায়। একে বলে duality principle, আর এজন্যই প্রায় প্রতিটি সূত্র জোড়ায় জোড়ায় আসে। একটি অভ্যাস ভাঙতে হবে: সাধারণ পাটিগণিতে a + (b × c) আর (a + b) × (a + c) সমান নয়, কিন্তু যুক্তিতে ∨-এর ওপর ∧ এবং ∧-এর ওপর ∨, দুই দিকেই distributive সূত্র খাটে।
Conditional আর biconditional-এর জন্য দ্বিতীয় একটি তালিকা কাজে লাগে। এগুলোর প্রথমটি দিয়ে → সরিয়ে বাকিগুলো উপরের তালিকা থেকেই বের করা যায়।
| Conditional | Biconditional |
|---|---|
| p → q ≡ ¬p ∨ q | p ↔ q ≡ (p → q) ∧ (q → p) |
| p → q ≡ ¬q → ¬p | p ↔ q ≡ ¬p ↔ ¬q |
| p ∨ q ≡ ¬p → q | p ↔ q ≡ (p ∧ q) ∨ (¬p ∧ ¬q) |
| ¬(p → q) ≡ p ∧ ¬q | ¬(p ↔ q) ≡ p ↔ ¬q |
| (p → q) ∧ (p → r) ≡ p → (q ∧ r) | p → (q → r) ≡ (p ∧ q) → r |
| (p → r) ∧ (q → r) ≡ (p ∨ q) → r | (p → q) ∨ (p → r) ≡ p → (q ∨ r) |
| (p → r) ∨ (q → r) ≡ (p ∧ q) → r | |
→ commutative-ও নয়, associative-ও নয়। p → q আর q → p আলাদা (অংশ ২)। আর (p → q) → r ≢ p → (q → r): p = F, r = F হলে বাঁ দিকে p → q = T, তাই পুরোটা T → F = F; ডান দিকে p মিথ্যা বলে পুরোটা T. তাই বন্ধনী ছাড়া p → q → r লিখবেন না। পরীক্ষায় সবচেয়ে বেশি ভুল হয় ¬(p → q)-কে ¬p → ¬q লেখায়; সঠিক উত্তর p ∧ ¬q, অর্থাৎ “p ঘটেছে কিন্তু q ঘটেনি”।
এই তালিকা দেখতে পাটিগণিতের নিয়মের মতো, আর তা কাকতালীয় নয়। সেটের union, intersection আর complement-এর জন্যও হুবহু একই আকারের সূত্র আছে (পর্ব ১৫, সেটের অপারেশন — union, intersection, Venn diagram আর identity), আর সবগুলোর পেছনে একটিই কাঠামো, Boolean algebra (পর্ব ৬৯)। Hardware-এর দৃষ্টিকোণ থেকে একই সূত্র কম্পিউটার আর্কিটেকচার ও ডিজিটাল লজিক কোর্সের পর্ব ০৭-এ আছে, যেখানে ∧-কে · আর ∨-কে + লেখা হয়।
যুক্তিকে বীজগণিতের মতো লেখার চিন্তা জনপ্রিয় করেন George Boole, ১৮৪৭ সালের The Mathematical Analysis of Logic আর ১৮৫৪ সালের An Investigation of the Laws of Thought বইয়ে। একই সময়ে Augustus De Morgan ১৮৪৭ সালে Formal Logic প্রকাশ করেন; তাঁর নামে সূত্রগুলো পরিচিত হলেও এদের কোনো কোনো রূপ মধ্যযুগের যুক্তিবিদদের লেখাতেও পাওয়া যায় বলে ইতিহাসবিদরা উল্লেখ করেন। প্রায় একশ বছর পর, ১৯৩৭ সালে Claude Shannon তাঁর master's thesis-এ দেখান যে relay আর switch-এর circuit ঠিক এই বীজগণিত মেনে চলে। সেখান থেকেই digital circuit নকশার আধুনিক পথ শুরু।
৪ · সূত্রের শিকল দিয়ে প্রমাণ
সূত্র-তালিকা হাতে থাকলে truth table ছাড়াই equivalence প্রমাণ করা যায়। পদ্ধতিটি সহজ: এক দিক থেকে শুরু করে প্রতিটি ধাপে একটি সূত্র প্রয়োগ করুন, আর পাশে সূত্রের নাম লিখুন। অংশ ২-এর transitive ধর্মের জন্য শুরু আর শেষের রাশি equivalent হয়। একটি গুরুত্বপূর্ণ কথা: সূত্র একটি উপ-রাশিতেও প্রয়োগ করা যায়। A ≡ B হলে বড় কোনো রাশির ভেতরে A-র জায়গায় B বসালে পুরো রাশির মান কোনো সারিতেই বদলায় না, কারণ প্রতিটি সারিতে A আর B-এর মান সমান।
নিচের stepper-এ একটি পরিচিত পরীক্ষার প্রশ্ন: দেখান যে ¬(p ∨ (¬p ∧ q)) ≡ ¬p ∧ ¬q. প্রতিটি ধাপে শেষ সারিতে চার সারির মান (pq = TT, TF, FT, FF ক্রমে) দেওয়া আছে। খেয়াল করুন, রাশির চেহারা বদলায়, কিন্তু এই কলাম একবারও বদলায় না। Equivalence-এর অর্থ ঠিক এটাই।
| রাশি | |
| সূত্র | |
| ৪ সারির মান |
- শুরু। বাঁ দিকের রাশি। বাইরের ¬ পুরো একটি ∨-এর ওপর বসে আছে, তাই প্রথম কাজ ¬-কে ভেতরে নামানো। চার সারির মান F F F T: শুধু p = F, q = F হলে রাশিটি সত্য।
- De Morgan (দ্বিতীয় রূপ)। ¬(A ∨ B) ≡ ¬A ∧ ¬B, যেখানে A = p আর B = ¬p ∧ q. ফল ¬p ∧ ¬(¬p ∧ q). মান-কলাম একই আছে।
- De Morgan (প্রথম রূপ)। এবার ভেতরের ¬(¬p ∧ q)-তে ¬(A ∧ B) ≡ ¬A ∨ ¬B, তাই এটি হলো ¬¬p ∨ ¬q. সূত্রটি একটি উপ-রাশিতে প্রয়োগ হলো, বাকি অংশ ¬p ∧ অপরিবর্তিত।
- Double negation. ¬¬p ≡ p, তাই ¬p ∧ (p ∨ ¬q). এখন আর কোনো ¬ বন্ধনীর বাইরে বসে নেই।
- Distributive. ¬p-কে বন্ধনীর ভেতরে বণ্টন: ¬p ∧ (p ∨ ¬q) ≡ (¬p ∧ p) ∨ (¬p ∧ ¬q). রাশি লম্বা হলো, কিন্তু এর উদ্দেশ্য আছে: একটি অংশ এখন স্পষ্টতই অসম্ভব।
- Negation সূত্র। ¬p ∧ p হলো p ∧ ¬p-এর commutative রূপ, যা সবসময় মিথ্যা, অর্থাৎ F. ফল F ∨ (¬p ∧ ¬q).
- Commutative আর identity. F ∨ X ≡ X ∨ F ≡ X, তাই ফল ¬p ∧ ¬q, যা ডান দিক। সাত ধাপে কলাম F F F T একবারও বদলায়নি। প্রমাণ সম্পূর্ণ। ∎
এবার শুরুর কুপনের প্রশ্ন। রুমানার রাশি থেকে শুরু করি:
- ¬(¬a ∨ (¬b ∧ ¬c)) ≡ ¬¬a ∧ ¬(¬b ∧ ¬c) (De Morgan)
- ≡ a ∧ ¬(¬b ∧ ¬c) (double negation)
- ≡ a ∧ (¬¬b ∨ ¬¬c) (De Morgan, উপ-রাশিতে)
- ≡ a ∧ (b ∨ c) (double negation, দুবার) ∎
দুই ডেভেলপারের নিয়ম একই; তানভীরের রূপটি পড়তে সহজ, তাই কোডে সেটিই রাখা ভালো। আরেকটি ছোট উদাহরণ পরের অংশে কাজে লাগবে: (p ∧ q) ∨ (p ∧ ¬q) ≡ p ∧ (q ∨ ¬q) (distributive, উল্টো দিকে) ≡ p ∧ T (negation) ≡ p (identity). অর্থাৎ যে দুটি পদ শুধু একটি চলকের চিহ্নে আলাদা, তারা জুড়ে সেই চলকটি বাদ পড়ে।
(১) প্রথমে ↔ আর → সরান (p ↔ q ≡ (p → q) ∧ (q → p), p → q ≡ ¬p ∨ q). (২) De Morgan দিয়ে ¬-কে ভেতরে নামান, যতক্ষণ না প্রতিটি ¬ একটি চলকের ঠিক সামনে বসে; double negation দিয়ে ¬¬ মুছুন। (৩) তারপর লক্ষ্য অনুযায়ী distributive দিয়ে ছড়ান বা গোছান, আর negation, identity, domination, absorption দিয়ে ছোট করুন। Tautology প্রমাণ করতে চাইলে রাশিটিকে T-তে নামিয়ে আনুন।
শিকল-প্রমাণের তিনটি পরিচিত ভুল: (১) ¬(p ∧ q)-কে ¬p ∧ ¬q লেখা, অর্থাৎ ¬ ভেতরে নামানোর সময় ∧-কে ∨-এ না বদলানো। (২) এক ধাপে দুই-তিনটি সূত্র লুকিয়ে প্রয়োগ করা, যাতে পরীক্ষক ধাপটি যাচাই করতে পারেন না। (৩) উল্টো দিক থেকে কাজ করে যে রাশিতে পৌঁছানো হলো, তাকে বিনা কারণে “প্রমাণিত” ধরে নেওয়া। দুই দিক থেকে একই রাশিতে পৌঁছানো বৈধ পদ্ধতি, কিন্তু তখন দুটি শিকলই পুরো লিখতে হয়।
৫ · DNF আর CNF — truth table থেকে normal form
এ পর্যন্ত আমরা রাশি দিয়ে শুরু করে truth table পেয়েছি। উল্টো প্রশ্নটি সমান গুরুত্বপূর্ণ: একটি truth table দেওয়া আছে (যেমন বাজারঘরের product team একটি টেবিলে নিয়ম লিখে দিয়েছে); এমন একটি রাশি লিখুন যার truth table ঠিক এটি। উত্তর দেয় normal form বা প্রমিত রূপ। কয়েকটি শব্দ আগে জেনে নিন।
- Literal: একটি চলক বা তার negation, যেমন p বা ¬q.
- Minterm: n চলকের প্রতিটিকে ঠিক একবার (literal হিসেবে) নিয়ে তৈরি ∧, যেমন p ∧ ¬q ∧ r. এটি truth table-এর ঠিক একটি সারিতে T.
- Clause: কয়েকটি literal-এর ∨, যেমন p ∨ ¬q ∨ r. প্রতিটি চলক ঠিক একবার থাকলে তাকে maxterm বলে; maxterm ঠিক একটি সারিতে F.
- DNF (disjunctive normal form): কয়েকটি literal-∧-এর ∨. CNF (conjunctive normal form): কয়েকটি clause-এর ∧.
উদাহরণ নিয়মটি বাজারঘরের free delivery: p = “অর্ডার ১০০০ টাকার বেশি”, q = “ঠিকানা ঢাকা সিটির ভেতরে”, r = “গ্রাহক প্রিমিয়াম সদস্য”। তিন শর্তের অন্তত দুটি সত্য হলে delivery ফ্রি। ক্রিকেটে তিন আম্পায়ারের সংখ্যাগরিষ্ঠ রায়ের মতো, তাই একে majority function-ও বলে।
| সারি | p | q | r | f (free delivery) |
|---|---|---|---|---|
| ১ | T | T | T | T |
| ২ | T | T | F | T |
| ৩ | T | F | T | T |
| ৪ | T | F | F | F |
| ৫ | F | T | T | T |
| ৬ | F | T | F | F |
| ৭ | F | F | T | F |
| ৮ | F | F | F | F |
তিন চলকের আটটি সারিকে একটি ঘনকের আটটি কোণ হিসেবে আঁকা যায়: প্রতিটি কোণ একটি মান-বিন্যাস, আর পাশাপাশি দুটি কোণ ঠিক একটি চলকে আলাদা। নিচের ছবিতে 1 মানে T আর 0 মানে F.
তিন চলকের truth table একটি ঘনক
The 8 assignments of (p, q, r) as corners of a cube; green corners make the majority rule true
এবার stepper-এ সত্য সারিগুলো থেকে DNF বানানো দেখুন। নিয়ম: সারিতে যে চলক T, সেটি literal হিসেবে যেমন আছে তেমন বসে; যে চলক F, তার আগে ¬ বসে।
| সারি | |
| নতুন পদ | |
| DNF |
- টেবিল পড়া। আটটি সারির চারটিতে f = T: সারি ১, ২, ৩ আর ৫. প্রতিটির জন্য একটি করে minterm লাগবে, যা শুধু সেই সারিতেই T.
- সারি ১ (T, T, T). তিন চলকই T, তাই কোনো ¬ লাগে না: p ∧ q ∧ r. এটি T হয় শুধু যখন তিনটিই T, অর্থাৎ ঠিক সারি ১-এ।
- সারি ২ (T, T, F). r মিথ্যা, তাই r-এর জায়গায় ¬r: p ∧ q ∧ ¬r. DNF-এ ∨ দিয়ে যোগ হলো।
- সারি ৩ (T, F, T). এবার q মিথ্যা: p ∧ ¬q ∧ r.
- সারি ৫ (F, T, T). p মিথ্যা: ¬p ∧ q ∧ r. চারটি minterm-এর ∨-ই free delivery নিয়মের canonical DNF, যার মান ঠিক এই চার সারিতে T.
- একটি মিথ্যা সারি যাচাই। সারি ৪-এ (p = T, q = F, r = F) প্রথম পদে q, দ্বিতীয়তে q, তৃতীয়তে r, চতুর্থতে ¬p মিথ্যা। প্রতিটি পদে অন্তত একটি literal F, তাই চার পদই F, আর DNF-ও F. যেকোনো মিথ্যা সারিতে একই যুক্তি খাটে।
- সরল রূপ। Idempotent সূত্রে p∧q∧r-কে তিনবার লেখা যায়। প্রতিটি কপি একটি পাশের পদের সঙ্গে জুড়ে অংশ ৪-এর নিয়মে একটি চলক হারায়: (p∧q∧r) ∨ (p∧q∧¬r) ≡ p∧q, একইভাবে p∧r আর q∧r. ফল: (p ∧ q) ∨ (p ∧ r) ∨ (q ∧ r), অর্থাৎ “কোনো দুটি শর্ত একসঙ্গে সত্য”। Python দিয়ে আট সারিতেই মিল যাচাই করা হয়েছে।
এই কৌশল যে সবসময় কাজ করে, তা একটি উপপাদ্য।
n চলকের প্রতিটি truth table-এর জন্য একটি DNF রাশি আর একটি CNF রাশি আছে, যাদের truth table ঠিক সেটি। ফলে প্রতিটি যৌগিক proposition একটি DNF আর একটি CNF রাশির সঙ্গে logically equivalent.
প্রমাণ।
- ধরুন টেবিলে অন্তত একটি সারিতে T. প্রতিটি সত্য সারি s-এর জন্য minterm ms নিন: s-এ T চলক literal হিসেবে, F চলক ¬ সহ। (minterm-এর সংজ্ঞা)
- ms সারি s-এ T, কারণ সেখানে এর প্রতিটি literal T. অন্য যেকোনো সারি t-তে কোনো একটি চলক s-এর থেকে আলাদা মান পায়; সেই চলকের literal t-তে F, তাই ms = F. (∧-এর সংজ্ঞা)
- D = সব ms-এর ∨. একটি সারিতে D = T ঠিক তখন, যখন কোনো ms T, অর্থাৎ (ধাপ ২ অনুযায়ী) সারিটি নিজেই একটি সত্য সারি। তাই D-এর টেবিল প্রদত্ত টেবিলের সমান। (∨-এর সংজ্ঞা)
- কোনো সারিতেই T না থাকলে D = p1 ∧ ¬p1 নিন, যা নিজেই একটি DNF (একটি পদ)। (negation সূত্র)
- CNF-এর জন্য উল্টো টেবিল, অর্থাৎ ¬f-এর টেবিলে ধাপ ১–৪ প্রয়োগ করে DNF D′ বানান। তাহলে f ≡ ¬D′. De Morgan দিয়ে ¬-কে ভেতরে নামালে প্রতিটি minterm একটি maxterm হয়ে যায় (∧ হয় ∨, প্রতিটি literal উল্টে যায়), আর বাইরের ∨ হয় ∧. ফল একটি CNF. (De Morgan, double negation)
- প্রদত্ত যৌগিক proposition-এর নিজের truth table-এ ধাপগুলো প্রয়োগ করলে equivalent DNF আর CNF পাওয়া যায়। ∎
ধাপ ৫ ব্যবহারে সহজ একটি নিয়ম দেয়: প্রতিটি মিথ্যা সারির জন্য একটি maxterm লিখুন, যেখানে সারিতে T চলকের আগে ¬ বসে আর F চলক যেমন আছে তেমন। নিচের ব্লক দুটি নিয়মই প্রয়োগ করে, তারপর লেখা রাশিগুলোকে আবার Python রাশিতে বদলে সব সারিতে মিলিয়ে দেখে।
from itertools import product
def free_delivery(p, q, r): # তিনটি শর্তের অন্তত দুটি সত্য
return p + q + r >= 2
def dnf(f, names): # প্রতিটি সত্য সারি → একটি minterm
terms = []
for row in product([True, False], repeat=len(names)):
if f(*row):
terms.append("(" + "∧".join(x if v else "¬" + x for x, v in zip(names, row)) + ")")
return " ∨ ".join(terms)
def cnf(f, names): # প্রতিটি মিথ্যা সারি → একটি maxterm
clauses = []
for row in product([True, False], repeat=len(names)):
if not f(*row):
clauses.append("(" + "∨".join("¬" + x if v else x for x, v in zip(names, row)) + ")")
return " ∧ ".join(clauses)
D, C = dnf(free_delivery, "pqr"), cnf(free_delivery, "pqr")
print("DNF:", D)
print("CNF:", C)
def value(formula, row): # লেখা সূত্রটিকে Python রাশি বানিয়ে মান বের করা
py = formula.replace("¬", " not ").replace("∧", " and ").replace("∨", " or ")
return eval(py, {}, dict(zip("pqr", row)))
rows = list(product([True, False], repeat=3))
print("৮ সারিতেই DNF = CNF = মূল নিয়ম:",
all(value(D, r) == value(C, r) == free_delivery(*r) for r in rows))
# XOR (parity)-এর DNF-এ কয়টি minterm লাগে?
print("parity, n = 1..8:", [sum(1 for r in product([0, 1], repeat=n) if sum(r) % 2)
for n in range(1, 9)])আসল আউটপুট (ব্রাউজারের Python):
DNF: (p∧q∧r) ∨ (p∧q∧¬r) ∨ (p∧¬q∧r) ∨ (¬p∧q∧r)
CNF: (¬p∨q∨r) ∧ (p∨¬q∨r) ∧ (p∨q∨¬r) ∧ (p∨q∨r)
৮ সারিতেই DNF = CNF = মূল নিয়ম: True
parity, n = 1..8: [1, 2, 4, 8, 16, 32, 64, 128]
DNF-এর চারটি পদ stepper-এর চারটি minterm. CNF-এর চার clause চারটি মিথ্যা সারি থেকে এসেছে; যেমন সারি ৪ (T, F, F) দিয়েছে ¬p ∨ q ∨ r, যা শুধু সেই সারিতে F. তৃতীয় লাইন নিশ্চিত করে যে দুটি লেখা রাশি আর মূল নিয়ম আট সারিতেই সমান। শেষ লাইনটি সাবধানবাণী: n চলকের parity (বিজোড় সংখ্যক চলক T হলে T, অর্থাৎ p1 ⊕ p2 ⊕ … ⊕ pn)-এর canonical DNF-এ minterm-এর সংখ্যা 1, 2, 4, …, 128, অর্থাৎ 2n−1.
Canonical DNF বড় হয়, তা স্বাভাবিক; প্রশ্ন হলো সরল করলে কি ছোট হয়? Free delivery-তে চারটি পদ সরল হয়ে তিনটি দুই-literal পদে নেমেছিল। Parity-তে তা হয় না, আর এর একটি সুন্দর প্রমাণ আছে। দাবি: n চলকের parity-র যেকোনো DNF-এ অন্তত 2n−1টি পদ লাগে।
- ধরুন DNF-এর কোনো পদ P-তে একটি চলক x নেই, আর P কোনো সারি s-এ T. (বিপরীত অনুমান)
- s থেকে শুধু x-এর মান উল্টে সারি s′ পান। P-তে x নেই, তাই P সারি s′-এও T, ফলে পুরো DNF s′-এ T. (∨-এর সংজ্ঞা)
- কিন্তু s আর s′-এ T চলকের সংখ্যা ঠিক এক কম-বেশি, তাই একটিতে parity T হলে অন্যটিতে F. DNF আর parity তাই s বা s′-এর অন্তত একটিতে আলাদা, যা অসম্ভব। (P = T বলে s-এ parity T হতেই হবে)
- অতএব প্রতিটি পদে n চলকের সবকটি আছে, আর প্রতিটি পদ ঠিক একটি সারিতে T. 2n−1টি সত্য সারি ঢাকতে অন্তত 2n−1টি পদ লাগে। ∎
হাতে Boolean রাশি সরল করার কাজ (K-map, Quine–McCluskey) circuit-এর দিক থেকে কম্পিউটার আর্কিটেকচার ও ডিজিটাল লজিক কোর্সের পর্ব ১০-এ আছে, আর এর গণিত এই কোর্সের পর্ব ৬৯-এ (Boolean algebra-র গণিত — function, identity আর minimization).
৬ · Functional completeness — NAND একাই যথেষ্ট
উপপাদ্য ৪-এর একটি চমকপ্রদ ফল আছে। DNF-এ শুধু ¬, ∧ আর ∨ লাগে। তাই যেকোনো truth table, অর্থাৎ যেকোনো Boolean function, শুধু এই তিনটি connective দিয়ে লেখা যায়। যে connective-সেটের এই ক্ষমতা আছে, তাকে বলে functionally complete. প্রশ্ন হলো, তিনটির কম দিয়ে কি চলে?
একটি connective-সেট functionally complete, যদি যেকোনো সংখ্যক চলকের যেকোনো truth table-এর একটি রাশি শুধু সেই connective-গুলো দিয়ে লেখা যায়। {¬, ∧, ∨}, {¬, ∧} আর {¬, ∨} functionally complete.
প্রমাণ। {¬, ∧, ∨}-এর কথা উপপাদ্য ৪ থেকে আসে। {¬, ∧}-এর জন্য De Morgan আর double negation থেকে p ∨ q ≡ ¬(¬p ∧ ¬q); তাই DNF-এর প্রতিটি ∨ এভাবে বদলে দিলে শুধু ¬ আর ∧ থাকে। একইভাবে p ∧ q ≡ ¬(¬p ∨ ¬q) থেকে {¬, ∨}. ∎ (একই যুক্তিতে {¬, →}-ও complete, কারণ p ∨ q ≡ ¬p → q.)
এবার আরও এক ধাপ। দুটি নতুন connective: NAND, লেখা হয় p ↑ q, যার অর্থ ¬(p ∧ q); আর NOR, লেখা হয় p ↓ q, যার অর্থ ¬(p ∨ q). ↑ চিহ্নটিকে Sheffer stroke-ও বলে। নিচের stepper দেখায় কীভাবে শুধু NAND দিয়ে ¬, ∧ আর ∨ বানানো যায়।
| লক্ষ্য | |
| রাশি | |
| মান | |
| কারণ |
- NAND-এর টেবিল। p ↑ q = ¬(p ∧ q), তাই শুধু p = q = T সারিতে F, বাকি তিন সারিতে T: কলাম F T T T.
- ¬ বানানো। দুই ইনপুটেই একই p দিন: p ↑ p = ¬(p ∧ p) ≡ ¬p, কারণ idempotent সূত্রে p ∧ p ≡ p. কলাম F F T T, যা ¬p-এর কলাম।
- ∧-এর প্রথম রূপ। Double negation: p ∧ q ≡ ¬¬(p ∧ q) ≡ ¬(p ↑ q). কলাম T F F F. কিন্তু এখানে এখনো একটি ¬ রয়ে গেছে।
- ¬ সরানো। ধাপ ২-এর কৌশল X = p ↑ q-তে প্রয়োগ: ¬X ≡ X ↑ X. ফল (p↑q) ↑ (p↑q), যাতে শুধু ↑ আছে। Circuit-এ এটি দুটি NAND gate.
- যাচাই। চার সারিতে কলাম T F F F, আর p ∧ q-এর কলামও T F F F. মিলে গেছে। যেহেতু {¬, ∧} complete আর দুটিই শুধু ↑ দিয়ে লেখা গেল, {↑} একাই functionally complete.
- বোনাস ∨। De Morgan: p ∨ q ≡ ¬(¬p ∧ ¬q) ≡ (¬p) ↑ (¬q) ≡ (p↑p) ↑ (q↑q). কলাম T T T F, যা p ∨ q. তিনটি NAND gate লাগল।
(ক) {↑} আর {↓} প্রতিটি একাই functionally complete. (খ) {∧, ∨} functionally complete নয়।
প্রমাণ। (ক) NAND-এর কথা stepper-এ দেখানো হলো: ¬p ≡ p ↑ p আর p ∧ q ≡ (p ↑ q) ↑ (p ↑ q), আর {¬, ∧} complete (উপপাদ্য ৫)। NOR-এর জন্য একইভাবে ¬p ≡ p ↓ p আর p ∨ q ≡ (p ↓ q) ↓ (p ↓ q), আর {¬, ∨} complete. (খ)-এর জন্য:
- দাবি: শুধু চলক, ∧ আর ∨ দিয়ে তৈরি যেকোনো রাশি, সব চলক T হলে T. (যা প্রমাণ করতে হবে)
- রাশিটি একটি চলক হলে কথাটি স্পষ্টতই সত্য। (ভিত্তি)
- রাশিটি A ∧ B বা A ∨ B হলে, A আর B ছোট রাশি, আর ধরে নেওয়া যায় দাবিটি তাদের জন্য সত্য: সব চলক T হলে A = T, B = T. তখন T ∧ T = T, T ∨ T = T. (∧, ∨-এর সংজ্ঞা)
- রাশি ছোট থেকে বড় করে এভাবেই গঠিত হয়, তাই দাবিটি সব রাশির জন্য সত্য। এই ধরনের যুক্তির নাম structural induction; পর্ব ১২-এ (Recursive সংজ্ঞা আর structural induction) একে পুরোপুরি নিয়মে বাঁধা হবে।
- কিন্তু ¬p, p = T হলে F. তাই ¬p কোনো {∧, ∨} রাশির সঙ্গে equivalent নয়, আর {∧, ∨} complete নয়। ∎
নিচের ব্লক এই প্রশ্নগুলোকে brute force দিয়ে দেখে। দুই চলকের প্রতিটি function-এর চার সারির কলামকে একটি 4-bit সংখ্যা হিসেবে রাখা হয় (যেমন p = 1100, q = 1010), তারপর p আর q থেকে শুরু করে প্রদত্ত connective বারবার প্রয়োগ করে নতুন কলাম খোঁজা হয়, যতক্ষণ না আর নতুন কিছু আসে। দুই চলকের মোট function 24 = 16টি।
# দুই চলকের প্রতিটি function = ৪ সারির truth table = একটি 4-bit সংখ্যা
# সারির ক্রম: pq = TT, TF, FT, FF
P, Q, ALL = 0b1100, 0b1010, 0b1111
def closure(start, ops):
"""start থেকে শুধু ops বারবার প্রয়োগ করে যত function পাওয়া যায়"""
seen = set(start)
while True:
new = {op(a, b) for a in seen for b in seen for op in ops} - seen
if not new:
return seen
seen |= new
NOT = lambda a, b: ALL & ~a # একটি ইনপুটই লাগে, b উপেক্ষিত
AND = lambda a, b: a & b
OR = lambda a, b: a | b
NAND = lambda a, b: ALL & ~(a & b)
NOR = lambda a, b: ALL & ~(a | b)
XOR = lambda a, b: a ^ b
IFF = lambda a, b: ALL & ~(a ^ b)
sets = [("¬, ∧", [NOT, AND]), ("¬, ∨", [NOT, OR]), ("NAND", [NAND]),
("NOR", [NOR]), ("∧, ∨", [AND, OR]), ("⊕, ↔", [XOR, IFF])]
for name, ops in sets:
got = closure({P, Q}, ops)
print(f"{name:<6} → {len(got):2d}/16", "functionally complete" if len(got) == 16 else "")
print("∧, ∨ দিয়ে পাওয়া:", sorted(format(x, "04b") for x in closure({P, Q}, [AND, OR])))আসল আউটপুট (ব্রাউজারের Python):
¬, ∧ → 16/16 functionally complete
¬, ∨ → 16/16 functionally complete
NAND → 16/16 functionally complete
NOR → 16/16 functionally complete
∧, ∨ → 4/16
⊕, ↔ → 8/16
∧, ∨ দিয়ে পাওয়া: ['1000', '1010', '1100', '1110']
প্রথম চার সেট থেকে ষোলোটি function-ই পাওয়া গেছে, উপপাদ্য ৫ আর ৬(ক)-এর সঙ্গে মিল। {∧, ∨} থেকে মাত্র চারটি: 1000 (p ∧ q), 1010 (q), 1100 (p) আর 1110 (p ∨ q). প্রতিটির প্রথম bit 1, অর্থাৎ TT সারিতে T; উপপাদ্য ৬(খ)-এর প্রমাণ ঠিক এই ধর্মটিই ব্যবহার করে। {⊕, ↔} থেকে আটটি আসে, কিন্তু ∧ আসে না; কারণটি “আরও গভীরে” বাক্সে। মনে রাখবেন, এই ব্লক শুধু দুই চলকের function দেখে, তাই এটি উদাহরণ, প্রমাণ নয়; সব n-এর জন্য দাবি প্রমাণ করে উপরের উপপাদ্যগুলো।
১৯১৩ সালে Henry M. Sheffer একটি গবেষণাপত্রে দেখান যে Boolean algebra একটিমাত্র connective দিয়েই লেখা যায়; তাঁর নামেই “Sheffer stroke”. Charles Sanders Peirce এর অনেক আগে, ১৮৮০-র দিকে, একই পর্যবেক্ষণ লিখে রেখেছিলেন বলে জানা যায়, কিন্তু তা অপ্রকাশিত ছিল আর পরে প্রকাশিত হয়; NOR-কে তাই অনেক সময় Peirce arrow বলা হয়। Hardware-এ NAND আর NOR-কে universal gate বলে; CMOS-এ কেন NAND সস্তা, তা কম্পিউটার আর্কিটেকচার ও ডিজিটাল লজিক কোর্সের পর্ব ০৮-এ আছে।
৭ · Satisfiability — SAT, 2n সারি আর NP-completeness-এর প্রথম দেখা
Tautology-র উল্টো দিকের প্রশ্নটি কম্পিউটার বিজ্ঞানের অন্যতম কেন্দ্রীয় প্রশ্ন: রাশিটি কি অন্তত একবার সত্য হতে পারে?
একটি যৌগিক proposition satisfiable, যদি চলকগুলোর অন্তত একটি মান-বিন্যাসে এর মান T হয়; সেই বিন্যাসকে একটি সমাধান বা satisfying assignment বলে। কোনো বিন্যাসেই T না হলে রাশিটি unsatisfiable, অর্থাৎ contradiction. “দেওয়া রাশি satisfiable কি না” প্রশ্নটির নাম SAT; রাশি সাধারণত CNF-এ দেওয়া থাকে।
সংজ্ঞাগুলো একে অপরের সঙ্গে খুব ঘনিষ্ঠ। নিচের তিনটি কথা সরাসরি সংজ্ঞা থেকে আসে, কারণ ¬ প্রতিটি সারির মান উল্টে দেয়:
- A tautology ⇔ ¬A unsatisfiable.
- A ≡ B ⇔ A ↔ B tautology ⇔ ¬(A ↔ B) unsatisfiable.
- A satisfiable ⇔ A contradiction নয় ⇔ ¬A tautology নয়।
অর্থাৎ equivalence যাচাই আর satisfiability আসলে একই প্রশ্নের দুই রূপ: একটির দ্রুত পদ্ধতি পেলে অন্যটিরও পাওয়া যায়। পর্ব ০২-এ যে specification-এর consistency দেখেছেন, সেটিও SAT: বাজারঘরের সব নিয়ম একসঙ্গে মানা যায় কি না, মানে নিয়মগুলোর ∧ satisfiable কি না।
নিচের ব্লকটি clause-কে সংখ্যার তালিকায় লেখে, যেভাবে SAT solver-রা লেখে (DIMACS ধারা): 3 মানে চলক ৩, আর −3 মানে ¬(চলক ৩)। যেমন [−3, 1] হলো ¬x3 ∨ x1, অর্থাৎ x3 → x1. বাজারঘরের delivery-র পাঁচটি নিয়ম: ঠিক একটি slot বেছে নিতে হবে (প্রথম দুই clause); express হলে সকালের slot; express আর cash on delivery একসঙ্গে নয়; আর অর্ডারটি হয় express, নয়তো cash on delivery.
from itertools import product
import random
def count_models(cnf, n):
"""সব 2**n assignment যাচাই: কয়টি CNF-কে সত্য করে, আর প্রথমটি কোনটি"""
count, first = 0, None
for bits in product([False, True], repeat=n):
if all(any(bits[abs(l) - 1] == (l > 0) for l in cl) for cl in cnf):
count += 1
first = first or "".join("1" if b else "0" for b in bits)
return count, first
# 1 = সকালের slot, 2 = বিকেলের slot, 3 = express, 4 = cash on delivery
spec = [[1, 2], [-1, -2], [-3, 1], [-3, -4], [3, 4]]
print("নিয়ম ৫টি:", count_models(spec, 4))
print("আরও দুটি নিয়ম যোগ করলে:", count_models(spec + [[-1], [-4]], 4))
random.seed(7)
n, m = 12, 50
f = [[random.choice([-1, 1]) * v for v in random.sample(range(1, n + 1), 3)]
for _ in range(m)]
c, first = count_models(f, n)
print(f"এলোমেলো 3-CNF, n={n}, m={m}: {2**n}টি সারি দেখে {c}টি সমাধান, প্রথম {first}")
for n in (20, 40, 60, 80, 100):
sec = 2**n / 1e9 # সেকেন্ডে 10^9 সারি দেখলে
print(f"n={n:3d}: {2**n:.2e} সারি, {sec:.1e} সেকেন্ড ≈ {sec / 31_536_000:.1e} বছর")আসল আউটপুট (ব্রাউজারের Python):
নিয়ম ৫টি: (3, '0101')
আরও দুটি নিয়ম যোগ করলে: (0, None)
এলোমেলো 3-CNF, n=12, m=50: 4096টি সারি দেখে 2টি সমাধান, প্রথম 001011010111
n= 20: 1.05e+06 সারি, 1.0e-03 সেকেন্ড ≈ 3.3e-11 বছর
n= 40: 1.10e+12 সারি, 1.1e+03 সেকেন্ড ≈ 3.5e-05 বছর
n= 60: 1.15e+18 সারি, 1.2e+09 সেকেন্ড ≈ 3.7e+01 বছর
n= 80: 1.21e+24 সারি, 1.2e+15 সেকেন্ড ≈ 3.8e+07 বছর
n=100: 1.27e+30 সারি, 1.3e+21 সেকেন্ড ≈ 4.0e+13 বছর
পাঁচ নিয়মে ষোলো বিন্যাসের তিনটি গ্রহণযোগ্য; প্রথমটি 0101, অর্থাৎ বিকেলের slot আর cash on delivery. বাকি দুটি 1001 (সকাল, cash on delivery) আর 1010 (সকাল, express). এরপর দুটি নতুন নিয়ম, “সকালে delivery নেই” আর “cash on delivery বন্ধ”, যোগ করলে সমাধান শূন্য: তখন অর্ডারটিকে express হতে হয়, express-এর জন্য সকালের slot লাগে, আর সকাল নিষেধ। Specification স্ববিরোধী হয়ে গেছে, আর এই প্রোগ্রাম তা ধরেছে। তৃতীয় লাইনে seed 7 দিয়ে বানানো এলোমেলো 3-CNF (প্রতি clause-এ তিনটি literal, বারো চলকে পঞ্চাশটি clause): 4096টি সারির মাত্র দুটি সমাধান। শেষ পাঁচ লাইন হিসাবটি বড় করে দেখায়: সেকেন্ডে একশ কোটি সারি দেখতে পারে এমন যন্ত্রও n = 40-এ প্রায় ১৮ মিনিট, n = 60-এ প্রায় ৩৭ বছর, আর n = 100-এ প্রায় 4 × 1013 বছর নেবে। বাস্তবের circuit বা সফটওয়্যারের সূত্রে চলক থাকে হাজার থেকে লাখে।
তাহলে SAT কি আসলে কঠিন, নাকি আমরা চালাক পদ্ধতি এখনো খুঁজে পাইনি? এখানে দুটি কাজের পার্থক্য লক্ষ করুন। কেউ একটি সমাধান হাতে দিলে তা যাচাই করা সহজ: প্রতিটি clause-এ একটি সত্য literal আছে কি না দেখা, রাশির আকারের প্রায় সমান সময়ে। কিন্তু সমাধান খুঁজে বের করার জন্য কোনো দ্রুত পদ্ধতি জানা নেই। যেসব হ্যাঁ/না প্রশ্নের “হ্যাঁ” উত্তরের প্রমাণ polynomial সময়ে (চলকের সংখ্যার কোনো নির্দিষ্ট ঘাতের মধ্যে) যাচাই করা যায়, তাদের শ্রেণিকে বলে NP.
১৯৭১ সালে Stephen Cook “The Complexity of Theorem-Proving Procedures” গবেষণাপত্রে প্রমাণ করেন যে NP-এর প্রতিটি সমস্যাকে polynomial সময়ে SAT-এর একটি উদাহরণে রূপান্তর করা যায়। প্রায় একই সময়ে সোভিয়েত ইউনিয়নে Leonid Levin স্বাধীনভাবে কাছাকাছি ফল পান (প্রকাশিত হয় ১৯৭৩ সালে বলে সাধারণত উল্লেখ করা হয়); তাই ফলটির নাম Cook–Levin উপপাদ্য। এর ফলে SAT হলো প্রথম প্রমাণিত NP-complete সমস্যা: SAT-এর একটি দ্রুত (polynomial) সমাধান পাওয়া গেলে NP-এর সব সমস্যারই দ্রুত সমাধান হবে। পরের বছর, ১৯৭২ সালে, Richard Karp আরও ২১টি পরিচিত সমস্যাকে NP-complete দেখান। এমন দ্রুত পদ্ধতি আছে কি না, অর্থাৎ P = NP কি না, আজও অমীমাংসিত।
সব SAT সমান কঠিন নয়। প্রতিটি clause-এ বড়জোর দুটি literal থাকলে (2-SAT) polynomial সময়ের, এমনকি linear সময়ের algorithm জানা আছে; ঠিক তিনটি literal-এর 3-SAT-ই NP-complete. P, NP, reduction আর NP-completeness-এর পুরো কাঠামো algorithm-এর দিক থেকে DSA কোর্সের পর্ব ৬৪-এ আছে, আর বাস্তবে এমন সমস্যার মোকাবিলা পর্ব ৬৫-এ। মজার ব্যাপার হলো, তত্ত্বে কঠিন হলেও আধুনিক SAT solver অনেক বাস্তব instance বিপুল আকারেও দ্রুত সমাধান করে; একটি আসল solver চালিয়ে দেখবেন পর্ব ০৭-এ (কাজে যুক্তি — specification, ধাঁধা আর SAT solver), আর software যাচাইয়ে এর ব্যবহার পর্ব ৭৭-এ।
আরও গভীরে: যেকোনো রাশিকে equivalent CNF-এ আনলে আকার exponential হতে পারে (অংশ ৫-এর parity-র মতো)। Tseitin-এর রূপান্তর প্রতিটি উপ-রাশির জন্য একটি নতুন চলক যোগ করে প্রায় linear আকারের CNF দেয়, যা মূল রাশির equivalent নয় কিন্তু equisatisfiable: একটি satisfiable হলে অন্যটিও; SAT solver-এর সামনে রাশি এভাবেই যায়। কোন connective-সেট functionally complete, তার সম্পূর্ণ উত্তর দেন Emil Post (১৯৪১ সালে প্রকাশিত কাজে): একটি সেট complete ঠিক তখন, যখন সেটি পাঁচটি বিশেষ শ্রেণির কোনোটির ভেতরে আটকে থাকে না, যার একটি হলো “affine” function (⊕ আর ধ্রুবক দিয়ে লেখা যায়); এজন্যই {⊕, ↔} থেকে ∧ আসেনি। আর NP-complete সমস্যার জন্য exponential সময় সত্যিই লাগে কি না, অর্থাৎ P ≠ NP কি না, গণিতের সবচেয়ে বিখ্যাত খোলা প্রশ্নগুলোর একটি।
পরীক্ষা ও ইন্টারভিউতে: এই ধরনের প্রশ্ন বিশ্ববিদ্যালয়, চাকরি বা ইন্টারভিউর পরীক্ষায় প্রায়ই আসে।
- truth table দিয়ে দেখান (p → q) ∧ (q → r) → (p → r) একটি tautology. উত্তর: আট সারির প্রতিটিতে T; অথবা সূত্রের শিকলে T-তে নামান।
- ¬(p → q)-এর সরল রূপ লিখুন। উত্তর: p ∧ ¬q (conditional সূত্র, তারপর De Morgan আর double negation).
- প্রদত্ত truth table থেকে canonical DNF আর CNF লিখুন। উত্তর: সত্য সারি থেকে minterm-এর ∨, মিথ্যা সারি থেকে maxterm-এর ∧.
- দেখান NAND functionally complete. উত্তর: ¬p ≡ p ↑ p, p ∧ q ≡ (p ↑ q) ↑ (p ↑ q), আর {¬, ∧} complete.
- A ≡ B যাচাইকে SAT প্রশ্নে বদলান। উত্তর: ¬(A ↔ B) unsatisfiable কি না জিজ্ঞেস করুন।
৮ · AI-এর যুগে equivalence যাচাইয়ের অভ্যাস
AI assistant-কে “এই দুটি শর্ত কি একই?” বা “এই রাশিটি সরল করে দাও” জিজ্ঞেস করলে দ্রুত, আত্মবিশ্বাসী উত্তর আসে। সমস্যা হলো, ভুল উত্তরও একই আত্মবিশ্বাসে আসে, আর যুক্তির ভুল চোখে ধরা কঠিন, কারণ প্রতিটি লাইন দেখতে বিশ্বাসযোগ্য। সুখবর হলো, এই পর্বের বিষয়ে যাচাই প্রায় বিনামূল্যে: কয়েক চলকের যেকোনো দাবি অংশ ২-এর ব্লকের মতো দশ লাইনের Python দিয়ে সব সারিতে মিলিয়ে দেখা যায়।
| AI-এর সাধারণ ভুল | কীভাবে ধরবেন |
|---|---|
| ¬(p ∧ q)-কে ¬p ∧ ¬q লেখা, বা ¬(p → q)-কে ¬p → ¬q | p = T, q = F সারি বসিয়ে দেখুন; সব সারিতে মেলানোর ব্লক চালান |
| Converse আর contrapositive গুলিয়ে ফেলা, ফলে উল্টো দিকের দাবি “প্রমাণ” করা | প্রমাণের শেষে লেখা দাবি আর চাওয়া দাবি অক্ষরে অক্ষরে মেলান |
| এক ধাপে কয়েকটি সূত্র লুকিয়ে প্রয়োগ, বা ভুল নামের সূত্র উল্লেখ | প্রতিটি ধাপের জন্য সূত্রের নাম চান, আর তালিকার সঙ্গে মেলান |
| CNF বানাতে গিয়ে একটি clause বাদ পড়া বা literal উল্টে যাওয়া | ফলাফলকে মূল রাশির সঙ্গে সব সারিতে মেলান; clause-এর সংখ্যা মিথ্যা সারির সংখ্যার সঙ্গে মেলান |
| “SAT সাধারণভাবে দ্রুত সমাধান করা যায়” বা P বনাম NP মীমাংসিত বলে দাবি | উৎস চান; DSA কোর্সের পর্ব ৬৪-এর সঙ্গে মেলান; অচেনা reference নিজে খুঁজে দেখুন |
| উপপাদ্য তার শর্ত ছাড়া বলা, যেমন duality-কে → থাকা রাশিতে প্রয়োগ | “এই উপপাদ্যের শর্ত কী?” জিজ্ঞেস করুন; একটি counterexample খুঁজুন |
AI-কে দিয়ে প্রমাণ লেখাতে চাইলে এমনভাবে বলুন যাতে প্রতিটি ধাপ যাচাইযোগ্য হয়, আর সঙ্গে নিজে চালানোর মতো একটি পরীক্ষাও চান:
AI-এর দেওয়া যুক্তি হাতে পেলে — যাচাইয়ের চেকলিস্ট
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন, তারপর “→ উত্তর” চাপুন।
প্র ০১Truth table দিয়েই যদি যেকোনো equivalence প্রমাণ করা যায়, তবে সূত্রের শিকল শেখার দরকার কী?
Truth table একটি সম্পূর্ণ সিদ্ধান্ত-পদ্ধতি (decision procedure): যেকোনো দুটি propositional রাশি নিলে সসীম সময়ে নিশ্চিত হ্যাঁ বা না বলে দেয়। তবু তিনটি কারণে সূত্রের শিকল অপরিহার্য।
- আকার: n চলকে 2nটি সারি। পাঁচ চলকে ৩২টি সারি হাতে লেখা যায়, কিন্তু ত্রিশ চলকে প্রায় একশ কোটি সারি। অন্যদিকে শিকল-প্রমাণ অনেক সময় চলকের সংখ্যার ওপর নির্ভর করে না: ¬(p ∧ q) ≡ ¬p ∨ ¬q সূত্রে p আর q-এর জায়গায় যত বড় রাশিই বসান (অংশ ১-এর প্রতিস্থাপন), এক লাইনেই কাজ শেষ।
- সাধারণীকরণ: একই সূত্র সেটের union আর intersection-এ (পর্ব ১৫), quantifier-এ (পর্ব ০৪-এ ∀ আর ∃-এর De Morgan), আর যেকোনো Boolean algebra-য় খাটে, যেখানে “সারি” গোনা যায় না বা অসীম। ১৮৫৪ সালে Boole যুক্তিকে বীজগণিত হিসেবে দেখাতে চেয়েছিলেন ঠিক এই কারণে: নিয়ম একবার জানলে সব জায়গায় ব্যবহার করা যায়।
- বোঝা আর বোঝানো: Truth table বলে যে দুটি রাশি এক; শিকল দেখায় কেন এক, আর কোন অংশ বাদ পড়ল। Code review-তে একটি জটিল if-শর্ত কেন সরল রূপের সমান, তা সহকর্মীকে বোঝাতে শিকলই কাজে আসে।
বাস্তবে দুটি পদ্ধতি একসঙ্গে চলে। Compiler আর computer algebra system রাশি সরল করতে rewriting rule, অর্থাৎ এই সূত্রগুলোই ব্যবহার করে, আর যন্ত্রে equivalence যাচাইয়ের সময় (যেমন chip নকশায় দুটি circuit একই কাজ করে কি না) SAT solver বা অন্য প্রতীকী পদ্ধতি লাগে, কারণ সারি গোনা অসম্ভব। পরীক্ষাতেও প্রশ্নে প্রায়ই বলে দেওয়া থাকে “truth table ব্যবহার না করে প্রমাণ করুন”, যাতে সূত্রের ওপর দখল যাচাই হয়।
মূল উপলব্ধি: Truth table হলো নিশ্চিত কিন্তু ধীর পরীক্ষক; সূত্রের শিকল হলো দ্রুত, সাধারণ আর ব্যাখ্যাযোগ্য প্রমাণ। ভালো গণিতজ্ঞ ছোট ক্ষেত্রে টেবিল দিয়ে যাচাই করেন আর প্রমাণ লেখেন সূত্র দিয়ে।
প্র ০২একটিমাত্র NAND দিয়ে সব যুক্তি লেখা যায় — এই গাণিতিক সত্যের প্রকৌশলে গুরুত্ব কী?
উপপাদ্য ৬ গাণিতিক দিক থেকে ছোট একটি ফল, কিন্তু প্রকৌশলে এর প্রভাব বিশাল। কোনো chip কারখানাকে যদি শুধু একটি ধরনের gate নিখুঁতভাবে বানাতে হয়, তাহলে নকশা, পরীক্ষা আর উৎপাদন সবই সহজ হয়। CMOS প্রযুক্তিতে একটি NAND gate বানাতে লাগে চারটি transistor; AND বানাতে সাধারণত NAND-এর পরে একটি NOT জুড়তে হয়, তাই AND আসলে NAND-এর চেয়ে বড় আর ধীর। এজন্যই digital নকশায় NAND আর NOR-কে “universal gate” বলা হয়, আর অনেক standard cell library-র ভিত্তি এই দুটি।
ইতিহাসে একটি পরিচিত উদাহরণ Apollo মিশনের guidance computer, যার logic প্রায় পুরোটাই একই ধরনের NOR gate-এর integrated circuit দিয়ে তৈরি বলে বর্ণনা করা হয়। ১৯৬০-এর দশকে integrated circuit নতুন আর অনিশ্চিত ছিল; একই ধরনের একটি chip বিপুল সংখ্যায় কিনে আর পরীক্ষা করে নির্ভরযোগ্যতা বাড়ানো সহজ ছিল।
গাণিতিক দিক থেকে প্রশ্নটি আরও গভীরে যায়। Sheffer ১৯১৩ সালে দেখান যে Boolean algebra-র সব axiom একটি connective দিয়ে লেখা যায়; Peirce আগেই একই কথা লিখে রেখেছিলেন বলে জানা যায়, কিন্তু প্রকাশ করেননি। কোন connective-সেট যথেষ্ট, তার পূর্ণ উত্তর দেন Emil Post: পাঁচটি শ্রেণি আছে (যেমন “সব চলক T হলে T থাকে”, যে ধর্ম উপপাদ্য ৬(খ)-এ ব্যবহার করেছি), আর একটি সেট complete ঠিক তখন, যখন তা এই শ্রেণিগুলোর কোনোটির ভেতরে পুরোপুরি আটকে থাকে না। NAND পাঁচটি শ্রেণি থেকেই বেরিয়ে যায়, তাই একাই যথেষ্ট।
তবে “একাই যথেষ্ট” মানে “সবচেয়ে ভালো” নয়। শুধু NAND দিয়ে ∨ বানাতে তিনটি gate লাগে, যেখানে একটি OR gate একাই কাজটি করে। বাস্তব নকশায় তাই নানা gate মিলিয়ে ব্যবহার হয়, আর synthesis সফটওয়্যার সূত্রের শিকলের মতো rewriting দিয়ে সবচেয়ে ছোট বা দ্রুত রূপ খোঁজে।
মূল উপলব্ধি: Functional completeness বলে কী সম্ভব; খরচ, গতি আর নির্ভরযোগ্যতা ঠিক করে কী ব্যবহারযোগ্য। গণিত সম্ভাবনার সীমানা আঁকে, প্রকৌশল সেই সীমানার ভেতরে সবচেয়ে ভালো পথটি বাছে।
প্র ০৩একই function-এর DNF আর CNF আকারে এত আলাদা হয় কেন, আর SAT solver কেন CNF-ই চায়?
অংশ ৫-এ দেখেছেন, parity-র যেকোনো DNF-এ 2n−1টি পদ লাগে। উল্টো দিকেরও একটি পরিচিত উদাহরণ আছে: (x1 ∨ y1) ∧ (x2 ∨ y2) ∧ … ∧ (xn ∨ yn) রাশিটি CNF-এ মাত্র nটি clause, কিন্তু distributive সূত্র দিয়ে DNF-এ খুললে প্রতিটি বন্ধনী থেকে একটি করে literal বাছাইয়ের 2nটি উপায়, আর এর কোনোটি বাদ দেওয়া যায় না। তাই একটি রূপ থেকে অন্যটিতে যাওয়ার খরচ exponential হতে পারে; কোনো একটি রূপ সবসময় ছোট নয়।
দুই রূপের শক্তিও আলাদা। DNF-এর satisfiability দেখা খুব সহজ: যেকোনো একটি পদে p আর ¬p একসঙ্গে না থাকলে সেই পদ সত্য করা যায়, ফলে পুরো রাশি satisfiable. CNF-এর tautology যাচাইও সমান সহজ: প্রতিটি clause-এ কোনো p আর ¬p জোড়া থাকতে হবে। কঠিন কাজটি উল্টো জোড়ায়: CNF-এর satisfiability (SAT) আর DNF-এর tautology. তাহলে কি রাশিকে DNF-এ এনে SAT সহজে সমাধান করা যায়? না, কারণ রূপান্তরই exponential হতে পারে। কঠিনতা কোথাও উধাও হয় না, শুধু জায়গা বদলায়।
SAT solver CNF চায় ব্যবহারিক কারণে। বাস্তব নিয়মগুলো স্বাভাবিকভাবেই “এগুলোর প্রতিটি মানতে হবে” ধরনের, অর্থাৎ শর্তের ∧. প্রতিটি clause একটি ছোট, স্বাধীন শর্ত, যা “unit propagation”-এর মতো কৌশলে খুব দ্রুত পরীক্ষা করা যায়। আর যেকোনো রাশিকে Tseitin-এর রূপান্তরে (১৯৬০-এর দশকের শেষ দিকের কাজ বলে সাধারণত উল্লেখ করা হয়) নতুন সহায়ক চলক যোগ করে প্রায় একই আকারের CNF-এ আনা যায়। এই CNF মূল রাশির equivalent নয়, কিন্তু equisatisfiable, আর SAT-এর প্রশ্নের জন্য সেটুকুই যথেষ্ট। AI-এর ভিত্তি কোর্সের পর্ব ৪৫-এ knowledge base-কে CNF-এ এনে resolution চালানোর কাজে একই কৌশল দেখবেন।
মূল উপলব্ধি: “Equivalent” আর “equisatisfiable” আলাদা প্রতিশ্রুতি। প্রশ্ন কী চায়, তা ঠিক করে কোন প্রতিশ্রুতি যথেষ্ট; দুর্বল প্রতিশ্রুতি মেনে নিলে অনেক সময় exponential খরচ থেকে বাঁচা যায়।
প্র ০৪SAT প্রশ্নটি এত সরল দেখায়, তবু এটি কম্পিউটার বিজ্ঞানের এত কেন্দ্রীয় কেন?
প্রশ্নটি সত্যিই সরল: কয়েকটি true/false চলক, কয়েকটি শর্ত, সব শর্ত একসঙ্গে মানা যায় কি না। কিন্তু Cook ১৯৭১ সালে দেখান যে এই সরল প্রশ্নের ভেতরে NP-এর সব সমস্যা লুকিয়ে আছে। মূল ধারণা: NP-এর যেকোনো সমস্যার “হ্যাঁ” উত্তর যাচাই করে এমন একটি যন্ত্রের ধাপে ধাপে কাজকে true/false চলক আর clause দিয়ে বর্ণনা করা যায়; যন্ত্রটি গ্রহণ করে এমন কোনো সাক্ষী আছে কি না, এ প্রশ্নটি তখন রাশির satisfiability-র প্রশ্ন হয়ে যায়। Leonid Levin স্বাধীনভাবে একই ধরনের ফলে পৌঁছান বলে উপপাদ্যটি দুজনের নামে পরিচিত।
এর পরের বছর Richard Karp ১৯৭২ সালে দেখান যে graph coloring, clique, Hamiltonian cycle, knapsack-এর মতো ২১টি পরিচিত সমস্যাও NP-complete, প্রতিটিকে SAT থেকে বা একে অপর থেকে রূপান্তর করে। হঠাৎ করে আলাদা আলাদা ক্ষেত্রের অনেক কঠিন সমস্যা একই সুতোয় বাঁধা পড়ল: একটির দ্রুত সমাধান মানে সবগুলোর দ্রুত সমাধান। পরে হাজার হাজার সমস্যা এই তালিকায় যোগ হয়েছে, আর এই কোর্সেও পর্ব ৬০ (Euler আর Hamilton path) আর পর্ব ৬৩-তে (Graph coloring) এদের দেখা পাবেন।
P = NP কি না, এই প্রশ্ন ২০০০ সালে Clay Mathematics Institute-এর Millennium Prize সমস্যার তালিকায় রাখা হয়। বেশিরভাগ গবেষক মনে করেন P ≠ NP, কিন্তু প্রমাণ নেই। মজার বৈপরীত্য হলো, তত্ত্বে কঠিন হলেও বাস্তবে SAT solver অসাধারণ সফল: hardware যাচাই, software-এর bug খোঁজা, সময়সূচি বানানো, এমনকি কিছু package manager-এ কোন library-র কোন version একসঙ্গে বসানো যায়, তা নির্ধারণেও SAT solver ব্যবহার হয়। কারণ, বাস্তব instance-এ এমন কাঠামো থাকে যা চালাক search কাজে লাগাতে পারে; worst case কঠিন হলেও সব case কঠিন নয়।
আরেকটি দিক: NP-complete হওয়ার অর্থ এই নয় যে ছোট বা বিশেষ ধরনের instance কঠিন। 2-SAT আর Horn clause-এর SAT polynomial সময়ে হয়। তাই কোনো সমস্যা NP-complete শুনে হাল ছাড়ার আগে জিজ্ঞেস করুন, আপনার instance-এর বিশেষ কাঠামো আছে কি না।
মূল উপলব্ধি: SAT হলো কঠিন সমস্যাগুলোর “সাধারণ ভাষা”। কোনো সমস্যাকে SAT-এ রূপান্তর করতে পারা মানে দুটি জিনিস একসঙ্গে জানা: সমস্যাটি সাধারণভাবে কত কঠিন হতে পারে, আর বাস্তবে কোন শক্তিশালী যন্ত্র দিয়ে আক্রমণ করা যায়।
প্র ০৫প্রোগ্রামের if-শর্তে De Morgan আর commutative সূত্র কি সবসময় নিরাপদে খাটে?
গণিতের সূত্রগুলো প্রমাণিত হয়েছে একটি নির্দিষ্ট জগতে: প্রতিটি রাশির মান ঠিক T বা F, মান বের করতে কোনো পার্শ্বপ্রতিক্রিয়া (side effect) নেই, আর কোনো রাশি ব্যর্থ হয় না। প্রোগ্রামে এর প্রতিটি শর্ত ভাঙতে পারে, আর তখন সূত্রগুলোও সাবধানে ব্যবহার করতে হয়।
- Short-circuit evaluation: Python, C, Java-তে
and/&&বাঁ দিক মিথ্যা হলে ডান দিক আর হিসাবই করে না।x != 0 and 10 / x > 1নিরাপদ, কিন্তু commutative সূত্র মেনে উল্টে লিখলে10 / x > 1 and x != 0, x = 0 হলে ZeroDivisionError. যুক্তিতে p ∧ q ≡ q ∧ p, কিন্তু প্রোগ্রামে ক্রম অর্থ বহন করে। - NaN: floating point-এ NaN-এর সঙ্গে প্রতিটি তুলনা মিথ্যা। তাই x = NaN হলে
not (x < y)সত্য, কিন্তুx >= yমিথ্যা। “x < y-এর negation হলো x ≥ y” সূত্রটি ধরে নেয় যে দুটি সংখ্যা সবসময় তুলনীয়। - SQL-এর NULL: SQL তিন-মানের যুক্তি (true, false, unknown) ব্যবহার করে।
WHERE a = 1 OR NOT (a = 1)লিখলে যেসব সারিতে a NULL, সেগুলো বাদ পড়ে, অর্থাৎ p ∨ ¬p এখানে tautology নয়। - Truthy মান: Python-এর
and/orTrue/False না দিয়ে একটি operand ফেরত দেয়;[] or "default"-এর মান "default". সত্যতা একই থাকলেও ফেরত আসা মান বদলাতে পারে।
তাহলে কি সূত্রগুলো প্রোগ্রামে অকেজো? একদমই না। Compiler-গুলো প্রতিনিয়ত এগুলো দিয়ে কোড সরল করে, কিন্তু শুধু তখনই, যখন প্রমাণ করা যায় যে কোনো side effect, exception বা বিশেষ মান নেই। আপনার কাজও একই: শর্ত সরল করার আগে দেখুন রাশিগুলো “বিশুদ্ধ” কি না, অর্থাৎ কোনো function call কিছু বদলায় কি না, শূন্য দিয়ে ভাগের মতো ব্যর্থ হওয়ার পথ আছে কি না, আর মান সবসময় সত্য বা মিথ্যা কি না। পর্ব ০৭-এ (কাজে যুক্তি — specification, ধাঁধা আর SAT solver) if-শর্ত সরল করার এমন উদাহরণ ধাপে ধাপে দেখবেন।
মূল উপলব্ধি: প্রতিটি উপপাদ্য তার শর্তের ভেতরেই সত্য। দুই-মানের, পার্শ্বপ্রতিক্রিয়াহীন জগতে প্রমাণিত সূত্র প্রোগ্রামে ব্যবহারের আগে জিজ্ঞেস করুন, সেই শর্তগুলো এখানে মানা হচ্ছে কি না।
অনুশীলন
আগে খাতায় নিজে করুন, তারপর উত্তর মেলান। ছোট দাবিগুলো Python দিয়েও যাচাই করতে পারেন।
-
প্রমাণ: truth table ব্যবহার না করে প্রমাণ করুন — (ক) (p ∧ q) → (p ∨ q) একটি tautology; (খ) ¬(p → q) ≡ p ∧ ¬q.
(ক)
- (p ∧ q) → (p ∨ q) ≡ ¬(p ∧ q) ∨ (p ∨ q) (conditional সূত্র)
- ≡ (¬p ∨ ¬q) ∨ (p ∨ q) (De Morgan)
- ≡ (¬p ∨ p) ∨ (¬q ∨ q) (associative আর commutative, কয়েকবার)
- ≡ (p ∨ ¬p) ∨ (q ∨ ¬q) (commutative)
- ≡ T ∨ T (negation)
- ≡ T (domination) ∎
(খ) ¬(p → q) ≡ ¬(¬p ∨ q) (conditional) ≡ ¬¬p ∧ ¬q (De Morgan) ≡ p ∧ ¬q (double negation). ∎ অর্থে: “যদি p তবে q” মিথ্যা হয় ঠিক তখন, যখন p ঘটেছে অথচ q ঘটেনি।
-
গণনা: (ক) তিন চলক p, q, r-এর কতগুলো ভিন্ন truth table (Boolean function) আছে? এদের কতগুলো tautology, আর কতগুলো satisfiable? (খ) (p ∨ q) ∧ (¬p ∨ r) ∧ (q ∨ ¬r)-এর কয়টি satisfying assignment আছে, কোনগুলো? এর canonical DNF-এ কয়টি minterm আর canonical CNF-এ কয়টি maxterm থাকবে?
(ক) তিন চলকে 23 = ৮টি সারি; প্রতিটি সারিতে function-এর মান T বা F, দুটি পছন্দ। গুণের নিয়মে 28 = ২৫৬টি function. সাধারণভাবে n চলকে 22nটি; n = 4 হলে 65536. এদের মাত্র একটি tautology (সব সারিতে T), আর একটি contradiction (সব সারিতে F), তাই satisfiable ২৫৬ − ১ = ২৫৫টি।
(খ) দুই ভাগে দেখুন। p = T হলে দ্বিতীয় clause থেকে r = T লাগে, তখন তৃতীয় clause থেকে q = T: একটি সমাধান (T, T, T). p = F হলে প্রথম clause থেকে q = T, আর তখন তৃতীয় clause আপনাআপনি সত্য, দ্বিতীয়টিও (¬p = T): r যেকোনো, দুটি সমাধান (F, T, T) আর (F, T, F). মোট ৩টি; Python-এ brute force দিয়েও ৩টিই পাওয়া গেছে। Canonical DNF-এ ৩টি minterm (প্রতি সত্য সারিতে একটি), আর canonical CNF-এ ৮ − ৩ = ৫টি maxterm.
-
প্রমাণের ভুল খুঁজুন: একজন শিক্ষার্থী লিখেছেন: “¬(p ∧ (q ∨ r)) ≡ ¬p ∧ ¬(q ∨ r) (De Morgan) ≡ ¬p ∧ ¬q ∧ ¬r (De Morgan).” কোন ধাপে ভুল, সঠিক উত্তর কী, আর একটি counterexample দিন।
প্রথম ধাপেই ভুল। ¬(A ∧ B) ≡ ¬A ∨ ¬B; ¬ ভেতরে নামানোর সময় ∧ বদলে ∨ হয়। সঠিক শিকল: ¬(p ∧ (q ∨ r)) ≡ ¬p ∨ ¬(q ∨ r) (De Morgan) ≡ ¬p ∨ (¬q ∧ ¬r) (De Morgan). দ্বিতীয় ধাপটি নিজে ঠিক ছিল, কিন্তু ভুল রাশির ওপর প্রয়োগ হয়েছে।
Counterexample: p = F, q = T, r = F. মূল রাশি: q ∨ r = T, p ∧ T = F, তাই ¬F = T. শিক্ষার্থীর উত্তর: ¬p ∧ ¬q ∧ ¬r = T ∧ F ∧ T = F. দুই মান আলাদা, তাই দাবিটি ভুল। সঠিক উত্তর ¬p ∨ (¬q ∧ ¬r) = T ∨ … = T, মূলের সঙ্গে মেলে; আট সারিতেই মিল Python-এ যাচাই করা হয়েছে।
-
আউটপুট অনুমান করুন: চালানোর আগে খাতায় হিসাব করুন, নিচের প্রোগ্রাম কী ছাপবে, আর কেন।
from itertools import product rows = list(product([True, False], repeat=3)) a = sum(1 for p, q, r in rows if (p or q) and (not p or r)) b = sum(1 for p, q, r in rows if q or r) print(a, b, a <= b)আউটপুট (ডেস্কটপে CPython 3.14 দিয়ে চালানো):
4 6 Trueaগোনে (p ∨ q) ∧ (¬p ∨ r)-এর সত্য সারি: p = T হলে r = T লাগে, q যেকোনো (২টি); p = F হলে q = T লাগে, r যেকোনো (২টি); মোট ৪.bগোনে q ∨ r: আট সারির মধ্যে শুধু q = F, r = F-এর দুটি সারি (p = T বা F) বাদ, তাই ৬. প্রথম রাশি যে চারটি সারিতে সত্য, তার প্রতিটিতে q ∨ r-ও সত্য: দুই clause-এ p আর ¬p কেটে দিলে q ∨ r থাকে। এই “কেটে দেওয়া” নিয়মটির নাম resolution, যা পর্ব ০৬-এ (অনুমানের নিয়ম — modus ponens থেকে resolution) আসছে।
নিজেকে যাচাই করুন
ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।
ক্রমTruth table থেকে canonical CNF বানানোর ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)
- সব চলকের সব মান-বিন্যাসসহ truth table লেখা
- যেসব সারিতে রাশির মান F, শুধু সেগুলো বেছে নেওয়া
- প্রতিটি মিথ্যা সারির জন্য maxterm লেখা: সারিতে T চলকের আগে ¬, F চলক যেমন আছে
- সব maxterm ∧ দিয়ে জোড়া
- ফলাফলকে সব সারিতে মূল টেবিলের সঙ্গে মিলিয়ে যাচাই করা
¬(p ∧ q)-এর সঙ্গে logically equivalent কোনটি?
- ¬p ∧ ¬q
- ¬p ∨ ¬q
- p ∨ q
- ¬p → ¬q
p → q-এর সঙ্গে কোনটি logically equivalent?
- q → p
- ¬p → ¬q
- ¬q → ¬p
- p ∧ ¬q
(p → q) ∨ (q → p) রাশিটি কোন ধরনের?
- Tautology
- Contradiction
- Contingency
- এটি proposition নয়, তাই কোনো ধরনেই পড়ে না
নিচের কোন connective-সেট functionally complete নয়?
- {NAND}
- {¬, ∨}
- {NOR}
- {∧, ∨}
তিন চলকের একটি রাশির truth table-এর ৮টি সারির ৩টিতে মান T. এর canonical DNF-এ কয়টি minterm, আর canonical CNF-এ কয়টি maxterm থাকবে?
- ৩টি minterm, ৩টি maxterm
- ৩টি minterm, ৫টি maxterm
- ৫টি minterm, ৩টি maxterm
- ৮টি minterm, ৮টি maxterm
৩০টি চলকের একটি CNF রাশি satisfiable কি না, সব মান-বিন্যাস একে একে দেখে যাচাই করলে সবচেয়ে খারাপ ক্ষেত্রে প্রায় কতটি বিন্যাস দেখতে হবে?
- ৬০টি
- ৯০০টি
- প্রায় ১০⁹ (2³⁰)টি
- অসীম সংখ্যক
শব্দকোষ
লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন — অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:
মনে রাখুন
- Tautology সব সারিতে T, contradiction সব সারিতে F, বাকিগুলো contingency; A tautology ⇔ ¬A contradiction.
- p ≡ q মানে truth table-এর কলাম এক, অর্থাৎ p ↔ q tautology; “equivalent নয়” দেখাতে একটি counterexample সারিই যথেষ্ট।
- De Morgan: ¬(p ∧ q) ≡ ¬p ∨ ¬q, ¬(p ∨ q) ≡ ¬p ∧ ¬q; আর p → q ≡ ¬p ∨ q ≡ ¬q → ¬p, কিন্তু converse-এর সমান নয়।
- সত্য সারি থেকে DNF, মিথ্যা সারি থেকে CNF; {¬, ∧}, {¬, ∨}, {NAND}, {NOR} functionally complete, {∧, ∨} নয়।
- SAT: n চলকে 2n সারি; A ≡ B যাচাই মানে ¬(A ↔ B) unsatisfiable কি না; SAT প্রথম প্রমাণিত NP-complete সমস্যা (Cook, ১৯৭১)।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পর্ব ০৪ · Predicate logic আর quantifier — "সব" আর "কোনো একটি" লেখাপরবর্তী পর্বPredicate, ∀ আর ∃, quantifier-এর negation আর অনুবাদ।
- ডিসক্রিট ম্যাথমেটিক্স · কোর্স হোম৮৩টি পর্বপুরো কোর্সের রোডম্যাপ — কোন পর্ব কখন।
- AI-এর ভিত্তি আর Python for AI · পর্ব ৪৫পাশের ট্র্যাকKnowledge base, CNF আর resolution — AI agent-এর যুক্তিতে একই logic.
- ডেটা স্ট্রাকচার ও অ্যালগরিদম · পর্ব ৬৪গভীরে যানP বনাম NP, reduction আর NP-complete সমস্যার algorithm-এর দিক।
- কম্পিউটার আর্কিটেকচার ও ডিজিটাল লজিক · পর্ব ০৮পাশের ট্র্যাকNAND আর NOR universal gate, transistor দিয়ে logic.