{"id":4145,"date":"2013-04-25T08:31:22","date_gmt":"2013-04-25T06:31:22","guid":{"rendered":"https:\/\/www.herr-rau.de\/wordpress\/?p=4145"},"modified":"2026-01-22T17:57:41","modified_gmt":"2026-01-22T16:57:41","slug":"das-halteproblem","status":"publish","type":"post","link":"https:\/\/www.herr-rau.de\/wordpress\/2013\/04\/das-halteproblem.htm","title":{"rendered":"Das Halteproblem"},"content":{"rendered":"<div style='text-align:right;'><small>(<a href='https:\/\/www.herr-rau.de\/wordpress\/2013\/04\/das-halteproblem.htm#comments'>7 Kommentare.<\/a>)<\/small> <\/div>\n<p>Zum Abitur und im Semester davor schreiben die Sch\u00fcler in Informatik Computerprogramme in einer Assembler-Programmiersprache. Die besteht zwar aus ganz einfachen Einzelschritten, aber genau das f\u00fchrt dazu, dass das ganze Programm etwas un\u00fcbersichtlich ist und man nicht auf den ersten Blick sieht, was es genau tut. Wenn ich die Sch\u00fclerprogramme also bewerten will, muss ich sie abtippen und laufen lassen, und dann sehe ich, ob am Schluss das richtige Ergebnis herauskommt. Wenn ja: volle Punktzahl, wenn nein: puh. Dann muss ich das Programm Schritt f\u00fcr Schritt nachvollziehen, um herauszufinden, wo das Problem ist &#8211; wo sich zum Beispiel eine Endlosschleife verbirgt, so dass das Programm nie aufh\u00f6rt zu laufen.<\/p>\n\n\n\n<p>In dieser Situation w\u00fcnschte ich mir ein Programm, das diese Arbeit automatisch f\u00fcr mich erledigt. Ich w\u00fcrde es mit den Sch\u00fclerprogrammen f\u00fcttern, und es w\u00fcrde mir danach sagen &#8222;ja, das Programm kommt fr\u00fcher oder sp\u00e4ter an ein Ende&#8220; oder &#8222;nein, das Programm wird in eine Endlosschleife geraten und nie aufh\u00f6ren&#8220; oder &#8222;das Programm kann in eine Endlosschleife geraten, je nach Startwert.&#8220;<\/p>\n\n\n\n<p>Die Frage, ob es so ein Programm gibt, hei\u00dft <strong>Halteproblem<\/strong> der Informatik. Und das Halteproblem ist allgemein nicht l\u00f6sbar &#8211; es <em>kann<\/em> so ein Programm nicht geben, egal wie gut Computer noch werden. (F\u00fcr spezielle Sonderf\u00e4lle, etwa Programme, die sich an bestimmte Vorgaben halten, ist es oft l\u00f6sbar. Aber eben nicht, wenn es um beliebige Programme geht.)<\/p>\n\n\n\n<p>Der Beweis folgt.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Teil 1: Was ein Computerprogramm ist.<\/h3>\n\n\n\n<p>Ein Computerprogramm kann man sich als ein Frage-Antwort-Maschinchen vorstellen, in das man zum Beispiel eine Zahl eingibt, dann rechnet das Maschinchen, um am Schluss macht es &#8222;Ping!&#8220; und eine Zahl kommt als Antwort heraus. Da gibt es zum Beispiel das Verdoppelungsmaschinchen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>verdoppeln(eines eingangswertes):\n  ergebnis: eingangswert mal 2<\/code><\/pre>\n\n\n\n<p>Das funktioniert nat\u00fcrlich nicht nur mit Zahlen, sondern auch mit Text. Lehrer tr\u00e4umen ja von einem Korrektur- und Benotungsmaschinchen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>benoten(eines aufsatzes):\n  (rechnen, rechnen, rechnen)\n  ergebnis: note<\/code><\/pre>\n\n\n\n<p>Die praktische Schwierigkeit liegt dabei in dem Schritt, den ich weggelassen habe: das mit dem Rechnen. Um das geht es hier aber gar nicht. <em>Wie<\/em> der Computer vorgeht, um zum gew\u00fcnschten Ergebnis zu kommen, interessiert uns im Moment nicht. Wichtig ist nur, dass ein Programm zum Berechnen eine Wiederholungsschleife ausf\u00fchren kann, dass ein Programmteil also immer und immer wiederholt wird, bis eine bestimmte Bedingung (die Wiederholbedingung) nicht mehr gilt. Bei den meisten \u00fcblichen Berechnungen kann man vorher sagen, wie oft das h\u00f6chstens der Fall sein wird, bei anderen Berechnungen ist das schwieriger.<\/p>\n\n\n\n<p>Um das zu veranschaulichen, verwende ich drei Beispielprogramme, auf die ich auch sp\u00e4ter zur\u00fcckkommen werde. Die Programme sind <code>countdown (von einer beliebigen Startzahl aus), endlosdrucken (eines beliebigen Starttextes)<\/code> und <code>ausdrucken(eines beliebigen Starttextes)<\/code>.<\/p>\n\n\n\n<p>Mein erstes Programm ist eigentlich nur ein kleines Hilfsprogramm:<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Ausdruckprogramm<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>ausdrucken(eines Textes):\n  druckt den Text aus<\/code><\/pre>\n\n\n\n<p>Jetzt die anderen Progr\u00e4mmchen:<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Countdownprogramm<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>countdown(von einer Zahl aus):\n  wiederhole solange zahl&gt;0:\n    ausdrucken(der zahl)\n    um_eins_verringern(die zahl)<\/code><\/pre>\n\n\n\n<p>Man sieht sehr schnell, wie lange dieses Countdown-Programm braucht, bis es fertig ist: Wenn ich mit der Zahl 5 anfange, sind es 5 Durchg\u00e4nge durch die Schleife, mit jeweils sinkender Zahl (5-4-3-2-1).<\/p>\n\n\n\n<p>Merke: Dieses Programm kommt immer fr\u00fcher oder sp\u00e4ter zu einem Ende, egal mit welcher Startzahl ich anfange.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Endlosdrucker<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>endlosdrucken(eines Textes):\n  wiederhole solange Textl\u00e4nge gr\u00f6\u00dfer als -1:\n    ausdrucken(des Textes)<\/code><\/pre>\n\n\n\n<p>Man sieht schnell, dass dieses Programm nie zu einem Ende kommt. Es wird immer wieder den gleichen Text ausdrucken.<\/p>\n\n\n\n<p>Merke: Dieses Programm kommt nie zu einem Ende, egal mit welchem Starttext ich anfange.<\/p>\n\n\n\n<p>Und der Vollst\u00e4ndigkeit halber: Es gibt nat\u00fcrlich auch viele Programme, bei denen es vom Startwert abh\u00e4ngt, ob das Programm ewig l\u00e4uft oder nicht. Hier ein ganz simples Beispiel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>manchmalprogramm(text):\n  wiederhole solange Textl\u00e4nge &gt; 5:\n    ausdrucken(text)<\/code><\/pre>\n\n\n\n<p>Das Programm druckt den Eingabetext immer und immer wieder aus und h\u00f6rt nie auf &#8211; es sei denn, der Eingabetext ist k\u00fcrzer als 5 Zeichen lang. Dann tut das Programm gar nichts.<\/p>\n\n\n\n<p><b>Wir merken uns:<\/b><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Manche Programme terminieren (kommen zu einem Ende), andere nicht (sind in einer Endlosschleife gefangen).<\/li>\n\n\n\n<li>Ob sie das eine oder andere tun, h\u00e4ngt auch von den Eingabewerten ab, mit denen das Programm aufgerufen wird.<\/li>\n\n\n\n<li>Bei einfachen Programmen sieht man sehr schnell, wann sie terminieren oder nicht.<\/li>\n\n\n\n<li>Bei komplizierten Programmen geht das nicht so einfach, oder gar nicht.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Teil 2: Noch ein Beispiel, warum es sch\u00f6n w\u00e4re, wenn das Halteproblem l\u00f6sbar w\u00e4re.<\/h3>\n\n\n\n<p>Es gibt mathematische Probleme, bei denen wei\u00df man die L\u00f6sung nicht. Man wei\u00df nicht einmal, ob es eine L\u00f6sung gibt. Etwa bei der wiederholten Anwendung der Collatz-Funktion. Die geht so: Beginne mit einer nat\u00fcrlichen Zahl. Wenn sie gerade ist, halbiere sie; wenn sie ungerade ist, multipliziere sie mit 3 und addiere 1. Wiederhole das mit der neuen Zahlen, die du erhalten hast &#8211; und dann immer weiter.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Wenn man mit 5 beginnt, erh\u00e4lt man folgende Reihe: 5-16-8-4-2-1 (und bei der 1 h\u00f6rt man dann auf, weil es dann mit der 4 weitergeht).<\/li>\n\n\n\n<li>Wenn man mit 3 beginnt, erh\u00e4lt man folgende Reihe: 3-10-5-16-8-4-2-1 (und bei der 1 h\u00f6rt man dann auf).<\/li>\n\n\n\n<li>Wenn man mit 7 beginnt, erh\u00e4lt man folgende Reihe: 7-22-11-34&#8230; &#8230;4-2-1 (und bei der 1 h\u00f6rt man dann auf).<\/li>\n<\/ul>\n\n\n\n<p>Landet man bei jeder Zahl fr\u00fcher oder sp\u00e4ter bei 4-2-1? Das wird vermutet, bewiesen ist aber noch gar nichts. Eine Alternative w\u00e4re zum Beispiel ein anderer Zyklus als 4-2-1-4-2-1&#8230;, in den man ger\u00e4t. Oder die Zahlen werden im Prinzip immer gr\u00f6\u00dfer, ohne sich je exakt zu wiederholen, k\u00f6nnte auch sein.<\/p>\n\n\n\n<p>Man kann leicht ein Programm schreiben, das der Reihe nach f\u00fcr alle nat\u00fcrlichen Zahlen ausprobiert, ob sie bei 1 landen oder in einem anderen Zyklus. Das Programm terminiert, sobald eine Zahl gefunden ist, die nicht bei 1 landet (sondern in einem anderen Zyklus), ansonsten probiert es halt der Reihe nach alle Zahlen aus.<\/p>\n\n\n\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-4164\" src=\"https:\/\/www.herr-rau.de\/wordpress\/archiv\/collatz_conjecture.png\" alt=\"collatz_conjecture\" width=\"311\" height=\"452\" srcset=\"https:\/\/www.herr-rau.de\/wordpress\/archiv\/collatz_conjecture.png 311w, https:\/\/www.herr-rau.de\/wordpress\/archiv\/collatz_conjecture-103x150.png 103w\" sizes=\"auto, (max-width: 311px) 100vw, 311px\" \/><br><small><a href=\"http:\/\/xkcd.com\/710\/\">xkcd webcomic<\/a> &#8211; immer wieder lesenswert<\/small><\/p>\n\n\n\n<p>Wenn das Programm l\u00e4uft, sitzt man vor dem Rechner und wartet, ob es eine Antwort ausspuckt. Und wartet. Und wartet. M\u00f6glicherweise wartet man ewig, wenn es so eine Zahl nicht gibt. Oder man wartet einfach noch nicht lange genug, weil es doch eine solche Zahl gibt. Da w\u00e4re es doch sch\u00f6n, wenn man sein hypothetischen \u00dcberpr\u00fcfungsprogramm mit dem Collatz-Programm f\u00fcttern k\u00f6nnte, damit das dann entscheidet, ob das Collatz-Programm irgendwann mal anhalten wird oder nicht.<\/p>\n\n\n\n<p><small><a href=\"http:\/\/texttheater.net\/semi-entscheidbar\">(Siehe dazu auch die Sache mit der Medizinerparty.)<\/a><\/small><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Teil 3: Der Beweis.<\/h3>\n\n\n\n<p><strong>(1) Nehmen wir an, es g\u00e4be so ein Checkerprogramm.<\/strong> Man w\u00fcrde es f\u00fcttern mit zwei Informationen, n\u00e4mlich dem Programm, das es testen soll, und dem Startwert, mit dem das Programm laufen soll. Wir haben ja oben gesehen, dass es vom Startwert abh\u00e4ngen kann, ob ein Programm anh\u00e4lt oder nicht.<\/p>\n\n\n\n<figure class=\"wp-block-image alignleft\"><img decoding=\"async\" src=\"https:\/\/www.herr-rau.de\/wordpress\/archiv\/halteproblem_eckstein_checker.jpg\" alt=\"\"\/><\/figure>\n\n\n\n<p>Es h\u00e4tte dann ungef\u00e4hr folgende Form:<\/p>\n\n\n\n<pre class=\"wp-block-code scroll\"><code>anhaltechecker (eingabeprogramm, eingabewerte):\n  (rechnen, rechnen, rechnen)\n  wenn das Programm mit diesen Startwerten anhalten wird:\n    ausgeben (\"Ja, wird anhalten!\")  \n    ergebnis: wahr\n  sonst:\n    ausgeben (\"Nein, terminiert nicht.\")\n    ergebnis: falsch<\/code><\/pre>\n\n\n\n<p>Wenn ich es aufrufe :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>anhaltechecker (countdownprogramm, 10)<\/code><\/pre>\n\n\n\n<p>&#8211; dann wird es mir ausgeben: &#8222;Ja, wird anhalten!&#8220;, weil das Countdownprogramm ja tats\u00e4chlich anh\u00e4lt, wenn man es mit einer 10 als Argument aufruft, wie bei jeder anderen nat\u00fcrlichen Zahl auch.<\/p>\n\n\n\n<p>Und wenn ich es aufrufe:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>anhaltechecker (endlosdrucken, \"Hallo Susi\")<\/code><\/pre>\n\n\n\n<p>&#8211; dann wird es mir ausgeben: &#8222;Nein, terminiert nicht.&#8220;, weil das Endlosprogramm ja tats\u00e4chlich nie fertig wird, sondern immer nur den Eingabetext ausdruckt.<\/p>\n\n\n\n<p>Und wenn ich es aufrufe:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>anhaltechecker (ausdrucken, ausdrucken)<\/code><\/pre>\n\n\n\n<p>&#8211; dann wird es mir ausgeben: &#8222;Ja, wird anhalten!&#8220;, weil mein Ausdruckprogramm nat\u00fcrlich einen l\u00e4ngeren Text ausdrucken kann und dann fertig ist, auch wenn der l\u00e4ngerere Text ein Computerprogramm ist, und sei es zuf\u00e4lligerweise auch der eigene Programmcode.<\/p>\n\n\n\n<p><strong>(2) Nehmen wir jetzt folgendes fieses kleines Programm:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image alignnone\"><img decoding=\"async\" src=\"https:\/\/www.herr-rau.de\/wordpress\/archiv\/halteproblem_eckstein_fiesling.jpg\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Illustration: Anja Eckstein<\/figcaption><\/figure>\n\n\n\n<pre class=\"wp-block-code scroll\"><code>fiesling(eingabeprogramm):\n  solange anhaltechecker(eingabeprogramm, eingabeprogramm) sagt, dass angehalten wird:\n    nichtstun\n  danach:\n    ausgeben(\"Fertig.\")<\/code><\/pre>\n\n\n\n<p>Das tats\u00e4chlich ganz leicht zu schreibende Fieslingsprogramm nimmt ein Programm als Eingabewert, und leitet es weiter an unser hypothetisches Anhaltechecker-Programm. Das soll das testen, und zwar mit dem zu \u00fcberpr\u00fcfenden Programm als Eingabeargument seiner selbst. <strong>Das ist der Knackpunkt.<\/strong> Wenn wir zum Beispiel aufrufen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>fiesling(ausdruckprogramm)<\/code><\/pre>\n\n\n\n<p>Dann wird zuerst <code>anhaltechecker(ausdruckprogramm,ausdruckprogramm)<\/code> aufgerufen, und solange das zu einem Ende kommt (was es tut, siehe oben), kommt das Fieslingsprogramm genau <em>nicht<\/em> zu einem Ende. So ein dummes Programm.<\/p>\n\n\n\n<p>Wenn ich es dagegen aufrufen w\u00fcrde:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>fiesling(endlosprogramm)<\/code><\/pre>\n\n\n\n<p>Dann w\u00fcrde zuerst <code>anhaltechecker(endlosprogramm, endlosprogramm)<\/code> aufgerufen werden, und da (das Endlosdruckprogramm) nicht zu einem Ende kommt (sondern nur endlos den Programmtext ausdrucken w\u00fcrde), w\u00fcrde mein Fieslingsprogramm das eben schon tun und ausgeben: &#8222;Fertig.&#8220;<\/p>\n\n\n\n<p><strong>(3) Das Zusammenbauen.<\/strong><\/p>\n\n\n\n<p>Was passiert, wenn ich aufrufe:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>fiesling(fiesling)<\/code><\/pre>\n\n\n\n<p>Das war&#8217;s dann eigentlich. Das Fieslingsprogramm w\u00fcrde seinerseits aufrufen <code>anhaltechecker(fiesling,fiesling)<\/code>, und wenn das ausgibt, dass <code>fiesling(fiesling)<\/code> anh\u00e4lt, w\u00fcrde es nicht anhalten. Und wenn es ausgibt, dass es nicht anh\u00e4lt, w\u00fcrde es anhalten. Das ist ein nicht aufl\u00f6sbarer Widerspruch. Absurd. Also muss eine unserer Pr\u00e4missen falsch sein, und das kann nur die sein, dass es so ein Programm wie den Anhaltechecker geben kann. Also kann es so ein Programm nicht geben.<\/p>\n\n\n\n<p>Verallgemeinerung: Man kann kein Programm schreiben, das \u00fcberpr\u00fcft, wie sich ein beliebig anderes Programm verh\u00e4lt (weil das ja schon mal beim Anhalten nicht klappt). In Spezialf\u00e4llen geht das nat\u00fcrlich schon.<\/p>\n\n\n\n<p><em>Ich habe ein paarmal versucht, das einfacher zu fassen. Herausgekommen ist das, was herausgekommen ist.<\/em><\/p>\n\n\n\n<p><em>Nachtrag 2023: Jetzt mit Illustrationen von Anja Eckstein.<\/em><\/p>\n\n\n\n<p><em>Nachtrag 2026: <\/em>Neuformulierung mit denm aktuellen Kurs.<\/p>\n\n\n\n<p>DEFINITION HYPOTHETISCHE METHODE: <br><code>boolean terminiert(String m, String n) { \u2026 }<\/code> <\/p>\n\n\n\n<p>DEFINITION GEGENMETHODE (gar nicht hypothetisch): <br><code>boolean laeuftEwig(String m) { <\/code><br>  <code>if (terminiert(m,m)) { while (true) {} } <\/code><br>  <code>else return true; <\/code><br><code>}<\/code><\/p>\n\n\n\n<p>AUFRUF: <br><mark style=\"background-color:rgba(0, 0, 0, 0);color:#9b51e0\" class=\"has-inline-color\">laeuftEwig(laeuftEwig) <\/mark><\/p>\n\n\n\n<p>F\u00dcHRT LETZTLICH ZU:<br>if (<mark style=\"background-color:rgba(0, 0, 0, 0);color:#cf2e2e\" class=\"has-inline-color\">terminiert(laeuftEwig, laeuftEwig)<\/mark>) { while(true) {} }<\/p>\n\n\n\n<p>HEISST:<br>(1) genau wenn <mark style=\"background-color:rgba(0, 0, 0, 0);color:#cf2e2e\" class=\"has-inline-color\">terminiert(laeuftEwig, laeuftEwig),<\/mark><br>(2) dann l\u00e4uft<mark style=\"background-color:rgba(0, 0, 0, 0);color:#9b51e0\" class=\"has-inline-color\"> laeuftEwig(laeuftEwig)<\/mark> ewig<\/p>\n\n\n\n<p>Und das ist der Widerspruch.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>(7 Kommentare.) Zum Abitur und im Semester davor schreiben die Sch\u00fcler in Informatik Computerprogramme in einer Assembler-Programmiersprache. Die besteht zwar aus ganz einfachen Einzelschritten, aber genau das f\u00fchrt dazu, dass das ganze Programm etwas un\u00fcbersichtlich ist und man nicht auf den ersten Blick sieht, was es genau tut. Wenn ich die Sch\u00fclerprogramme also bewerten will, [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":4164,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[25],"tags":[227],"class_list":["post-4145","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-informatik","tag-informatik"],"jetpack_featured_media_url":"https:\/\/www.herr-rau.de\/wordpress\/archiv\/collatz_conjecture.png","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.herr-rau.de\/wordpress\/wp-json\/wp\/v2\/posts\/4145","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.herr-rau.de\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.herr-rau.de\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.herr-rau.de\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.herr-rau.de\/wordpress\/wp-json\/wp\/v2\/comments?post=4145"}],"version-history":[{"count":3,"href":"https:\/\/www.herr-rau.de\/wordpress\/wp-json\/wp\/v2\/posts\/4145\/revisions"}],"predecessor-version":[{"id":68100,"href":"https:\/\/www.herr-rau.de\/wordpress\/wp-json\/wp\/v2\/posts\/4145\/revisions\/68100"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.herr-rau.de\/wordpress\/wp-json\/wp\/v2\/media\/4164"}],"wp:attachment":[{"href":"https:\/\/www.herr-rau.de\/wordpress\/wp-json\/wp\/v2\/media?parent=4145"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.herr-rau.de\/wordpress\/wp-json\/wp\/v2\/categories?post=4145"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.herr-rau.de\/wordpress\/wp-json\/wp\/v2\/tags?post=4145"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}