未知の完全性のプログラミング言語を書く


91

言語をチューリング完全であるかどうかを判断することは、言語を設計するときに非常に重要です。また、多くの難解なプログラミング言語にとって最初から非常に困難な作業ですが、一気に追い上げましょう。チューリング・コンプリートを証明するのが非常に困難なプログラミング言語を作成して、世界の最高の数学者でさえ、どちらの方法でも証明できないようにします。あなたの仕事は、チューリング完全性が数学の主要な未解決問題に依存している言語を考案して実装することです。

ルール

  • 選択する問題は、少なくとも10年前に提起されたものでなければならず、この質問の投稿時点で未解決でなければなりません。ウィキペディアのページにリストされているものの1つだけでなく、数学の証明可能な推測でもかまいません。

  • 言語の仕様と既存の言語での実装を提供する必要があります。

  • 推測が成り立つ場合に限り、プログラミング言語はチューリング完全でなければなりません。(または、推測が成り立たない場合にのみ)

  • 選択した推測に基づいて、チューリングが完全または不完全になる理由に関する証拠を含める必要があります。インタプリタまたはコンパイルされたプログラムを実行するときに、無制限のメモリへのアクセスを想定できます。

  • チューリングの完全性に関心があるため、I / Oは必要ありませんが、目標は最も興味深い言語を作成して、それが役立つようにすることです。

  • これはので、投票数が最も多い答えが勝ちます。

対象基準

良い答えは何をすべきですか?投票の際に探す必要があるものの、技術的には必須ではないものを以下に示します。

  • 既存の言語の単純なパッチであってはなりません。既存の言語を仕様に合わせて変更することは問題ありませんが、退屈なため、条件にパッチを当てることはお勧めしません。Nineteeth Byteのais523によると:

    エソランの仕掛けをよりしっかりと言語に焼き付けたい

  • スタンドアロンの難解な言語として興味深いはずです。



13
全体として、私はここで期待はずれの答えを見つけています。それらはほとんど「チューリング完全言語から始めて、推測XがTrue / Falseであるかどうかをテストし、そうであれば、キー機能を終了または無効にする」です。
-xnor

1
@xnor私はあなたに同意します、私はこの賞金がいくつかのより興味深い答えを引き起こすことを望んでいましたが、それは起こらないようです。
小麦ウィザード

2
問題の1つは、ほとんどの推測が無限の数の値に対して真であることが証明されているが、反例は無限の数の値に対しても真であることだと思います。その結果、チューリングの完全性が真であると証明することはほぼ不可能になります。
fəˈnɛtɪk

1
チューリングの完全性が与えられた推測と一対一で結び付けられているという要件は、かなり強い要件だと思います。チューリングの完全性を証明または反証することで、2つの異なる未解決の問題をそれぞれ決定できれば、簡単だと思います。(つまり、チューリングの完全性が未解決の問題Aを決定し、反証が未解決の問題Bを決定する)。
PyRulez

回答:


48

ルジャンドル

この言語は、ルジャンドル予想が偽、つまりn ^ 2と(n + 1)^ 2の間に素数がないような整数n> 0が存在する場合にのみチューリング完全です。この言語はUnderloadからいくつかのインスピレーションを受けていますが、いくつかの点で非常に異なっています。

Legendreのプログラムは、一連の正の整数で構成されています(0は、言語の目的全体を本質的に否定するため、特に禁止されています)。各整数は、ルジャンドルの基本コマンド、または潜在的なユーザー定義のコマンドに対応しています。どのコマンドに割り当てられるかは、その平方と次の整数(OEISシーケンスA014085に相当)の間の素数の数に基づきます。

