Alle bis auf die trivialsten Programme sind mit Fehlern gefüllt, und alles, was verspricht, sie zu entfernen, ist äußerst verführerisch. Gegenwärtig sind Korrektheitsnachweise als Code extrem esoterisch, vor allem aufgrund der Schwierigkeit, dies zu lernen, und des zusätzlichen Aufwands, der erforderlich ist, um ein Programm als korrekt zu beweisen. Glauben Sie, dass die Codeprüfung jemals erfolgreich sein wird?
quelle
kann nicht mit vertretbarem Aufwand auf Richtigkeit überprüft werden. Für einen formalen Nachweis der Richtigkeit benötigen Sie mindestens eine formale Spezifikation, die vollständig und korrekt sein muss. Dies ist normalerweise nichts, was Sie für die meisten realen Programme leicht erstellen können. Versuchen Sie beispielsweise, eine solche Spezifikation für so etwas wie die Benutzeroberfläche dieser Diskussionsseite zu schreiben, und Sie wissen, was ich meine.
Hier habe ich einen schönen Artikel zum Thema gefunden:
http://www.encyclopedia.com/doc/1O11-programcorrectnessproof.html
quelle
printf("1")
korrekt ist oder nicht (zum Beispiel, weil die Anforderung lautete "eine gleichmäßig verteilte Zufallszahl von 1 bis 6 drucken"), kann von einem solchen statischen Analysegerät nicht entschieden werden.Das Problem bei formalen Beweisen ist, dass das Problem nur einen Schritt zurückversetzt wird.
Zu sagen, dass ein Programm korrekt ist, entspricht der Aussage, dass ein Programm das tut, was es tun soll. Wie definieren Sie, was das Programm tun soll? Sie geben es an. Und wie definieren Sie, was das Programm in Randfällen tun soll, die die Spezifikation nicht abdeckt? Nun, dann müssen Sie die Spezifikation detaillierter gestalten.
Nehmen wir also an, Ihre Spezifikation wird endlich detailliert genug, um das korrekte Verhalten aller Aspekte des gesamten Programms zu beschreiben. Jetzt müssen Sie Ihren Proof-Tools die Möglichkeit geben, dies zu verstehen. Sie müssen die Spezifikation also in eine formale Sprache übersetzen, die das Proof-Tool verstehen kann ... hey, warten Sie eine Minute!
quelle
Die formale Verifizierung hat einen langen Weg zurückgelegt, doch in der Regel bleiben die in der Industrie und in weit verbreiteten Bereichen verwendeten Tools hinter den neuesten Forschungsergebnissen zurück. Hier sind einige der jüngsten Bemühungen in diese Richtung:
Spec # http://research.microsoft.com/en-us/projects/specsharp/ Dies ist eine Erweiterung von C #, die Codeverträge (Vor- / Nachbedingungen und Invarianten) unterstützt und diese Verträge für verschiedene Arten statischer Analysen verwenden kann .
Ähnliche Projekte wie dieses existieren für andere Sprachen, wie JML für Java, und Eiffel hat dies ziemlich genau integriert.
Darüber hinaus können Projekte wie Slam und Blast verwendet werden, um bestimmte Verhaltenseigenschaften mit minimalen Programmieranmerkungen / Eingriffen zu überprüfen, können jedoch nicht die vollständige Allgemeingültigkeit moderner Sprachen erfassen (Dinge wie Ganzzahlüberlauf / Zeigerarithmetik werden nicht modelliert).
Ich glaube, dass wir in Zukunft noch viel mehr von diesen Techniken in der Praxis sehen werden. Das Haupthindernis besteht darin, dass Programminvarianten ohne manuelle Annotationen schwer abzuleiten sind und Programmierer diese Annotationen normalerweise nicht bereitstellen, da dies zu mühsam / zeitaufwendig ist.
quelle
Nur wenn sich eine Methode zum automatischen Testen des Codes ohne umfangreiche Entwicklerarbeit ergibt.
quelle
Einige formale Methoden- Tools (wie z. B. Frama-C für wichtige eingebettete C-Software) können als (Art) Bereitstellung oder zumindest Überprüfung eines (Korrektheits-) Nachweises einer bestimmten Software angesehen werden. (Frama-C prüft, ob ein Programm in gewisser Weise seiner formalisierten Spezifikation entspricht und respektiert explizit annotierte Invarianten im Programm).
In einigen Bereichen sind solche formalen Methoden möglich, z. B. als DO-178C für kritische Software in zivilen Flugzeugen. In einigen Fällen sind solche Ansätze möglich und hilfreich.
Natürlich ist die Entwicklung weniger fehlerhafter Software sehr kostspielig. Aber der formale Methodenansatz ist für eine Art Software sinnvoll. Wenn Sie pessimistisch sind, könnten Sie denken, dass der Fehler vom Code in seine formale Spezifikation verschoben wurde (was einige "Fehler" haben kann, da die Formalisierung des beabsichtigten Verhaltens einer Software schwierig und fehleranfällig ist).
quelle
Ich bin über diese Frage gestolpert und denke, dass dieser Link interessant sein könnte:
Industrielle Anwendungen von Astrée
Es scheint nicht schlecht zu sein, das Fehlen von RTE in einem System zu beweisen, das von Airbus 2003 mit mehr als 130.000 Codezeilen verwendet wurde.
quelle
Nein. Das gemeinsame Sprichwort lautet: "Theorie und Praxis sind gleich. In der Praxis nicht."
Ein sehr einfaches Beispiel: Tippfehler.
Wenn Sie den Code tatsächlich durch Unit-Tests laufen lassen, werden solche Dinge fast sofort gefunden, und eine zusammenhängende Reihe von Tests macht formale Beweise überflüssig. Alle Anwendungsfälle - gute, schlechte, fehlerhafte und Randfälle - sollten in den Komponententests aufgezählt werden. Dies ist ein besserer Beweis dafür, dass der Code korrekt ist als jeder andere Beweis, der vom Code getrennt ist.
Insbesondere wenn sich die Anforderungen ändern oder der Algorithmus aktualisiert wird, um einen Fehler zu beheben, ist es wahrscheinlicher, dass der formale Beweis nicht mehr aktuell ist, wie dies bei Codekommentaren häufig der Fall ist.
quelle
Ich denke, dass die Grenzen, die Korrektheitsnachweisen aufgrund des Halteproblems auferlegt wurden , das größte Hindernis für die Verbreitung von Korrektheitsnachweisen sein könnten.
quelle
Es wird bereits von allen benutzt. Jedes Mal, wenn Sie die Typprüfung Ihrer Programmiersprache verwenden, führen Sie einen mathematischen Beweis für die Richtigkeit Ihres Programms durch. Dies funktioniert bereits sehr gut - Sie müssen lediglich für jede Funktion und Datenstruktur, die Sie verwenden, die richtigen Typen auswählen. Je genauer der Typ, desto besser ist die Überprüfung. Die vorhandenen Typen, die in Programmiersprachen verfügbar sind, verfügen bereits über ausreichend leistungsstarke Tools, um nahezu jedes mögliche Verhalten zu beschreiben. Dies funktioniert in jeder verfügbaren Sprache. C ++ und die statischen Sprachen führen nur die Überprüfungen in der Kompilierungszeit durch, während dynamischere Sprachen wie Python dies tun, wenn das Programm ausgeführt wird. Die Prüfung ist in allen diesen Sprachen noch vorhanden. (c ++ unterstützt beispielsweise bereits die Überprüfung von Nebenwirkungen auf die gleiche Weise wie haskell,
quelle
mutable
oder verwendenconst_cast
. Ich sehe sicherlich die Verbindung, die Sie dort ziehen, aber der Geschmack von zwei Ansätzen scheint mir ziemlich unterschiedlich.