সরাসরি পর্বে যান
পর্ব ০৯ · ৬২-এর মধ্যে · মডিউল ২

K-map দিয়ে সরলীকরণ — ২ থেকে ৪ চলক, don't care

Karnaugh Maps — Gray-Code Adjacency, Grouping Rules, Prime & Essential Prime Implicants, Don't Cares, POS and NAND/NOR Forms

Taught in Bangla, this lesson explains why minimisation saves gates and why K-maps work through Gray-code adjacency and wrap-around, draws 2-, 3- and 4-variable maps, forms and reads groups, finds minimal SOP systematically with prime and essential prime implicants in worked examples, uses don't cares for BCD and seven-segment circuits, derives POS by grouping zeros, converts to NAND–NAND and NOR–NOR, and checks every answer with a hands-on K-map simulator.

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

  • কেন সরলীকরণ দরকার, আর খরচ কীভাবে মাপা হয় — literal, term, gate, delay আর power
  • K-map কেন কাজ করে — Gray ক্রম, পাশাপাশি ঘরের সূত্র XY + XY′ = X, আর কেন দলের আকার ২-এর ঘাত
  • ২, ৩ আর ৪ চলকের map আঁকা, ঘরের নম্বর মনে রাখা, কোণ আর কিনারা পেরোনো দল চেনা
  • prime আর essential prime implicant দিয়ে পদ্ধতিগতভাবে minimal SOP আর POS বের করা — একাধিক সঠিক উত্তর থাকলেও
  • don't care দিয়ে BCD আর 7-segment circuit সরল করা, NAND–NAND/NOR–NOR-এ রূপ দেওয়া, আর script দিয়ে প্রতিটি উত্তর যাচাই করা

১ · কেন সরলীকরণ — কম literal মানে কম gate, কম খরচ

পর্ব ০৭-এ দেখেছেন, যেকোনো truth table থেকে সরাসরি একটি রাশি লেখা যায়: যে সারিতে আউটপুট 1, সেই সারির minterm লিখে সবগুলো OR করে দিলেই হলো। এই রূপকে বলে canonical SOP (sum of products). রাশিটি সবসময় সঠিক — কিন্তু প্রায়ই অনেক বড়।

একটি উদাহরণ নিন। চার চলকের (A, B, C, D; A হলো সবচেয়ে বাঁয়ের বিট) একটি Boolean function F = Σm(0, 1, 2, 5, 8, 9, 10) — অর্থাৎ সারি ০, ১, ২, ৫, ৮, ৯ আর ১০-এ আউটপুট 1. Canonical রূপে এখানে ৭টি minterm, প্রতিটিতে ৪টি করে literal (চলক বা তার উল্টো রূপ): মোট ২৮টি literal, ৭টি চার-ইনপুটের AND gate আর একটি সাত-ইনপুটের OR gate. এই পর্বের শেষে একই function দাঁড়াবে B′D′ + B′C′ + A′C′D — মাত্র ৭টি literal, তিনটি ছোট AND আর একটি তিন-ইনপুটের OR.

এই পর্বের লেখার রীতি: complement (উল্টো মান) লেখা হবে prime চিহ্নে — A′ মানে “A নয়”। Product term মানে কয়েকটি literal-এর AND (পাশাপাশি লেখা, যেমন A′C′D), আর + মানে OR. কোডের আউটপুটে একই জিনিস সাধারণ apostrophe দিয়ে আসবে: A'C'D. Minterm-এর নম্বর হলো চলকগুলোকে ABCD ক্রমে binary সংখ্যা হিসেবে পড়লে যা হয় — m5 = 0101 = A′BC′D.

খরচ মাপার একক

বাস্তব chip-এ “ছোট রাশি” মানে কী? দুই স্তরের (two-level) AND-OR circuit-এ মোটামুটি এই হিসাব চলে:

যা মাপিcircuit-এ যা বোঝায়কেন কমানো দরকার
term-এর সংখ্যাপ্রথম স্তরে কয়টি AND gate, আর শেষ OR gate-এর ইনপুট (fan-in)কম gate মানে কম জায়গা; ছোট fan-in-এর gate দ্রুত
literal-এর সংখ্যাAND gate-গুলোর মোট ইনপুট — প্রতিটি ইনপুট মানে transistor আর তারCMOS-এ প্রতিটি ইনপুটে মোটামুটি দুটি transistor লাগে (পর্ব ০৮)
স্তরের সংখ্যাসংকেতকে কয়টি gate পেরোতে হয়propagation delay যোগ হয়, তাই circuit-এর গতি কমে
switchingপ্রতিটি gate বদলানোর সময় চার্জ ভরা-খালিকম gate মানে কম power — মোবাইলে বেশি charge থাকে

এই পর্বে “minimal” বলতে প্রচলিত পাঠ্যবইয়ের সংজ্ঞা নেব: প্রথমে term সবচেয়ে কম, তারপর literal সবচেয়ে কম — দুই স্তরের SOP বা POS-এর মধ্যে। ওপরের উদাহরণে canonical রূপ ৭ term ২৮ literal, minimal রূপ ৩ term ৭ literal. NAND দিয়ে বানালে (পর্ব ০৮), complement করা ইনপুট আগে থেকেই আছে ধরে নিয়ে মোটামুটি হিসাব: canonical রূপে ৭টি চার-ইনপুটের NAND (৫৬ transistor) আর একটি সাত-ইনপুটের NAND (১৪ transistor) — প্রায় ৭০টি; minimal রূপে (২ + ২ + ৩) × ২ = ১৪ আর তিন-ইনপুটের NAND-এ ৬ — প্রায় ২০টি। একটি ছোট function-এই সাড়ে তিন গুণ পার্থক্য।

সুইচবোর্ডের উপমা: ধরুন একটি বাতি জ্বলবে সাতটি আলাদা সুইচ-সমন্বয়ে। মিস্ত্রি চাইলে প্রতিটি সমন্বয়ের জন্য আলাদা তার টেনে দিতে পারেন — কাজ করবে, কিন্তু দেয়ালে তারের জঙ্গল। বুদ্ধিমান মিস্ত্রি লক্ষ্য করেন, “A আর C যা-ই থাকুক, B বন্ধ আর D বন্ধ থাকলেই বাতি জ্বলে” — একটি ছোট শর্তে চারটি সমন্বয় একসাথে ধরা পড়ে। K-map ঠিক এই ধরনের মিল চোখে দেখার যন্ত্র।

পর্ব ০৭-এর Boolean algebra-র সূত্র দিয়েও একই কাজ করা যায়। কিন্তু algebra-য় দুটি সমস্যা: কোন সূত্র কোন ক্রমে লাগাবেন তার কোনো নির্দিষ্ট নিয়ম নেই, আর শেষে পৌঁছে জানা যায় না যে আরও ছোট করা সম্ভব কি না। K-map চার চলক পর্যন্ত দুটি সমস্যাই মিটিয়ে দেয় — চোখের সামনে সব সম্ভাব্য দল দেখা যায়, আর একটি পদ্ধতি মানলে minimal উত্তর নিশ্চিত।

২ · K-map-এর মূল ধারণা — পাশাপাশি ঘর, Gray ক্রম আর torus

সরলীকরণের প্রায় পুরোটাই দাঁড়িয়ে আছে একটি ছোট সূত্রের ওপর, যাকে বলে combining theorem:

X·Y + X·Y′ = X·(Y + Y′) = X·1 = X

অর্থাৎ দুটি product term যদি ঠিক একটি চলকে আলাদা হয় — একটিতে Y, অন্যটিতে Y′, বাকি সব হুবহু এক — তাহলে দুটি মিলে একটি term হয়, আর সেই চলকটি বাদ পড়ে। যেমন A′B′C′D′ (m0) + A′B′C′D (m1) = A′B′C′. এমন দুটি minterm-কে বলে logically adjacent (যৌক্তিকভাবে পাশাপাশি)। Binary নকশায় এর মানে তাদের Hamming distance ১।

সমস্যা হলো, truth table-এ এই “পাশাপাশি” সারিগুলো পাশাপাশি থাকে না। ৪ চলকে m0 (0000)-এর পাশাপাশি minterm চারটি: m1, m2, m4 আর m8 — truth table-এ ছড়িয়ে আছে সারি ১, ২, ৪ আর ৮-এ। Karnaugh map (K-map)-এর বুদ্ধি হলো truth table-এর ঘরগুলোকে একটি ছকে এমনভাবে সাজানো যাতে যৌক্তিক পাশাপাশি = কাগজে পাশাপাশি।

কেন 00, 01, 11, 10 — সাধারণ ক্রম কেন নয়

দুটি চলক (ধরুন C আর D) দিয়ে কলাম বানাতে হলে চারটি কলাম লাগে। সাধারণ গণনার ক্রমে লিখলে 00, 01, 10, 11 — কিন্তু 01 থেকে 10-এ যেতে দুটি বিটই বদলায়। তখন কাগজে পাশাপাশি দুটি ঘর যৌক্তিকভাবে পাশাপাশি নয়, আর উল্টোভাবে 01 আর 11 যৌক্তিকভাবে পাশাপাশি হলেও কাগজে দূরে। সমাধান হলো Gray code-এর ক্রম: 00, 01, 11, 10 — প্রতি ধাপে ঠিক একটি বিট বদলায় (পর্ব ০৪-এর Gray code অংশে এর নিয়ম দেখেছেন)। আর এই ক্রমের একটি বিশেষ গুণ আছে: শেষ 10 থেকে আবার প্রথম 00-তে ফিরতেও মাত্র একটি বিট বদলায়। Gray code চক্রাকার।

ফলাফল: সবচেয়ে ডানের কলাম সবচেয়ে বাঁয়ের কলামের পাশাপাশি, আর সবচেয়ে নিচের সারি সবচেয়ে ওপরের সারির পাশাপাশি। কাগজটিকে প্রথমে নল বানিয়ে ডান-বাঁ কিনারা জুড়ে দিন, তারপর নলটিকে বাঁকিয়ে ওপর-নিচ জুড়ে দিন — পাবেন একটি ডোনাট, গণিতের ভাষায় torus. চার চলকের K-map আসলে একটি torus, যাকে কেটে সমান করে কাগজে বিছানো হয়েছে। এ কারণেই চারটি কোণের ঘর একে অপরের পাশাপাশি — যা প্রথমবার দেখলে অদ্ভুত লাগে।

ছোট প্রমাণ — কেন দলের আকার ২-এর ঘাত

ধরুন n চলকের একটি product term-এ n−k টি literal আছে, আর k টি চলক অনুপস্থিত। অনুপস্থিত k টি চলক যেকোনো মান নিতে পারে, তাই term-টি ঠিক ২kটি minterm-এ 1 হয়। উল্টো দিকে, ঐ ২kটি minterm-এর যোগফল = (স্থির literal-গুলোর গুণফল) × Π(x + x′) — প্রতিটি অনুপস্থিত চলক x-এর জন্য একটি (x + x′) = 1 উৎপাদক — অর্থাৎ শুধু স্থির literal-গুলোর গুণফল। তাই একটি product term = ঠিক ২kটি ঘরের একটি দল, যেখানে k টি চলক সব রকম মান নেয় আর বাকিগুলো স্থির। ৩টি বা ৬টি ঘর কখনো একটি term হতে পারে না। আর Gray ক্রমের কারণে এমন প্রতিটি ঘরের সেট map-এ একটি আয়তক্ষেত্র (কিনারা পেরিয়ে হলেও) হয়ে দেখা দেয়।

একটু ইতিহাস: ছক এঁকে Boolean function সরল করার ধারণা সাধারণত দুজনের নামে জড়িত। Edward Veitch ১৯৫২ সালে একটি “chart method” প্রকাশ করেন, যেখানে truth table-এর ঘর ছকে সাজানো হয়েছিল। এক বছর পর, ১৯৫৩ সালে Bell Labs-এর প্রকৌশলী Maurice Karnaugh তাঁর “map method” প্রকাশ করেন — মূল পার্থক্য ছিল সারি-কলামকে Gray ক্রমে সাজানো, যাতে পাশাপাশি থাকা চোখে দেখা যায়। আজ যে ছকটি সবাই আঁকেন, সেটি মূলত Karnaugh-এর রূপ; কিছু বইয়ে একে Veitch diagram বা KV-map-ও বলা হয়। এর আগে উনিশ শতকে যুক্তিবিদ Allan Marquand-এর আঁকা যুক্তির ছককে অনেকে এই ধারণার পূর্বসূরি বলে উল্লেখ করেন।

৩ · ২, ৩ আর ৪ চলকের map — ঘরের নম্বর, দলের নিয়ম আর দল পড়া

K-map-এ প্রতিটি ঘর truth table-এর একটি সারি। নিচের ছকগুলোতে প্রতিটি ঘরে লেখা আছে সেটি কোন minterm. সারির চলকগুলো বাঁয়ে, কলামের চলকগুলো ওপরে, আর দুটোই Gray ক্রমে। Minterm-এর নম্বর = (সারির বিট)(কলামের বিট) একসাথে binary হিসেবে পড়লে যা হয়।

২ চলক (A, B) — ৪টি ঘর

A \ B01
0m0 (A′B′)m1 (A′B)
1m2 (AB′)m3 (AB)

৩ চলক (A | BC) — ৮টি ঘর

A \ BC00011110
0m0m1m3m2
1m4m5m7m6

৪ চলক (AB | CD) — ১৬টি ঘর

AB \ CD00011110
00m0m1m3m2
01m4m5m7m6
11m12m13m15m14
10m8m9m11m10

