পাঠ ৪৬ · ৫৬-এর মধ্যে · মডিউল ১০
Home / Courses / Formal Language & Automata Theory / Theory of Computation / কুক-লেভিন থিওরেম

কুক-লেভিন থিওরেম — SAT NP-কমপ্লিট

Cook-Levin theorem — SAT is NP-complete
৯ মিনিট পড়া উচ্চ · Advanced Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • কুক-লেভিন থিওরেমের সঠিক স্টেটমেন্ট ও এর ঐতিহাসিক গুরুত্ব
  • প্রমাণের হাই-লেভেল কৌশল — কম্পিউটেশন-হিস্টোরিকে বুলিয়ান ফর্মুলায় এনকোড করা
  • এই এনকোডিং কৌশলের একটি ছোট্ট, হাতে-তৈরি, কোড-ভেরিফাইড দৃষ্টান্ত
  • Cook-Levin কেন এই কোর্সের বাকি NP-কমপ্লিটনেস আলোচনার ভিত্তি (L47-এর সেতু)

১ · কুক-লেভিন থিওরেম

থিওরেম (কুক, ১৯৭১; লেভিন, স্বাধীনভাবে একই সময়ে): SAT NP-কমপ্লিট। এটি এই মডিউলের সবচেয়ে গুরুত্বপূর্ণ, ঐতিহাসিকভাবে তাৎপর্যপূর্ণ ফলাফল — কারণ এটিই ছিল প্রথম সমস্যা যার NP-কমপ্লিটনেস প্রমাণিত হয়েছিল, যা প্রথমবার প্রতিষ্ঠা করে যে NP-কমপ্লিট ক্লাসটি খালি নয় — এবং L45-এর রিডাকশন-টেকনিক ব্যবহার করে আরও সমস্যা NP-কমপ্লিট প্রমাণ করার জন্য একটি concrete শুরুর বিন্দু দেয়।

২ · প্রমাণের কৌশল

SAT যে NP-তে, তা আমরা আগেই জানি (L44 — সার্টিফিকেট হলো একটি ভেরিয়েবল-অ্যাসাইনমেন্ট, যাচাই পলিনমিয়াল সময়ে)। কঠিন দিকটি হলো দেখানো NP-এর প্রতিটি ল্যাঙ্গুয়েজ SAT-তে রিডিউস করা যায়। প্রমাণটি — একটি নির্বিচারে বেছে নেওয়া নন-ডিটারমিনিস্টিক পলিনমিয়াল-টাইম TM $M$ ও ইনপুট $w$-এর জন্য — একটি বুলিয়ান ফর্মুলা $\phi_{M,w}$ নির্মাণ করে যা সন্তোষজনক হয় যদি এবং শুধু যদি $M$ ইনপুট $w$-তে accept করে। ফর্মুলার ভেরিয়েবলগুলো $M$-এর সম্পূর্ণ কম্পিউটেশন হিস্টোরি এনকোড করে — টেপের বিষয়বস্তু, হেড-এর অবস্থান, ও অবস্থা (state), পলিনমিয়াল টাইম-বাউন্ড পর্যন্ত প্রতিটি সময়-ধাপে — আর ফর্মুলার ক্লজগুলো নিশ্চিত করে এই এনকোড করা হিস্টোরি $M$-এর একটি বৈধ, সঠিকভাবে-transitioning কম্পিউটেশন প্রতিনিধিত্ব করে যা accept-এ শেষ হয়। এই নির্মাণ সম্পূর্ণ বিস্তারিতভাবে genuinely জটিল (সৎভাবে বলা প্রয়োজন) — কিন্তু মূল অন্তর্দৃষ্টিটি স্পষ্টভাবে বলা যায়:

মূল অন্তর্দৃষ্টি

যেকোনো TM-এর যেকোনো কম্পিউটেশন একটি পলিনমিয়াল-সাইজ বুলিয়ান ফর্মুলায় "চ্যাপ্টা" (flatten) করে ফেলা যায় — যা বলে "এটি একটি বৈধ, accepting কম্পিউটেশন হিস্টোরি।"

৩ · একটি ছোট্ট, হাতে-তৈরি দৃষ্টান্ত

