Verfeinerungsarten ableiten

11

Bei der Arbeit wurde ich beauftragt, einige Typinformationen über eine dynamische Sprache abzuleiten. Ich schreibe Folgen von Anweisungen in verschachtelte letAusdrücke um, wie folgt:

return x; Z            =>  x
var x; Z               =>  let x = undefined in Z
x = y; Z               =>  let x = y in Z
if x then T else F; Z  =>  if x then { T; Z } else { F; Z }

Da ich von allgemeinen Typinformationen ausgehe und versuche, spezifischere Typen abzuleiten, sind Verfeinerungstypen die natürliche Wahl. Beispielsweise gibt der bedingte Operator eine Vereinigung der Typen seiner wahren und falschen Zweige zurück. In einfachen Fällen funktioniert es sehr gut.

Ich bin jedoch auf einen Haken gestoßen, als ich versucht habe, auf Folgendes zu schließen:

function g(f) {
  var x;
  x = f(3);
  return f(x);
}

Welches wird umgeschrieben in:

\f.
  let x = undefined in
    let x = f 3 in
      f x

HM würde und folglich . Der tatsächliche Typ, auf den ich schließen möchte, ist:f::ichntichntG::(ichntichnt)ichnt

G::τ1τ2.(ichntτ1τ1τ2)τ2

Ich verwende bereits funktionale Abhängigkeiten, um den Typ eines überladenen +Operators aufzulösen. Daher dachte ich, es sei eine natürliche Wahl, sie zum Auflösen des Typs von finnerhalb zu verwenden g. Das heißt, die Typen von fin all seinen Anwendungen zusammen bestimmen eindeutig den Typ von g. Wie sich jedoch herausstellt, eignen sich Fundeps nicht besonders gut für eine variable Anzahl von Quelltypen.

Wie auch immer, das Zusammenspiel von Polymorphismus und Verfeinerungstypisierung ist problematisch. Gibt es einen besseren Ansatz, den ich vermisse? Ich verdaue derzeit "Verfeinerungstypen für ML" und würde mich über mehr Literatur oder andere Hinweise freuen.

Jon Purdy
quelle

Antworten:

9

Sie sind auf die Tatsache gestoßen, dass die Folgerung statischer Invarianten für Sprachen höherer Ordnung in der Praxis ziemlich schwierig ist und nicht nur theoretisch unentscheidbar ist. Ich bin mir nicht sicher, wie die endgültige Antwort auf Ihre Frage lautet, aber beachten Sie einige Dinge:

  • Wie Sie bemerkt haben, verhalten sich Polymorphismus- und Verfeinerungstypen schlecht zusammen, insbesondere geht der Begriff des allgemeinsten Typs verloren. Dies hat zur Folge, dass Analysen, die auf Verfeinerungstypen bei Vorhandensein von Polymorphismus basieren, möglicherweise zwischen der Analyse des gesamten Programms (im Gegensatz zur Analyse der Zusammensetzung) und der Verwendung von Heuristiken wählen müssen, um zu entscheiden, welchen Typ Sie Ihrem Programm zuweisen möchten.

  • Es besteht eine starke Beziehung zwischen der Schlussfolgerung von Verfeinerungstypen und:

    1. Berechnung der abstrakten Interpretation Ihres Programms

    2. Berechnen von Schleifeninvarianten in einer imperativen Sprache.

In diesem Sinne finden Sie hier einige unorganisierte Verweise auf die Schlussfolgerung von Verfeinerungstypen. Beachten Sie, dass es viele verschiedene Arten von Verfeinerungstypen gibt: Ich bin eher an Verfeinerungen induktiver Datentypen interessiert, daher kann diese Liste in diese Richtung verzerrt sein.

  1. Beginnen Sie mit den Klassikern: Relationale abstrakte Interpretation von Funktionsprogrammen höherer Ordnung von Cousot & Cousot. Dies erklärt, wie die abstrakte Interpretation mithilfe relationaler Semantik auf Programme höherer Ordnung ausgedehnt werden kann.

  2. Liquid Types von Rhondon, Kawaguchi und Jhala. Dies ist eine sehr weiterentwickelte Arbeit, die HM und eine Art Prädikatverfeinerung kombiniert, um auf Sicherheitsanmerkungen (z. B. Array-gebundene Prüfungen) für Programme im ML-Stil zu schließen. Die Inferenz erfolgt in 2 Schritten; Die erste ist die HM-Inferenz von Typanmerkungen, die die Auswahl der durchzuführenden Verfeinerungen leiten.

  3. Ich sollte wahrscheinlich auch die Arbeit von Fournet, Swarmy, Chen, Strub ... über erwähnen , eine Erweiterung von die dem Ansatz der Flüssigkeitstypen ähnlich zu sein scheint, aber mit dem Ziel, kryptografische Protokolle und Algorithmen für zu überprüfen verteiltes Rechnen. Ich bin mir nicht sicher, wie viel veröffentlichte Arbeit es gibt, um in diesem Fall auf Anmerkungen zu schließen.F.F.#

  4. Es gibt ein schönes Papier von Chin und Khoo über die Schlussfolgerung einer bestimmten Art von Verfeinerungstypen: Typen mit Größenanmerkungen.

  5. Die Programmiersprache ATS ist ein System, das verschiedene Verfeinerungen ermöglicht und Möglichkeiten zum Schreiben von Programmen mit ihnen bietet. Die Anmerkungen können jedoch beliebig komplex (und daher unentscheidbar) sein und erfordern daher möglicherweise eine Benutzerinteraktion. Ich glaube, dass es für diese Typen eine Form der Folgerung gibt, ich bin mir jedoch nicht sicher, welchen Artikel ich empfehlen soll.

  6. Last but not least Der kartesische Produktalgorithmus von Ole Agesen. Obwohl Verfeinerungstypen nicht explizit erwähnt werden, scheint dies die Arbeit zu sein, die der Lösung des Problems, das Sie zu haben scheinen, am nächsten kommt. Lassen Sie sich nicht von der abstrakten Erwähnung des parametrischen Polymorphismus täuschen: Sie wollen auf konkrete Typen schließen , die nur Tupel möglicher Atomtypen sind. Der Schwerpunkt liegt auf Effizienz. Ich empfehle, diesen Artikel zuerst zu lesen, um festzustellen, ob er Ihr Problem löst.

Randnotiz: Typinferenz bei Vorhandensein von Schnittpunkttypen kann sehr unentscheidbar sein: In der einfachsten Form sind Terme mit Schnittpunkttyp genau die stark normalisierenden Begriffe. Tritt sanft um sie herum :)λ

Cody
quelle