言語のコマンドは、任意の大きな正の整数を保持できるスタックを変更します。スタックが0を保持する場合、0はすぐに削除されます。コマンドの詳細は次のとおりです。

  • 2(このコマンドを生成する最小の整数:1):プログラム内の次の整数をスタックにプッシュします。

  • 3(最小の生成整数:4):スタックの一番上の整数をポップし、それに関連するコマンドを実行します。

  • 4(最小:6):上の整数をポップします。1だった場合、スタックの一番上の整数を増やします。

  • 5(10):上の2つのスタックアイテムを交換します。

  • 6(15):スタックの一番上の整数をデクリメントします。結果が0の場合、0をポップして破棄します。

  • 7(16):スタックの一番上の整数を複製します。

  • 8(25):実行を停止し、スタックの内容を出力します。

これは基本的な命令セットであり、ループはもちろんのこと、面白いことは何もできません。ただし、別のコマンドがあり、ルジャンドルの推測が誤りであることが証明された場合にのみアクセスできます。

  • 0(不明):スタックからすべての項目を削除し、それらを新しい関数に結合します。この関数は、スタックの元の一番下から始まり、「コマンド番号」が等しいコマンドとしてアクセス可能な一番上で終わるすべてのコマンドを実行しますプログラムソースの次の整数に対応するもの。

このコマンドに何らかの方法でアクセスできる場合、言語はチューリング完全になります。これは、Minskyマシンをシミュレートできるためです。

コマンド8が実行されるか、プログラムの最後に到達すると、プログラムは終了し、スタック上の各整数に対応する(Unicode)文字が出力されます。

サンプルプログラム

1 2 1 3 1 10 4

この単純なプログラムは、2(3)、最後に10をプッシュしてから4(コマンド:3)を実行し、10(コマンド:5)をポップして実行し、2と3を入れ替えます。

1 5 3 15 2 1 6 7

このプログラムは、整数からコマンドへの間接的な対応の使用方法を示しています。最初に5がプッシュされ、次に2つのコマンドをエンコードする3つの異なる方法を使用して15と1がプッシュされます。次に、1がポップされ、その結果、15が16にインクリメントされ、最終的に実行されます。プログラムは、スタック上の番号5の2つのインスタンスで終了します。

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

このプログラムは、?を使用して0コマンドを使用する方法を示しています。プレースホルダー番号として。プログラムは、最初に関数9に「1 5」を格納し、次に10に「15 31」を格納してから、関数9(24を使用)を実行します。 。その後、プログラムは停止します。

ミンスキー機

MinskyマシンをLegendreコードに変換するには、0コマンドを使用する必要あります。Legendreの推測が偽でない限り、このコマンドにはアクセスできないため、プレースホルダーを使用しましたか?代わりに。

すべてのMinskyマシンの命令行名には、相互に異なるA014085対応の整数と、ベースコマンド、および24(9)と31(10)が必要であることに注意してください。

初期化:
1 1 1 1 ? 24
x INC(A / B)y:

A:

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 DEC(A / B)yz:

A:

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

最終プログラムを作成するには、すべての部分を追加し(x、y、zを対応する部分で置き換え)、単一の整数を追加して、チェーンの最初の命令を開始します。これは、ルジャンドルの推測が反例によって間違っていることが証明された場合の言語のチューリング完全性を証明するはずです。

通訳

このインタープリターはPython(3)で記述されており、上記の3つの例すべてでテストされています。-a /-allowZeroフラグを使用して、?使用するには、ファイルから直接コードを実行する-f /-fileと、代わりにPythonリストとしてスタックを出力する-s /-stackOutを使用します。ファイルが指定されていない場合、インタープリターは一種のREPLモードに入ります。これは--stackOutで使用するのが最適です。

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())

14

ユニオン閉鎖

このプログラミング言語は、Union-closed Setsの推測が正しくない場合、チューリング完全です。

コントロール

コマンドのリスト:
x ++ Increment x(INC)
x-- Decrement x(DEC)
j(x、y)yが0の場合、命令セットxを命令キューの最後に追加

すべての変数は0として初期化されます

構文

プログラムは一連のコマンドセットとして記述されます。
Command1 Command2 Command3 ...
Command1 Command2 ...
...

