Schreiben Sie eine Programmiersprache von unbekannter Vollständigkeit

91

Beim Entwerfen einer Sprache ist es sehr wichtig festzustellen, ob eine Sprache vollständig ist. Es ist auch eine ziemlich schwierige Aufgabe für viele esoterische Programmiersprachen, aber lassen Sie es uns noch ein bisschen besser angehen. Lassen Sie uns einige Programmiersprachen erstellen, die so schwer zu beweisen sind, dass selbst die besten Mathematiker der Welt sie nicht beweisen können. Ihre Aufgabe ist es, eine Sprache zu entwickeln und zu implementieren, deren Turing-Vollständigkeit auf einem großen ungelösten Problem in der Mathematik beruht .

Regeln

  • Das von Ihnen gewählte Problem muss mindestens 10 Jahre zurückliegen und zum Zeitpunkt der Veröffentlichung dieser Frage ungelöst sein. Es kann jede nachweisbare Vermutung in der Mathematik sein, nicht nur eine der auf der Wikipedia-Seite aufgelisteten .

  • Sie müssen eine Spezifikation der Sprache und eine Implementierung in einer vorhandenen Sprache bereitstellen.

  • Die Programmiersprache muss genau dann vollständig sein, wenn die Vermutung zutrifft. (oder nur wenn die Vermutung nicht zutrifft)

  • Sie müssen einen Beweis beifügen, warum Turing aufgrund der gewählten Vermutung vollständig oder unvollständig wäre. Sie können beim Ausführen des Interpreters oder des kompilierten Programms den Zugriff auf den unbegrenzten Speicher übernehmen.

  • Da wir uns mit der Vollständigkeit von Turing befassen, ist I / O nicht erforderlich. Das Ziel ist jedoch, die interessanteste Sprache zu erstellen, damit dies hilfreich sein kann.

  • Dies ist ein , bei dem die Antwort mit den meisten Stimmen gewinnt.

Zielkriterien

Was soll eine gute Antwort tun? Hier sind einige Dinge, auf die Sie bei der Abstimmung achten müssen, die jedoch technisch nicht erforderlich sind

Weizen-Assistent
quelle
Diese Unterhaltung wurde in den Chat verschoben .
Dennis
13
Insgesamt finde ich die Antworten hier enttäuschend. Sie lauten so ziemlich "Beginnen Sie mit einer Turing-vollständigen Sprache, testen Sie dann, ob die Vermutung X wahr / falsch ist, und beenden oder deaktivieren Sie in diesem Fall eine wichtige Funktion."
Xnor
1
@xnoder ich stimme Ihnen zu, ich hatte gehofft, dass dieses Kopfgeld einige interessantere Antworten hervorrufen würde, aber es sieht so aus, als würde das nicht passieren.
Wheat Wizard
2
Ich denke, eines der Probleme ist, dass sich die meisten Vermutungen für eine unendliche Anzahl von Werten als wahr erwiesen haben, aber die Gegenbeispiele wären auch für eine unendliche Anzahl von Werten wahr. Infolgedessen wird es nahezu unmöglich, die Vollständigkeit zu beweisen, wenn dies der Fall ist.
Freitag,
1
Ich denke, die Anforderung, dass Turing-Vollständigkeit eins zu eins mit einer gegebenen Vermutung verknüpft ist, ist eine ziemlich starke Anforderung. Ich denke, es wäre einfach, wenn der Nachweis oder die Widerlegung der Vollständigkeit von Turing zwei unterschiedliche offene Probleme ergeben würde. (dh der Nachweis der Vollständigkeit von Turing entscheidet über das offene Problem A und das Widerlegen entscheidet über das offene Problem B).
PyRulez

Antworten:

48

Legendre

Diese Sprache ist nur dann vollständig, wenn die Vermutung von Legendre falsch ist, dh es gibt eine ganze Zahl n> 0, so dass es keine Primzahlen zwischen n ^ 2 und (n + 1) ^ 2 gibt. Diese Sprache wurde von Underload inspiriert, unterscheidet sich jedoch in mancher Hinsicht erheblich davon.

Programme in Legendre bestehen aus einer Reihe positiver Ganzzahlen (0 ist besonders verboten, da es im Wesentlichen den gesamten Zweck der Sprache negiert). Jede Ganzzahl entspricht einem Basisbefehl in Legendre oder einem potenziellen benutzerdefinierten Befehl. Welchem ​​Befehl er zugewiesen wird, hängt von der Anzahl der Primzahlen zwischen seinem Quadrat und der nächsten Ganzzahl ab (entspricht der OEIS-Sequenz A014085 ).

Die Sprachbefehle modifizieren einen Stapel, der beliebig große positive ganze Zahlen enthalten kann. Wenn der Stapel jemals 0 enthält, wird die 0 sofort entfernt. Im Detail sind die Befehle:

  • 2 (kleinste Ganzzahl, die diesen Befehl erzeugt: 1): Schieben Sie die nächste Ganzzahl im Programm auf den Stapel.

  • 3 (kleinste produzierende Ganzzahl: 4): Füge die oberste Ganzzahl in den Stapel ein und führe den dazugehörigen Befehl aus.

  • 4 (kleinste: 6): Pop die oberste Ganzzahl. Wenn es 1 war, erhöhen Sie die oberste Ganzzahl auf dem Stapel.

  • 5 (10): Vertausche die beiden obersten Stapelgegenstände.

  • 6 (15): Verringert die oberste Ganzzahl auf dem Stapel. Wenn dies zu 0 führt, platzieren Sie die 0 und verwerfen Sie sie.

  • 7 (16): Duplizieren Sie die oberste Ganzzahl auf dem Stapel.

  • 8 (25): Die Ausführung anhalten und den Stapelinhalt drucken.

Dies ist der grundlegende Befehlssatz, der nichts Interessantes kann, geschweige denn eine Schleife. Es gibt jedoch einen anderen Befehl, auf den nur zugegriffen werden kann, wenn sich Legendres Vermutung als falsch herausstellt.

  • 0 (unbekannt): Entfernen Sie alle Elemente aus dem Stapel und kombinieren Sie sie zu einer neuen Funktion, mit der alle Befehle ausgeführt werden, die am ursprünglichen Ende des Stapels beginnen und am oberen Ende enden. Dies ist ein Befehl, dessen "Befehlsnummer" gleich ist derjenige, dem die nächste Ganzzahl in der Programmquelle entspricht.

Wenn dieser Befehl irgendwie zugänglich ist, wird die Sprache zu Turing-complete, da man eine Minsky-Maschine darin simulieren kann.

Wenn der Befehl 8 ausgeführt wird oder das Programmende erreicht ist, wird das Programm beendet und das (Unicode-) Zeichen, das jeder Ganzzahl auf dem Stapel entspricht, wird gedruckt.

