Ich suche nach einem Konzept in der Typentheorie, von dem ich sicher bin, dass es wahrscheinlich untersucht wurde, aber den Namen dahinter nicht kenne.
Betrachten wir eine ML-ähnliche Sprache mit Produkt- und Summentypen und ein Hindley-Milner-ähnliches Typsystem. Ich werde die OCaml-Syntax verwenden.
Ich frage mich, wie zwei verschiedene Werte unterschiedlich sein können.
Verwenden
Mein Anwendungsfall ist das Schreiben von "klareren" Fehlermeldungen in eine xUnit-ähnliche Bibliothek: Wenn zwei Werte unterschiedlich sind, als erwartet wurde, dass sie gleich sind, kann dies dazu beitragen, eine klarere, bessere Meldung zu erstellen:
Vor:
Werte unterscheiden sich: erwartet
{x = [1;2;3;4], y = "a long string"}
, bekommen{x = [1;2;3;3], y = "a long string"}
Nach:
Werte unterscheiden sich: an Position
.x[3]
, erwartet 4, bekam 3.
(Möglicherweise besteht eine Beziehung zu funktionalen Linsen, da wir letztendlich eine Linse mit einem kleineren Wert konstruieren, der sich unterscheidet.)
Produkttypen
Zum Beispiel:
type p =
{ x : int
; y : string
}
Gleichheit kann definiert werden als:
let equal a b =
equal_int a.x b.x && equal_string a.y b.y
Es ist aber auch möglich, die Unterschiede zu wiederholen:
type delta_p =
| Equal
| Diff_x of int * int
| Diff_y of string * string
let diff_p a b =
if not (equal_int a.x b.x) then
Diff_x (a.x, b.x)
else if not (equal_string a.y b.y) then
Diff_y (a.y, b.y)
else
Equal
(Es kann sinnvoll sein, einen delta_int
Typ zu definieren, um int * int
zu zeigen, dass er rekursiv ist.)
Summentypen
Für einen Summentyp gibt es mehrere Möglichkeiten, sich zu unterscheiden: einen anderen Konstruktor oder einen anderen Wert
type s = X of int | Y of string
type ctor_s =
| Ctor_X
| Ctor_Y
type delta_s =
| Equal
| Diff_ctor of ctor_s * ctor_s
| Diff_X of int * int
| Diff_Y of string * string
let diff_s a b = match (a, b) with
| X xa, X xb ->
if equal_int xa xb then
Equal
else
Diff_X (xa, xb)
| (* Y case similar *)
| X _, Y _ -> Diff_ctor (Ctor_X, Ctor_Y)
| Y _, X _ -> Diff_ctor (Ctor_Y, Ctor_X)
Wie heißt dieses Konzept? Wo kann ich mehr darüber erfahren?
Vielen Dank!
quelle
Antworten:
Ich denke, Sie suchen nach einer typisierten Variante der Anti-Vereinigung . Anti-Unification kann wie folgt beschrieben werden. Nehmen wir zunächst an, wir haben eine Grammatik von Begriffen wie folgt:
Hier
()
und(t, t)
bezeichnet Einheiten und Paare,C t
ist ein Term mit einem führenden Konstruktor undX
eine Termvariable, die für jeden Term eingesetzt werden kann.Das Anti-Vereinigungs-Problem besagt, wenn Sie zwei Begriffe angeben
t1
undt2
was ist der am wenigsten allgemeine Begriff,t
so dass es Substitutionen gibts1
unds2
dasss1(t) = t1
unds2(t) = t2
.Als konkretes Beispiel mit zwei Begriffen
Der Anti-Unification-Algorithmus würde den Anti-Unifier zurückgeben
denn die ersetzungen
s1 = [X:3, Y:1]
unds2 = [X:1, Y:3]
beantragtent
würden dirt1
undt2
zurück geben. Nebenbei mussten wir "am wenigsten allgemein" angeben, weil sonst:mit den Auswechslungen
s1 = [Z:t1]
unds2 = [Z:t2]
würde den Trick machen.gen
Erweitern Sie diesen Algorithmus, um die beiden Substitutionen zurückzugeben,
s1
unds2
ich gehe als Übung.quelle