プログラムがユニオンで閉じられているかどうかを判断するために、各セットは、セット
j(x、y)!= j(a、b)
+(x)!= +(y)にあるさまざまなコマンドのリストのみを考慮します。

少なくとも半分のセットにコマンドタイプ(+、-、j)が表示される場合、何も実行されません。

命令キューの最後に命令がない場合、プログラムは終了します

空のループを含む無限ループは、j(x、y)を使用して実現できます。

通訳

チューリング完全性

j(x、y)、インクリメント、デクリメントの3つのコマンドがすべて使用可能な場合、Minskyマシンをシミュレートできます。

j(x、y)を使用して到達するj(x、y)のみのセットはHALT
x ++はINC
x-- DEC
j(x、y)はJZです

ユニオンの閉じた集合の推測が正しい場合、3つのコマンドの少なくとも1つは常に無効になり、それによりこの言語がチューリング完全になることができなくなります。


私がやることは、3つの演算子を持つ代わりに、無限の数の値を持ち、それぞれのモジュロ4を取り、3つの操作の1つと何もしないことです。プログラムが起動すると、セットの結合が閉じていることを確認し、セットの半分以上にある要素をすべて削除します。次に、そのような要素がなくなるまでこれを繰り返します。推測が真であれば、すべてのプログラムは空のプログラムと同じですが、偽であれば、すべての可能なプログラムを表現できます(そのため、no-opが含まれます)。
小麦ウィザード

@WheatWizardインタープリターによって閉じられた和集合の決定は、異なる変数の同じ演算子が異なると見なします。x ++はy ++とは異なると見なされます。結果として、作成可能なさまざまなセットが無限にあります。可能なセットの数が無限であるため、3つの主要なタイプのいずれもセットの半分を超えていない場合、チューリングは完了しています。
-fəˈnɛtɪk

連合閉集合予想に対する証明は、3つの演算子のうちの1つへの変換をチューリング完了のままにする可能性があります。プログラム内のすべての異なる演算子を残すことができるため、無限の数のうち3つだけが必要になります残る値。
fəˈnɛtɪk

13

フェルマー素数

言語は、テープの各場所に任意の整数を格納できる、2つの潜在的に無限のテープで動作します。両方のテープは-1、開始時に満たされています。両方のテープの位置0から始まる2つのテープヘッドもあります。

インタープリターは最初に入力を読み取り、値を最初の(データ)テープに位置0から保存します。

次に、提供されたプログラムを読み取ります。遭遇するすべての数について、値がフェルマー素数であるかどうかを最初にチェックします。はいの場合、フェルマーがプライムする2つ目の(命令)テープに書き込み-1ます。そうでない場合は、命令テープに書き込みます。

次に、命令ポインタの値を確認し、次のいずれかを実行します。

  • -1 以下:プログラムを終了します
  • 0:データテープの位置を1つ左に移動します。指示テープの位置を1つ右に移動します
  • 1:データテープの位置を1つ右に移動します。指示テープの位置を1つ右に移動します
  • 2:データテープ位置の値を増やします。指示テープの位置を1つ右に移動します
  • 3:データテープの位置の値を減らします。指示テープの位置を1つ右に移動します
  • 4:現在のデータテープ位置の値がゼロの場合、命令テープの5値が一致する(または大きい)か、またはより小さい値になるまで、命令テープを右に移動します0。それがある場合5(またはそれ以上)、それはよりも小さいです場合は、再び命令ポインタを右に移動0し、プログラムを終了します。現在のデータテープの位置がゼロでない場合は、単に指示テープを1つ右に移動します
  • 5以上:対応する4値に達するまで、または未満の値が見つかるまで、命令ポインターを左に移動します0。後者の場合、プログラムを終了します。