Beispielprogramme

1 2 1 3 1 10 4

Dieses einfache Programm drückt die Zahl 2, dann 3 und schließlich eine 10, bevor eine 4 (Befehl: 3) ausgeführt wird, wodurch die 10 (Befehl: 5) abgesetzt und ausgeführt wird, wobei die 2 und 3 vertauscht werden.

1 5 3 15 2 1 6 7

Dieses Programm demonstriert die Verwendung der indirekten Entsprechung von Ganzzahlen zu Befehlen. Zuerst wird eine 5 gedrückt, dann eine 15 und eine 1, wobei drei verschiedene Methoden zum Codieren des 2-Befehls verwendet werden. Dann wird die 1 getoppt und als Ergebnis wird die 15 zu einer 16 inkrementiert und schließlich ausgeführt. Das Programm endet mit zwei Instanzen der Nummer 5 auf dem Stapel.

1 1 1 5 ? 24 1 15 1 31 ? 31 24 31

Dieses Programm demonstriert die Verwendung des Befehls 0 unter Verwendung von? als Platzhalterzahl. Das Programm speichert zuerst '1 5' in der Funktion 9, dann '15 31' in 10, bevor die Funktion 9 (unter Verwendung von 24) ausgeführt wird, die 5 auf den Stapel schiebt, und diese wiederholt dekrementiert, bis sie 0 erreicht und entfernt wird . Dann stoppt das Programm.

Minsky-Maschine

Um eine Minsky Maschine zu Legendre - Code zu konvertieren, das 0 Befehl muss verwendet werden. Da auf diesen Befehl nur zugegriffen werden kann, wenn die Vermutung von Legendre falsch ist, habe ich einen Platzhalter verwendet? stattdessen.

Beachten Sie, dass alle Minsky-Maschinenbefehlszeilennamen Ganzzahlen mit unterschiedlichen A014085-Entsprechungen voneinander und von den Basisbefehlen sowie 24 (9) und 31 (10) haben müssen.

Initialisierung:
1 1 1 1 ? 24
x INC (A / B) y:

EIN:

1 y 1 24 1 ? 1 6 1 1 16 1 24 ? x

B:

1 y 1 24 1 ? 1 10 1 6 1 1 16 1 10 1 24 ? x
x DEZ (A / B) yz:

EIN:

1 4 1 10 1 15 1 10 1 31 1 1 1 10 1 z 1 1 1 16 1 24 1 31 1 ? 1 24 1 15 1 y 1 6 16 1 24 16 1 ? 1 1 16 1 10 1 1 16 1 24 ? x

B:

1 4 1 10 1 15 1 10 1 31 1 1 1 10 1 z 1 1 1 16 1 24 1 31 1 ? 1 24 1 15 1 10 1 y 1 6 16 1 24 16 1 ? 1 1 16 1 10 1 1 16 1 10 1 24 ? x
x HALT:
1 25 ? x

Um das endgültige Programm zu erstellen, hängen Sie alle Teile an (wobei x, y, z durch ihre Gegenstücke ersetzt werden) und fügen Sie eine einzelne Ganzzahl hinzu, um die erste Anweisung in der Kette zu starten. Dies sollte die Turing-Vollständigkeit der Sprache beweisen, falls die Vermutung von Legendre durch ein Gegenbeispiel als falsch erwiesen wird.

Dolmetscher

Dieser Interpreter ist in Python (3) geschrieben und wurde an allen drei obigen Beispielen getestet. Verwenden Sie die Flags -a / - allowZero, um zuzulassen? Zu verwenden ist -f / - file, um Code direkt aus einer Datei auszuführen, und -s / - stackOut, um den Stack stattdessen als Python-Liste auszugeben. Wird keine Datei angegeben, wechselt der Interpreter in eine Art REPL-Modus, der am besten mit --stackOut verwendet wird.

import sys
import argparse
import io

class I_need_missing(dict): #used to avoid try/except statements. Essentially a dict
    def __missing__(self,key):
        return None 

def appropriate(integer,prev): #returns number of primes between the square of the integer given and the next

    return_value = 0

    if prev[integer]:
        return prev[integer],prev
    if integer == "?":
        return 0,prev
    for i in range(integer ** 2, (integer + 1) ** 2):
        t = False
        if i > 1:
            t = True
            for j in range(2,int(i ** 0.5)+1):
                t = i/j != round(i/j)
                if not t:
                    break
        return_value += t

    prev[integer] = return_value
    return return_value,prev

def run_command(commandseries,stack,functions,prev): #Runs the appropriate action for each command.

    command,prev = appropriate(commandseries.pop(0),prev)

    halt = False

    if command == 0: #store in given number
        functions[appropriate(commandseries.pop(0),prev)[0]] = stack
        stack = []

    elif command == 2:#push
        stack.append(commandseries.pop(0))

    elif command == 3:#execute top instruction
        commandseries.insert(0,stack.pop())

    elif command == 4:#pop, add 1 to new top if popped value was 1
        if stack.pop() == 1:
            stack[-1] += 1

    elif command == 5:#swap top two integers/?
        stack[-1],stack[-2] = stack[-2],stack[-1]

    elif command == 6:#subtract 1 from top of stack
        stack[-1] -= 1
        if stack[-1] == 0:
            stack.pop()

    elif command == 7:#duplicate top of stack
        stack.append(stack[-1])

    elif command == 8:#halt
        halt = True

    else:#run custom
        try:
            commandseries[0:0] = functions[command]
        except TypeError:
            print("Warning: unassigned function " + str(command) + " is unassigned", file = sys.stderr)

    return commandseries,stack,functions,prev,halt

def main(stack,functions,prev):
    #Parser for command line options
    parser = argparse.ArgumentParser(description = "Interpreter for the Legendre esoteric programming language.")
    parser.add_argument("-a","--allowZero", action = "store_true")
    parser.add_argument("-f","--file")
    parser.add_argument("-s","--stackOut", action = "store_true")

    args = parser.parse_args()
    allow_zero = bool(args.allowZero)

    #Program decoding starts
    pre = ""

    if not args.file:
        pre = input()
        if pre == "":
            return
    else:
        pre = open(args.file).read()

    mid = pre.split()
    final = []

    for i in mid:
        if i == "?" and allow_zero:
            final.append("?")
        elif i != 0 or allow_zero: #and allow_zero)
            final.append(int(i))

    halt = False

    #Functional programming at its best
    while final and not halt:
        final,stack,functions,prev,halt = run_command(final,stack,functions,prev)

    #Halting and output
    else:
        if args.stackOut:
            print(stack)
        else:
            for i in stack:
                print(i == "?" and "?" or chr(i),end = "")
            print("")
        if args.file or halt:
            return
        else:
            main(stack,functions,prev)


