Hat jemand über die Möglichkeit einer Programmiersprache und eines Compilers nachgedacht, so dass der Compiler automatisch asymptotische Analysen im schlimmsten Fall durchführen kann? Der Anwendungsfall, an den ich denke, ist eine Programmiersprache, in der ich Code schreibe und kompiliere. Der Compiler teilt mir mit, dass mein Code beispielsweise in O (n ^ 2) ausgeführt wird. Dies geschieht, indem das getan wird, was die intelligenten Leute tun, die algorithmische Analysen durchführen, möglicherweise Schleifen zählen und so weiter.
Aufgrund des Anhaltens von Problemproblemen und da man Programme haben kann, die durch Verzahnung funktionieren, zum Beispiel Levins Algorithmus für SAT, der in Polynomzeit läuft, wenn P = NP, vermute ich, dass man die Programmiersprache möglicherweise so restriktiv gestalten muss, dass sie dies zulässt etwas wie das. Gibt es negative Ergebnisse, die bestimmte Arten von Programmiersprachen davon abhalten, solche Compiler zu haben?
Ich würde mich auch für Systeme interessieren, die keine exakte asymptotische Analyse liefern, sondern eine "interessante" Obergrenze.
Ich interessiere mich NICHT für Black-Box- und statistische Methoden, die aus Eingaben bestimmter Länge abtasten und herausfinden, wie lange das Programm dauert. Diese Methoden sind sehr interessant, aber sie sind nicht das, wonach ich suche. Ich interessiere mich für genaue Methoden, die ungefähre Grenzen geben können.
Ich wäre sehr dankbar, wenn mich jemand auf einige Hinweise zur Arbeit in dieser Richtung hinweisen könnte.
Antworten:
Die implizite Komplexität hat uns gelehrt, dass (einige) Komplexitätsklassen nach Typsystemen klassifiziert werden können, in dem Sinne, dass es Typsysteme gibt, die beispielsweise nur Polynomprogramme akzeptieren. Ein weiterer praktischer Ableger dieser Forschung ist RAML (Resource Aware ML), eine funktionale Programmiersprache mit einem Typsystem, das Ihnen genaue Informationen über die Laufzeiten ihrer Programme gibt. Es ist in der Tat präziser als die Big-O-Komplexität, da auch konstante Faktoren enthalten sind, die durch ein Kostenmodell für die Basisoperationen parametrisiert werden.
Sie denken vielleicht, dass dies Betrug ist: Sicherlich haben einige Algorithmen eine Komplexität, die sehr schwer genau zu berechnen ist. Wie könnte diese Sprache also die Komplexität ihrer Programme leicht bestimmen? Der Trick ist, dass es viele Möglichkeiten gibt, einen bestimmten Algorithmus auszudrücken, einige, die das Typsystem ablehnt (es lehnt einige gute Programme ab), und einige, die es vielleicht akzeptiert. Der Benutzer erhält die Welt also nicht kostenlos: Er muss keine Kostenschätzungen mehr berechnen, sondern muss herausfinden, wie Code auf eine vom System akzeptierte Weise ausgedrückt werden kann.
(Es ist immer der gleiche Trick wie bei Programmiersprachen, bei denen nur Berechnungen oder nachweisbare Sicherheitseigenschaften usw. beendet werden.)
quelle
Das von der COSTA-Forschungsgruppe entwickelte COSTA-Tool macht genau das, was Sie wollen. Bei einem gegebenen Programm (im Java-Bytecode-Format) erstellt das Tool eine Kostengleichung basierend auf einem vom Programmierer bereitgestellten Kostenmodell. Das Kostenmodell kann Entitäten wie Laufzeit, Speichernutzung oder abrechnungsfähige Ereignisse (wie das Senden von Textnachrichten) umfassen. Die Laufzeitgleichung wird dann unter Verwendung eines speziellen Werkzeugs gelöst, um eine geschlossene Form, die Worst-Case-Obergrenze des Kostenmodells, zu erzeugen.
Natürlich funktioniert das Tool nicht in allen Fällen, indem entweder keine Laufzeitgleichung erstellt oder keine geschlossene Form gefunden wird. Das ist nicht überraschend.
quelle
Ich habe vor einiger Zeit über dieselbe Frage nachgedacht. Hier ist der Gedankengang, den ich hatte:
Wie Sie sagten, ist das Problem des Anhaltens ein Problem. Um dies zu vermeiden, benötigen wir eine Sprache, die nur Programme zulässt, die immer anhalten. Andererseits muss unsere Sprache ausdrucksstark genug sein, um die häufigsten Probleme zu lösen (z. B. sollte sie mindestens die gesamte Komplexitätsklasse EXP erfassen).
Schauen wir uns also die LOOP-Programme an. Ein LOOP-Programm wird immer angehalten und seine Ausdruckskraft geht weit über EXP hinaus - um eine bessere Vorstellung zu erhalten: Sie können jedes TM simulieren, für das die Laufzeitfunktion als LOOP-Programm ausgedrückt werden kann.
Jetzt können wir die Verschachtelungstiefe und die Größe der Anzahl der Wiederholungen für jede Schleife aus syntaktischer Sicht betrachten und haben einen Ausgangspunkt (wir wissen jedoch nicht, wie weit dies uns führt). Beachten Sie jedoch das folgende Problem:
Wie machen wir das mit nur begrenzten Schleifen? Das Problem besteht nun darin, über eine Obergrenze für den Zahlenbereich nachzudenken, den wir suchen müssen.
Meine Intuition hier ist, dass die einzige Information, die ein Compiler Ihnen geben kann, darin besteht, die Syntax, die am Ende vom Programmierer bereitgestellt wird, sorgfältig zu analysieren. Wenn der Compiler eine aussagekräftige Aussage über die zeitliche Komplexität eines Programms treffen kann, muss der Programmierer gezwungen werden, diese Informationen in das Programm aufzunehmen.
Der letzte Absatz ist jedoch subjektiv und es könnte sicherlich andere mögliche Ansätze geben, die interessante Ergebnisse liefern. Ich wollte nur eine Vorstellung davon geben, was mich auf diesem Weg nicht erwartet.
quelle