((5以上)と4値を一致させることにより、最初のコマンドと同じ値5(または(以上)または4)に出会うたびに命令テープで適切な値を検索している間、適切な数をスキップする必要があることを意味します検索上の他の値(4または5(またはそれ以上))

命令がプログラムを終了する必要があると言うまで、ループします。

プログラムが終了したら、位置0から-1値を含む最初のテープ位置までの値をデータテープに出力します。

証明

この言語は、本質的にIOなしのBrainfuckインタープリターにマップされF_5ます。このインタープリターでは、あらゆる種類の適切なループを実行できる必要があります。

ただし、フェルマー素数予想基づくと、フェルマー素数は5つF_0- F_4しかありませんF_5Brainfuckがチューリング完全であることがわかっているので、存在する場合、言語はチューリング完全です。ただし、F_5あなたがいなければ、分岐もループもできず、基本的に非常に単純なプログラムにロックされます。

実装

(ルビー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

例:

これは、改行で画面にH(の略Hello World!)を書き込みます:

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

名前を付けて保存しexample.fermat、次のように実行します(注:常に入力が必要です):

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

次の例では、入力の各値を1ずつ増加させることにより、単純なシーザースタイルの暗号を実行します。明らかに?、5番目のフェルマー素数に置き換える必要があります。

17 65537 5 17 ? 257

チートモードを有効に2 4 1 2 5 3し、ソースコードとして使用することで、動作することを試すことができます。

$ echo 'Hello' | ./fermat.rb example2_cheat.fermat

2
対応する素数を入力しなければならないかわいそうなコーダーに申し訳ありません5。彼らが良いキーボードを持っていることを願っています。
-AdmBorkBork

2
@AdmBorkBork心配しないでください。宇宙が元素の粒子よりも多くのビットを持っています。
-fəˈnɛtɪk

@LliwTelracsは、宇宙の元素粒子の量がAleph-null(オメガ)であり、オメガからは数値の実際のサイズを意味しないため、実際には意味がありません。(ない限り、そのアレフ1:P)
マシューノ

1
@MatthewRoh私は間違えていました。私は観測可能な宇宙でのことを意味しました。
-fəˈnɛtɪk

2
@MatthewRoh実際には、有限、無限、数え切れない、あるいは集合論と矛盾することさえあります!しかし、私たちは決して知りません:(
CalculatorFeline

10

ツバメw /ココナッツv2

以前のバージョンにはエラーがあり、このコンテストでは無効になり、大幅に異なるこのバージョンの以前のバージョンからの賛成票を持ちたくないので、このバージョンは新しい投稿として送信されています。

Collat​​z予想がすべての正の整数について証明できる場合、この言語はチューリング完全ではありません。それ以外の場合、言語はチューリング完全です。

この言語はCardinalに基づいていました。

まず、プログラムのcontValは、式
contVal = sum(sum(ASCII値の行)* 2 ^(行番号-1))を使用して計算されます

次に、AまたはEごとに反対方向の2つのツバメが作成され、すべての条件付きターンステートメントが初期化を待機するように設定されます。
Eで作成されたツバメは左/右に向かい、Aで作成されたツバメは上/下に向かいます。

最後に、コードは、すべてのポインターが削除されるか、contValが1つになるまでステップを実行します。

各ステップで、contVal%2 == 0の場合は2で除算され、それ以外の場合は3で乗算され、1ずつ増分されます。

コマンド:

0:値を0に設定
+:値を1ずつインクリメント
>:方向を右に
変更v:方向を下に
変更<:方向を左に
変更^:方向を上に変更
R:最初のポインタの後の後続のポインタを値と比較最初のポインター。等しい場合はまっすぐに進み、そうでない場合は右に曲がります。
L:最初のポインターの後の後続のポインターは、最初のポインターの値と比較されます。等しい場合はまっすぐに進み、そうでない場合は左に曲がります。
E:ポインターを複製しますが、左右
の方向に向かっていますA:ポインターを複製しますが、上下の方向に向かってい
ますか?:値が0の場合、ポインターを削除します

説明:

Collat​​z予想がすべての正の整数について証明できる場合、contValは常に1に収束し、それによりプログラムが終了するため、この言語で実行されるプログラムの期間は有限です。

そうでなければ、この言語が次の機能を実装できることを証明する必要があります

インクリメント:+で表される
0:0で表される
変数アクセス:変数は移動するときにポインターとして格納される
ステートメント連結:操作への移動距離を変更することにより、操作が実行される順序を変更できます
Forループ:この言語で

E   > V
    ^+R
      +
      A

forループとして機能します> 1までカウント(さらにコードをループに追加できます)

同様に、コード

Rv
^<

Rループで設定された条件値に等しくなるまでdoとして機能します。


あなたも私を打ち負かした、私はcollat​​zの推測で何かをするつもりだった。いい仕事だ、面白いと思う。1に収束した場合にのみ数値を保存できる言語を作成するつもりでした。
Rohan Jhunjhunwala

よくわかりません。Collat​​z関数はどこにこれを理解しますか?2回目の読み直しから、関数はcontValすべてのステップに適用されると言っていると思います(したがって、推測が真である場合、無限ループはありません)-しかし、答えのどこかに明示的に述べられていることはわかりません。?
DLosc

申し訳ありませんが、それが行われている間に、ある時点で誤って説明から
削除

10

完璧/不完全

ふう、楽しかった。

完全/不完全は、無限の完全数がある場合にのみ完全です。存在する場合、それは完璧と呼ばれ、存在しない場合、不完全と呼ばれます。この謎が解決されるまで、両方の名前が保持されます。

完全数とは、除数の合計が数になる数であるため、6は完全数です1+2+3=6

Perfection / Imperfectionには次の機能があります。

Perfection / Imperfectionはスタックベースで、インデックスがゼロのスタックです。

コマンド:

p(x, y):xをスタックのy番目の位置にプッシュします。

z(x, y):xをスタックのy番目の位置にプッシュし、以前にy番目の位置にあったものを取り除きます

r(x):x番目のアイテムをスタックから削除します

k(x):スタックのx番目のアイテムを返します

a(x, y):xとyを追加します。文字列と一緒に使用すると、xyの順に並べられます。

s(x, y):xからyを減算します。文字列の場合、xから最後のlen(y)を削除します

m(x, y):xとyを乗算します。文字列とともに使用する場合、x len yを乗算します。

d(x, y):xをyで除算します

o(x):xを印刷

i(x, y):xがtrueと評価された場合、関数yを実行します

n():コードブロックが呼び出されているカウンターを返します。

q():スタックの長さを返します

t():ユーザー入力

e(x, y):xが整数の場合、xとyの値が同じ場合、1を返します。yが文字列の場合、yの長さを取得します。xが文字列の場合、yを文字列に変換し、それらが同じかどうかをチェックし、同じ場合は1を返し、そうでない場合は0を返します。

l(x, y):xがyより大きい場合、1を返します。文字列がある場合、文字列の長さを使用します。

b():プログラムを停止します。

c(x, y):x、yの順に実行します。

Python andに相当するものを取得するには、2つの値を乗算します。の場合ornot値を加算し、の場合、1から値を減算します。これは、値が1または0の場合にのみ機能します。これは、数値をそれ自体で除算することで実現できます。

データ型:整数と文字列。文字''列はで示され、すべての非整数は丸められます。

構文:

コードは、10 {}秒以内のネストされた関数で構成されます。たとえば、入力を取得し、それらを追加して印刷するプログラムは次のようになります{o(a(t(), t()))}。プログラムの背景には、0から始まり、コードブロックを実行するたびに1ずつ進むカウンターがあります。最初のコードブロックは0、などで実行されます。10個のコードブロックが実行されると、カウンターが完全な数に達するたびに6番目のコードブロックが実行されます。プログラムが機能するために10個すべてのコードブロックを用意する必要はありませんが、ループを作成する場合は7個必要です。この言語の仕組みをよりよく理解するには、次のプログラムを実行します。このプログラムは、カウンターが完全な数に達するたびにカウンターを出力します{}{}{}{}{}{}{o(n())}

インタープリターは、repl.it / GL7S / 37にあります。1を選択してターミナルにコードを入力するか、code.perfect実行時にコードをタブに貼り付けて2を選択します。試してみると意味があります。

チューリング完全性の証明/チューリング完全性の欠如。

よると、このソフトウェアエンジニアリング・スタック交換品、完全なチューリングは、ジャンプの条件付き繰り返しの形を持つことができる、とメモリを読み書きする方法を持っている必要があります。スタックの形でメモリを読み書きできます。また、カウンタが完全な数に達するたびに6番目のコードブロックが実行されるため、ループする可能性があります。完全な数が無限にある場合、無限にループする可能性があり、チューリング完全であり、そうでない場合はそうではありません。

入力として5文字(1または0)を使用する自己ビット単位のサイクリックタグインタープリター:

{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)))))}

