Werden Korrektheitsnachweise von Code jemals zum Mainstream? [geschlossen]

14

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?

Casebash
quelle

Antworten:

8

Nicht wirklich in diesem Sinne, aber rein funktionale Programmierung ist in diesem Bereich gut. Wenn Sie Haskell verwenden, ist Ihr Programm wahrscheinlich korrekt, wenn der Code kompiliert wird. Abgesehen von IO ist ein gutes Typensystem eine gute Hilfe.

Auch das Programmieren auf Vertrag kann hilfreich sein. Siehe Microsoft-Codeverträge

Jonas
quelle
6
Entschuldigung - ich habe nicht viel "real world" Haskell gemacht, aber ich habe für mehrere Lebenszeiten genug Tutorial-Übungen gemacht. Nur weil es kompiliert, heißt das noch lange nicht, dass es wahrscheinlich funktioniert. Verglichen mit zB Ada (gewählt, weil es eine streng statisch typisierte imperative Sprache ist), würde ich sagen, dass Haskell ein bisschen einfacher ist, aber hauptsächlich, weil es prägnanter ist (geringere zyklomatische Komplexität). Beim Umgang mit der IO - Monade, gibt es Belästigungen , die Haskell machen können mehr schwer richtig zu machen - es ist nur unterschiedlich genug von Imperativ Stil ist , dass es Dinge gibt es nicht als selbstverständlich tun.
Steve314
Bei "nicht so natürlich" sollten Sie eine "while" -Schleife in Betracht ziehen. Ja, Sie können Ihre eigenen Rollen spielen - aber die while-Bedingung muss innerhalb der Monade liegen, da sie auf Nebenwirkungen des Loop-Körpers reagieren muss. Dies bedeutet nicht nur, dass Sie die Erlaubnis erhalten haben, innerhalb der while-Bedingung Nebenwirkungen zu verursachen, sondern es ist auch umständlich, diese while-Schleife zu verwenden. Endergebnis - es ist im Allgemeinen einfacher, die Rekursion auch in E / A-Monaden-Code zu verwenden - und das bedeutet, dass Sie die Dinge auf eine bestimmte Weise strukturieren müssen.
Steve314
14

Alles außer den einfachsten Programmen

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

Doc Brown
quelle
Richtig - für jedes Programmierprojekt gibt es einen Übergang von einer informellen Beschreibung des Problems zu einer formalen (normalerweise heute in Form eines Programms), und das lässt sich nicht ändern.
David Thornley
astree.ens.fr Sehen Sie industrielle Anwendungen von Astrée hier
zw324
@ ZiyaoWei: Solche Tools sind hilfreich, aber sie finden nur einige formale Fehler, nicht mehr. Ob ein einzeiliges Programm wie 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.
Doc Brown
10

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!

Mason Wheeler
quelle
2
Also .. "Vorsicht vor Fehlern im obigen Code; ich habe es nur als richtig erwiesen, nicht ausprobiert." - Donald Knuth
Brendan
8

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.

Lucina
quelle
4

Nur wenn sich eine Methode zum automatischen Testen des Codes ohne umfangreiche Entwicklerarbeit ergibt.

Fischtoaster
quelle
Betrachten Sie das wirtschaftliche Argument: Vielleicht ist es für Entwickler besser, Zeit mit Korrektheitsnachweisen zu "verschwenden", als Geld wegen Softwarefehlern zu verlieren.
Andres F.
Ich stimme fishtoaster zu, es sei denn, es wird viel weniger ressourcenintensiv. Viele reguläre Unternehmenssoftware wird einfach nicht die Kosten / den Nutzen haben, um dieses Korrektheitsniveau zu unterstützen. In einer LOB-App für ein gefangenes Publikum besteht der größte geschäftliche Nutzen für die Kosten in Bezug auf einen Fehlerbericht manchmal darin, den Dokumenten eine Zeile hinzuzufügen, die besagt, dass dies nicht der Fall ist
Bill
3

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).

Basile Starynkevitch
quelle
3

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.

zw324
quelle
2

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.

Izkata
quelle
3
Falsch. Kein Unit Test wird jemals in der Lage sein, den gesamten Bereich möglicher Parameter abzudecken. Stellen Sie sich vor, Sie testen einen Compiler auf diese Weise, um sicherzustellen, dass die Semantik der Pass-Änderung nicht überschritten wird.
SK-logic
3
Unit Testing ist nicht der heilige Gral ...
Ryathal
1
@ Winston Ewert, es gibt verifizierte Compiler (und viele weitere verifizierte Assembler). Und Hardware wird viel häufiger formal verifiziert als die Software. Siehe hier: gallium.inria.fr/~xleroy/publi/compiler-certif.pdf
SK-logic
1
@ SK-logic, ja, es gibt Spielzeug-Compiler, die sich für akademische Zwecke als richtig erwiesen haben. Aber was ist mit Compilern, die die Leute tatsächlich benutzen? Ich vermute, dass die meisten Compiler mithilfe verschiedener automatisierter Tests überprüft werden und fast keine formalen korrekten Beweise vorliegen.
Winston Ewert
1
@ Winston Ewert, Korrektheitsnachweise sind praktisch und im wirklichen Leben weit verbreitet. Was nicht sehr praktisch ist, sind die meisten modernen Hauptsprachen. Ich hoffe, dass sie alle aussterben, damit der Wert von Korrektheitsnachweisen in Zukunft zunimmt.
SK-logic
1

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.

Paddyslacker
quelle
8
Das Problem des Anhaltens besagt, dass wir nicht feststellen können, ob ein beliebiges Programm anhält. Diese Programme können seltsame Dinge tun, zum Beispiel jede ganze Zahl testen, um festzustellen, ob es sich um eine Mersenne-Primzahl handelt. Wir machen das nicht in normalen Programmen!
Casebash
1
@Casebash, die Frage ist, ob es eine nützliche Untermenge von Programmen gibt, für die das Halteproblem gelöst werden kann. Das ist keineswegs klar so oder so. Dh können wir unsere Programme so einschränken, dass wir nicht jede ganze Zahl testen können, ohne unsere Fähigkeit zu beeinträchtigen, nützliche Aufgaben auszuführen?
Winston Ewert
1

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,

tp1
quelle
Beziehen Sie sich mit dem Hinweis auf Nebenwirkungen in C ++ auf die const-Korrektheit?
Winston Ewert
Ja, const + const Mitgliedsfunktion. Wenn alle Mitgliedsfunktionen const sind, können alle Daten in den Objekten nicht geändert werden.
tp1
Sie können nach wie vor geändert werden, wenn Sie mutableoder verwenden const_cast. Ich sehe sicherlich die Verbindung, die Sie dort ziehen, aber der Geschmack von zwei Ansätzen scheint mir ziemlich unterschiedlich.
Winston Ewert
Nun, deshalb müssen Sie sich dafür entscheiden, es zu verwenden - es gibt immer Möglichkeiten, es zu umgehen. Das wichtigste ist jedoch, wie Compiler nach Problemen in der Umgebung suchen können.
tp1