মনে রাখার কৌশল: প্রতিটি সারিতে সংখ্যাগুলো “০ ১ ৩ ২” ছাঁচে চলে — শেষ দুটি অদলবদল। আর সারিগুলোও একই ছাঁচে: ওপরে ০–৩, তারপর ৪–৭, তারপর ১২–১৫, শেষে ৮–১১. পরীক্ষার খাতায় সবচেয়ে বেশি ভুল হয় এখানেই — m2 আর m3, বা ৮–১১ আর ১২–১৫-এর সারি অদলবদল হয়ে যায়। Map ভরার আগে প্রতিবার ছোট করে ঘরের নম্বর লিখে নিন।

দল বানানোর নিয়ম

  1. আকার ২-এর ঘাত: ১, ২, ৪, ৮ বা ১৬টি ঘর (অংশ ২-এর প্রমাণ)। ৩, ৫, ৬ চলে না।
  2. আয়তাকার: ১×২, ২×২, ১×৪, ২×৪, ৪×৪ — সারি বা কলাম ধরে, কোনাকুনি কখনো নয়। কোনাকুনি দুটি ঘর দুটি চলকে আলাদা।
  3. কিনারা পেরোনো চলে: বাঁ আর ডান কিনারা পাশাপাশি, ওপর আর নিচ পাশাপাশি; চারটি কোণ মিলে একটি ৪-এর দল হতে পারে।
  4. শুধু 1 (আর দরকার হলে X): দলে কোনো 0 থাকবে না।
  5. প্রতিটি 1 অন্তত একবার ঢাকা: একটি 1 একাধিক দলে থাকতে পারে — overlap করা সম্পূর্ণ বৈধ, কারণ X + X = X.
  6. দল যত বড় সম্ভব: প্রতিবার দল দ্বিগুণ হলে একটি literal কমে।
  7. দলের সংখ্যা যত কম সম্ভব: যে দলের সব 1 অন্য দলে ঢাকা পড়ে গেছে, সেটি বাদ।

দলকে product term হিসেবে পড়া

একটি দলের ভেতরে ঘুরে দেখুন কোন চলকের মান বদলায়। যে চলক বদলায় (কোথাও 0, কোথাও 1), সেটি বাদ। যে চলক পুরো দলে 1 থাকে, সেটি সরাসরি লিখুন; যে চলক পুরো দলে 0 থাকে, সেটি complement করে লিখুন। ৪ চলকে:

দলের আকারযত চলক বাদ পড়েterm-এ literalউদাহরণ
১ ঘর০৪m5 → A′BC′D
২ ঘর১৩m1, m5 → A′C′D (B বদলায়)
৪ ঘর২২m0, m2, m8, m10 (চার কোণ) → B′D′
৮ ঘর৩১ওপরের দুই সারি m0–m7 → A′
১৬ ঘর৪০সব ঘর 1 → F = 1

চার কোণের দলটি একবার মিলিয়ে নিন: m0 = 0000, m2 = 0010, m8 = 1000, m10 = 1010. A বদলায় (0 ও 1), C বদলায়; B সবসময় 0, D সবসময় 0. তাই term = B′D′. Map-এ চারটি ঘর অনেক দূরে মনে হলেও torus-এ তারা একটি ২×২ বর্গ।

৪ · সমাধান করা উদাহরণ — ৩ চলক থেকে কোণ-কিনারার ৪ চলক

উদাহরণ ১: F(A, B, C) = Σm(0, 2, 5, 7)

প্রথমে map ভরুন। m0 আর m2 ওপরের সারিতে (A = 0), কলাম 00 আর 10-এ; m5 আর m7 নিচের সারিতে (A = 1), কলাম 01 আর 11-এ।

A \ BC   00   01   11   10
  0       1    0    0    1      <- m0, m2 : two edges of the same row
  1       0    1    1    0      <- m5, m7 : neighbours in the middle

ওপরের সারিতে m0 আর m2 দেখতে দূরে, কিন্তু ডান-বাঁ কিনারা পেরিয়ে পাশাপাশি: 000 আর 010 — শুধু B আলাদা। দল (0, 2): A = 0, C = 0 স্থির → A′C′. নিচের সারিতে m5 = 101 আর m7 = 111 — শুধু B আলাদা। দল (5, 7): A = 1, C = 1 → AC. কোনো ৪-এর দল সম্ভব নয়, কারণ যেকোনো ২×২-এ অন্তত একটি 0 পড়ে।

F = A′C′ + AC  (= A ⊙ C, অর্থাৎ A XNOR C) — ৪ literal, canonical রূপে ছিল ১২

লক্ষ্য করুন, B একেবারে উধাও — আউটপুট B-এর ওপর নির্ভরই করে না। Truth table-এ এটি চোখে পড়া কঠিন, K-map-এ এক নজরে ধরা পড়ে। আর A′C′ + AC মানে “A আর C সমান হলে 1” — ⊕ (XOR)-এর উল্টো, XNOR. তিন বা তার বেশি চলকের XOR (যেমন A ⊕ B ⊕ C) K-map-এ দাবার ছকের মতো দেখায় — কোনো দুটি 1 পাশাপাশি নেই, তাই K-map একটি literal-ও কমাতে পারে না। তখন XOR gate সরাসরি ব্যবহার করাই সস্তা (পর্ব ১১-এর adder-এ দেখবেন)।

উদাহরণ ২: F(A, B, C, D) = Σm(0, 1, 2, 5, 8, 9, 10) — কোণ আর কিনারার ক্লাসিক

এটি সম্ভবত সবচেয়ে বেশি পরীক্ষায় আসা ধরনের map, কারণ এতে তিন রকম ফাঁদ একসাথে আছে: চার কোণ, ওপর-নিচ কিনারা পেরোনো দল, আর একটি একা পড়ে থাকা 1. নিচের stepper-এ ধাপে ধাপে দেখুন — চিহ্নিত ঘরগুলো এই ধাপের দল, আর P, Q, R লেখা দেখায় কোন 1 কোন দলে পড়েছে।

ধাপ ১map-এ 1 বসানো
AB\CD   00    01    11    10
 00     1     1     0     1
 01     0     1     0     0
 11     0     0     0     0
 10     1     1     0     1
ones: m0 m1 m2 m5 m8 m9 m10  (7 ones)
ধাপ ২চার কোণ → P
AB\CD   00    01    11    10
 00     1P    1     0     1P
 01     0     1     0     0
 11     0     0     0     0
 10     1P    1     0     1P
P = m0 m2 m8 m10 : B=0, D=0 fixed  -> B'D'
ধাপ ৩ওপর-নিচ কিনারা → Q
AB\CD   00    01    11    10
 00     1PQ   1Q    0     1P
 01     0     1     0     0
 11     0     0     0     0
 10     1PQ   1Q    0     1P
Q = m0 m1 m8 m9 : B=0, C=0 fixed  -> B'C'
ধাপ ৪বাকি m5 → R
AB\CD   00    01    11    10
 00     1PQ   1QR   0     1P
 01     0     1R    0     0
 11     0     0     0     0
 10     1PQ   1Q    0     1P
R = m1 m5 : A=0, C=0, D=1 fixed  -> A'C'D
ধাপ ৫উত্তর আর যাচাই
F = B'D' + B'C' + A'C'D
P = B'D'  -> m0 m2 m8 m10
Q = B'C'  -> m0 m1 m8 m9
R = A'C'D -> m1 m5
union     -> m0 m1 m2 m5 m8 m9 m10   = all 7 ones, no 0
cost: 3 terms, 7 literals   (canonical: 7 terms, 28 literals)
  1. Map ভরা। সাতটি 1 বসান: ওপরের সারিতে m0, m1, m2; দ্বিতীয় সারিতে m5; নিচের সারিতে m8, m9, m10. খেয়াল করুন, নিচের সারিটি AB = 10 (m8–m11), তৃতীয়টি AB = 11 (m12–m15) — এই ক্রম ভুল হলে পুরো উত্তর ভুল।
  2. চার কোণ — দল P. m0, m2, m8, m10 চারটি কোণে। Torus-এ এরা একটি ২×২ বর্গ: A আর C বদলায়, B = 0 আর D = 0 সব জায়গায় স্থির। তাই P = B′D′ — ৪ ঘরের দল, ২টি literal.
  3. ওপর-নিচ কিনারা — দল Q. প্রথম দুই কলামের ওপরের সারি (m0, m1) আর নিচের সারি (m8, m9) ওপর-নিচ কিনারা পেরিয়ে একটি ২×২ বর্গ। A আর D বদলায়, B = 0, C = 0 স্থির → Q = B′C′. m0 আর m8 এখন দুই দলে — overlap বৈধ।
  4. বাকি m5 — দল R. m5 = 0101-এর চারটি প্রতিবেশী m1, m4, m7, m13; শুধু m1-এ 1. তাই m5-কে m1-এর সাথে জোড়া বানাতেই হবে: A = 0, C = 0, D = 1 স্থির, B বদলায় → R = A′C′D. এটিকে ৪-এর দলে বড় করা যায় না, কারণ (1, 5, 3, 7), (0, 1, 4, 5) আর (1, 5, 9, 13) — প্রতিটিতে অন্তত একটি 0 আছে।
  5. উত্তর ও যাচাই। F = B′D′ + B′C′ + A′C′D. তিনটি দলের মিলিত ঘর ঠিক সাতটি 1-ই, কোনো 0 নেই। প্রতিটি দল আর বড় করা যায় না, আর প্রতিটিই কোনো একটি 1-কে একা ঢাকে (m2 শুধু P-তে, m9 শুধু Q-তে, m5 শুধু R-এ) — তাই তিনটিই অপরিহার্য, আর এটিই একমাত্র minimal উত্তর: ৩ term, ৭ literal.

একটি অভ্যাস তৈরি করুন: সবচেয়ে “একা” 1 থেকে শুরু করুন। যে 1-এর মাত্র একটি দিকে বড় হওয়ার পথ আছে (যেমন এখানে m5), তার দল নিয়ে কোনো সিদ্ধান্তের সুযোগ নেই — সেটি আগে বসালে পরে ভুল হয় না। আর কোণ ও কিনারা সবসময় আলাদা করে যাচাই করুন — এগুলো চোখ এড়িয়ে যাওয়াই সবচেয়ে সাধারণ ভুল।

উদাহরণ ৩: একটি ৮-এর দল আর একটি জোড়া — F(A, B, C, D) = Σm(0–9), অর্থাৎ “BCD অঙ্কটি বৈধ কি না”

৪ বিটে ০ থেকে ১৫ লেখা যায়, কিন্তু BCD-তে শুধু ০–৯ বৈধ। V = 1 যখন ইনপুট ০–৯. ওপরের দুই সারি (m0–m7) পুরো 1 — একটি ৮-এর দল, যেখানে শুধু A = 0 স্থির → A′. নিচের সারিতে m8 আর m9 বাকি; এদের সবচেয়ে বড় দল ওপরের সারির m0, m1-এর সাথে ওপর-নিচ কিনারা পেরিয়ে (0, 1, 8, 9) → B′C′. উত্তর V = A′ + B′C′ — মাত্র ৩ literal. লক্ষ্য করুন, m0 আর m1 দুই দলেই আছে: m8, m9-কে বড় দলে নেওয়ার জন্য এই overlap দরকার। শুধু (8, 9) নিলে term হতো AB′C′ — একটি বাড়তি literal.

৫ · Implicant, prime implicant, essential prime implicant — পদ্ধতিগত উপায়

ছোট map-এ চোখে দেখে দল বানানো যায়। কিন্তু কোনো কোনো map-এ চোখ প্রতারণা করে — সবচেয়ে বড় দলটি নিয়েও minimal উত্তর পাওয়া যায় না। তাই পাঠ্যবই আর পরীক্ষা একটি পদ্ধতিগত উপায় চায়, যার জন্য তিনটি সংজ্ঞা লাগে:

Implicant

এমন product term যা যেখানে 1 হয় সেখানে F-ও 1 (বা X). K-map-এ: শুধু 1/X দিয়ে বানানো যেকোনো বৈধ দল — একটি ঘরও।

m5 = A′BC′D একটি implicant

Prime implicant (PI)

এমন implicant যা আর বড় করা যায় না — কোনো literal বাদ দিলেই কোনো 0 ঢুকে পড়ে। K-map-এ: এমন দল, যাকে আর দ্বিগুণ করা যায় না।

A′C′D একটি PI; A′BC′D নয়

Essential PI (EPI)

এমন PI যা অন্তত একটি 1-কে একাই ঢাকে — অন্য কোনো PI সেই 1-কে ঢাকে না। প্রতিটি minimal উত্তরে থাকতেই হবে।

m5-কে শুধু A′C′D ঢাকে → EPI

এখানে implicant, prime implicant আর essential prime implicant — এই তিন স্তর মনে রাখুন। একটি গুরুত্বপূর্ণ উপপাদ্য (theorem) আছে: প্রতিটি minimal SOP-এর প্রতিটি term একটি prime implicant. কারণ কোনো term prime না হলে তাকে বড় করা যায় — একটি literal কমে, আর ঢাকা ঘর শুধু বাড়ে, তাই খরচ কমে অথচ function একই থাকে। ফলে minimal উত্তর খুঁজতে শুধু PI-দের মধ্যে খুঁজলেই চলে।

পদ্ধতি — তিন ধাপ