if __name__ == '__main__':
    main([],I_need_missing(),I_need_missing())
ivzem
quelle
14

Union geschlossen

Diese Programmiersprache ist vollständig, wenn die Vermutung der unionsgeschlossenen Mengen falsch ist.

Kontrollen

Liste der Befehle:
x ++ Inkrementiere x (INC)
x-- Dekrementiere x (DEC)
j (x, y) Füge den Befehlssatz x hinzu, wenn y 0 ist, um das Ende der Befehlswarteschlange zu erreichen

Alle Variablen werden mit 0 initialisiert

Syntax

Programme werden als eine Reihe von Befehlssätzen geschrieben.
Befehl1 Befehl2 Befehl3 ... Befehl1 Befehl2
...
...

Um festzustellen, ob das Programm unionsgeschlossen ist, berücksichtigt jede Menge nur die Liste der verschiedenen Befehle, die in der Menge
j (x, y)! = J (a, b)
+ (x)! = + (Y) enthalten sind.

Wenn ein Befehlstyp (+, -, j) in mindestens der Hälfte der Sätze vorkommt, hat dies keine Auswirkungen.

Programme können enden, wenn sich am Ende der Anweisungswarteschlange keine Anweisungen befinden

Endlosschleifen, einschließlich der leeren Schleife, können mit j (x, y) erreicht werden

Dolmetscher

Vollständigkeit prüfen

Wenn alle drei Befehle, j (x, y), Inkrementieren und Dekrementieren, verfügbar sind, kann eine Minsky-Maschine simuliert werden.

Jede Menge mit nur j (x, y), die mit j (x, y) erreicht wird, ist HALT.
X ++ ist INC.
X-- ist DEC.
J (x, y) ist JZ

Wenn die Vermutung der Union Closed Sets korrekt ist, wird mindestens einer der drei Befehle immer deaktiviert, wodurch es unmöglich wird, dass diese Sprache vollständig ist.

fəˈnəˈtɛk
quelle
Statt 3 Operatoren zu haben, würde ich eine unendliche Anzahl von Werten haben und das Modulo 4 von jedem nehmen, um eine der drei Operationen plus ein No-Op zu erhalten. Beim Programmstart wird überprüft, ob die Vereinigung der Mengen geschlossen ist, und alle Elemente entfernt, die sich in mehr als der Hälfte der Mengen befinden. Dies wird dann wiederholt, bis es kein solches Element gibt. Wenn die Vermutung wahr ist, stimmen alle Programme mit dem leeren Programm überein. Wenn sie jedoch falsch sind, können Sie jedes mögliche Programm ausdrücken (daher ist das No-Op enthalten).
Wheat Wizard
@WheatWizard Die vom Interpreter geschlossene Bestimmung der Vereinigung betrachtet denselben Operator für verschiedene Variablen als unterschiedlich. x ++ unterscheidet sich von y ++. Infolgedessen gibt es unendlich viele verschiedene Mengen, die erstellt werden können. Wenn bei einer unendlichen Anzahl von möglichen Sätzen keiner der drei Haupttypen in mehr als der Hälfte der Sätze vorkommt, ist er vollständig.
Freitag,
Es ist möglich, dass ein Beweis für die Union Closed Sets-Vermutung eine Umwandlung in einen von drei Operatoren als vollständig zurücklässt, da es möglich sein könnte, alle verschiedenen Operatoren im Programm zu belassen, würden Sie nur 3 von unendlich vielen benötigen Werte bleiben.
Freitag,
13

Fermat-Primzahlen

Die Sprache funktioniert auf zwei potenziell unendlichen Bändern, auf denen an jeder Stelle des Bandes eine beliebige Ganzzahl gespeichert werden kann. Beide Bänder werden -1zu Beginn mit gefüllt . Es gibt auch zwei Bandköpfe, die auf beiden Bändern bei Position 0 beginnen.

Der Interpreter liest zuerst die Eingabe und speichert die Werte ab Position 0 auf dem ersten (Daten-) Band.

Dann liest es das mitgelieferte Programm. Für jede Zahl, auf die es trifft, wird zuerst geprüft, ob der Wert eine Fermat-Primzahl ist oder nicht. Wenn ja, wird auf das zweite (Anweisungs-) Band geschrieben, welches Fermat-Prime es ist, andernfalls wird -1auf das Anweisungsband geschrieben.

Überprüfen Sie als Nächstes den Wert am Anweisungszeiger und führen Sie einen der folgenden Schritte aus:

  • -1 oder weniger: Beenden Sie das Programm
  • 0: Bewegen Sie das Datenband um eine Position nach links. Bewegen Sie das Anweisungsband um eine Position nach rechts
  • 1: Bewegen Sie das Datenband um eine Stelle nach rechts. Bewegen Sie das Anweisungsband um eine Position nach rechts
  • 2: Erhöhen Sie den Wert an der Position des Datenbands. Bewegen Sie das Anweisungsband um eine Position nach rechts
  • 3: Verringern Sie den Wert an der Position des Datenbands. Bewegen Sie das Anweisungsband um eine Position nach rechts
  • 4: Wenn der Wert an der aktuellen Position des Datenbands Null ist, schieben Sie das Anweisungsband nach rechts, bis Sie entweder einen übereinstimmenden 5(oder einen größeren) Wert auf dem Anweisungsband oder einen kleineren Wert als erreichen 0. Wenn es ein 5(oder größer) ist, bewegen Sie den Anweisungszeiger erneut nach rechts, wenn er kleiner 0ist, beenden Sie das Programm. Wenn der Wert der aktuellen Datenbandposition nicht Null ist, schieben Sie das Anweisungsband einfach um eins nach rechts
  • 5oder mehr: Bewegen Sie den Anweisungszeiger nach links, bis Sie den entsprechenden 4Wert erreichen, oder Sie finden etwas weniger als 0. Beenden Sie in letzterem Fall das Programm.