入力として任意の数の文字を取るように拡張できます。無限の入力が可能ですが、無限の完全な数がある場合のみです!


1
関数と共有されていないため、ローカルでループするための新しい値を作成しているだけかもしれません。
-fəˈnɛtɪk

3
現状では、TCの証拠はありません。リンクするソフトウェアエンジニアリングの記事には、大まかな要件が記載されていますが、TCはチェックするだけの箱ではありません。TCオートマトン(Minsky Machineなど)を実装するか、言語が決定できないことを示す必要があります。
小麦ウィザード

2
@WheatWizardそこで、Bitwise Cyclic Tagインタープリターを追加しました。入力として任意の量の文字を取得するように変更できます。入力として無限の文字を使用できますが、無限の完全な数がある場合のみです!
同志SparklePony

2
「10個のコードブロックが実行されると、6番目のブロックは、カウンターが完全な数に達するたびに実行されます。」それでは、インタープリターは完全な数を直接カウントするだけですか。これは挑戦の精神に反すると思う。実際の言語仕様はそれほど重要ではなく、チューリング完全なものに加えて、「完璧な数に達した場合にのみステップを実行する」ことができます。
xnor

10

ソール

このプログラミング言語は、ショルツ予想が真実である場合にチューリング完全です。

@SztupYが、チューリング完全であると推測されることに依存する結果はないだろうと言っていたので、私はこの言語を書きました。