(১) সব prime implicant খুঁজুন: প্রতিটি 1 থেকে শুরু করে যত বড় দল সম্ভব — সবগুলো, overlap সহ।
(২) Essential PI নিন: প্রতিটি 1 দেখুন — একে কয়টি PI ঢাকে? মাত্র একটি হলে সেই PI essential; উত্তরে নিন আর তার সব 1-কে “ঢাকা হয়েছে” চিহ্ন দিন।
(৩) বাকি 1 সবচেয়ে কম খরচে ঢাকুন: বাকি PI-দের মধ্যে থেকে সবচেয়ে কম সংখ্যক (তারপর কম literal-এর) PI বেছে নিন। যে PI-এর সব 1 আগেই ঢাকা পড়েছে, সেটি বাদ।

তৃতীয় ধাপটি আসলে একটি set cover সমস্যা — বড় function-এ কঠিন, কিন্তু ৪ চলকের map-এ প্রায় সবসময় হাতেই হয়ে যায়। নিচের map-টি দেখুন — এখানে সবচেয়ে বড়, সবচেয়ে চোখে পড়া দলটিই অপ্রয়োজনীয়।

ধাপ ১map
AB\CD   00    01    11    10
 00     0     1     0     0
 01     0     1     1     1
 11     1     1     1     0
 10     0     0     1     0
ones: m1 m5 m6 m7 m11 m12 m13 m15
ধাপ ২সব prime implicant
BD    (m5 m7 m13 m15)   centre 2x2 square
A'C'D (m1 m5)           column 01, rows 00-01
A'BC  (m6 m7)           row 01, columns 11-10
ABC'  (m12 m13)         row 11, columns 00-01
ACD   (m11 m15)         column 11, rows 11-10
5 prime implicants; none can grow without a 0
ধাপ ৩–৫কোন 1-কে কয়টি PI ঢাকে
m1  : A'C'D            -> only one  => A'C'D essential
m6  : A'BC             -> only one  => A'BC essential
m12 : ABC'             -> only one  => ABC' essential
m11 : ACD              -> only one  => ACD essential
m5  : BD, A'C'D        -> two
m7  : BD, A'BC         -> two
m13 : BD, ABC'         -> two
m15 : BD, ACD          -> two
ধাপ ৬BD কি লাগবে?
covered by the 4 EPIs:
  A'C'D -> m1 m5     A'BC -> m6 m7
  ABC'  -> m12 m13   ACD  -> m11 m15
BD = m5 m7 m13 m15  -> all already covered: redundant
F = A'C'D + A'BC + ABC' + ACD     4 terms, 12 literals
(with BD added: 5 terms, 14 literals - not minimal)
  1. Map. আটটি 1: m1, m5, m6, m7, m11, m12, m13, m15. মাঝখানে একটি ২×২ বর্গ (m5, m7, m13, m15) সবার আগে চোখে পড়ে — অনেকেই প্রথমেই সেটি নিয়ে নেন।
  2. সব prime implicant. মাঝের বর্গ BD (৪ ঘর), আর চারটি জোড়া: A′C′D, A′BC, ABC′, ACD. প্রতিটি জোড়ার পাশে 0 আছে, তাই আর বড় হয় না — পাঁচটিই prime.
  3. m1-কে কে ঢাকে? শুধু A′C′D. তাই A′C′D essential — যেকোনো সঠিক minimal উত্তরে এটি থাকবেই। একইভাবে m6-কে শুধু A′BC ঢাকে, তাই সেটিও essential.
  4. m12 আর m11. m12-কে শুধু ABC′, m11-কে শুধু ACD ঢাকে — দুটিই essential. মোট চারটি essential PI, প্রতিটি “কিনারার” একটি জোড়া।
  5. মাঝের চারটি 1. m5, m7, m13, m15 প্রত্যেককে দুটি করে PI ঢাকে — BD আর একটি জোড়া। তাই এদের কোনোটিই BD-কে essential বানায় না। BD prime, কিন্তু essential নয়।
  6. BD অপ্রয়োজনীয়। চারটি essential PI মিলেই আটটি 1 ঢেকে ফেলে — BD-এর প্রতিটি ঘর আগেই ঢাকা। উত্তর F = A′C′D + A′BC + ABC′ + ACD (৪ term, ১২ literal). BD যোগ করলে ৫ term, ১৪ literal — function একই, কিন্তু খরচ বেশি। সবচেয়ে বড় দলটিই বাদ!

“আগে বড় দল” নিয়মটি অন্ধভাবে মানবেন না। “দল যত বড় সম্ভব” মানে প্রতিটি দল নিজে যতটা পারে বড় হবে (prime হবে) — এর মানে এই নয় যে সবচেয়ে বড় দলটি আগে নিতে হবে। নিয়ম হলো: essential আগে, তারপর বাকিটুকু। তবে একটি ব্যতিক্রম আছে — circuit-এ ক্ষণিকের ভুল সংকেত (static hazard) এড়াতে নকশাকারীরা কখনো ইচ্ছা করে এমন বাড়তি দল যোগ করেন। সেটি পর্ব ১০-এর বিষয়।

যখন একাধিক minimal উত্তর থাকে — essential PI একটিও নেই

F(A, B, C) = Σm(0, 1, 2, 5, 6, 7) নিন। Map-এ ছয়টি 1 একটি চক্র বানায়:

A \ BC   00   01   11   10
  0       1    1    0    1
  1       0    1    1    1
PIs: A'B'(0,1)  A'C'(0,2)  B'C(1,5)  BC'(2,6)  AC(5,7)  AB(6,7)

ছয়টি PI, প্রত্যেকটি ২ ঘরের জোড়া, আর প্রতিটি 1-কে ঠিক দুটি PI ঢাকে — তাই কোনো essential PI নেই। এমন অবস্থাকে বলে cyclic (চক্রাকার) map. পদ্ধতি: যেকোনো একটি PI ধরে নিন, তারপর বাকিটুকু সবচেয়ে কম খরচে ঢাকুন। A′B′ নিলে বাকি থাকে 2, 5, 6, 7 — BC′ (2, 6) আর AC (5, 7) দিয়ে শেষ: F = A′B′ + BC′ + AC. আবার A′C′ দিয়ে শুরু করলে বাকি 1, 5, 6, 7 — B′C (1, 5) আর AB (6, 7): F = A′C′ + B′C + AB. দুটিই ৩ term, ৬ literal — দুটিই সঠিক minimal উত্তর। পরীক্ষায় যেকোনো একটি লিখলেই পূর্ণ নম্বর পাওয়ার কথা; খাতায় দ্বিতীয়টির কথা উল্লেখ করলে বোঝা যায় আপনি পদ্ধতিটি জানেন।

এবার পুরো পদ্ধতিটি যন্ত্রে চালিয়ে দেখুন। নিচের ছোট minimiser map আঁকে (সারি-কলাম Gray ক্রমে, 1, X আর 0-এর জায়গায় .), সব prime implicant আর essential PI ছাপে, তারপর সব PI-এর প্রতিটি সম্ভাব্য সমষ্টি পরীক্ষা করে (exhaustive search — ৪ চলকে PI খুব বেশি হয় না, তাই এক মুহূর্তে শেষ) সবচেয়ে কম খরচের উত্তর বের করে। শেষে truth table-এর ১৬টি সারি মিলিয়ে দেখে। Run চাপুন, তারপর শেষের লাইনগুলোতে নিজের function বসিয়ে দেখুন:

// K-map minimiser for 2-4 variables: draw the map, find every prime implicant,
// pick a minimal SOP cover by exhaustive search, then verify with the truth table.
const V = "ABCD", G = { 1: ["0", "1"], 2: ["00", "01", "11", "10"] };   // Gray order
const cubes = n => n ? cubes(n - 1).flatMap(s => ["0" + s, "1" + s, "-" + s]) : [""];
const cells = c => c.includes("-") ? [...cells(c.replace("-", "0")), ...cells(c.replace("-", "1"))] : [parseInt(c, 2)];
const term = c => [...c].map((b, i) => b === "-" ? "" : V[i] + (b === "0" ? "'" : "")).join("") || "1";
const lits = S => S.reduce((s, c) => s + c.replace(/-/g, "").length, 0);
function kmap(n, on, dc = []) {
  const rb = n >> 1, cb = n - rb, val = m => on.includes(m) ? "1" : dc.includes(m) ? "X" : ".";
  console.log(`${V.slice(0, rb)}\\${V.slice(rb, n)}`.padEnd(6) + G[cb].join("  "));
  for (const r of G[rb]) console.log(r.padEnd(6) + G[cb].map(c => val(parseInt(r + c, 2)).padEnd(cb)).join("  "));
  const imp = cubes(n).filter(c => cells(c).every(m => on.includes(m) || dc.includes(m)) && cells(c).some(m => on.includes(m)));
  const pis = imp.filter(a => !imp.some(b => b !== a && cells(a).every(m => cells(b).includes(m))));
  const epi = pis.filter(p => on.some(m => pis.filter(q => cells(q).includes(m)).length === 1 && cells(p).includes(m)));
  console.log("prime implicants:", pis.map(p => `${term(p)}(${cells(p).join(",")})`).join("  "));
  console.log("essential:", epi.map(term).join(", ") || "none");
  let best = [];
  for (let mask = 1; mask < 1 << pis.length; mask++) {
    const S = pis.filter((_, i) => mask >> i & 1);
    if (!on.every(m => S.some(p => cells(p).includes(m)))) continue;
    const cost = S.length * 100 + lits(S), b = best[0] ? best[0].length * 100 + lits(best[0]) : 1e9;
    if (cost < b) best = [S]; else if (cost === b) best.push(S);
  }
  best.forEach(S => {
    const ok = [...Array(1 << n).keys()].every(m => dc.includes(m) || S.some(p => cells(p).includes(m)) === on.includes(m));
    console.log(`F = ${S.map(term).join(" + ")}   [${S.length} terms, ${lits(S)} literals, truth table ${ok ? "OK" : "FAIL"}]`);
  });
  console.log("-".repeat(44));
}
kmap(3, [0, 2, 5, 7]);
kmap(4, [0, 1, 2, 5, 8, 9, 10]);
kmap(3, [0, 1, 2, 5, 6, 7]);                 // two equally good answers
kmap(4, [1, 5, 6, 7, 11, 12, 13, 15]);       // BD is prime but not needed
kmap(4, [1, 3, 7, 11, 15], [0, 2, 5]);       // with don't cares

আউটপুট (নির্ধারিত — প্রতিবার একই):

A\BC  00  01  11  10
0     1   .   .   1
1     .   1   1   .
prime implicants: A'C'(0,2)  AC(5,7)
essential: A'C', AC
F = A'C' + AC   [2 terms, 4 literals, truth table OK]
--------------------------------------------
AB\CD 00  01  11  10
00    1   1   .   1
01    .   1   .   .
11    .   .   .   .
10    1   1   .   1
prime implicants: B'D'(0,2,8,10)  A'C'D(1,5)  B'C'(0,1,8,9)
essential: B'D', A'C'D, B'C'
F = B'D' + A'C'D + B'C'   [3 terms, 7 literals, truth table OK]
--------------------------------------------
A\BC  00  01  11  10
0     1   1   .   1
1     .   1   1   1
prime implicants: BC'(2,6)  A'C'(0,2)  B'C(1,5)  AC(5,7)  A'B'(0,1)  AB(6,7)
essential: none
F = BC' + AC + A'B'   [3 terms, 6 literals, truth table OK]
F = A'C' + B'C + AB   [3 terms, 6 literals, truth table OK]
--------------------------------------------
AB\CD 00  01  11  10
00    .   1   .   .
01    .   1   1   1
11    1   1   1   .
10    .   .   1   .
prime implicants: A'C'D(1,5)  ACD(11,15)  BD(5,7,13,15)  ABC'(12,13)  A'BC(6,7)
essential: A'C'D, ACD, ABC', A'BC
F = A'C'D + ACD + ABC' + A'BC   [4 terms, 12 literals, truth table OK]
--------------------------------------------
AB\CD 00  01  11  10
00    X   1   1   X
01    .   X   1   .
11    .   .   1   .
10    .   .   1   .
prime implicants: CD(3,7,11,15)  A'D(1,3,5,7)  A'B'(0,1,2,3)
essential: CD
F = CD + A'D   [2 terms, 4 literals, truth table OK]
F = CD + A'B'   [2 terms, 4 literals, truth table OK]
--------------------------------------------