সম্পূর্ণ সাধারণ কুক-লেভিন নির্মাণ এই ফরম্যাটের জন্য বেশি জটিল — তার বদলে, একটি অতি ক্ষুদ্র, নির্দিষ্ট টয় কম্পিউটেশনের উপর এনকোডিং-এর ধারণাটি concretely দেখানো যাক। একটি ৩-সেল টেপ ($p=0,1,2$), ৩টি সম্ভাব্য সিম্বল ({0, 1, _}), এবং দুটি সময়-ধাপ ($t=0$ শুরু, $t=1$ এক ধাপ পরে) বিবেচনা করুন। ভেরিয়েবল $\texttt{t}i\texttt{\_p}j\texttt{\_s}k$ মানে "সময় $i$-এ, পজিশন $j$-এ সিম্বল $k$ আছে।" দুই ধরনের ক্লজ লাগবে —

  • (a) প্রতিটি সেল-সময়ে ঠিক একটি সিম্বল: প্রতি $(t,p)$-এর জন্য অন্তত একটি সিম্বল সত্য (at-least-one), এবং কোনো দুটি সিম্বল একসাথে সত্য নয় (at-most-one, প্রতিটি জোড়ার জন্য একটি ক্লজ)।
  • (b) ট্রানজিশন সামঞ্জস্যতা: একটি নির্দিষ্ট ট্রানজিশন রুল অনুযায়ী, সময় $t$-এ পজিশন $p$-এ সিম্বল $s$ থাকলে, সময় $t{+}1$-এ সেই পজিশনে rule[p][s] সিম্বল থাকতেই হবে — একটি ইমপ্লিকেশন ক্লজ ($\lnot a \lor b$ আকারে) হিসেবে এনকোড করা।

নিচের কোড সেলে এই ক্লজগুলো নির্মাণ করে, এবং L44-এর verify_sat ব্যবহার করে যাচাই করা হবে যে TM-এর প্রকৃত, সঠিক কম্পিউটেশন ট্রেসের সাথে মিলে যাওয়া অ্যাসাইনমেন্ট এই সব ক্লজ সন্তুষ্ট করে — এবং একটি ভুল (ট্রানজিশন-রুল-লঙ্ঘনকারী) ট্রেস তা করে না।

Python
# Cook-Levin-স্টাইল এনকোডিং-এর একটি ছোট্ট, হাতে-তৈরি দৃষ্টান্ত -- সম্পূর্ণ সাধারণ নির্মাণ নয়
# L44-এর verify_sat পুনর্ব্যবহার করে (একই eval_formula লজিক, eval()/exec()/re ছাড়াই)

import itertools

def eval_formula(node, assignment):
    if isinstance(node, str):
        return assignment[node]
    op = node[0]
    if op == 'not':
        return not eval_formula(node[1], assignment)
    if op == 'and':
        return eval_formula(node[1], assignment) and eval_formula(node[2], assignment)
    if op == 'or':
        return eval_formula(node[1], assignment) or eval_formula(node[2], assignment)
    raise ValueError(f"অজানা অপারেটর: {op}")

def verify_sat(formula, assignment):
    return eval_formula(formula, assignment)

def var(t, p, s):
    return f"t{t}_p{p}_s{s}"

def conjunction(subformulas):
    result = subformulas[0]
    for f in subformulas[1:]:
        result = ('and', result, f)
    return result

def disjunction(subformulas):
    result = subformulas[0]
    for f in subformulas[1:]:
        result = ('or', result, f)
    return result

cells = [0, 1, 2]
symbols = ['0', '1', '_']
time_steps = [0, 1]   # t=0 (শুরু) -> t=1 (এক ধাপ পরে)

# একটি নির্দিষ্ট, দেওয়া ট্রানজিশন রুল -- পজিশন 0: '0' -> '1' (flip), বাকি সব identity;
# পজিশন 1, 2: সবসময় identity (অপরিবর্তিত থাকে)
rule = {
    0: {'0': '1', '1': '1', '_': '_'},
    1: {'0': '0', '1': '1', '_': '_'},
    2: {'0': '0', '1': '1', '_': '_'},
}

clauses = []

# (a) প্রতিটি সেল-সময়ে ঠিক একটি সিম্বল
for t in time_steps:
    for p in cells:
        vars_tp = [var(t, p, s) for s in symbols]
        clauses.append(disjunction(vars_tp))                    # at least one
        for s1, s2 in itertools.combinations(symbols, 2):
            clauses.append(('or', ('not', var(t, p, s1)), ('not', var(t, p, s2))))  # at most one

# (b) t -> t+1 ট্রানজিশন rule-এর সাথে সামঞ্জস্যপূর্ণ
for p in cells:
    for s in symbols:
        clauses.append(('or', ('not', var(0, p, s)), var(1, p, rule[p][s])))

phi = conjunction(clauses)
print(f"মোট ক্লজ সংখ্যা: {len(clauses)}")

def build_assignment(trace):
    assignment = {}
    for t in time_steps:
        for p in cells:
            for s in symbols:
                assignment[var(t, p, s)] = (trace[t][p] == s)
    return assignment

# আসল, সঠিক কম্পিউটেশন ট্রেস: t=0 টেপ = 0,1,_  ->  t=1 টেপ = 1,1,_  (rule অনুযায়ী পজিশন 0 ফ্লিপ হয়েছে)
correct_trace = {0: ['0', '1', '_'], 1: ['1', '1', '_']}
correct_assignment = build_assignment(correct_trace)
print("সঠিক কম্পিউটেশন ট্রেস phi সন্তুষ্ট করে?", verify_sat(phi, correct_assignment), "(প্রত্যাশিত: True)")

