Ich versuche, einige Aussagen über die Ausführung in Java-Programmen unter einigen starken Einschränkungen zu beweisen (im Grunde genommen habe ich die Vermutung, dass zwei Methoden, die eine Reihe von Einschränkungen für eine bestimmte Eingabe erfüllen, äquivalent sind - dh den Wert und den Status danach zurückgeben Ausführung sind identisch). Um dies zu beweisen, suche ich nach einer Art Formalismus, der mich darüber sprechen lässt.
Ich bin mit der operativen Semantik funktionaler Sprachen vertraut und könnte möglicherweise für Schleifen / while-Schleifen in rekursive Funktionen übersetzen ... Ich würde dies lieber nicht tun, und es wäre schön, einige Maschinen zu haben, damit ich im imperativen Land bleiben kann .
Insbesondere möchte ich über den Zustand einer Methode im k- ten Ausführungsschritt nachdenken. Dies beinhaltet den globalen Zustand:
- Aufrufe wie
this.field = 2
aktualisieren unseren Klassenstatus - Aufrufe zur Änderung des Aktualisierungsstatus von Parametern außerhalb unserer Methode:
myParam.setFoo(...)
myParam.x = y
- Aufruf statischer Methoden
Blah.static_side_effects()
Ich gehe davon aus, dass dies alles deterministisch ist . Das heißt, ich möchte die Annahme formalisieren, dass, wenn eine dieser globalen Statusaktualisierungen in zwei Methoden erfolgt, deren globaler und lokaler Ausführungsstatus identisch sind, der neue Status ebenfalls identisch ist - dass jeder Berechnungsschritt bestimmt wird genau nach globalem Staat und lokalem Staat. Dies schließt offensichtlich RNGs und Parallelität aus (aber ich kann später darauf eingehen ...).
Irgendwelche Ideen oder Quellen, wie ich das angehen könnte? Mein einziger Gedanke ist, Methoden als Liste von Anweisungen zu behandeln und zu versuchen, eine Anweisungssemantik formal zu beschreiben.
Wenn möglich, würde ich dies gerne auf Java-Sprachebene und nicht auf JVM-Ebene tun. Dies ist möglicherweise nicht machbar, aber mein Ziel ist es, vorerst einige vernünftige Annahmen über meine operative Semantik zu treffen und diese dann von dort zu übernehmen.
Oh, eine letzte Anmerkung - alle Vorschläge, wie ich diese Frage verbessern kann, wären sehr dankbar. Ich versuche, die richtige Sprache zu finden, um die Frage zu stellen, und wenn ich Terminologie missbrauche (wie den lokalen / globalen Ausführungsstatus ...), würde ich dies gerne korrigieren.
quelle
Antworten:
Featherweight Java wird in der PL-Community sehr geschätzt. Wenn dies jedoch nicht Ihren Anforderungen entspricht, finden Sie hier einen allgemeinen Ansatz für die Modellierung:
Diese Grundstruktur bringt Sie ziemlich weit. Um Java zu modellieren, möchten Sie Ihren Statussatz wahrscheinlich hierarchisch um bestimmte Objekte herum strukturieren, aber die Grundprinzipien sind dieselben. Sie möchten auch den dynamischen Versand modellieren, daher ist es wahrscheinlich sinnvoll, Klassenmethoden in Funktionen umzuwandeln, die ein explizites "this" -Argument verwenden.
Eine axiomatische Semantik, dh Hoare-Tripel, die eine Logik von Vor- und Nachbedingungen für Anweisungen zur Modellierung imperativer Programme definieren. Ich weiß nicht, wie diese mit OOP zusammenhängen, aber ich bin sicher, dass jemand in den 50 Jahren, in denen er da war, es versucht hat.
Sie könnten auch an Software Foundations interessiert sein . Es orientiert sich an der Argumentation über imperative Sprachen im Coq-Theorembeweiser, bietet jedoch einen hervorragenden Überblick über die formale Semantik.
quelle
Es gibt eine (betriebliche) Semantik für Java 1.4, die in derK Rahmen . Diesem Framework ist ein Proofsystem namens Matching Logic zugeordnet . Während diese Seite eine Prototyp-Implementierung beschreibt, scheint es, dass die Funktionalität in die integriert wirdK Framework-Tools selbst als
kprover
. Leider scheint das Framework gerade aktualisiert zu werden, und es ist ein bisschen mühsam, das Framework zum Erstellen und Arbeiten zu bringen, und ich bin mir nicht sicher, wie praktisch und / oder funktional eskprover
derzeit ist. Sie können jedoch manuell Dinge beweisen, die auf die Betriebssemantik verweisen (und auf Wunsch auch das Matching Logic-Proof-System verwenden). Das Dokument zur Beschreibung der Java-Semantik, K-Java: Eine vollständige Semantik von Java , verweist auf einige andere Systeme, die weniger vollständig sind, aber für Ihre Zwecke möglicherweise vollständig genug sind. Das heißt, sie sind möglicherweise nicht darauf ausgerichtet, Eigenschaften von Java-Programmen zu beweisen. In der Tat wird die Semantik in der Arbeit eher zur Modellprüfung als zur Überprüfung der Korrektheit verwendet.Dies ist eine Antwort, wenn Sie ein hohes Maß an Sicherheit wünschen, dass sich der tatsächliche Java-Code so verhält, wie Sie es beabsichtigen. Wenn das Ziel darin besteht, den Algorithmus mehr zu verifizieren als die spezifische Realisierung in Java, ist dies wahrscheinlich ein Overkill. Das heißt, Sie könnten leicht eine einfache imperative Sprache in formalisierenK wenn Sie nur grundlegende Imperativ- / OO-Funktionen benötigen. Dies geschieht in der Tat als Übung in derK Framework-Tutorial. Wenn Sie Ihr Problem in das Fragment von C umformulieren können, das der Matching Logic-Prototyp unterstützt, können Sie es möglicherweise so verwenden, wie es ist.
quelle