প্রতিটি ফল ওপরের হাতের হিসাবের সাথে মেলে। প্রথম map-এ A'C' + AC; দ্বিতীয়টিতে তিনটি PI-ই essential, উত্তর B'D' + A'C'D + B'C' — ৭ literal (term-এর ক্রম আলাদা, কিন্তু OR-এ ক্রমের কিছু যায় আসে না)। চক্রাকার map-এ essential: none, আর দুটি আলাদা উত্তর সমান খরচে — ৩ term, ৬ literal. চতুর্থ map-এ BD(5,7,13,15) prime implicant-এর তালিকায় আছে, কিন্তু essential-এর তালিকায় নেই, আর চূড়ান্ত উত্তরেও নেই — stepper-এর ঠিক সেই ফল। শেষ map-এ X (don't care, পরের অংশে) ব্যবহার করে দুটি সমান ভালো উত্তর। প্রতিটি লাইনে truth table OK মানে উত্তরটি প্রতিটি 1 আর 0-এর সারিতে মূল function-এর সাথে মিলেছে; X-এর সারি মুক্ত। এখানে খরচ = term × ১০০ + literal, অর্থাৎ আগে term, তারপর literal তুলনা।

৬ · Don't care — যে ইনপুট কখনো আসে না, তাকে কাজে লাগানো

অনেক বাস্তব circuit-এ কিছু ইনপুট-সমন্বয় কখনো আসেই না। BCD-তে ৪ বিটে ১৬টি নকশা সম্ভব, কিন্তু বৈধ মাত্র ০–৯; 1010 থেকে 1111 পর্যন্ত ছয়টি নকশা কোনো সঠিক উৎস থেকে আসার কথা নয়। এমন সারির আউটপুট নিয়ে আমাদের মাথাব্যথা নেই — তাই সেখানে লেখা হয় X (বা d), নাম don't care. লেখার রীতি: F = Σm(…) + d(…)।

নিয়মটি সহজ: X-কে প্রয়োজনমতো 1 বা 0 ধরুন। কোনো দল বড় করতে X কাজে লাগলে সেটিকে 1 ধরে দলে নিন; না লাগলে ছেড়ে দিন (0 ধরা হলো)। কিন্তু শুধু X দিয়ে কোনো দল বানাবেন না — সেটি কোনো 1-কে ঢাকে না, শুধু খরচ বাড়ায়। আর X ঢাকতে হবে, এমন কোনো বাধ্যবাধকতাও নেই।

রেস্তোরাঁর উপমা: রান্নাঘরে নিয়ম — “ভাত আর ডাল একসাথে অর্ডার হলে সালাদ দিতে হবে।” মেনুতে এমন কিছু সমন্বয় আছে যা কেউ কখনো অর্ডার করতে পারে না (যেমন একই সাথে “শুধু ভাত” আর “ভাত ছাড়া”)। সেই অসম্ভব অর্ডারে সালাদ দেবেন কি না, তা নিয়ে নিয়ম লেখার দরকার নেই — যে নিয়ম লিখতে সবচেয়ে সহজ, সেটিই বেছে নিন। Don't care ঠিক এই স্বাধীনতা।

7-segment display — segment e

ক্যালকুলেটর আর ডিজিটাল ঘড়ির অঙ্ক দেখায় seven-segment display: সাতটি দাগ, নাম a (ওপরে), b (ওপরের ডানে), c (নিচের ডানে), d (নিচে), e (নিচের বাঁয়ে), f (ওপরের বাঁয়ে) আর g (মাঝে)। একটি BCD-to-7-segment decoder চার বিটের BCD (ABCD) নিয়ে সাতটি আউটপুট দেয় — প্রতিটি segment-এর জন্য একটি করে Boolean function. Segment e (নিচের বাঁয়ের দাগ) জ্বলে শুধু ০, ২, ৬ আর ৮-এ:

e = Σm(0, 2, 6, 8) + d(10, 11, 12, 13, 14, 15)
ধাপ ১map: 1, 0 আর X
AB\CD   00    01    11    10
 00     1     0     0     1
 01     0     0     0     1
 11     X     X     X     X
 10     1     0     X     X
ones: m0 m2 m6 m8   don't care: m10..m15
ধাপ ২X-কে 0 ধরলে
AB\CD   00    01    11    10
 00     1P    0     0     1Q
 01     0     0     0     1Q
 11     0     0     0     0
 10     1P    0     0     0
P = m0 m8 -> B'C'D'    Q = m2 m6 -> A'CD'    6 literals
ধাপ ৩m10-এর X নিয়ে চার কোণ
AB\CD   00    01    11    10
 00     1P    0     0     1P
 01     0     0     0     1
 11     X     X     X     X
 10     1P    0     X     XP
P = m0 m2 m8 (+X m10) -> B'D'
ধাপ ৪m14, m10-এর X নিয়ে পুরো কলাম
AB\CD   00    01    11    10
 00     1P    0     0     1PQ
 01     0     0     0     1Q
 11     X     X     X     XQ
 10     1P    0     X     XPQ
Q = m2 m6 (+X m14 m10) : C=1, D=0 -> CD'
ধাপ ৫উত্তর আর অব্যবহৃত X
e = B'D' + CD'           4 literals   (was 6)
used as 1 : m10 m14
left as 0 : m11 m12 m13 m15
if a bad code arrives anyway:
  input 10 11 12 13 14 15
  e  =   1  0  0  0  1  0
  1. Map ভরা। m0, m2, m6, m8-এ 1 (অঙ্ক ০, ২, ৬, ৮)। তৃতীয় সারি (m12–m15) পুরোটাই X, আর নিচের সারির m10, m11-ও X — সব মিলিয়ে ছয়টি don't care.
  2. X না থাকলে। X-কে 0 ধরলে m8-এর একমাত্র সঙ্গী m0 (জোড়া B′C′D′), আর m6-এর একমাত্র সঙ্গী m2 (জোড়া A′CD′)। এই দুটি জোড়াই চারটি 1 ঢেকে ফেলে — দুটি ৩-literal-এর term, মোট ৬ literal.
  3. m10-এর X কাজে লাগানো। m10 (কোণ)-কে 1 ধরলে চার কোণ m0, m2, m8, m10 একটি ৪-এর দল: B′D′. এক ধাক্কায় m0, m2, m8 ঢাকা, আর term-এ মাত্র ২ literal.
  4. কলাম CD = 10. m6 এখনো বাকি। m14 আর m10-কে 1 ধরলে পুরো শেষ কলাম (m2, m6, m14, m10) একটি ১×৪ দল: C = 1, D = 0 স্থির → CD′. m10 এখন দুই দলে — X-এর বেলাতেও overlap চলে।
  5. উত্তর। e = B′D′ + CD′ — ৬ থেকে ৪ literal. m10 আর m14-কে 1 হিসেবে কাজে লাগানো হলো; m11, m12, m13, m15 কোনো দলে নেই, তাই সেগুলো কার্যত 0. ভুল করে ১০ বা ১৪ ইনপুট এলে e জ্বলবে — don't care মানে “যা খুশি”, আর circuit ঠিক এই নির্দিষ্ট “যা খুশি”-টাই করবে।

Segment a — এক বড় সাশ্রয়

Segment a (ওপরের দাগ) জ্বলে ০, ২, ৩, ৫, ৬, ৭, ৮, ৯-এ — বাকি থাকে শুধু ১ আর ৪. (অঙ্ক ৬-এর ওপরে আর ৯-এর নিচে দাগ থাকবে কি না, তা display-ভেদে আলাদা হয়; কিছু decoder chip ৬ আর ৯-কে এই “লেজ” ছাড়া দেখায়। এখানে আমরা লেজসহ রূপ ধরছি, যা পাঠ্যবইয়ে বেশি প্রচলিত — অন্য রূপ ধরলে উত্তর বদলাবে।)

a = Σm(0,2,3,5,6,7,8,9) + d(10..15)

AB\CD   00   01   11   10
 00      1    0    1    1
 01      0    1    1    1
 11      X    X    X    X
 10      1    1    X    X

X-গুলো ধরে চারটি বড় দল: নিচের দুই সারি (m8–m15, X-সহ) একটি ৮-এর দল → A; শেষ দুই কলাম (C = 1, m2, m3, m6, m7 আর X m10, m11, m14, m15) আরেকটি ৮-এর দল → C; মাঝের ২×২ বর্গ (m5, m7, m13, m15) → BD; আর চার কোণ (m0, m2, m8, m10) → B′D′. ফল a = A + C + BD + B′D′ — মাত্র ৬ literal. X ছাড়া একই segment লাগে ১১ literal. নিচের কোডটি দুই segment-এর হিসাবই চালিয়ে মিলিয়ে দেয়, আর বলে দেয় অবৈধ ইনপুটে circuit আসলে কী দেখাবে:

// BCD to 7-segment decoder: minimise segments a and e with and without don't cares.
// Inputs ABCD = BCD digit 0-9 (A = MSB). Codes 1010-1111 never arrive -> don't care.
const V = "ABCD";
const SEG = { a: [0, 2, 3, 5, 6, 7, 8, 9], e: [0, 2, 6, 8] };     // digits that light the segment
const DC = [10, 11, 12, 13, 14, 15];
const cubes = n => n ? cubes(n - 1).flatMap(s => ["0" + s, "1" + s, "-" + s]) : [""];
const cells = c => c.includes("-") ? [...cells(c.replace("-", "0")), ...cells(c.replace("-", "1"))] : [parseInt(c, 2)];
const lits = S => S.reduce((s, c) => s + c.replace(/-/g, "").length, 0);
const term = c => [...c].map((b, i) => b === "-" ? "" : V[i] + (b === "0" ? "'" : "")).join("") || "1";
function minCover(on, dc) {
  const imp = cubes(4).filter(c => cells(c).every(m => on.includes(m) || dc.includes(m)) && cells(c).some(m => on.includes(m)));
  const pis = imp.filter(a => !imp.some(b => b !== a && cells(a).every(m => cells(b).includes(m))));
  let best = null;
  for (let mask = 1; mask < 1 << pis.length; mask++) {
    const S = pis.filter((_, i) => mask >> i & 1);
    if (on.every(m => S.some(p => cells(p).includes(m))) && (!best || S.length * 100 + lits(S) < best.length * 100 + lits(best))) best = S;
  }
  return best;
}
const f = (S, m) => S.some(p => cells(p).includes(m)) ? 1 : 0;
for (const s of ["a", "e"]) {
  const plain = minCover(SEG[s], []), withX = minCover(SEG[s], DC);
  console.log(`segment ${s}: on for digits ${SEG[s].join(",")}`);
  console.log(`  without don't care: ${plain.map(term).join(" + ")}  (${lits(plain)} literals)`);
  console.log(`  with    don't care: ${withX.map(term).join(" + ")}  (${lits(withX)} literals)`);
  const ok = [...Array(10).keys()].every(d => f(withX, d) === (SEG[s].includes(d) ? 1 : 0));
  console.log(`  digits 0-9 ${ok ? "all correct" : "MISMATCH"}; inputs 10-15 give ` + DC.map(m => f(withX, m)).join(""));
}
const tot = x => ["a", "e"].reduce((t, s) => t + lits(minCover(SEG[s], x)), 0);
console.log(`segments a + e together: ${tot([])} literals -> ${tot(DC)} literals with don't cares`);

আউটপুট:

segment a: on for digits 0,2,3,5,6,7,8,9
  without don't care: B'C'D' + A'BD + AB'C' + A'C  (11 literals)
  with    don't care: B'D' + BD + C + A  (6 literals)
  digits 0-9 all correct; inputs 10-15 give 111111
segment e: on for digits 0,2,6,8
  without don't care: B'C'D' + A'CD'  (6 literals)
  with    don't care: CD' + B'D'  (4 literals)
  digits 0-9 all correct; inputs 10-15 give 100010
segments a + e together: 17 literals -> 10 literals with don't cares

Segment a: don't care ছাড়া চারটি term আর ১১ literal (B'C'D' + A'BD + AB'C' + A'C), don't care-সহ B'D' + BD + C + A — ৬ literal. Segment e: ৬ থেকে ৪. দুই segment মিলিয়ে ১৭ থেকে ১০ literal — প্রায় ৪০% কম, আর পুরো সাত segment-এর decoder-এ সাশ্রয় আরও বেশি। digits 0-9 all correct বলছে বৈধ প্রতিটি অঙ্কে আউটপুট ঠিক আছে। শেষ অংশটি সতর্কবার্তা: ১০–১৫ ইনপুটে segment a সবসময় জ্বলবে (111111), আর segment e জ্বলবে ১০ আর ১৪-তে (100010). কোনো ত্রুটিপূর্ণ উৎস 1010 পাঠালে display একটি অর্থহীন নকশা দেখাবে — এই ঝুঁকি মেনে নেওয়ার বিনিময়েই সাশ্রয়।

আরেকটি প্রচলিত উদাহরণ — BCD থেকে excess-3: excess-3 কোডে প্রতিটি অঙ্কের সাথে ৩ যোগ হয়। চার আউটপুট W X Y Z-এর প্রতিটিতে ১০–১৫ don't care. সবচেয়ে উঁচু বিট W = 1 যখন অঙ্ক + ৩ ≥ ৮, অর্থাৎ অঙ্ক ৫–৯: W = Σm(5, 6, 7, 8, 9) + d(10–15) = A + BC + BD (৫ literal). X ছাড়া একই function লাগত A′BC + A′BD + AB′C′ — ৯ literal. বাকি তিন আউটপুট অনুশীলন ৩-এ।

৭ · POS — 0-এর দল বানিয়ে, তারপর NAND–NAND আর NOR–NOR

এতক্ষণ 1-এর দল বানিয়ে SOP পেয়েছি। একই map থেকে POS (product of sums) রূপও পাওয়া যায় — এবার 0-গুলোর দল বানিয়ে। যুক্তিটি দুই লাইনের:

  1. 0-গুলোর দল বানালে যে SOP আসে, সেটি F নয়, F′-এর minimal SOP — কারণ F′ ঠিক সেখানেই 1, যেখানে F হলো 0.
  2. F = (F′)′. এবার De Morgan লাগান: (P + Q + R)′ = P′Q′R′, আর প্রতিটি product term-এর complement একটি sum term — (B D′)′ = B′ + D. অর্থাৎ F′-এর প্রতিটি term থেকে প্রতিটি literal উল্টে, AND-এর জায়গায় OR বসিয়ে একটি বন্ধনী।

সরাসরি পড়ার নিয়ম: 0-এর দলে যে চলক স্থির 0, সেটি বন্ধনীতে সরাসরি; যে চলক স্থির 1, সেটি complement করে। (SOP-এর ঠিক উল্টো — কারণ একটি maxterm সেই সারিতেই 0 হয়।)

সমাধান: F = Σm(0, 1, 2, 5, 8, 9, 10)-এর POS

AB\CD   00   01   11   10
 00      1    1    0    1
 01      0    1    0    0
 11      0    0    0    0
 10      1    1    0    1
zeros: m3 m4 m6 m7 m11 m12 m13 m14 m15