コマンド一覧

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

これらのコマンドを使用して、この言語はMinskyマシンをシミュレートできます。

通訳

これを実行しないことを強くお勧めします。追加チェーンをチェックする非常に遅い方法を使用します。

チューリング完全性

この言語は、実行されるコマンドの数にカウンターを使用し、Scholzの推測と照合して、言語のチューリングの完全性を変更します。

ショルツの推測がtrueの場合、このプログラムは、正確で、通常のミンスキー・マシンのように動作します
インクリメント
デクリメント
ゼロの場合はジャンプ
停止

ただし、ショルツ予想が偽である場合、カウンターは最終的に、ショルツ予想が成り立たない値に到達します。この言語は、Scholzの推測が偽である数に達すると終了するように設計されているため、プログラムはその数のコマンドを実行した後に毎回終了します。したがって、すべてのプログラムの長さは制限されます。これは、言語がチューリング完全であるための要件と一致しないため、

「テープの長さを固定することはできません。これは、指定された定義に対応せず、マシンが実行できる計算範囲を線形境界オートマトンの計算範囲に大幅に制限するためです」

ショルツ予想が偽である場合、言語はチューリング完全ではないだろう


1
+1、これは実際に推測要件を言語にハードベイクするため、推測が真/偽の場合に言語を殺すために無関係な何かを追加するのではなく、
Gryphon

わかりません。提供するコマンドは、Minskyマシンをシミュレートするために必要なコマンドとまったく同じであるため、それがあれば、Scholzの推測に関係なく、言語はチューリング完全になります。あなたの説明から何かを見逃しているに違いありません。
ナサニエル

