Ich bin nicht in der Lage , wie viel zu sagen , mehr Forschung sollte zu dem Thema durchgeführt werden, aber ich kann Ihnen sagen , dass es ist Forschung getan werden, zum Beispiel des Verisoft XT Programm der Deutsch Regierung finanziert.
Die Konzepte, nach denen Sie meines Erachtens suchen, werden als formale Verifizierung und vertragsbasierte Programmierung bezeichnet , wobei letztere eine programmiererfreundliche Möglichkeit darstellt, die erste zu erstellen. Bei der vertragsbasierten Programmierung schreiben Sie zunächst Ihren Code wie gewohnt und fügen dann sogenannte Verträge in den Code ein. Eine leicht verwendbare Sprache, die auf diesem Paradigma basiert, ist Spec # von Microsoft Research und die funktional ähnliche, aber etwas weniger hübsche Code Contracts- Erweiterung für C #, die Sie beide online ausprobieren können (ähnliche Tools für andere Sprachen finden Sie unter rise4fun) ). Der von Ihnen erwähnte "int with range type" würde sich in zwei Verträgen in einer Funktion widerspiegeln:
Contract.Requires(-3 <= a && a <= 24);
Contract.Requires( 3 <= b && b <= 10);
Wenn Sie diese Funktion aufrufen möchten, müssen Sie Parameter verwenden, die diese Kriterien erfüllen. Andernfalls tritt ein Fehler bei der Kompilierung auf. Bei den oben genannten Verträgen handelt es sich um sehr einfache Verträge. Sie können nahezu jede Annahme oder Anforderung zu Variablen oder Ausnahmen und deren Beziehung einfügen, die Sie sich vorstellen können, und der Compiler prüft, ob jede Anforderung durch eine Annahme oder eine zu sichernde, dh ableitbare Bedingung abgedeckt ist aus den Annahmen. Daher kommt der Name: Der Angerufene stellt Anforderungen , der Anrufer stellt sicher, dass diese erfüllt werden - wie in einem Geschäftsvertrag.
P( x1, x2, . . . , xn)nPwird genutzt. Auf der CS-Seite sind diese beiden Faktoren die kritischen Teile des Prozesses - die Generierung von Verifizierungsbedingungen ist schwierig, und SMT ist je nach den berücksichtigten Theorien entweder ein NP-vollständiges oder ein nicht entscheidbares Problem. Es gibt sogar einen Wettbewerb für SMT-Löser, daher wird hier sicherlich nachgeforscht. Darüber hinaus gibt es alternative Ansätze zur Verwendung von SMT für die formale Verifizierung wie die Aufzählung von Zustandsräumen, die Prüfung symbolischer Modelle, die Prüfung beschränkter Modelle und vieles mehr, die ebenfalls untersucht werden, auch wenn SMT afaik derzeit der "modernste" Ansatz ist.
In Bezug auf die Grenzen der allgemeinen Idee:
- Wie bereits erwähnt, ist der Nachweis der Korrektheit des Programms ein rechenintensives Problem. Daher kann es sein, dass die Überprüfung der Kompilierungszeit eines Programms mit Verträgen (oder einer anderen Form der Spezifikation) sehr lange dauert oder sogar unmöglich ist. Heuristiken anzuwenden, die die meiste Zeit gut funktionieren, ist das Beste, was man dagegen tun kann.
- Je mehr Sie über Ihr Programm angeben, desto höher ist die Wahrscheinlichkeit, dass Fehler in der Spezifikation selbst auftreten . Dies kann zu Fehlalarmen führen (die Überprüfung der Kompilierungszeit schlägt fehl, obwohl alles fehlerfrei ist) oder zu dem falschen Eindruck, sicher zu sein, obwohl Ihr Programm immer noch Fehler enthält.
- Das Schreiben von Verträgen oder Spezifikationen ist wirklich mühsam und die meisten Programmierer sind zu faul, um dies zu tun. Versuchen Sie, überall ein C # -Programm mit Code-Verträgen zu schreiben. Nach einer Weile werden Sie denken: Komm schon, ist das wirklich notwendig? Aus diesem Grund wird die formale Verifizierung in der Regel nur für Hardware-Design und sicherheitskritische Systeme verwendet, z. B. für die Software-Steuerung von Flugzeugen oder Automobilen.
Eine letzte erwähnenswerte Sache, die nicht ganz der obigen Erklärung entspricht, ist ein Feld namens "Implizite Komplexitätstheorie", zum Beispiel dieses Papier . Es zielt darauf ab, Programmiersprachen zu charakterisieren, in denen jedes Programm, das Sie schreiben können, einer bestimmten Komplexitätsklasse zuzuordnen ist, beispielsweise P. In einer solchen Sprache wird automatisch sichergestellt, dass jedes von Ihnen geschriebene Programm eine polynomielle Laufzeit hat, die "überprüft" werden kann. beim kompilieren einfach das programm kompilieren. Ich kenne jedoch keine praktisch verwertbaren Ergebnisse dieser Forschung, bin aber auch weit davon entfernt, ein Experte zu sein.