Halting Problem dengan Pembuktian Diagonal

Ketidakmampuan komputer menjawab halting problem juga dapat dibuktikan dengan pembuktian diagonal seperti yang Georg Cantor lakukan untuk bilangan real dalam interval (0, 1).

Pertanyaan dasarnya adalah sebagai berikut:

Adakah program yang dapat memeriksa sembarang program dengan sembarang input akan berhenti?

Kita akan membuktikan secara tak langsung dengan kontradiksi. Hipotesis nolnya adalah:

H0

Ada program yang dapat memeriksa keberhentian sembarang program untuk sembarang input.

Kita belum tahu apakah program itu benar-benar ada. Tapi kita akan namakan program itu sebagai \text{ncek}(p,i) dengan p adalah bilangan Gödel untuk sebuah program P (P kapital), dan i adalah input yang diberikan untuk dikerjakan oleh program tersebut.

\text{ncek}(p,i) = \begin{cases} \bold{ya}, &\text{ jika } P(i) \text{ akan berhenti} \\ \bold{tidak}, &\text{ jika } P(i) \text{ tidak akan berhenti} \\ \end{cases}

Karena \text{ncek} selalu dapat menentukan jawabannya, berarti \text{ncek} adalah program yang decidable.

Kemudian kita modifikasi sedikit program \text{ncek} ini menjadi semidecidable, yaitu berhenti dan menjawab ya jika P(i) akan berhenti, dan tidak berhenti (yang berarti tidak menjawab) jika P(i) tidak bisa berhenti.

\text{ncek}'(p,i) = \begin{cases} \bold{ya} (berhenti), &\text{ jika } P(i) \text{ akan berhenti} \\ \bold{...} (tidak\,berhenti), &\text{ jika } P(i) \text{ tidak akan berhenti} \\ \end{cases}

Dalam bentuk program Python (bukan program aktual), bentuknya kira-kira akan seperti ini:

def ncek'(p,i):
  if P(I) decidable:
    return 'Ya'
  else:
    while True:
      pass

Yang dibaca: Apakah P(i) akan berhenti? Jika ya maka berhenti dan laporkan ya, jika tidak maka jangan berhenti juga.

Karena program P bisa sangat banyak, kita akan mendaftarkannya sebagai P_1, P_2, P_3, dan seterusnya. Karena input yang diberikan adalah bilangan Gödel untuk masing-masing program, maka inputnya adalah p_1, p_2, p_3, dan seterusnya.

Program Program
p1 p2 p3 p4 p5 p6 p7 p8 p9 p10
P1 :
P2 :
P3 :
P4 :
P5 :
P6 :
P7 :
P8 :
P9 :
P10 :
:

Setiap sel dalam tabel akan mewakili kondisi dari \text{ncek}'(p_i,p_j).

Program Program
p1 p2 p3
P1 : ncek'(P1,p1) ncek'(P1,p2) ncek'(P1,p3)
P2 : ncek'(P2,p1) ncek'(P2,p2) ncek'(P2,p3)
P3 : ncek'(P3,p1) ncek'(P3,p2) ncek'(P3,p3)
P4 : ncek'(P4,p1) ncek'(P4,p2) ncek'(P4,p3)
P5 : ncek'(P5,p1) ncek'(P5,p2) ncek'(P5,p3)
P6 : ncek'(P6,p1) ncek'(P6,p2) ncek'(P6,p3)
P7 : ncek'(P7,p1) ncek'(P7,p2) ncek'(P7,p3)
P8 : ncek'(P8,p1) ncek'(P8,p2) ncek'(P8,p3)
P9 : ncek'(P9,p1) ncek'(P9,p2) ncek'(P9,p3)
P10 : ncek'(P10,p1) ncek'(P10,p2) ncek'(P10,p3)
:

Kemudian kita akan melakukan sesuatu yang nakal: Alih-alih mengerjakan \text{ncek}'(p,i) untuk menguji P(i), kita akan menggunakan nilai p sendiri sebagai input.

\text{ncek}'(p,p)

Hal nakal yang kita lakukan ini tidak lain adalah mengambil diagonal dari tabel.

Program Program
p1 p2 p3
P1 : ncek'(P1,p1) ncek'(P1,p2) ncek'(P1,p3)
P2 : ncek'(P2,p1) ncek'(P2,p2) ncek'(P2,p3)
P3 : ncek'(P3,p1) ncek'(P3,p2) ncek'(P3,p3)
P4 : ncek'(P4,p1) ncek'(P4,p2) ncek'(P4,p3)
P5 : ncek'(P5,p1) ncek'(P5,p2) ncek'(P5,p3)
P6 : ncek'(P6,p1) ncek'(P6,p2) ncek'(P6,p3)
P7 : ncek'(P7,p1) ncek'(P7,p2) ncek'(P7,p3)
P8 : ncek'(P8,p1) ncek'(P8,p2) ncek'(P8,p3)
P9 : ncek'(P9,p1) ncek'(P9,p2) ncek'(P9,p3)
P10 : ncek'(P10,p1) ncek'(P10,p2) ncek'(P10,p3)
:
D : ncek'(D,p1) ncek'(D,p2) ncek'(D,p3)

Jika \text{ncek}' menjawab tidak, berarti ia berhenti. Tandanya adalah · (titik). Jika \text{ncek}' tidak menjawab karena tidak pernah berhenti, tandanya adalah ∞.

Program Program
p1 p2 p3 p4 p5 p6 p7 p8 p9 p10
P1 : · · · · ·
P2 : · · ·
P3 : · · · · ·
P4 : · · · · ·
P5 : · · · · · · ·
P6 : · · · · ·
P7 : · · ·
P8 : · · · · · ·
P9 : · ·
P10 : · · · ·
:

Jadi apakah arti D ini? Setiap tanda dalam D mewakili \text{ncek}'(p_i,p_i), yaitu keberhentian P(p) alias keberhentian program yang diberi input bilangan Godel dirinya sendiri.

\begin{aligned} D(p_i) &= \text{ncek}'(p_i,p_i) \end{aligned}

atau

\begin{aligned} D(x) &= \text{ncek}'(x,x) \\ &= \begin{cases} \bold{ya}, &\text{ jika } X(x) \text{ akan berhenti} \\ \bold{...} (tidak\,berhenti), &\text{ jika } X(x) \text{ tidak akan berhenti} \\ \end{cases} \end{aligned}

Kemudian kita akan membalik diagonalnya menjadi D'.

Program Program
p1 p2 p3
P1 : ncek'(P1,p1) ncek'(P1,p2) ncek'(P1,p3)
P2 : ncek'(P2,p1) ncek'(P2,p2) ncek'(P2,p3)
P3 : ncek'(P3,p1) ncek'(P3,p2) ncek'(P3,p3)
P4 : ncek'(P4,p1) ncek'(P4,p2) ncek'(P4,p3)
P5 : ncek'(P5,p1) ncek'(P5,p2) ncek'(P5,p3)
P6 : ncek'(P6,p1) ncek'(P6,p2) ncek'(P6,p3)
P7 : ncek'(P7,p1) ncek'(P7,p2) ncek'(P7,p3)
P8 : ncek'(P8,p1) ncek'(P8,p2) ncek'(P8,p3)
P9 : ncek'(P9,p1) ncek'(P9,p2) ncek'(P9,p3)
P10 : ncek'(P10,p1) ncek'(P10,p2) ncek'(P10,p3)
:
D : ncek'(D,p1) ncek'(D,p2) ncek'(D,p3)
D' : ncek'(D',p1) ncek'(D',p2) ncek'(D',p3)
\begin{aligned} D(x) &= \text{ncek}'(x, x) \\ D'(x) &= \text{kebalikan } \text{ncek}'(x, x) \end{aligned}

D' sendiri merupakan program yang terdapat dalam daftar di atas, karena daftar tersebut sudah diasumsikan mengandung semua program. Juga D' memiliki bilangan Gödel d'. Namun jika demikian, berarti akan ada satu sel perpotongan antara baris D' dengan kolom d' yang merupakan keberhentian dari D'(d').

d'
D' ?
\begin{aligned} D'(d') &= \text{kebalikan } \text{ncek}'(d', d') \\ D'(d') &= \begin{cases} \bold{...} (tidak\,berhenti), &\text{ jika } D'(d') \text{ akan berhenti} \\ (berhenti), &\text{ jika } D'(d') \text{ tidak akan berhenti} \\ \end{cases} \end{aligned}

Apa yang akan terjadi berikutnya? Kondisi D'(d') dapat merupakan salah satu dari berhenti maupun tidak berhenti, sesuai definisi \text{ncek}'.

Jika D'(d') tidak berhenti

Jika D'(d') tidak berhenti, maka D'(d') sesuai instruksi justru akan berhenti.

\begin{aligned} D'(d') &= \begin{cases} \bold{...} (tidak\,berhenti), &\text{ jika } D'(d') \text{ akan berhenti} \\ \boxed{(berhenti)}, &\text{ jika } D'(d') \boxed{\text{ tidak akan berhenti}} \\ \end{cases} \end{aligned}

Jika D'(d') akan berhenti

Jika D'(d') akan berhenti, maka sesuai instruksi, D'(d') justru tidak berhenti.

\begin{aligned} D'(d') &= \begin{cases} \bold{...} \boxed{(tidak\,berhenti)}, &\text{ jika } D'(d') \boxed{\text{ akan berhenti}} \\ (berhenti), &\text{ jika } D'(d') \text{ tidak akan berhenti} \\ \end{cases} \end{aligned}

Kesimpulan untuk D'(d')

Karena baik berhenti maupun tidak berhenti mengharuskan D' untuk melakukan kebalikannya, ini menimbulkan kontradiksi, sehingga D' tidak dapat bekerja sesuai instruksinya. Penyebabnya tidak lain adalah hipotesis awal kita:

H0

Ada program yang dapat memeriksa keberhentian sembarang program untuk sembarang input.

Sehingga kita harus simpulkan bahwa bahwa H0 salah, dan menerima hipotesis alternatifnya.

H0

Ada program yang dapat memeriksa keberhentian sembarang program untuk sembarang input.

HA

Tidak ada program yang dapat memeriksa keberhentian sembarang program untuk sembarang input.

Konsekuensinya

Program seperti \text{ncek} ini adalah program yang sangat berguna karena kita jadi tidak harus menunggu sangat lama untuk mulai curiga bahwa suatu program tidak akan pernah berhenti. Cukup bertanya pada \text{ncek} apakah program P akan berhenti pada input I, dan \text{ncek} akan memberitahu kita.

Namun hasil pembuktian ini menunjukkan bahwa program seperti itu tidak mungkin dibuat.

Ini juga dapat kita tarik lebih luas lagi artinya. Berarti mungkin akan ada jenis program yang kita pikir cukup masuk akal untuk dibuat, ternyata tidak dapat diwujudkan.

Berikutnya: Apakah permasalahan ini hanya untuk komputer?

Ditulis oleh
Ari Prasetyo
Ditulis pada
Terakhir diupdate
Dipublikasikan
Frase kunci
sejarah pemikiran tokoh argumen diagonal