@Nathanielチューリング完全言語の要件の1つは、言語が無限ループ(停止問題)になる可能性があることです。命令を実行するとコードがカウントアップされ、Scholzの推測が偽である場合、プログラムは設定された数の命令の後に常に停止します。
fəˈnɛtɪk

はい、しかし、あなたは、ショルツ予想が偽である場合、それが停止する原因を説明するのを忘れました。あなたの答えをもう一度見てください-それはまったくありません。
ナサニエル

@Nathanielこのプログラムは、scholz推測で機能するかどうかすべての数値をチェックすることで、文字通り機能します。推測と一致しない番号を見つけると、自動的に終了します。
fəˈnɛtɪk

9

婚約

Githubの婚約

READMEと仕様はgithubの「README.txt」の下にあります。

一般に、婚約されたプログラムは行のペアで構成され、その長さは異なる双子の素数ペアまたは婚約されたペアです(重複は発生しません)。プログラムは、2行目のペアの最初の行の「柔軟なサブセット」を見つけることによって実行されます。そのようなサブセットの数と、元の2行目と柔軟なサブセットのない2行目との間のレーベンシュタイン距離を組み合わせて、実行するコマンドを決定します。

この投稿の証拠を抜粋します。

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.

4
「現在、制限されたプログラムサイズでチューリング完全にすることはできません。」私はこの声明について混乱しています...一方では、限られたプログラムサイズでは有限数の異なるプログラムしか書けないのは事実ですが、チューリング完全性の一般的な証明は、制限のないプログラムサイズをまったく必要としないチューリング完全言語
レオ

1
さて、インタープリターに渡されるプログラムは、インタープリターのコードに入れる必要はありません。入力としてインタープリターに渡される必要があります
レオ

7
@レオ。言語をTCにするには、プログラムをエンコードしてインタープリターに渡す必要があります(つまり、この言語に入力コマンドがないと想像してください)。1つのコマンドで言語を想像してくださいb。これは、のようなBFプログラムを解釈しb+++++.ます。ただし、プログラムのサイズは10文字に制限されています。BFを解釈できますが、チューリングマシンが実行できるすべてのプログラムを計算することはできません。
コナーオブライエン

3
@EriktheOutgolferあなたの問題の主な問題は、「入力から取得したBFプログラムを置くことができる...」です。このため、以前のコメント、特にこの最初の文を読んだり、読んだりすることを強くお勧めします。言語が入力に基づいてチューリング完全である場合、どのように入力なしでチューリング完全になることができますか?つまり、言語をチューリング完全にするために、プログラムをエンコードする必要があるのは言語のプログラムそのものです。それ以外の場合は、入力でプログラムをエンコードしていることがわかりますが、これは有効なプログラミング方法ではありません。
コナーオブライエン

1
これは決まった点だとは思いません。このEsolangの記事ではこの問題について説明しています。(チューリング完全言語可能なすべての終了プログラムをその出力とともに印刷するプログラムが、チューリング完全性のデモンストレーションであるかどうかの問題もあります。これは、入力を必要とせず、有限の長いプログラムで実行できます。)

5

友好的なパリティ

この言語は、反対のパリティを持つ友好的な数字があるかどうかに基づいています。

コマンド

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.  

制御フロー

プログラムは左から右に繰り返し循環してから、最初にループバックします。「j」が検出されると、値をチェックして行を変更する必要があるかどうかを判断します。番号がその一致と反対のパリティを持つ友好的な数である場合、それは1行下に移動します(先頭にループバックします)。

プログラムは、一番上の行以外の行でxに到達した場合にのみ終了できます。

チューリング完全性

このプログラムは、反対のパリティを持つ友好的な数字のペアがあると仮定して、ミンスキーマシンをシミュレートするために使用できます。