# ভুল ট্রেস: পজিশন 0 flip না হয়ে '0'-ই থেকে গেছে -- rule (b) লঙ্ঘন করে
wrong_trace = {0: ['0', '1', '_'], 1: ['0', '1', '_']}
wrong_assignment = build_assignment(wrong_trace)
print("ভুল কম্পিউটেশন ট্রেস phi সন্তুষ্ট করে?", verify_sat(phi, wrong_assignment), "(প্রত্যাশিত: False)")

    
লক্ষ্য করুন phi সম্পূর্ণ একটি সাধারণ TM-এর নয়, বরং একটি নির্দিষ্ট, দেওয়া ট্রানজিশন রুলের সাথে সামঞ্জস্যতা যাচাই করছে — সম্পূর্ণ কুক-লেভিন নির্মাণে ভেরিয়েবল ও ক্লজের সংখ্যা $M$-এর স্টেট-সেট, $\Sigma$, এবং টাইম-বাউন্ডের উপর নির্ভর করে (এখনও পলিনমিয়াল, কিন্তু অনেক বড়) — এখানে যা দেখানো হলো তা সেই একই নীতির একটি ক্ষুদ্রতম সম্ভব দৃষ্টান্ত মাত্র।
মূল কথা · Key takeaway

কুক-লেভিন থিওরেম প্রতিষ্ঠা করে SAT NP-কমপ্লিট — NP-এর প্রতিটি সমস্যা এতে পলিনমিয়াল সময়ে রিডিউস করা যায়, কারণ যেকোনো নন-ডিটারমিনিস্টিক পলিনমিয়াল-টাইম TM-এর কম্পিউটেশন একটি পলিনমিয়াল-সাইজ বুলিয়ান ফর্মুলায় এনকোড করা সম্ভব। এটিই ছিল ইতিহাসের প্রথম NP-কমপ্লিটনেস প্রমাণ — এখন থেকে (L47) প্রতিটি নতুন NP-কমপ্লিট সমস্যা SAT (বা আগে থেকে-জানা অন্য কোনো NP-কমপ্লিট সমস্যা) থেকে সরাসরি রিডাকশনের একটি চেইন দিয়ে প্রমাণিত হবে — ট্রানজিটিভিটি ব্যবহার করে।

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

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

প্র ০১ কুক-লেভিন থিওরেম কেন "ইতিহাসের প্রথম NP-কমপ্লিটনেস প্রমাণ" হওয়ার কারণে এত গুরুত্বপূর্ণ — শুধু "SAT NP-তে কঠিন সমস্যা" জানাটুকু কি যথেষ্ট ছিল না?

না — L45-এর NP-হার্ড ও NP-কমপ্লিটের সংজ্ঞা স্মরণ করুন: NP-হার্ড হতে হলে NP-এর প্রতিটি সমস্যা রিডিউস করা যেতে হবে, যা প্রমাণ করতে একটি সাধারণ, নির্বিচারে-বাছাই-করা TM $M$ নিয়ে কাজ করতে হয় — এটি করার আগে NP-কমপ্লিট ক্লাসে কোনো পরিচিত সদস্যই ছিল না, তাই L45-এর "যদি একটি NP-কমপ্লিট সমস্যা রিডিউস করা যায়, তাহলে ট্রানজিটিভিটি দিয়ে আরেকটি প্রমাণ করা যায়" কৌশলটি ব্যবহারই করা যেত না। কুক-লেভিন সেই প্রথম "anchor" সরবরাহ করে যা ছাড়া বাকি সব NP-কমপ্লিটনেস প্রমাণ (L47) সম্ভবই হতো না।

প্র ০২ উপরের কোড সেলে ক্লজ (a) ("প্রতিটি সেল-সময়ে ঠিক একটি সিম্বল") না থাকলে কী সমস্যা হতে পারত?

ক্লজ (a) ছাড়া, একটি অ্যাসাইনমেন্ট একই সেল-সময়ে একাধিক (বা শূন্য) সিম্বলকে True করতে পারত — অর্থাৎ $\phi$ সন্তুষ্ট করলেও সেই অ্যাসাইনমেন্ট আর কোনো বাস্তব, ভৌত অর্থপূর্ণ TM টেপ-কনফিগারেশনের প্রতিনিধিত্ব করত না (একটি টেপ-সেলে একসাথে দুটি ভিন্ন সিম্বল থাকা অর্থহীন)। এই "exactly-one" ক্লজগুলো নিশ্চিত করে ফর্মুলার প্রতিটি সন্তোষজনক অ্যাসাইনমেন্ট একটি বৈধ, ভালোভাবে-সংজ্ঞায়িত টেপ-স্ন্যাপশট বর্ণনা করে।