(Bei Übereinstimmung 5(oder mehr) mit 4Werten bedeutet dies, dass bei der Suche nach dem richtigen Wert auf dem Anweisungsband immer dann, wenn es auf denselben Wert stößt wie der ursprüngliche Befehl (entweder 5(oder mehr) oder 4), die entsprechende Nummer übersprungen werden muss des anderen Wertes ( 4oder 5(oder mehr) auf der Suche)

Schleife, bis die Anweisung besagt, dass Sie das Programm beenden müssen.

Wenn das Programm beendet wird, geben Sie die Werte auf dem Datenband von der Position 0bis zur ersten Bandposition aus, die einen -1Wert enthält .

Beweis

Beachten Sie, dass die Sprache im Wesentlichen einem E / A-freien Brainfuck-Interpreter zugeordnet F_5ist, in dem alle möglichen Schleifen ausgeführt werden müssen.

Basierend auf der Fermat-Prim-Vermutung gibt es jedoch nur 5 Fermat-Primzahlen ( F_0- F_4). Wenn F_5vorhanden, ist die Sprache Turing-vollständig, da wir wissen, dass Brainfuck Turing-vollständig ist. Ohne können F_5Sie jedoch weder verzweigen noch schleifen und sind im Grunde genommen an sehr einfache Programme gebunden.

Implementierung

(getestet mit ruby ​​2.3.1)

#!/usr/bin/env ruby
require 'prime'

CHEAT_MODE = false
DEBUG_MODE = false
NUM_CACHE = {}

def determine_number(n)
  return n.to_i if CHEAT_MODE
  n = n.to_i
  -1 if n<3

  return NUM_CACHE[n] if NUM_CACHE[n]

  i = 0

  loop do
    num = 2**(2**i) + 1
    if num == n && Prime.prime?(n)
      NUM_CACHE[n] = i
      break
    end
    if num > n
      NUM_CACHE[n] = -1
      break
    end
    i += 1
  end

  NUM_CACHE[n]
end

data_tape = Hash.new(-1)
instruction_tape = Hash.new(-1)

STDIN.read.each_char.with_index { |c,i| data_tape[i] = c.ord }
File.read(ARGV[0]).split.each.with_index do |n,i|
  instruction_tape[i] = determine_number(n)
end

data_pos = 0
instruction_pos = 0

while instruction_tape[instruction_pos] >= 0
  p data_tape, data_pos, instruction_tape, instruction_pos,'------------' if DEBUG_MODE

  case instruction_tape[instruction_pos]
  when 0 then data_pos -= 1; instruction_pos += 1
  when 1 then data_pos += 1; instruction_pos += 1
  when 2 then data_tape[data_pos] += 1; instruction_pos += 1
  when 3 then data_tape[data_pos] -= 1; instruction_pos += 1
  when 4 then
    if data_tape[data_pos] == 0
      count = 1
      instruction_pos += 1
      while count>0 && instruction_tape[instruction_pos] >= 0
        count += 1 if instruction_tape[instruction_pos] == 4
        count -= 1 if instruction_tape[instruction_pos] >= 5
        instruction_pos += 1
      end
      break if count != 0
    else
      instruction_pos += 1
    end
  else
    count = 1
    instruction_pos -= 1
    while count>0 && instruction_tape[instruction_pos] >= 0
      count += 1 if instruction_tape[instruction_pos] >= 5
      count -= 1 if instruction_tape[instruction_pos] == 4
      instruction_pos -= 1 if count>0
    end
    break if count != 0
  end
end

data_pos = 0

while data_tape[data_pos] >= 0
  print data_tape[data_pos].chr
  data_pos += 1
end

Beispiele:

Dies wird H(kurz für Hello World!) mit einer neuen Zeile auf den Bildschirm schreiben:

17 17 17 17 17 17 17 17 17 17
17 17 17 17 17 17 17 17 17 17
17 17 17 17 17 17 17 17 17 17
17 17 17 17 17 17 17 17 17 17
17 17 17 17 17 17 17 17 17 17
17 17 17 17 17 17 17 17 17 17
17 17 17 17 17 17 17 17 17 17
17 17 17
5
17 17 17 17 17 17 17 17 17 17
17

Speichern unter example.fermatund starten Sie es wie folgt (Hinweis: Sie müssen immer eine Eingabe haben):

$ echo -n '' | ./fermat.rb example.fermat

In diesem nächsten Beispiel wird eine einfache Caesar-Verschlüsselung durchgeführt, indem jeder Wert der Eingabe um eins erhöht wird. Sie müssen natürlich durch ?die 5. Fermat-Primzahl ersetzen :

17 65537 5 17 ? 257

Sie können ausprobieren, dass es funktioniert, indem Sie den Cheat-Modus aktivieren und 2 4 1 2 5 3als Quellcode verwenden:

$ echo 'Hello' | ./fermat.rb example2_cheat.fermat
SztupY
quelle
2
Es tut mir leid für den armen Programmierer, der die entsprechende Primzahl eingeben muss, um zu kommen 5. Ich hoffe sie haben eine gute Tastatur.
AdmBorkBork
2
@AdmBorkBork Mach dir keine Sorgen. Es hat einfach mehr Teile als das Universum Elementarteilchen hat.
8.
@LliwTelracs Das macht eigentlich keinen Sinn, da die Menge der Elementarteilchen im Universum Aleph-null (Omega) ist und von Omega aus nicht die tatsächliche Größe der Zahl bedeutet. (Es sei denn, es ist ein Aleph: P)
Matthew Roh
1
@MatthewRoh Ich hatte einen Fehler gemacht. Ich meinte im beobachtbaren Universum.
8.
2
@MatthewRoh Eigentlich könnte es endlich, unendlich, unzählig oder sogar unvereinbar mit der Mengenlehre sein! Wir werden es jedoch nie erfahren :(
CalculatorFeline
10

Schwalben mit Kokosnuss v2

Da die vorherige Version Fehler aufwies, die sie für diesen Wettbewerb ungültig machten, und ich nicht möchte, dass die Upvotes der vorherigen Version für diese Version zählen, die sich erheblich unterscheidet, wird diese Version als neuer Beitrag übermittelt.

Diese Sprache ist nicht vollständig, wenn die Collatz-Vermutung für alle positiven ganzen Zahlen bewiesen werden kann. Ansonsten ist die Sprache Turing vollständig.

Diese Sprache basierte auf Kardinal .

Zunächst wird der contVal des Programms mit der Formel
contVal = sum (summe (ASCII-Werte der Zeile) * 2 ^ (Zeilennummer-1)) berechnet.

Als nächstes werden an jedem A oder E 2 Schwalben mit entgegengesetzter Richtung erzeugt und alle bedingten Turn-Anweisungen werden so eingestellt, dass sie auf die Initialisierung warten.
Schwalben, die an einem E erstellt wurden, werden nach links / rechts geleitet, und Schwalben, die an einem A erstellt wurden, werden nach oben / unten geleitet.

Schließlich führt der Code Schritte aus, bis alle Zeiger entfernt wurden oder contVal auf eins gefallen ist.

Bei jedem Schritt wird contVal% 2 == 0 durch 2 geteilt, andernfalls wird es mit drei multipliziert und mit eins inkrementiert.

Befehle:

0: Wert auf 0 setzen
+: Wert um 1
erhöhen>: Richtung nach rechts
ändern v: Richtung nach unten
ändern <: Richtung nach links
ändern ^: Richtung nach oben ändern
R: Nachfolgende Zeiger nach dem ersten Zeiger vergleichen mit dem Wert des erster Zeiger. Wenn gleich, fahren Sie geradeaus, sonst biegen Sie rechts ab.
L: Nachfolgende Zeiger nach dem ersten Zeiger vergleichen mit dem Wert des ersten Zeigers. Wenn gleich, geradeaus, sonst links abbiegen.
E: Den Zeiger duplizieren, aber in die Richtungen nach links und rechts zeigen
A: Den Zeiger duplizieren, aber in die Richtungen nach oben und unten zeigen
? : Entfernen Sie den Zeiger, wenn der Wert 0 ist

Erläuterung:

Wenn die Collatz-Vermutung für alle positiven ganzen Zahlen bewiesen werden kann, ist die Dauer eines in dieser Sprache ausgeführten Programms begrenzt, da contVal immer gegen 1 konvergiert und damit das Programm beendet.

Ansonsten muss ich nur beweisen, dass diese Sprache die folgenden Funktionen implementieren kann

Inkrement: Wird durch +
Konstante dargestellt. 0
Wird durch 0 dargestellt. Variablenzugriff: Variablen werden als Zeiger während der Fahrt gespeichert.
Anweisungsverkettung: Durch Ändern der zurückgelegten Entfernung zu Operationen kann die Reihenfolge, in der Operationen ausgeführt werden, geändert werden.
For-Schleife: In dieser Sprache

E   > V
    ^+R
      +
      A

fungiert als for-Schleife> zählt bis zu 1 (weiterer Code könnte zur Schleife hinzugefügt werden)

Ebenso der Code

Rv
^<

Wirkt so lange wie möglich, bis der in der R-Schleife festgelegte bedingte Wert erreicht ist.

fəˈnəˈtɛk
quelle
Du hast mich auch geschlagen, ich wollte etwas mit der Collatz-Vermutung anfangen. Gute Arbeit, auf die interessante Art und Weise. Ich wollte nur eine Sprache erstellen, die nur Zahlen speichern kann, wenn sie zu 1 konvergieren.
Rohan Jhunjhunwala
Ich bin verwirrt. Wo spielt die Collatz-Funktion eine Rolle? Ich denke, Sie wollen von einem zweiten Durchlesen sagen, dass die Funktion contValbei jedem Schritt angewendet wird (und daher gibt es, wenn die Vermutung wahr ist, keine Endlosschleifen) - aber ich sehe das nirgends in der Antwort explizit. ??
DLosc
Es tut mir leid, aber ich glaube, ich habe das versehentlich irgendwann aus meiner Beschreibung
gestrichen
10

Perfektion / Unvollkommenheit

Puh, das hat Spaß gemacht.

Perfektion / Unvollkommenheit ist nur dann vollständig, wenn es unendlich perfekte Zahlen gibt. Wenn es welche gibt, nennt man sie Perfektion, und wenn es keine gibt, nennt man sie Imperfektion. Bis dieses Rätsel gelöst ist, enthält es beide Namen.

Eine perfekte Zahl ist eine Zahl, deren Teiler sich zur Zahl addieren, also ist sechs eine perfekte Zahl, weil 1+2+3=6.

Perfektion / Unvollkommenheit hat folgende Funktionen:

Perfektion / Unvollkommenheit ist stapelbasiert, mit einem Null-Index-Stapel.

Befehle:

p(x, y): schiebt x in die y-te Position zum Stapel.

z(x, y): drückt x in der y-ten Position auf den Stapel, entfernt das, was vorher in der y-ten Position war

r(x): Entfernt den x-ten Gegenstand vom Stapel

k(x): Gibt das x-te Element auf dem Stapel zurück

a(x, y): fügt x und y hinzu. Bei Verwendung mit Zeichenfolgen werden diese in der Reihenfolge xy zusammengefasst.

s(x, y): subtrahiert y von x. Entfernt mit Strings das letzte len (y) von x

m(x, y): multipliziert x und y. Bei Verwendung mit Zeichenfolgen wird x mal len y multipliziert.

d(x, y): dividiert x durch y

o(x): druckt x

i(x, y): Wenn x true ergibt, führt es die Funktion y aus

n(): gibt den Zähler zurück, auf den der Codeblock aufgerufen wird.

q(): gibt die Länge des Stapels zurück

t(): Benutzereingabe

e(x, y): Wenn x eine Ganzzahl ist und x und y denselben Wert haben, wird 1 zurückgegeben. Wenn y eine Zeichenfolge ist, wird die Länge von y abgerufen. Wenn x eine Zeichenfolge ist, konvertiert es y in eine Zeichenfolge und überprüft, ob sie identisch sind. Wenn dies der Fall ist, wird 1 zurückgegeben. Andernfalls wird 0 zurückgegeben.

l(x, y): Wenn x größer als y ist, wird 1 zurückgegeben. Wenn eine Zeichenfolge vorhanden ist, wird die Länge der Zeichenfolge verwendet.

b(): stoppt das Programm.

c(x, y): Läuft x, dann y.

Um das Äquivalent zu einem Python zu erhalten and, multiplizieren Sie die beiden Werte. Für or, fügen Sie die Werte und für notsubtrahieren Sie den Wert von 1. Das funktioniert nur , wenn der Wert 1 oder 0 ist, die durch Teilen der Zahl von selbst erreicht werden kann.

Datentypen: Ganzzahlen und Zeichenfolgen. Zeichenfolgen werden mit gekennzeichnet '', und alle nicht ganzzahligen Zahlen werden gerundet.

Syntax:

Code besteht aus verschachtelten Funktionen innerhalb von zehn {}Sekunden. Zum Beispiel kann ein Programm , das würde sich mit den Eingängen und ausdrucken würde hinzugefügt: {o(a(t(), t()))}. Im Hintergrund des Programms befindet sich ein Zähler, der bei 0 beginnt und bei jeder Ausführung eines Codeblocks um 1 fortschreitet. Der erste Codeblock läuft um 0und so weiter. Sobald die zehn Codeblöcke ausgeführt sind, wird der sechste jedes Mal ausgeführt, wenn der Zähler eine perfekte Zahl erreicht. Sie müssen nicht alle zehn Codeblöcke haben, damit das Programm funktioniert, aber Sie benötigen 7, wenn Sie eine Schleife erstellen möchten. Um besser zu verstehen , wie diese Sprache funktioniert, führen Sie das folgende Programm, das den Zähler druckt jedes Mal , wenn der Zähler eine perfekte Zahl erreicht: {}{}{}{}{}{}{o(n())}.

Den Interpreter finden Sie hier: repl.it/GL7S/37 . Wählen Sie entweder 1 aus, und geben Sie Ihren Code im Terminal ein, oder fügen Sie Ihren Code in die code.perfectRegisterkarte ein und wählen Sie 2, wenn Sie ausgeführt werden. Es macht Sinn, wenn Sie es versuchen.

Nachweis der Turing-Vollständigkeit / Mangel an Turing-Vollständigkeit.

Gemäß diesem Artikel über den Austausch von Software-Engineering-Stapeln muss ein Turing-Abschluß in der Lage sein, eine Form der bedingten Wiederholung des Sprungs zu haben und einen Weg zum Lesen oder Schreiben des Speichers zu haben. Es kann Speicher in Form des Stapels lesen / schreiben und es kann eine Schleife ausführen, da der sechste Codeblock jedes Mal ausgeführt wird, wenn der Zähler eine perfekte Zahl erreicht. Wenn es unendlich viele perfekte Zahlen gibt, kann es eine Endlosschleife geben, und Turing ist abgeschlossen. Andernfalls ist dies nicht der Fall.

Self Bitwise Cyclic Tag-Interpreter, der 5 Zeichen (1 oder 0) als Eingabe akzeptiert:

{p(t(),0)}{(p(t(),0)}{p(t(),0)}{p(t(),0)}{p(t(),0)}{p(0,0)}{c(i(e(k(s(q(),k(0))),0),c(r(q()),i(l(k(0),0),z(s(k(0),1),0)))),i(e(k(s(q(),k(0))),1),c(z(a(k(0),1),0),i(e(k(q()),1),p(k(s(q(),k(0))),1)))))}

Es kann erweitert werden, um eine beliebige Anzahl von Zeichen als Eingabe zu verwenden. Es könnte unendlich viele Eingaben erfordern, aber nur, wenn es unendlich perfekte Zahlen gibt!

Genosse SparklePony
quelle
1
Ich denke, dass Sie möglicherweise nur einen neuen Wert für die lokale Schleife erstellen, da er nicht mit der Funktion geteilt wird.
9.
3
Wie es aussieht, haben Sie keinen TC-Nachweis. Der Software-Engineering-Artikel, auf den Sie verlinken, enthält eine grobe Reihe von Anforderungen. TC ist jedoch nicht nur eine Reihe von Kästchen, die Sie abhaken müssen. Sie müssen einen TC-Automaten (wie eine Minsky-Maschine) implementieren oder zeigen, dass Ihre Sprache unentscheidbar ist.
Wheat Wizard
2
@ WheatWizard Dort habe ich einen Bitwise Cyclic Tag-Interpreter hinzugefügt. Es kann modifiziert werden, um eine beliebige Anzahl von Zeichen als Eingabe zu verwenden. Möglicherweise werden unendliche Zeichen als Eingabe verwendet, aber nur, wenn es unendlich perfekte Zahlen gibt!
Genosse SparklePony
2
"Sobald die zehn Codeblöcke ausgeführt sind, wird der sechste jedes Mal ausgeführt, wenn der Zähler eine perfekte Zahl erreicht." Der Interpreter zählt also einfach direkt perfekte Zahlen? Ich glaube, das widerspricht dem Geist der Herausforderung. Die tatsächliche Sprachspezifikation spielt keine Rolle, es kann alles sein, was Turing-complete plus "nur für einen Schritt ausführen, wenn Sie eine perfekte Zahl treffen".
Xnor
10

Sohlen

Diese Programmiersprache ist vollständig, wenn die Scholz-Vermutung wahr ist.

Ich habe diese Sprache geschrieben, weil @SztupY sagte, dass es keine Ergebnisse geben würde, bei denen davon ausgegangen wird, dass die Vermutung wahr ist, dass Turing vollständig ist

Liste der Befehle

+(x)      Increment x (INC)   
-(x)      Decrement x (DEC)  
j(x,y)    Jump to instruction x if y is 0 (JZ)  
x         End program (HALT) 

Mit diesen Befehlen kann diese Sprache eine Minsky-Maschine simulieren

Dolmetscher

Ich würde empfehlen, dies nicht auszuführen. Es verwendet eine außerordentlich langsame Methode zur Überprüfung der Additionskette.

Vollständigkeit prüfen

Die Sprache verwendet einen Zähler für die Anzahl der ausgeführten Befehle, die sie anhand der Scholz-Vermutung überprüft, um die Vollständigkeit der Sprache zu ändern.

Wenn die Scholz-Vermutung wahr ist, funktioniert dieses Programm genau wie eine normale Minsky-Maschine mit
Increment
Decrement
Jump, wenn Zero
Halt

Wenn jedoch die Scholz-Vermutung falsch ist, erreicht der Zähler irgendwann einen Wert, für den die Scholz-Vermutung nicht gilt. Da die Sprache so konzipiert wurde, dass sie bei Erreichen einer Zahl beendet wird, bei der die Scholz-Vermutung falsch ist, wird das Programm jedes Mal beendet, nachdem so viele Befehle ausgeführt wurden. Daher haben alle Programme eine begrenzte Länge. Da dies nicht mit den Anforderungen für die Vollständigkeit der Sprache übereinstimmt,

"Das Band kann nicht in der Länge fixiert werden, da dies nicht der vorgegebenen Definition entspricht und den Rechenumfang der Maschine erheblich auf die eines linear begrenzten Automaten einschränken würde",

Die Sprache wäre nicht vollständig, sollte die Scholz-Vermutung falsch sein

fəˈnəˈtɛk
quelle
1
+1, da dies tatsächlich die Vermutungsanforderung hart in die Sprache einbringt, anstatt etwas Fremdes hinzuzufügen, um die Sprache zu töten, wenn die Vermutung wahr / falsch ist
Gryphon
Ich verstehe es nicht. Die Befehle, die Sie bereitstellen, sind genau die, die Sie zur Simulation einer Minsky-Maschine benötigen. Wenn das alles ist, ist Ihre Sprache Turing-vollständig, unabhängig von der Scholz-Vermutung. Sie müssen etwas aus Ihrer Erklärung fehlen.
Nathaniel
@ Nathaniel Eine der Anforderungen für eine vollständige Turing-Sprache ist, dass die Sprache in einer Endlosschleife enden kann (Halteproblem). Mein Code zählt, während er Anweisungen ausführt, und wenn die Scholz-Vermutung falsch ist, stoppt das Programm immer nach einer festgelegten Anzahl von Anweisungen.
15.
Ja, aber Sie haben vergessen zu erklären, warum es aufhört, wenn die Scholz-Vermutung falsch ist. Schauen Sie sich Ihre Antwort noch einmal an - sie ist überhaupt nicht da.
Nathaniel
@ Nathaniel Das Programm überprüft buchstäblich jede einzelne Zahl, ob sie in der Scholz-Vermutung funktioniert. Es wird automatisch beendet, wenn es eine Zahl findet, die mit der Vermutung nicht übereinstimmt.
15.
9

Verlobt

Verlobter Github .

Die Readme-Datei und die Spezifikation befinden sich auf dem Github unter "README.txt".

Im Allgemeinen besteht ein Verlobungsprogramm aus Linienpaaren, deren Länge aus unterschiedlichen Twin-Prim-Paaren oder Verlobungspaaren besteht (es können keine Duplikate auftreten). Das Programm wird ausgeführt, indem "biegsame Teilmengen" der ersten Zeile in dem Paar innerhalb der zweiten Zeile gefunden werden. Die Anzahl solcher Teilmengen, kombiniert mit dem Abstand zwischen der ursprünglichen zweiten Zeile und der zweiten Zeile ohne die biegsamen Teilmengen, bestimmen den auszuführenden Befehl.

Ich werde den Beweis für diesen Beitrag extrahieren:

V. PROOF OF TURING COMPLETENESS

Now, no language can be Turing Complete with bounded program size. Therefore, if Betrothed
is Turing Complete, it must have unbounded program size. Since the lengths of the lines of
a Betrothed program must be twin prime pairs or betrothed pairs, and since both sequences
are unproven to be infinite or finite, Betrothed has unbounded program size if and only if
there are infintie betrothed pairs, there are infinite twin prime pairs, or both.

    Next: to prove that if Betrothed has an unbounded program size, then it is Turing
Complete. I will use the op-codes from the above table to demonstrate key factors of a
Turing Complete language; they are of the form  [index]<[ld]> .

  1. Conditional goto: 6<> 5<>, or if-popjump. This can be used to form a loop.
  2. Inequality to a constant K: 10<K> 
  3. Arbitrarily large variable space: you can use some separator constant C.

    With this, I have sufficient reason to believe that Betrothed is Turing Complete.
Conor O'Brien
quelle
4
"Jetzt kann keine Sprache mit begrenzter Programmgröße Turing Complete sein." Ich bin verwirrt über diese Aussage ... Einerseits ist es wahr, dass wir mit einer begrenzten Programmgröße nur eine begrenzte Anzahl verschiedener Programme schreiben können, andererseits besteht ein gemeinsamer Beweis für die Vollständigkeit von Turing darin, einen Interpreter für ein anderes Programm zu schreiben Turing Vollständige Sprache, die überhaupt keine unbegrenzte Programmgröße benötigt ...
Leo
1
Nun, das an den Dolmetscher übergebene Programm muss nicht in den Code des Dolmetschers eingefügt werden, sondern sollte dem Dolmetscher als Eingabe übergeben werden
Leo
7
@Löwe. Ich werde sagen , dass, um für die Sprache TC zu sein, muss es in der Lage sein , das Programm zu kodieren , an den Interpreter übergeben werden (das heißt, sich vorstellen , dass diese Sprache keine Eingabebefehl hat.) , Eine Sprache mit einem Befehl Stellen Sie sich vor: b. Dies interpretiert ein BF-Programm, das dahinter steht, wie b+++++.. Die Größe des Programms ist jedoch auf 10 Zeichen begrenzt. Während es BF interpretieren kann, kann es nicht alle Programme berechnen, die eine Turing-Maschine kann.
Conor O'Brien
3
@EriktheOutgolfer das Hauptproblem bei deinem Problem ist "es kann das BF-Programm setzen, das es von der Eingabe erhält ..." Aus diesem Grund empfehle ich dir nachdrücklich, meinen vorherigen Kommentar, insbesondere diesen ersten Satz, zu lesen oder erneut zu lesen. Wenn die Sprache nur auf der Grundlage der Eingabe vollständig ist, wie kann sie dann ohne Eingabe vollständig sein? Das heißt, damit die Sprache vollständig ist, muss das Programm der Sprache selbst das Programm codieren. Andernfalls wird festgestellt, dass sie das Programm in der Eingabe codieren, was keine gültige Art der Programmierung ist.
Conor O'Brien
1
Ich denke nicht, dass dies ein klarer Punkt ist. Dieser Esolang-Artikel behandelt das Problem. (Es stellt sich auch die Frage, ob ein Programm, das jedes mögliche Abschlussprogramm in einer Turing-vollständigen Sprache ausgibt, zusammen mit seiner Ausgabe eine Turing-Vollständigkeitsdemonstration darstellt, die keine Eingabe erfordert und mit einem endlich langen Programm durchgeführt werden kann .)
5

Einvernehmliche Parität

Diese Sprache basiert darauf, ob es einvernehmliche Zahlen mit entgegengesetzter Parität gibt .

Befehle

x : End program if not on top line  
+ : increment stored value  
- : decrement stored value  
{ : set next goto x value to current x value
} : goto previous x value set by {  
j : Go down one line if the special value is an amicable number and the
    parity is opposite to the matching number (loops back to top). If the
    special value is not an amicable number and not on the top line, go up
    one line.  

Kontrollfluss

Das Programm wechselt wiederholt von links nach rechts, bevor es zum Start zurückkehrt. Wenn es auf ein "j" stößt, überprüft es den Wert, um festzustellen, ob Zeilen geändert werden sollen. Wenn es sich bei der Zahl um eine freundliche Zahl mit entgegengesetzter Parität zu ihrer Übereinstimmung handelt, wird sie um eine Zeile nach unten verschoben (Schleife nach oben). Wenn es sich bei der Zahl um eine freundliche Zahl handelt, wird sie um eine Zeile nach oben verschoben, sofern sie nicht bereits in der oberen Zeile enthalten ist.

Das Programm kann nur beendet werden, wenn das Programm in einer Zeile außerhalb der obersten Zeile ein x erreicht.

Vollständigkeit prüfen

Mit diesem Programm kann eine Minsky-Maschine simuliert werden, vorausgesetzt, es gibt ein Paar von befreundeten Zahlen mit entgegengesetzter Parität.

j, {und} können verwendet werden, um JZ (r, x) zu simulieren, obwohl nach gütlichen Zahlen anstatt nach Null gesucht wird.
+ ist INC (r)
- ist DEC (r)
x ist HALT

Wenn Sie die erste Zeile nicht verlassen können, tun die Befehle x und} nichts. Dies führt dazu, dass das Programm nicht in den Status HALT wechseln kann, es sei denn, es ist ein leeres Programm. Daher wäre unter der Beschreibung, dass die Vollständigkeit von Turing einen HALT-Zustand erfordert , die Sprache Turing unvollständig.

Dolmetscher

fəˈnəˈtɛk
quelle
2

Neue Zeile

Disclaimer: Es ist ein bisschen chaotisch und ziemlich einfach. Dies ist die erste Sprache, die ich jemals geschrieben habe, und die Vermutung ist die einzige, die ich verstanden habe. Ich weiß, dass ein anderer Benutzer eine längere Antwort mit derselben hatte, aber ich habe mich trotzdem dazu entschlossen, diese zu schreiben.

Um in Newline zu schreiben, müssen Sie viel Zeit und Zeilenumbrüche haben ( \n). Dies geht von der Legendre-Vermutung aus, dass sie wahr ist. Jeder Operator muss auf eine Zahl in der Legendre-Vermutung fallen, die wir mit n = 1 beginnen. Jedes Mal, wenn Sie einen Operator haben, nehmen Sie die Menge von \ n und stecken Sie diese in die Legendre-Vermutung und erhalten die Reichweite der nächsten Primzahl von \ Es muss n geben. Zu Beginn \n\nwechseln Sie zu einem Operator, dann zu einem \nanderen Operator. Wir haben 3 neue Zeilen. Der nächste ist 5, also addieren Sie \n\nund stellen Sie sicher, dass die letzte Operatorzeile die richtige Anzahl von Zeilenumbrüchen enthält, die Sie auf einer Primzahl haben, die der Legendre-Vermutung entspricht, die wir gestartet haben.

Zahlen (das Array) sind wie die Variablen. Jedes Mal, wenn ein Operator ausgeführt wird (der Zahlen verwendet), wird er inkrementiert.

+ adds
- subtracts
/ divide
* multiply 
s sqrt
% mod
a push to vars
g sets stack to numbers
q pushes value of stack to numbers
i increment 
d decrement
r stops subtraction at 0
w turns back on subtraction past 0
[ starts loop
] ends loop runs until stack is 0
{ starts loop
} ends loop and loops until loops[ln] is 0
k increment loops

Solange wir unbegrenzt Primzahlen haben, die den Regeln folgen, hat diese Sprache kein endliches Band.

Minsky-Maschine

\n\ng\nr\n\n[\n\nd\n\n\n\n]

Wie es funktioniert:

\n\ng     # the first two newlines are to get to a prime number of newlines (2) then sets the value of stack to the first variable in the array numbers (see code in link)

\nr       # gets to the next number and makes it so subtraction stops at 0

\n\n[     # starts the loop

\n\nd     # decrements stack 

\n\n\n\n] # ends loop

Probieren Sie es auf KhanAcademy aus .

Christopher
quelle
@ Wheat es muss nicht mit nicht endlichen Speicher Schleife
Christopher
Es funktioniert nur, wenn es wahr ist. Ich kann das Schreiben gerade nicht beenden, da ich auf dem Handy bin, werde es aber heute Abend
Christopher
Auch wenn Sie unendlich viel Speicher haben, müssen Sie in der Lage sein, Endlosschleifen auszuführen.
Pavel
Ich habe Schleifen. Der Versuch, sie unendlich zu machen
Christopher
Im Moment stürzen sie ab
Christopher
2

Taggis

Taggis ist eine Sprache, die auf Tag-Systemen basiert .

Die Vollständigkeit von Taggis basiert auf der Collatz-Vermutung

Syntax

Die Syntax eines Taggis-Programms besteht einfach aus drei Zeichenfolgen (Produktionsregeln), die vollständig aus den durch Leerzeichen getrennten Buchstaben a, b und c bestehen.

Ausführung

Der einzige Programmstatus von Taggis ist eine Zeichenfolge, die aus den gleichen drei Zeichen besteht.

Taggis implementiert ein TS (3, 2) -Tag-System, bei dem in jedem Schritt die ersten zwei Buchstaben des aktuellen "Tags" entfernt werden und dem allerersten Buchstaben, der sich in diesem entfernten Teil befand, die entsprechende Produktionsregel an das Ende von angehängt wird die Saite.

Das Taggis-Programm bc a aaaimplementiert beispielsweise das 3n + 1-Problem, bei dem Iterationen durch eine entsprechende Anzahl von as dargestellt werden und der 3n + 1-Schritt durch (3n + 1) / 2 [1] ersetzt wird, was zur Programmausgabe führt:

aaa // 3
  abc
    cbc
      caaa
        aaaaa // 5
          aaabc
            abcbc
              cbcbc
                cbcaaa
                  caaaaaa
                    aaaaaaaa // 8
                      aaaaaabc
                        aaaabcbc
                          aabcbcbc
                            bcbcbcbc
                              bcbcbca
                                bcbcaa
                                  bcaaa
                                    aaaa // 4
                                      aabc
                                        bcbc
                                          bca
                                            aa // 2
                                              bc
                                                a // 1 and halt because we then begin an infinite loop
                                                 HALT

Vollständigkeit prüfen

Natürlich mag dieses einfache System viel zu einfach erscheinen, um die Turing-Vollständigkeit zu emulieren, aber es stellt sich heraus, dass jede Turing-Maschine mit 2 Symbolen (eine Klasse, die Universalmaschinen umfasst) in ein Tag-System mit 2 entfernten Zeichen vom Kopf konvertiert werden kann. und 32 * m Produktionsregeln, wo mist die Anzahl der Zustände in der Turing-Maschine.

Die kleinste bekannte Universal-Turing-Maschine mit nur 2 Symbolen verwendet 18 Zustände und somit enthält das entsprechende Tag-System satte 576 Produktionsregeln [2].

Die rechnerische Klasse der Menge aller Tag-Systeme mit 3 Produktionen und 2 entfernten Symbolen ist jedoch an die Collatz-Vermutung gebunden [2]. Wenn sich die Collatz-Vermutung als falsch herausstellt, ist Taggis vollständig. Ansonsten basiert es auf einem weiteren ungelösten Problem in der Mathematik, eine kleinere Turing-Maschine zu finden als

def taggis(inp, a, b, c):
    current = inp
    seen = set()
    while True:
        seen.add(tuple(current))

        yield current

        head = current[0]

        current = current[2:]

        current.extend([a, b, c][head])

        if tuple(current) in seen:
            return

def parse():
    program = input().split(" ")

    assert len(program) == 3, "There has to be exactly 3 production rules!" 

    productions = []

    for production in program:

        production = [{"a": 0, "b": 1, "c": 2}[x] for x in production]
        productions.append(production)  

    program_input = [{"a": 0, "b": 1, "c": 2}[x] for x in input()]

    k = 0   

    for step in taggis(program_input, *productions):
        print(' ' * k +''.join(['abc'[x] for x in step]))

        k += 2
    print(' ' * (k - 1) + 'HALT')

parse()
  1. Dies entspricht der ursprünglichen Collatz-Funktion, da 3n + 1 einer ungeraden nimmer gerade ist und daher die Division automatisch angewendet werden kann

  2. Tag-Systeme und Collatz-ähnliche Funktionen, Liesbeth De Mol ,

DiePlasmaRailgun
quelle