তিনটি ৪-এর দলে নয়টি 0 ঢাকা যায়: পুরো তৃতীয় সারি (m12–m15) → A = 1, B = 1 স্থির → F′-এর term AB; কলাম CD = 11 (m3, m7, m15, m11) → CD; আর দ্বিতীয়-তৃতীয় সারির প্রথম ও শেষ কলাম (m4, m6, m12, m14 — ডান-বাঁ কিনারা পেরিয়ে) → B = 1, D = 0 → BD′. তাই F′ = AB + CD + BD′, আর De Morgan:

F = (A′ + B′)(C′ + D′)(B′ + D) — ৩ বন্ধনী, ৬ literal

লক্ষ্য করুন: একই function-এর minimal SOP ছিল ৭ literal, minimal POS ৬ literal. কোনটি সস্তা তা আগে থেকে বলা যায় না — দুটিই বের করে তুলনা করাই নিয়ম। নিচের কোড দুটি রূপ পাশাপাশি বের করে, আর POS-টিকে সরাসরি truth table-এ মিলিয়ে দেখে:

// POS minimisation: group the 0s (and X) to get a minimal SOP for F', then apply
// De Morgan: every product term of F' becomes one sum term (clause) of F.
const V = "ABCD";
const cubes = n => n ? cubes(n - 1).flatMap(s => ["0" + s, "1" + s, "-" + s]) : [""];
const cells = c => c.includes("-") ? [...cells(c.replace("-", "0")), ...cells(c.replace("-", "1"))] : [parseInt(c, 2)];
const lits = S => S.reduce((s, c) => s + c.replace(/-/g, "").length, 0);
const prod = c => [...c].map((b, i) => b === "-" ? "" : V[i] + (b === "0" ? "'" : "")).join("");
const sum = c => "(" + [...c].map((b, i) => b === "-" ? "" : V[i] + (b === "1" ? "'" : "")).filter(Boolean).join(" + ") + ")";
function minCover(n, on, dc) {                 // same exhaustive search as before
  const imp = cubes(n).filter(c => cells(c).every(m => on.includes(m) || dc.includes(m)) && cells(c).some(m => on.includes(m)));
  const pis = imp.filter(a => !imp.some(b => b !== a && cells(a).every(m => cells(b).includes(m))));
  let best = null;
  for (let mask = 1; mask < 1 << pis.length; mask++) {
    const S = pis.filter((_, i) => mask >> i & 1);
    if (on.every(m => S.some(p => cells(p).includes(m))) && (!best || S.length * 100 + lits(S) < best.length * 100 + lits(best))) best = S;
  }
  return best;
}
function pos(n, on, dc = []) {
  const zeros = [...Array(1 << n).keys()].filter(m => !on.includes(m) && !dc.includes(m));
  const sop = minCover(n, on, dc), neg = minCover(n, zeros, dc);
  console.log(`F  = Σm(${on})` + (dc.length ? ` + d(${dc})` : "") + `   zeros: ${zeros}`);
  console.log(`F' = ${neg.map(prod).join(" + ")}`);
  console.log(`F  = ${neg.map(sum).join("")}   [POS: ${neg.length} clauses, ${lits(neg)} literals]`);
  console.log(`F  = ${sop.map(prod).join(" + ")}   [SOP: ${sop.length} terms, ${lits(sop)} literals]`);
  const evalPOS = m => neg.every(c => [...c].some((b, i) => b !== "-" && ((m >> (n - 1 - i)) & 1) !== +b));
  const ok = [...Array(1 << n).keys()].every(m => dc.includes(m) || evalPOS(m) === on.includes(m));
  console.log(`truth table check of POS: ${ok ? "OK" : "FAIL"}\n`);
}
pos(4, [0, 1, 2, 5, 8, 9, 10]);
pos(3, [0, 2, 5, 7]);
pos(4, [1, 3, 7, 11, 15], [0, 2, 5]);
pos(3, [3, 5, 6, 7]);                         // 3-input majority

আউটপুট:

F  = Σm(0,1,2,5,8,9,10)   zeros: 3,4,6,7,11,12,13,14,15
F' = BD' + CD + AB
F  = (B' + D)(C' + D')(A' + B')   [POS: 3 clauses, 6 literals]
F  = B'D' + A'C'D + B'C'   [SOP: 3 terms, 7 literals]
truth table check of POS: OK

F  = Σm(0,2,5,7)   zeros: 1,3,4,6
F' = AC' + A'C
F  = (A' + C)(A + C')   [POS: 2 clauses, 4 literals]
F  = A'C' + AC   [SOP: 2 terms, 4 literals]
truth table check of POS: OK

F  = Σm(1,3,7,11,15) + d(0,2,5)   zeros: 4,6,8,9,10,12,13,14
F' = D' + AC'
F  = (D)(A' + C)   [POS: 2 clauses, 3 literals]
F  = CD + A'D   [SOP: 2 terms, 4 literals]
truth table check of POS: OK

F  = Σm(3,5,6,7)   zeros: 0,1,2,4
F' = B'C' + A'C' + A'B'
F  = (B + C)(A + C)(A + B)   [POS: 3 clauses, 6 literals]
F  = BC + AC + AB   [SOP: 3 terms, 6 literals]
truth table check of POS: OK

প্রথম function-এ F' = BD' + CD + AB আর POS (B' + D)(C' + D')(A' + B') — হাতের উত্তরের সাথে হুবহু (বন্ধনীর ক্রম ভিন্ন), ৬ literal বনাম SOP-এর ৭. দ্বিতীয়টিতে (Σm(0,2,5,7)) দুই রূপই ৪ literal: (A′ + C)(A + C′) আসলে A′C′ + AC-এরই আরেক চেহারা। তৃতীয়টিতে don't care-সহ POS মাত্র ৩ literal — (D)(A' + C), অর্থাৎ D(A′ + C) — যেখানে SOP-এর ৪. চতুর্থটি ৩-ইনপুটের majority (অন্তত দুটি 1 হলে 1): SOP আর POS দুটোই ৬ literal, আর দুটোর চেহারা দেখতে প্রায় আয়নার মতো। প্রতিটি POS truth table check ... OK.

Don't care থাকলে SOP আর POS আলাদা function হতে পারে। তৃতীয় উদাহরণে POS D(A′ + C) m5-কে 1 আর m0, m2-কে 0 বানায়; একটি SOP উত্তর CD + A′B′ ঠিক উল্টো (m0, m2-এ 1, m5-এ 0). দুটিই সঠিক — কারণ ঐ তিনটি সারি don't care — কিন্তু দুটি circuit অবৈধ ইনপুটে আলাদা আচরণ করবে। তাই “SOP আর POS-এর truth table হুবহু মেলে” — এই যাচাই don't care-এর সারিগুলো বাদ দিয়ে করতে হয়।

NAND–NAND আর NOR–NOR — K-map-এর উত্তর থেকে সরাসরি circuit

পর্ব ০৮-এ দেখেছেন, CMOS-এ AND আর OR আসলে NAND/NOR-এর পরে একটি inverter — তাই সরাসরি NAND বা NOR দিয়ে বানানো সস্তা আর দ্রুত। দুটিই universal gate. সুখবর হলো, দুই স্তরের SOP হুবহু NAND–NAND হয়ে যায়, আর POS হুবহু NOR–NOR:

F = B′D′ + B′C′ + A′C′D = ( (B′D′)′ · (B′C′)′ · (A′C′D)′ )′

অর্থাৎ প্রথম স্তরে প্রতিটি product term-এর জন্য একটি NAND (২, ২ আর ৩ ইনপুটের), দ্বিতীয় স্তরে তিনটির আউটপুট নিয়ে একটি তিন-ইনপুটের NAND. প্রমাণ De Morgan দিয়ে: (X′Y′Z′)′ = X + Y + Z, যেখানে X, Y, Z হলো তিনটি product. ছবিটা হুবহু AND-OR circuit-এর মতো, শুধু সব gate NAND — মাঝের দুটি “বুদবুদ” (inversion) একে অপরকে কেটে দেয়।

B' D'   --[NAND]--\
B' C'   --[NAND]---[NAND 3-input]--- F
A' C' D --[NAND]--/
(level 1)          (level 2)

POS থেকে একইভাবে NOR–NOR: F = (A′ + B′)(C′ + D′)(B′ + D) = ( (A′ + B′)′ + (C′ + D′)′ + (B′ + D)′ )′ — প্রথম স্তরে তিনটি দুই-ইনপুটের NOR, দ্বিতীয় স্তরে একটি তিন-ইনপুটের NOR. Complement করা ইনপুট (B′, C′, D′) চলকের পাশেই পাওয়া যায় ধরে নেওয়া হয়েছে; না থাকলে প্রতিটির জন্য একটি inverter (বা ইনপুট জোড়া দেওয়া একটি NAND) লাগবে।

৮ · সাধারণ ভুল, ৪-এর বেশি চলক, আর K-map-এর সীমা

ভুলউদাহরণকেন ভুল / কী করবেন
২-এর ঘাত নয় এমন দলপাশাপাশি তিনটি 1 একসাথে৩টি ঘর কোনো একটি term নয়; দুটি জোড়া (overlap সহ) নিন
কোনাকুনি দল৩ চলকে m2 আর m7010 আর 111 — দুটি চলকে আলাদা, তাই মেলে না
কিনারা/কোণ মিস করা(0, 1) আর (8, 9) আলাদা জোড়াওপর-নিচ পাশাপাশি — একসাথে B′C′; একটি literal আর একটি term কম
অপ্রয়োজনীয় দল রেখে দেওয়াঅংশ ৫-এর map-এ BDযার সব 1 অন্য দলে ঢাকা, সেটি বাদ — যদি না hazard-এর জন্য ইচ্ছা করে রাখা হয়
Essential PI বাদ পড়াবড় দল আগে নিয়ে কোণের একা 1 ভুলে যাওয়াপ্রতিটি 1-কে আলাদা করে জিজ্ঞেস করুন: “আমাকে কে কে ঢাকে?”
সারির ক্রম ভুলAB-এর সারি 00, 01, 10, 11 লেখাসারি-কলাম দুটোই Gray ক্রমে — 00, 01, 11, 10
শুধু X দিয়ে দলm12–m15 X, আলাদা দল বানানোকোনো 1 ঢাকে না, শুধু খরচ বাড়ায়
POS পড়তে SOP-এর নিয়ম0-এর দলে A = 1 স্থির, লেখা হলো APOS-এ স্থির 1 মানে A′, স্থির 0 মানে A

নিজের দল ঠিক হলো কি না, যন্ত্রে মিলিয়ে নেওয়া যায়। নিচের checker-কে আপনার দলগুলো ঘরের নম্বরের তালিকা হিসেবে দিন; এটি প্রতিটি দলে এই ভুলগুলো খোঁজে — আকার, আয়তাকার কি না, 0 আছে কি না, আরও বড় করা যায় কি না (prime কি না), অপ্রয়োজনীয় কি না, আর কোনো 1 বাদ পড়ল কি না:

// Grouping checker: give your groups as lists of cell numbers; it reports the
// classic mistakes (bad size, not a rectangle, covers a 0, not prime, redundant, 1 left out).
const V = "ABCD";
function cubeOf(g, n) {                    // the product term if g is a valid group, else null
  if (g.length & (g.length - 1)) return null;          // size must be a power of two
  let c = "";
  for (let i = n - 1; i >= 0; i--) {
    const bits = new Set(g.map(m => (m >> i) & 1));
    c += bits.size === 2 ? "-" : [...bits][0];
  }
  return 2 ** (c.split("-").length - 1) === g.length ? c : null;  // all cells of that rectangle?
}
const term = c => [...c].map((b, i) => b === "-" ? "" : V[i] + (b === "0" ? "'" : "")).join("") || "1";
function check(name, n, on, dc, groups) {
  console.log(`${name}: groups ${JSON.stringify(groups)}`);
  const ok = m => on.includes(m) || dc.includes(m);
  groups.forEach((g, k) => {
    const c = cubeOf(g, n), msg = [];
    if (!c) msg.push(g.length & (g.length - 1) ? `size ${g.length} is not a power of 2` : "not a rectangle (cells differ in too many variables)");
    if (g.some(m => !ok(m))) msg.push("covers a 0");
    if (c && !msg.length) {
      const bigger = [...c].some((b, i) => b !== "-" && g.every(m => ok(m ^ (1 << (n - 1 - i)))));
      if (bigger) msg.push("can be doubled (not prime)");
      const others = groups.filter((_, j) => j !== k).flat();
      if (g.filter(m => on.includes(m)).every(m => others.includes(m))) msg.push("redundant");
    }
    console.log(`  group ${k + 1} ${c ? term(c) : "?"}: ${msg.join("; ") || "fine"}`);
  });
  const left = on.filter(m => !groups.flat().includes(m));
  console.log(left.length ? `  1s not covered: ${left}` : "  every 1 is covered");
}
check("try 1", 4, [0, 1, 2, 5, 8, 9, 10], [], [[0, 1], [8, 9], [0, 2, 8, 10], [5]]);
check("try 2", 4, [0, 1, 2, 5, 8, 9, 10], [], [[0, 1, 8, 9], [0, 2, 8, 10], [1, 5]]);
check("try 3", 3, [0, 2, 5, 7], [], [[0, 2, 5], [2, 7]]);
check("try 4", 4, [1, 5, 6, 7, 11, 12, 13, 15], [], [[5, 7, 13, 15], [1, 5], [6, 7], [12, 13], [11, 15]]);

আউটপুট:

try 1: groups [[0,1],[8,9],[0,2,8,10],[5]]
  group 1 A'B'C': can be doubled (not prime)
  group 2 AB'C': can be doubled (not prime)
  group 3 B'D': fine
  group 4 A'BC'D: can be doubled (not prime)
  every 1 is covered
try 2: groups [[0,1,8,9],[0,2,8,10],[1,5]]
  group 1 B'C': fine
  group 2 B'D': fine
  group 3 A'C'D: fine
  every 1 is covered
try 3: groups [[0,2,5],[2,7]]
  group 1 ?: size 3 is not a power of 2
  group 2 ?: not a rectangle (cells differ in too many variables)
  every 1 is covered
try 4: groups [[5,7,13,15],[1,5],[6,7],[12,13],[11,15]]
  group 1 BD: redundant
  group 2 A'C'D: fine
  group 3 A'BC: fine
  group 4 ABC': fine
  group 5 ACD: fine
  every 1 is covered

try 1-এ সব 1 ঢাকা, কোনো দলে 0 নেই — দেখতে “ঠিক”। কিন্তু তিনটি দল can be doubled (not prime): (0, 1) আর (8, 9) কিনারা পেরিয়ে একটি B′C′ হওয়ার কথা, আর একা m5 জোড়া হতে পারে m1-এর সাথে। এই উত্তর সঠিক function দেয়, কিন্তু minimal নয় — পরীক্ষায় নম্বর কাটা যাবে। try 2 অংশ ৪-এর stepper-এর উত্তর — সব fine. try 3-এ দুটি ক্লাসিক ভুল: তিন ঘরের দল আর কোনাকুনি দল (m2 = 010, m7 = 111). try 4-এ BD বৈধ prime implicant, কিন্তু redundant — অংশ ৫-এর stepper-এর সিদ্ধান্তটি যন্ত্রও বলছে। একটি দল prime কি না তা এক ধাপে যাচাই যথেষ্ট: কোনো দলকে বড় করা গেলে, কোনো একটি স্থির চলক ছেড়ে দিয়ে ঠিক দ্বিগুণ করেও করা যায়।

৫ আর ৬ চলক — যেখানে K-map হাঁপিয়ে ওঠে

৫ চলকের map সাধারণত দুটি ৪×৪ ছক পাশাপাশি এঁকে বানানো হয় — একটি E = 0, আরেকটি E = 1 (যেখানে E পঞ্চম চলক)। দুই ছকের একই অবস্থানের ঘর পাশাপাশি ধরা হয়, যেন একটির ওপর আরেকটি রাখা। ৬ চলকে চারটি ছক লাগে। নিয়ম একই, কিন্তু চোখ আর কাজ করে না: একটি ঘরের প্রতিবেশী এখন ৫ বা ৬টি, যার কিছু অন্য ছকে, আর ত্রিমাত্রিক দল মনে মনে কল্পনা করতে হয়। ভুলের সম্ভাবনা লাফিয়ে বাড়ে।

আরও বড় সমস্যা মাপের। n চলকে ঘর ২nটি, আর prime implicant-এর সংখ্যা সবচেয়ে খারাপ ক্ষেত্রে ঘরের সংখ্যার চেয়েও দ্রুত বাড়তে পারে। তখন দরকার এমন পদ্ধতি যা কাগজের ছবির ওপর নির্ভর করে না, যন্ত্রে চালানো যায় — যেমন Quine–McCluskey পদ্ধতি, যা minterm-গুলো টেবিলে সাজিয়ে ধাপে ধাপে জোড়া মেলায় আর সব PI বের করে। পর্ব ১০-এ এটি, ৫–৬ চলকের map, একাধিক আউটপুট একসাথে সরল করা, আর hazard বিস্তারিত দেখবেন। আজকের chip-নকশায় এই কাজ করে logic synthesis software, যা হাজার হাজার চলক সামলায় — তবে ভেতরের ধারণা (implicant, cover) একই।

আরও গভীরে: বড় function-এ minimal দুই-স্তরের রূপ খোঁজা NP-hard বলে প্রমাণিত, তাই শিল্পে ব্যবহৃত tool-গুলো সাধারণত “প্রায়-minimal” উত্তরে থামে — ১৯৮০-এর দশকে IBM আর UC Berkeley-র গবেষকদের তৈরি Espresso এমন heuristic minimiser-এর সবচেয়ে পরিচিত উদাহরণ, যা আজও পাঠ্যবই আর গবেষণায় মানদণ্ড হিসেবে ব্যবহৃত হয়। আধুনিক synthesis আবার দুই স্তরে থামে না; gate-এর delay আর আকারের লক্ষ্য মেনে বহু-স্তরের (multi-level) circuit বানায়। আর FPGA-তে ৪–৬ ইনপুটের যেকোনো function একটি LUT-এ (ছোট মেমরিতে পুরো truth table) বসে — সেখানে literal কমানোর চেয়ে কয়টি LUT লাগছে সেটিই আসল খরচ।

পরীক্ষা ও ইন্টারভিউতে:

  • K-map-এ কলাম 00, 01, 11, 10 কেন? Gray ক্রম — পাশাপাশি ঘর ঠিক এক চলকে আলাদা, তাই XY + XY′ = X লাগানো যায়; শেষ আর প্রথম কলামও পাশাপাশি।
  • Prime আর essential prime implicant-এর পার্থক্য? PI আর বড় করা যায় না; EPI এমন PI যা অন্তত একটি 1-কে একাই ঢাকে, তাই minimal উত্তরে থাকতেই হয়।
  • Σm(0, 2, 8, 10)-এর minimal SOP? B′D′ — চার কোণ একটি দল।
  • Don't care কেন সাশ্রয় দেয়, আর ঝুঁকি কী? X-কে 1 ধরে দল বড় হয়, literal কমে; কিন্তু “অসম্ভব” ইনপুট সত্যিই এলে circuit একটি নির্দিষ্ট, অনিচ্ছাকৃত আউটপুট দেয়।
  • SOP থেকে NAND-only circuit? প্রতিটি product-এর জন্য একটি NAND, তারপর সবগুলোর আউটপুটে একটি NAND — De Morgan-এর কারণে দুই স্তরের NAND–NAND = AND–OR.

৯ · AI-এর যুগে — K-map-এর উত্তর নিজে যাচাই করুন

K-map-এর প্রশ্ন দিলে AI প্রায়ই আত্মবিশ্বাসী, সুন্দর ব্যাখ্যাসহ উত্তর দেয় — আর বেশ প্রায়ই সেটি ভুল। কারণ AI আসলে ছক দেখে না; লেখা থেকে অনুমান করে। কোণ আর কিনারার দল, ৮–১১ বনাম ১২–১৫ সারির ক্রম, আর don't care-এর ব্যবহার — এগুলোতেই ভুল বেশি। সুখবর হলো, K-map-এর উত্তর যাচাই করা খুব সহজ: truth table-এর ১৬টি সারি মিলিয়ে দেখলেই হয়।

AI প্রায়ই যা ভুল করেকীভাবে ধরবেন
m8–m11 আর m12–m15-এর সারি অদলবদল করে map আঁকাপ্রতিটি ঘরের নম্বর নিজে লিখে map-টি মিলিয়ে নিন
চার কোণ বা কিনারা পেরোনো দল না দেখা — উত্তর সঠিক, কিন্তু minimal নয়প্রতিটি term-কে জিজ্ঞেস করুন: একটি literal বাদ দিলে কোনো 0 ঢোকে কি?
এমন “সরল” উত্তর যা কোনো একটি সারিতে ভুলtruth table-এর সব সারিতে মূল আর নতুন রাশি মিলিয়ে দেখুন (এই পর্বের কোড)
Don't care-কে বাধ্যতামূলক 1 ধরা, বা শুধু X দিয়ে দল বানানোX শুধু দল বড় করতে; অবৈধ ইনপুটে আউটপুট কী হলো তা আলাদা করে লিখুন
POS পড়তে গিয়ে literal উল্টাতে ভুলে যাওয়াএকটি 0-এর সারি বসিয়ে দেখুন বন্ধনীটি সত্যিই 0 হয় কি না
“এটিই একমাত্র উত্তর” দাবি, যেখানে একাধিক minimal উত্তর আছেessential PI-গুলোর পর বাকি অংশে বিকল্প আছে কি না দেখুন

AI-কে শুধু উত্তর না চেয়ে প্রতিটি ধাপ আর একটি যাচাই চাইলে ভুল সহজে ধরা পড়ে:

আমি K-map দিয়ে সরলীকরণ অনুশীলন করছি। F(A,B,C,D) = Σm(0,1,2,5,8,9,10) + d(13)-কে minimal SOP আর minimal POS-এ সরল করো। ১. প্রথমে ৪×৪ map আঁকো — সারি AB আর কলাম CD দুটোই 00, 01, 11, 10 ক্রমে, প্রতিটি ঘরে minterm-এর নম্বর আর মান (1/0/X). ২. সব prime implicant-এর তালিকা দাও, প্রতিটির ঘরের নম্বরসহ। কোনগুলো essential, আর কেন — কোন 1-কে শুধু সেটিই ঢাকে। ৩. চূড়ান্ত উত্তরে term আর literal-এর সংখ্যা লেখো, আর বলো আরেকটি সমান ভালো উত্তর আছে কি না। ৪. don't care m13-কে কোথায় 1 আর কোথায় 0 ধরা হলো স্পষ্ট লেখো। ৫. শেষে ১৬টি সারির truth table-এ মূল function আর তোমার উত্তর পাশাপাশি দেখাও। নিশ্চিত না হলে অনুমান করো না, বলো।

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

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

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

প্র ০১Veitch-এর ছক আর Karnaugh-এর map প্রায় একই সময়ের। তাহলে Karnaugh-এর রূপটিই কেন টিকে গেল — আর ১৯৫০-এর দশকে এমন যন্ত্রের দরকার পড়ল কেন?

১৯৫০-এর দশকের শুরুতে টেলিফোন এক্সচেঞ্জ আর প্রথম দিকের কম্পিউটারের switching circuit বানানো হতো relay আর vacuum tube দিয়ে। প্রতিটি উপাদান ছিল দামি, জায়গা নিত, গরম হতো আর নষ্টও হতো। ১৯৩০-এর দশকের শেষে Claude Shannon দেখিয়েছিলেন যে relay circuit-কে Boolean algebra দিয়ে বর্ণনা করা যায় — ফলে প্রশ্ন দাঁড়াল, একটি নির্দিষ্ট truth table-কে সবচেয়ে কম উপাদানে কীভাবে বানানো যায়। Bell Labs-এর মতো জায়গায়, যেখানে টেলিফোন নেটওয়ার্কের জন্য বিপুল সংখ্যক switching circuit লাগত, এটি ছিল সরাসরি টাকার প্রশ্ন।

Edward Veitch ১৯৫২ সালে যে chart method প্রকাশ করেন, তাতে truth table-এর ঘরগুলো একটি ছকে সাজানো ছিল, কিন্তু সারি-কলাম সাজানো হয়েছিল সাধারণ binary ক্রমে। ফলে যৌক্তিকভাবে পাশাপাশি সব ঘর কাগজে পাশাপাশি পড়ত না, আর দল খুঁজতে বাড়তি নিয়ম মনে রাখতে হতো। ১৯৫৩ সালে Maurice Karnaugh মূলত একটি পরিবর্তন আনেন — সারি-কলামকে reflected binary, অর্থাৎ Gray ক্রমে সাজানো। এতে “এক বিটে আলাদা” সম্পর্কটি কাগজে “পাশে আছে” হয়ে গেল, আর মানুষের চোখ, যা আকৃতি চিনতে খুব দক্ষ, সরাসরি সরলীকরণের কাজ করতে পারল।

এটি একটি বড় শিক্ষা: একই তথ্যের ভালো উপস্থাপন অনেক সময় নতুন algorithm-এর চেয়েও বেশি কাজে আসে। Karnaugh-এর map নতুন কোনো গাণিতিক সত্য আবিষ্কার করেনি — XY + XY′ = X আগেই জানা ছিল। কিন্তু ছবিটি এই সূত্রকে এমনভাবে চোখের সামনে আনল যে প্রকৌশলীরা মিনিটে যে কাজ করতে পারতেন, algebra-য় তাতে অনেক বেশি সময় আর ভুলের ঝুঁকি থাকত। তাই আজ প্রায় সব পাঠ্যবইয়ে Karnaugh-এর রূপ, যদিও কিছু বইয়ে দুজনের সম্মানে KV-map নামটিও দেখা যায়। প্রায় একই সময়ে (১৯৫২ সালে) দার্শনিক W. V. Quine সরলীকরণের একটি টেবিল-ভিত্তিক পদ্ধতি নিয়ে লেখেন, যা পরে Edward McCluskey (১৯৫৬) যন্ত্রে চালানোর উপযোগী করেন — পর্ব ১০-এর বিষয়।

মূল উপলব্ধি: K-map কোনো নতুন গণিত নয়, একটি ভালো ছবি — Gray ক্রমে সাজানোর ফলে যৌক্তিক নৈকট্য চোখে দেখা যায়। ভালো উপস্থাপন মানুষের ভুল কমায়, আর সেই কারণেই সত্তর বছর পরেও এটি প্রতিটি digital logic কোর্সে টিকে আছে।

প্র ০২আজকের chip-এ কোটি কোটি gate, আর নকশা করে software. তাহলে হাতে K-map শেখার মূল্য কী — আর “সবচেয়ে কম literal” কি এখনো আসল লক্ষ্য?

সৎ উত্তর হলো: শিল্পে কেউ হাতে K-map এঁকে CPU বানান না। Verilog বা VHDL-এ বর্ণনা লেখা হয় (পর্ব ১৪), আর logic synthesis tool সেটি থেকে gate বানায়, সরল করে, আর নির্দিষ্ট প্রযুক্তির cell library-তে বসায়। এই tool-এর ভেতরে K-map-এর ধারণাগুলোই আছে — implicant, prime, cover, don't care — কিন্তু অনেক বড় মাপে আর heuristic দিয়ে।

তবু K-map শেখার তিনটি বাস্তব কারণ আছে। প্রথমত, এটি combinational logic-এর ভাষা শেখায়। “এই সংকেত কোন কোন শর্তে 1” — এভাবে ভাবতে পারা debugging-এ খুব কাজে লাগে, বিশেষ করে যখন simulation-এ কোনো আউটপুট একটি নির্দিষ্ট ইনপুটে ভুল আসে। দ্বিতীয়ত, ছোট control logic — যেমন একটি FSM-এর next-state equation (পর্ব ১৭), একটি decoder-এর কয়েকটি আউটপুট, বা একটি ALU-এর flag (পর্ব ১৩) — হাতে সরল করে তবেই বোঝা যায় synthesis tool কী বানাচ্ছে আর কেন। তৃতীয়ত, don't care-এর ধারণা synthesis-এও সরাসরি আছে: Verilog-এ default: out = 'bx; লিখলে tool সেটিকে don't care হিসেবে কাজে লাগাতে পারে — আর এর ঝুঁকিও একই।

এখন “সবচেয়ে কম literal” প্রশ্ন। দুই স্তরের লজিকে literal-এর সংখ্যা খরচের ভালো আনুমানিক মাপ, কিন্তু বাস্তবে লক্ষ্য একাধিক। Delay কমাতে কখনো বেশি gate লাগে, যাতে critical path ছোট হয় (পর্ব ১৮)। বহু-স্তরের circuit-এ সাধারণ অংশ একবার বানিয়ে ভাগাভাগি করা যায় (factoring), যা দুই স্তরে সম্ভব নয় — যেমন একাধিক আউটপুটে একই term থাকলে একবার বানানোই সস্তা। CMOS-এ বেশি ইনপুটের gate ধীর, তাই আট-ইনপুটের একটি AND-এর চেয়ে দুটি ছোট gate-এর গাছ ভালো হতে পারে। আর FPGA-তে খরচ হলো LUT-এর সংখ্যা: ৬ ইনপুটের LUT-এ ৬ চলকের যেকোনো function সমান খরচে বসে, তাই সেখানে literal কমানো অর্থহীন হতে পারে। Power কমাতে আবার কোন সংকেত কতবার বদলায় (switching activity) সেটিও বিবেচনায় আসে।

মূল উপলব্ধি: K-map হলো ধারণার যন্ত্র, শিল্পের যন্ত্র নয়। Literal কমানো খরচের একটি সরল মডেল; আসল নকশায় delay, আকার, power আর প্রযুক্তি (CMOS cell, FPGA LUT) মিলিয়ে সিদ্ধান্ত হয় — কিন্তু সেই সিদ্ধান্ত বুঝতে প্রথমে implicant আর cover বুঝতে হয়।

প্র ০৩Don't care মানে “যা খুশি”। কিন্তু বাস্তব hardware-এ “যা খুশি” বলে কিছু নেই — circuit কিছু একটা করবেই। কখন don't care ব্যবহার বিপজ্জনক?

Don't care-এর পেছনের অনুমান হলো: “এই ইনপুট কখনো আসবে না।” অনুমানটি সত্য হলে সাশ্রয় পুরোটাই লাভ। কিন্তু বাস্তবে অনুমান ভাঙার অনেক পথ আছে: বিদ্যুতের গোলমাল বা noise-এ একটি বিট উল্টে যাওয়া, power চালু হওয়ার মুহূর্তে register-এ এলোমেলো মান, অন্য দলের বানানো module যা নিয়ম না মেনে ভুল কোড পাঠায়, বা ভবিষ্যতে নকশা বদলে যাওয়া যখন কেউ ভুলে যান যে কোনো এক জায়গায় “অসম্ভব” ধরে নেওয়া হয়েছিল।

অংশ ৬-এর segment e-এর উদাহরণে দেখেছেন, don't care-সহ নকশায় ইনপুট 1010 এলে e জ্বলে, 1100 এলে জ্বলে না — অর্থাৎ circuit একটি নির্দিষ্ট আচরণ করে, যা নকশাকার বেছে নেননি, minimiser-এর সুবিধামতো ঠিক হয়েছে। ক্যালকুলেটরের display-এ এর ফল হয়তো একটি অদ্ভুত চিহ্ন — ক্ষতি সামান্য। কিন্তু একই ধরনের সিদ্ধান্ত যদি থাকে একটি finite state machine-এর অব্যবহৃত state-এ (পর্ব ১৭), তাহলে বিপদ বড়: কোনো গোলমালে machine অব্যবহৃত state-এ ঢুকে গেলে, don't care দিয়ে বানানো next-state logic তাকে হয়তো আরেকটি অব্যবহৃত state-এ পাঠায়, আর machine সেখানেই ঘুরতে থাকে — বাইরে থেকে মনে হয় যন্ত্রটি আটকে গেছে (lock-up). তাই নিরাপত্তা-সংবেদনশীল নকশায় — চিকিৎসা যন্ত্র, গাড়ির brake, রেলস্টেশনের সিগন্যাল — প্রকৌশলীরা প্রায়ই don't care ব্যবহার না করে প্রতিটি অবৈধ ইনপুটের জন্য একটি নিরাপদ আচরণ ঠিক করে দেন (যেমন reset বা নিরাপদ state-এ ফেরা), আর error ধরার জন্য আলাদা circuit রাখেন।

একটি মাঝামাঝি পথও আছে: don't care দিয়ে সরল করার পর minimiser অবৈধ ইনপুটে কী আউটপুট বেছে নিল, তা লিখে রাখা আর পর্যালোচনা করা — যেমন এই পর্বের ৭-segment কোড করেছে। তখন সিদ্ধান্তটি সচেতন হয়, লুকোনো থাকে না। Verilog-এ 'bx দিয়ে don't care লেখার ক্ষেত্রেও একই সতর্কতা: simulation-এ x দেখা গেলেও তৈরি chip-এ সেখানে 0 বা 1-এর একটি নির্দিষ্ট মান থাকবে, যা simulation আর বাস্তবের মধ্যে অমিল তৈরি করতে পারে।

মূল উপলব্ধি: Don't care খরচ কমায়, কিন্তু “কখনো আসবে না” একটি অনুমান — নিশ্চয়তা নয়। যেখানে ভুল ইনপুটের ফল গুরুতর, সেখানে নিরাপদ আচরণ নিজে ঠিক করুন; আর যেখানে don't care ব্যবহার করেন, সেখানে circuit আসলে কী করবে তা লিখে রাখুন।

প্র ০৪৪ চলকে K-map খুব সহজ লাগে। তাহলে বড় function-এ minimal SOP খোঁজা “কঠিন সমস্যা” কেন — কম্পিউটার কি সব সম্ভাবনা পরীক্ষা করে দেখতে পারে না?

এই পর্বের minimiser ঠিক সেটাই করে — সব সম্ভাবনা পরীক্ষা। ৪ চলকে এটি সহজ, কারণ সম্ভাব্য product term মাত্র ৩৪ = ৮১টি (প্রতিটি চলক থাকতে পারে সরাসরি, complement, বা অনুপস্থিত), আর prime implicant সাধারণত ১০টির কম। ১০টি PI-এর সব উপসেট মাত্র ২১০ = ১০২৪টি — এক পলকে শেষ।

কিন্তু দুটি জিনিস চলকের সংখ্যার সাথে বিস্ফোরণের মতো বাড়ে। প্রথমত, সম্ভাব্য product term ৩nটি, আর prime implicant-এর সংখ্যাও সবচেয়ে খারাপ ক্ষেত্রে সূচকীয়ভাবে বাড়তে পারে — গবেষণায় দেখানো হয়েছে এমন function আছে যার PI-এর সংখ্যা প্রায় ৩n/n-এর কাছাকাছি। ২০ চলকে ৩২০ প্রায় ৩৫০ কোটি। দ্বিতীয়ত, PI-গুলো থেকে সবচেয়ে ছোট cover বেছে নেওয়া হলো set cover সমস্যা — কম্পিউটার বিজ্ঞানের সবচেয়ে পরিচিত NP-hard সমস্যাগুলোর একটি। এর মানে, এখন পর্যন্ত জানা কোনো algorithm সব ক্ষেত্রে বহুপদী (polynomial) সময়ে নিশ্চিত minimal উত্তর দিতে পারে না, আর P ≠ NP হলে কখনো পারবেও না (DSA কোর্সের P বনাম NP পর্ব দেখুন)। তাত্ত্বিক গবেষণায় দেখানো হয়েছে, পূর্ণ truth table দেওয়া থাকলেও minimal SOP খোঁজার সাধারণ সমস্যাটি NP-hard.

তাহলে বাস্তবে কী হয়? দুটি পথ। এক, exact পদ্ধতি — Quine–McCluskey দিয়ে সব PI, তারপর Petrick-এর পদ্ধতি বা branch-and-bound দিয়ে cover; মাঝারি মাপে চলে, আর আধুনিক exact tool অনেক বুদ্ধিমান কৌশলে বেশ বড় সমস্যাও সমাধান করে। দুই, heuristic — Espresso-র মতো tool সব PI না বানিয়েই বর্তমান cover-কে বারবার “বড় করা, অপ্রয়োজনীয় বাদ দেওয়া, আবার ছোট করে নতুন দিকে বড় করা” চক্রে উন্নত করে, আর খুব কাছাকাছি-minimal উত্তরে দ্রুত পৌঁছায়। বাস্তবে এক-দুটি literal বেশি হলেও কয়েক সেকেন্ডে উত্তর পাওয়া বেশি মূল্যবান।

মূল উপলব্ধি: K-map সহজ লাগে কারণ ৪ চলক খুব ছোট। সমস্যার আসল চেহারা — সূচকীয় সংখ্যক PI আর NP-hard cover — চলক বাড়লেই প্রকাশ পায়, আর তখন algorithm ও heuristic ছাড়া উপায় নেই। ছোট উদাহরণে exhaustive search দিয়ে যাচাই করা, আর বড় উদাহরণে প্রায়-minimal মেনে নেওয়া — এটিই প্রকৌশলের বাস্তবতা।

প্র ০৫K-map-কে torus বলা হলো। আসলে এর পেছনে আরেকটি জ্যামিতি আছে — n-মাত্রার ঘনক (hypercube). এই ছবি কীভাবে দল, prime implicant আর ৫ চলকের সমস্যাকে ব্যাখ্যা করে?

n বিটের প্রতিটি নকশাকে একটি বিন্দু ধরুন, আর যে দুটি নকশা ঠিক এক বিটে আলাদা তাদের একটি দাগ দিয়ে জুড়ে দিন। n = ২-এ পাওয়া যায় একটি বর্গ (চার কোণ 00, 01, 11, 10), n = ৩-এ একটি সাধারণ ঘনক (আটটি কোণ), আর n = ৪-এ একটি চার-মাত্রার ঘনক — tesseract বা hypercube, যার ১৬টি কোণ আর প্রতিটি কোণ থেকে ৪টি দাগ। এখানে দুটি কোণের মধ্যে সবচেয়ে কম কয়টি দাগ পেরোতে হয় = তাদের Hamming distance.

এই ছবিতে একটি product term হলো একটি উপ-ঘনক (subcube): একটি literal-এর term (যেমন A′) অর্ধেক কোণ — একটি তিন-মাত্রার “মুখ”; দুই literal-এর term (যেমন B′D′) একটি বর্গাকার মুখ; তিন literal-এর term একটি দাগ (দুটি কোণ)। ২-এর ঘাতের নিয়মটি এখানে স্বতঃসিদ্ধ — k-মাত্রার উপ-ঘনকে ঠিক ২kটি কোণ। Prime implicant হলো এমন উপ-ঘনক যা পুরোটা 1 (বা X) কোণে, আর কোনো দিকে বাড়ালে একটি 0 কোণ ঢুকে পড়ে। সরলীকরণ মানে: সব 1-কোণকে সবচেয়ে কম, সবচেয়ে বড় উপ-ঘনক দিয়ে ঢাকা।

K-map এই চার-মাত্রার আকৃতিকে কাগজে চাপা দেওয়ার একটি চতুর উপায়। প্রতিটি ঘরের ৪টি প্রতিবেশী — ওপর, নিচ, ডান, বাঁ — ঠিক hypercube-এর ৪টি দাগ, যদি কিনারাগুলো জুড়ে দিই (torus). ৪ মাত্রা পর্যন্ত এটি নিখুঁতভাবে কাজ করে, কারণ দুই মাত্রার torus-এ প্রতিটি ঘরের ঠিক ৪টি প্রতিবেশী। কিন্তু ৫ চলকে প্রতিটি কোণের ৫টি প্রতিবেশী, আর সমতল ছকে ৫ম দিকটি রাখার জায়গা নেই — তাই দুটি ছক পাশাপাশি এঁকে “একটির ওপর আরেকটি” কল্পনা করতে হয়। এখানেই চোখের সুবিধা ভেঙে পড়ে।

এই জ্যামিতি অন্য জায়গাতেও ফিরে আসে। কিছু পুরোনো সমান্তরাল কম্পিউটারে processor-গুলো hypercube আকারে জোড়া ছিল, যাতে যেকোনো দুটির মধ্যে বার্তা যেতে সর্বোচ্চ n ধাপ লাগে। আর error-correcting code-এ (Computer Networks কোর্সের error detection পর্বে Hamming code) বৈধ codeword-গুলো এই ঘনকের কোণে পরস্পর থেকে দূরে বসানো হয়, যাতে এক-দুটি বিট উল্টালেও ধরা যায়।

মূল উপলব্ধি: K-map হলো চার-মাত্রার hypercube-এর একটি সমতল নকশা; প্রতিটি দল একটি উপ-ঘনক, আর ২-এর ঘাতের নিয়ম জ্যামিতি থেকেই আসে। ৫ চলকে সমতল নকশা আর যথেষ্ট নয় — তাই algorithm লাগে।

অনুশীলন

পরীক্ষার খাতার মতো করে map এঁকে, প্রতিটি দল চিহ্নিত করে সমাধান করুন, তারপর উত্তর মিলিয়ে দেখুন। ওপরের minimiser-এ নিজের উত্তর যাচাইও করতে পারেন।

  1. Don't care-সহ ৪ চলক — SOP আর POS: F(A, B, C, D) = Σm(1, 3, 7, 11, 15) + d(0, 2, 5). (ক) Minimal SOP বের করুন। কয়টি সমান ভালো উত্তর আছে? (খ) Minimal POS বের করুন। (গ) কোনটি সস্তা?
    AB\CD   00   01   11   10
     00      X    1    1    X
     01      0    X    1    0
     11      0    0    1    0
     10      0    0    1    0

    (ক) কলাম CD = 11 পুরোটা 1 (m3, m7, m15, m11) → CD — m11 আর m15-কে আর কেউ ঢাকে না, তাই এটি essential. বাকি থাকে শুধু m1. m1-এর সবচেয়ে বড় দল দুটি: X m0, m2-কে নিয়ে ওপরের সারি (m0, m1, m3, m2) → A′B′; অথবা X m5-কে নিয়ে (m1, m3, m5, m7) → A′D. দুটিই ২ literal. তাই দুটি minimal SOP: F = CD + A′B′ অথবা F = CD + A′D — প্রতিটি ২ term, ৪ literal.

    (খ) 0-গুলো: m4, m6, m8, m9, m10, m12, m13, m14. X m0, m2-কে 0 ধরলে কলাম 00 আর 10 মিলে (ডান-বাঁ কিনারা পেরিয়ে) ৮টি ঘর — m0, m4, m12, m8, m2, m6, m14, m10 — সবগুলোতে D = 0 → F′-এর term D′. বাকি 0 m9, m13: এদের সাথে m8, m12 মিলিয়ে (নিচের দুই সারি, কলাম 00-01) → A = 1, C = 0 → AC′. F′ = D′ + AC′, তাই F = D(A′ + C) — ২টি বন্ধনী, ৩ literal.

    (গ) POS সস্তা (৩ বনাম ৪ literal). মনে রাখুন, D(A′ + C) m5-কে 1 বানায় (CD + A′D-এর মতো), আর m0, m2-কে 0 — অর্থাৎ CD + A′B′-এর সাথে don't care সারিগুলোতে এর আচরণ আলাদা। অংশ ৭-এর কোডের তৃতীয় ফল এটিই নিশ্চিত করে।

  2. Prime আর essential চিহ্নিত করুন: F(A, B, C, D) = Σm(2, 3, 5, 7, 8, 9, 10, 11, 13, 15). সব prime implicant-এর তালিকা দিন, কোনগুলো essential বলুন, আর minimal SOP লিখুন। কোন PI-গুলো উত্তরে থাকবে না, আর কেন?
    AB\CD   00   01   11   10
     00      0    0    1    1
     01      0    1    1    0
     11      0    1    1    0
     10      1    1    1    1

    সব PI (৫টি, প্রতিটি ৪ ঘরের): AB′ (m8, m9, m11, m10 — নিচের সারি); B′C (m2, m3, m10, m11 — ওপর আর নিচের সারির শেষ দুই কলাম, ওপর-নিচ কিনারা পেরিয়ে); BD (m5, m7, m13, m15 — মাঝের বর্গ); CD (m3, m7, m15, m11 — কলাম 11); AD (m9, m11, m13, m15).

    Essential: m2-কে শুধু B′C ঢাকে → essential. m8-কে শুধু AB′ → essential. m5-কে শুধু BD → essential. এই তিনটি মিলে ঢাকে 2, 3, 10, 11, 8, 9, 5, 7, 13, 15 — দশটি 1-ই।

    উত্তর: F = AB′ + B′C + BD — ৩ term, ৬ literal. CD আর AD prime implicant হলেও অপ্রয়োজনীয় — তাদের প্রতিটি ঘর তিনটি essential PI-তে আগেই ঢাকা। CD-কে “দেখতে সুন্দর” পুরো কলাম বলে অনেকে নিয়ে ফেলেন; তাতে উত্তর ভুল হয় না, কিন্তু minimal থাকে না।

  3. নকশা — BCD থেকে excess-3 converter: ৪ বিটের BCD ইনপুট ABCD (০–৯) থেকে excess-3 আউটপুট WXYZ (অঙ্ক + ৩) বানানোর circuit নকশা করুন। ১০–১৫ don't care. চারটি আউটপুটের minimal SOP দিন, আর W-কে শুধু NAND gate দিয়ে আঁকুন।

    Truth table থেকে প্রতিটি আউটপুট কোন অঙ্কে 1: অঙ্ক ০–৯-এর excess-3 হলো 0011, 0100, 0101, 0110, 0111, 1000, 1001, 1010, 1011, 1100. তাই W = Σm(5, 6, 7, 8, 9), X = Σm(1, 2, 3, 4, 9), Y = Σm(0, 3, 4, 7, 8), Z = Σm(0, 2, 4, 6, 8) — প্রতিটিতে + d(10–15).

    W: নিচের দুই সারি (A, ৮-এর দল X-সহ), মাঝের বর্গ m5, m7, m13, m15 → BD, আর m6, m7, m14, m15 → BC. W = A + BC + BD (৫ literal).
    X: m1, m3, m9, m11 → B′D; m2, m3, m10, m11 → B′C; m4-এর সাথে X m12 → BC′D′. X = B′C + B′D + BC′D′ (৭ literal).
    Y: কলাম 00 (m0, m4, m12, m8) → C′D′; কলাম 11 (m3, m7, m15, m11) → CD. Y = CD + C′D′ (= C ⊙ D).
    Z: কলাম 00 আর 10 মিলে আটটি ঘর → Z = D′.

    W NAND–NAND-এ: W = A + BC + BD = ( A′ · (BC)′ · (BD)′ )′. প্রথম স্তরে দুটি দুই-ইনপুটের NAND (B, C) আর (B, D); একা literal A-কে NAND–NAND-এ নিতে হলে প্রথম স্তরে তার complement A′ লাগে (একটি এক-ইনপুটের NAND, অর্থাৎ inverter). দ্বিতীয় স্তরে তিন-ইনপুটের NAND: ইনপুট A′, (BC)′, (BD)′. আরও সরল রূপ: W = A + B(C + D) — বহু-স্তরের এই রূপে B একবারই লাগে, তাই literal ৫ থেকে ৪-এ নামে; এটিই পর্ব ১০-এর multi-level logic-এর ধারণা।

  4. আউটপুট অনুমান করুন, তারপর নকশা: অংশ ৫-এর minimiser-এর শেষের লাইনগুলোর জায়গায় kmap(3, [3, 5, 6, 7]); (৩-ইনপুটের majority — অন্তত দুটি ইনপুট 1 হলে 1) আর kmap(4, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); (BCD-বৈধতা) দিলে কী ছাপবে — প্রথমে কাগজে অনুমান করুন, তারপর চালিয়ে মিলিয়ে নিন। তারপর majority function-টি শুধু NAND দিয়ে আঁকুন।
    A\BC  00  01  11  10
    0     .   .   1   .
    1     .   1   1   1
    prime implicants: BC(3,7)  AC(5,7)  AB(6,7)
    essential: BC, AC, AB
    F = BC + AC + AB   [3 terms, 6 literals, truth table OK]
    --------------------------------------------
    AB\CD 00  01  11  10
    00    1   1   1   1
    01    1   1   1   1
    11    .   .   .   .
    10    1   1   .   .
    prime implicants: B'C'(0,1,8,9)  A'(0,1,2,3,4,5,6,7)
    essential: B'C', A'
    F = B'C' + A'   [2 terms, 3 literals, truth table OK]
    --------------------------------------------

    কেন: majority-তে m7 (111) তিনটি জোড়ার মাঝখানে — প্রতিটি জোড়া একটি করে আলাদা 1-কে (m3, m5, m6) একা ঢাকে, তাই তিনটিই essential: F = AB + BC + AC. BCD-বৈধতায় ওপরের দুই সারি একটি ৮-এর দল A′, আর m8, m9 ওপরের সারির সাথে কিনারা পেরিয়ে B′C′ — অংশ ৪-এর উদাহরণ ৩।

    Majority NAND–NAND-এ: F = ( (AB)′ · (BC)′ · (AC)′ )′ — প্রথম স্তরে তিনটি দুই-ইনপুটের NAND, দ্বিতীয় স্তরে একটি তিন-ইনপুটের NAND; মোট ৪টি gate, কোনো inverter লাগে না কারণ কোনো literal complement নয়। এই circuit-টি তিনটি কপির মধ্যে “ভোট” নেওয়ার জন্য ব্যবহৃত হয় (triple modular redundancy) — আর পর্ব ১১-এ দেখবেন, full adder-এর carry আউটপুটও ঠিক এই majority function.

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

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

ক্রমK-map দিয়ে minimal SOP বের করার ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)

  1. Gray ক্রমে map এঁকে প্রতিটি minterm-এ 1 আর don't care-এ X বসানো
  2. প্রতিটি 1 থেকে যত বড় সম্ভব দল খুঁজে সব prime implicant-এর তালিকা করা
  3. যে 1-কে মাত্র একটি PI ঢাকে, সেই essential PI-গুলো নেওয়া
  4. বাকি 1-গুলো সবচেয়ে কম সংখ্যক ও কম literal-এর PI দিয়ে ঢাকা
  5. প্রতিটি দলকে product term হিসেবে পড়ে OR করা
  6. truth table-এর প্রতিটি সারিতে নতুন রাশি মিলিয়ে যাচাই করা

৪ চলকের K-map-এ কলাম (CD) কোন ক্রমে সাজানো হয়?

  • 00, 01, 10, 11
  • 00, 01, 11, 10
  • 00, 11, 01, 10
  • 11, 10, 01, 00

F(A, B, C, D) = Σm(0, 2, 8, 10)-এর minimal SOP কোনটি?

  • B′D′
  • A′B′
  • A′B′D′ + AB′D′
  • C′D′

F(A, B, C, D) = Σm(1, 5, 6, 7, 11, 12, 13, 15)-এর জন্য কোন কথাটি সঠিক?

  • BD essential prime implicant, তাই উত্তরে থাকতেই হবে
  • কোনো essential prime implicant নেই
  • BD prime implicant-ই নয়
  • BD prime implicant, কিন্তু minimal উত্তরে থাকে না

৪ চলকের (A, B, C, D) K-map-এ নিচের কোন ঘরের সেটটি একটি বৈধ দল নয়?

  • m1, m3, m9, m11
  • m4, m6, m12, m14
  • m5, m10
  • m0, m8

একটি circuit BCD অঙ্ক ABCD (০–৯, A হলো MSB) নিয়ে আউটপুট 1 দেয় যখন অঙ্কটি ৫ বা তার বেশি। ইনপুট ১০–১৫ don't care হলে minimal SOP কোনটি?

  • AB′C′ + A′BD + A′BC
  • A + BD + BC
  • A + B
  • A + BCD

একটি K-map-এ 0-গুলোর দল বানিয়ে পাওয়া গেল BD′ + CD + AB. Function F-এর minimal POS কোনটি?

  • (B′ + D)(C′ + D′)(A′ + B′)
  • (B + D′)(C + D)(A + B)
  • BD′ + CD + AB
  • B′D + C′D′ + A′B′

শব্দকোষ

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

মনে রাখুন

  1. K-map = Gray ক্রমে (00, 01, 11, 10) সাজানো truth table; পাশাপাশি ঘর এক চলকে আলাদা, কিনারা আর কোণ পেরিয়েও — map একটি torus, আর প্রতিটি দল XY + XY′ = X-এর প্রয়োগ।
  2. দল: শুধু 1/X, ২-এর ঘাত আকার, আয়তাকার, কোনাকুনি নয়; ২k ঘরের দলে n−k literal — দলে যে চলক বদলায় না শুধু সেগুলো থাকে।
  3. পদ্ধতি: সব PI → essential PI → বাকিটুকু সবচেয়ে কম খরচে। সবচেয়ে বড় দলও অপ্রয়োজনীয় হতে পারে; essential না থাকলে একাধিক minimal উত্তর থাকতে পারে।
  4. Don't care দরকার হলে 1, না হলে 0 — segment a ১১ থেকে ৬ literal; কিন্তু অবৈধ ইনপুটে circuit কী করবে তা লিখে রাখুন।
  5. POS: 0-এর দল → F′ → De Morgan; SOP → NAND–NAND, POS → NOR–NOR. প্রতিটি উত্তর truth table দিয়ে যাচাই করুন।

পরের পর্বে: ৫–৬ চলকে K-map যখন হাঁপিয়ে ওঠে, তখন Quine–McCluskey — টেবিলে জোড়া মিলিয়ে যন্ত্রে চালানো যায় এমন পদ্ধতি; একাধিক আউটপুট একসাথে সরল করা, বহু-স্তরের logic, আর gate-এর delay থেকে জন্ম নেওয়া hazard ও তার প্রতিকার।

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

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