প্র ০৩ কোড সেলে wrong_trace কেন phi-কে সন্তুষ্ট করে না, ধাপে ধাপে ব্যাখ্যা করুন।

wrong_trace-এ পজিশন 0-এর সিম্বল $t=0$-এ '0' এবং $t=1$-এও '0' থেকে যায় — কিন্তু rule[0]['0'] = '1' অনুযায়ী পজিশন 0 flip হওয়ার কথা ছিল। ক্লজ (b)-এর সংশ্লিষ্ট ইমপ্লিকেশন ক্লজ হলো $\lnot \texttt{t0\_p0\_s0} \lor \texttt{t1\_p0\_s1}$ — এই wrong_trace-এ t0_p0_s0 True (t=0-এ পজিশন 0-এ সিম্বল '0' আছে), কিন্তু t1_p0_s1 False (t=1-এ পজিশন 0-এ সিম্বল '1' নেই, বরং '0' আছে) — তাই এই একটি ক্লজই False হয়ে যায়, ফলে পুরো conjunction ($\phi$) False হয়ে যায়। ঠিক এভাবেই ক্লজগুলো "অবৈধ" কম্পিউটেশন ট্রেস প্রত্যাখ্যান করে।

অনুশীলন

  1. পরীক্ষা করুন: উপরের কোড সেলে rule[1]-কে পরিবর্তন করে পজিশন 1-এও '0'→'1' ফ্লিপ রুল বসান, তারপর correct_trace-এর $t=1$ অংশ সেই অনুযায়ী আপডেট করে Run চেপে দেখুন এখনও verify_sat True ফেরত দেয় কি না।

    যদি rule[1] = {'0': '1', '1': '1', '_': '_'} করা হয় এবং correct_trace-এর $t=1$ পজিশন 1-কেও '1' করে আপডেট করা হয় (অর্থাৎ correct_trace = {0: ['0','1','_'], 1: ['1','1','_']} — এই নির্দিষ্ট উদাহরণে পজিশন 1 আগে থেকেই '1' ছিল বলে দৃশ্যত পরিবর্তন নেই), তাহলে সব ক্লজ এখনও সন্তুষ্ট হবে ও verify_sat এখনও True দেবে — যতক্ষণ ট্রেসটি নতুন rule-এর সাথে সামঞ্জস্যপূর্ণ থাকে, ততক্ষণ ফলাফল অপরিবর্তিত থাকা উচিত, যা নিশ্চিত করে ক্লজ (b) সত্যিই rule অনুযায়ী ট্রানজিশন যাচাই করছে, rule নিজে হার্ডকোড করা কোনো নির্দিষ্ট উত্তর নয়।

  2. চিন্তা করুন: সম্পূর্ণ কুক-লেভিন নির্মাণে সময়-ধাপের সংখ্যা $M$-এর পলিনমিয়াল টাইম-বাউন্ড পর্যন্ত হয় (এই উদাহরণে মাত্র ২টি সময়-ধাপ ব্যবহৃত হয়েছে)। যদি ইনপুট length $n$ ও টাইম-বাউন্ড $O(n^k)$ হয়, ভেরিয়েবল সংখ্যা মোটামুটি কীসের সমানুপাতিক হবে (সময়-ধাপ × টেপ-পজিশন × সিম্বল)? এটি কি এখনও পলিনমিয়াল?

    হ্যাঁ, এখনও পলিনমিয়াল — ভেরিয়েবল সংখ্যা মোটামুটি (সময়-ধাপ সংখ্যা) × (টেপ-পজিশন সংখ্যা) × (সিম্বল সংখ্যা)-এর সমানুপাতিক। সময়-ধাপ ও টেপ-পজিশন দুটোই $O(n^k)$ (যেহেতু একটি TM এক ধাপে সর্বোচ্চ এক ঘর টেপে নড়তে পারে, তাই $O(n^k)$ ধাপে সর্বোচ্চ $O(n^k)$ পজিশন ভ্রমণ করা যায়), আর সিম্বল-সংখ্যা একটি ধ্রুবক ($|\Gamma|$, TM-এর টেপ-আলফাবেটের আকার)। তাই মোট ভেরিয়েবল সংখ্যা $O(n^k) \times O(n^k) \times O(1) = O(n^{2k})$ — এখনও একটি পলিনমিয়াল, শুধু বড় exponent-এর — ঠিক যেমনটি L43-এ আলোচিত হয়েছিল, "পলিনমিয়াল" মানেই "ছোট" নয়, কিন্তু এটি এখনও এক্সপোনেনশিয়াল থেকে গুণগতভাবে ভিন্ন।

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

আগের পাঠ
L45 · পলিনমিয়াল-টাইম রিডাকশন ও NP-কমপ্লিটনেস