Diese Antwort ist ein formaler Beweis für die Antwort von TheNumberOne , Enumerate valid Brainf ** k programs , wobei es etwas schwierig sein kann , die genauen Punkte zu verstehen, warum die Aufzählung korrekt ist. Es ist nicht trivial zu verstehen, warum es kein ungültiges Programm gibt, das einer Nummer zugeordnet ist, die nicht von einem gültigen Programm abgedeckt wird.
In dieser Antwort werden Großbuchstaben für Programme und Kleinbuchstaben für Funktionen und ganze Zahlen verwendet. ~ ist der Verkettungsoperator.
Satz 1:
Die Funktion f sei das in dieser Antwort beschriebene Programm. Dann existiert für jedes Programm U ein gültiges Programm V, so dass f (U) = f (V)
Definition 1:
Sei g (X) die Nummer [
, die im Programm X erscheint, und sei h (X) die Nummer ]
, die erscheint.
Definition 2:
Definiere P (x) als diese Funktion:
P(x) = "" (the empty program) when x <= 0
P(x) = "]" when x = 1
P(x) = "]]" when x = 2
etcetera
Definition 3:
In einem gegebenen Programm X bezeichnen Sie X1 als das größte Präfix von [
Zeichen, X2 als das Zentrum und X3 als das größte Suffix von ]
Zeichen.
Beweis von Satz 1:
Wenn g (U) = h (U) ist, dann ist U ein gültiges Programm und wir können V = U nehmen. (Trivialfall).
Wenn g (U) <h (U) ist, können wir V erzeugen, indem wir n = h (U) - g (U) [
Symbole voranstellen . Offensichtlich ist f (V) = f (U), da alle [
Symbole im Präfix entfernt werden.
Betrachte nun g (U)> h (U). Definiere T = U2 ~ U3. wenn g (T) <= h (T), dann können wir V konstruieren, indem wir n = g (U) - h (U) [
Symbole entfernen .
Wir können also annehmen, dass h (T) <g (T) ist. Konstruiere V = T ~ P (g (T) - h (T)).
Wir brauchen drei kleine Fakten, um fortzufahren:
Anspruch 1: g (U2) = g (T)
U3 enthält [
laut Definition keine Symbole. Als T = U2 ~ U3 [
befinden sich alle Symbole im ersten Teil.
Anspruch 2: h (U3) <g (T)
Dies folgt aus der Feststellung, dass h (T) <g (T) und h (U3) <h (U3 - U2) = h (T) ist.
Anspruch 3: h (V3) = g (U2) - h (U2)
h(V3) = h(U3) + g(T) - h(T) using the construction of V
h(V3) = h(U3) + g(U2) + g(U3) - h(U2) - h(U3) apply the definition of T
h(V3) = g(U2) - h(U2) *one term cancels, g(U3) is always zero, as U3 contains only `]` symbols*
Nun zeigen wir, dass f (V) = f (U).
f(U) = U2 ~ P(h(U3) - g(U2)) = U2 claim 2, definition of P
f(V) = U2 ~ P(h(V3) - g(V2))
= U2 ~ P(h(V3) - g(U2))
= U2 ~ P(g(U2) - h(U2) - g(U2)) claim 3
= U2 ~ P(-h(U2))
= U2 definition P
Damit ist der Beweis abgeschlossen. QED
Lassen Sie uns auch die Einzigartigkeit tun.
Satz 2:
Sei U, V zwei verschiedene gültige Programme. Dann ist f (U)! = F (V)
Dies ist im Vergleich zum vorherigen Satz ziemlich einfach.
Nehmen wir an, U2 = V2. Aber dann können sich U und V nur dadurch unterscheiden, dass n [
und ]
Symbole zu U1 bzw. U3 hinzugefügt oder daraus entfernt werden . Dies ändert jedoch die Ausgabe von f, da f die Anzahl nicht übereinstimmender ]
Symbole im Suffix zählt.
Also U2! = V2.
Dies führt offensichtlich zu einem Widerspruch. Da U2 und V2 buchstäblich in der Ausgabe von f (U) bzw. f (V) enthalten sind, können sie sich nicht unterscheiden, außer am 'Rand' der Stelle, an der U2 mit U3 verkettet ist. Das erste und das letzte Symbol von U2 und V2 können jedoch nicht [
oder ]
definitionsgemäß sein, während dies die einzigen Symbole sind, die in U1, U3, V1, V3 bzw. erneut zulässig sind. Somit erhalten wir U2 = V2. QED