j、{および}を使用してJZ(r、x)をシミュレートできますが、ゼロではなく友好的な数をチェックします。
+はINC(r)
-DEC(r)は
xはHALT

最初の行を残すことができない場合、xおよび}コマンドは何もしません。これにより、空のプログラムでない限り、プログラムはHALT状態に入ることができなくなります。したがって、チューリングの完全性にはHALT状態が必要であるという説明の下では、言語はチューリングが不完全になります。

通訳


2

改行

免責事項:それは少し混乱し、非常にシンプルです。これは私が書いた最初の言語であり、推測は私が理解した唯一の言語です。別のユーザーが同じユーザーに対して長い回答を持っていることは知っていますが、とにかくこれを書くことにしました。

改行で書くには、多くの時間と改行が必要です(\n)。これは、ルジャンドル予想が真実であることから機能します。すべての演算子は、n = 1で始まるルジャンドル予想の数値に当てはまる必要があります。演算子があるたびに、\ nの量を取得してルジャンドル予想にプラグインし、次のプライム量の範囲を取得します\ nが該当する必要があります。そのため、開始\n\nするには、オペレーターに移動し、\n次に別のオペレーターに移動して、3つの改行に移動します。次は5ですので\n\n、演算子を追加して、最後の演算子行に、開始したルジャンドル予想に含まれるプライム量にある適切な量の改行があることを確認します。

数値(配列)は変数のようなものです。オペレーターが(数字を使用して)実行するたびに増分します。

+ 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

規則に従う無制限の素数がある限り、この言語には有限でないテープがあります。

ミンスキー機

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

使い方:

\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

KhanAcademyで試してみてください。


@wheat非有限メモリでループする必要はありません
クリストファー

それが本当である場合にのみ機能します。私はモバイルにいるので、今すぐ書き上げを終えることはできませんが、今夜
クリストファー

無限のメモリがある場合でも、無限ループできる必要があります。
パベル

ループがあります。それらを無限にしようとしています
クリストファー

今、彼らはクラッシュします
クリストファー

2

タギス

Taggisはタグシステムに基づく言語です

Taggisのチューリング完全性は、Collat​​z予想に基づいています

構文

Taggisプログラムの構文は、スペースで区切られた文字a、b、cのみで構成される3つの文字列(生産規則)です。

実行

Taggisの唯一のプログラム状態は、同じ3文字で構成される文字列です。

TaggisはTS(3、2)タグシステムを実装し、すべてのステップで現在の「タグ」の最初の2文字が削除され、削除された部分にあった最初の文字が対応するプロダクションルールの最後に追加されます文字列。

たとえば、Taggisプログラムbc a aaaは3n + 1問題を実装します。反復は対応するasの数で表され、3n + 1ステップは(3n + 1)/ 2 [1]に置き換えられ、プログラム出力につながります。

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

チューリング完全性

もちろん、このシンプルなシステムはチューリングの完全性をエミュレートするにはあまりにも単純に見えるかもしれませんが、2つのシンボル(ユニバーサルマシンを含むクラス)を持つチューリングマシンは、ヘッドから2つの文字を削除したタグシステムに変換できることがわかります。および32 * mの生産規則。ここmで、チューリングマシンの状態の数です。

シンボルが2つしかない最小の既知のユニバーサルチューリングマシンは18の状態を使用するため、対応するタグシステムには576個のプロダクションルールが含まれています[2]。

ただし、3つのプロダクションと2つのシンボルが削除されたすべてのタグシステムのセットの計算クラスは、Collat​​z予想に関連付けられています[2]。Collat​​z予想が偽であることが証明された場合、Taggisはチューリング完全です。それ以外の場合は、数学の別の未解決問題に基づいており、より小さなチューリング機械を見つけます

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. これは元のCollat​​z関数と同等で、奇数の3n + 1 nは常に偶数になるため、除算は自動的に適用されます。

  2. タグシステムとCollat​​zのような関数、Liesbeth De Mol

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.