1つの命令セットコンピューターを設計する!


31

通知:私は、おもしろいと思った答えに報奨金を差し上げます。

あなたの課題は、チューリング完全な 1命令セットコンピューター(OISC)を設計することです。

OISCは、1つの命令のみを使用する抽象マシンであり、機械語のオペコードが不要です。OISCは、単一の命令を賢明に選択し、無限のリソースを提供することで、複数の命令を持つ従来のコンピューターと同じ方法でユニバーサルコンピューターになることができます。

ここではチューリング完全OISCを作る単一のコマンドの例をいくつか示します。

ルール:

その解釈または証拠を提供する必要があります

あなたの言語の通訳者を提供する必要があります。このインタプリタは、メモリ/時間によってのみ制限される必要があります(たとえば、ユーザーが課した制限がない必要があります)。(怠laz以外の理由で)あなたの言語の通訳者を提供しない場合、あなたはそれが書かれることが可能であることを証明しなければなりません。通訳が可能でなければなりません

チューリング完全性を証明する必要があります

あなたの言語がチューリング完全であることの正式な証拠を含める必要があります。これを行う簡単な方法は、他のチューリング完全言語と同じ動作を解釈できることを証明することです。解釈する最も基本的な言語はBrainf ** kです。

たとえば、Brainf ** kと同じコマンド(およびユーザーが課すメモリ制限の同じ欠如)をすべて備えた通常の言語は、Brainf ** kで実装できるものはすべて言語で実装できるため、チューリング完全です。 。

これは、非常に実装しやすいチューリング完全言語のリストです。

追加のOISC要件

  • このOISCには1つの命令のみを含める必要があります。複数の命令を使用して、そのうちの1つをチューリング完全にすることはできません。

  • OISCは任意の構文を使用できます。あなたはあなたの答えの中で何が命令であり、何がデータであり、何がノーオペレーション(例えば空白)であるかを定義すべきです。クリエイティブに!

  • 引数は整数である必要はありません。たとえば、///はチューリング完全OISCの美しい例です。

  • 入力と出力の取得方法と提供方法は、ユーザーに任されています。ほとんどのOISCは、特定のメモリ位置を介してI / Oを実装しますが、他の方法で実装することもできますので、見つけることをお勧めします。

  • 有効な回答は、投稿に含めるか、言語で解決さ​​れた簡単な課題にリンクすることにより、OISCにサンプルコードを提供する必要があります。

投票

投票者は、退屈な投稿に賛成しないようにしてください。例:

  • 言語 - 同等
  • 既存のOISCの実装(回答者は独自に作成してください!)
  • 最初の引数が呼び出すコマンドを指定する「OISC」(

ただし、次のような興味深いクリエイティブな投稿を提出する必要があります。

  • 数学方程式に基づいたOISC
  • ニューラルネットワークに基づくチューリング完全ZISC
  • 特定のメモリ位置以外の方法で出力I / Oが発生するOISC

勝ち

同じように、最も多くの票と答えが勝ち!がんばろう!


10
「命令」とは何ですか?そして、それらをどのように数えますか?
小麦ウィザード

1
@NoOneIsHere xDに投票するのに十分な知識があればいいのに
ブライアンH.

2
これを断った。これは非常に興味深いアイデアだと思いますが、OISCが何であるか、何かが1つであることを確認する方法を正確には説明していません。BFをOISCにしましたが、それは明らかに質問の精神に反しますが、技術的には有効です。
NoOneIsHere

1
@MDXF私はあなたが///を取得するとは思わない:それは置換コマンドを持ち、それは置換コマンドの単なる副作用ではない印刷コマンドを持っている
Destructible Lemon

1
@NoOneIsHereだから人気コンテスト。はい、有効ですが、スコアが低い(投票)ため、勝ちません。
user202729

回答:


20

XOISC

このOISCは、次のように定義されているFokkerのXコンビネーターに基づいています。

X=λf .f (λg h x .g x (h x)) (λa b c .a)

XSKIX

S=X (X X)K=X XI=S K K=X (X X) (X X) (X X)

XOISCの仕組み

n

  • nf1fNf1 (f2 ((fN X)))

命令がなくなると、XOISCはすべてのコマンドライン引数(存在する場合)をスタックにプッシュします。次に例を示します。

[s1,, sMstack before, a1,, aNarguments]

((((s1 s2)) sM) a1))aN


XOISCの1つの命令は引数(メモリオフセット)を1つしか受け取らないため、その命令に名前を使用する理由さえありません。したがって、有効なソースファイルは、次の例のように、改行または空白で区切られた整数のみで構成されます。

0 0 2 0 1 0 1

オンラインでお試しください!

上記の例を見てみましょう(スタックは右に成長します):

0pop 0 and apply (ie. push single X):[X]0again simply push X:[X, X]2pop 2 (a,b) and push a (b X):[X (X X)]0simply push X:[X (X X), X]1pop 1 (a) and push a X:[X (X X), X X]0simply push X:[X (X X), X X, X]1pop 1 (a) and push a X:[X (X X), X X, X X]

((X (X X)) (X X)) (X X)X (X X) (X X) (X X)S K K

チューリング完全性

証明のアイデア

X

X

((X (X X)) (X X)) (X X)

  • X0
  • 次に、新しいレベルの括弧内にいるので、再び必要なのは 0
  • 2つのカッコが閉じるので、2つの要素をポップする必要があります。 2
  • 再び新しいレベルの括弧内にいるので、 0
  • 2つの括弧、閉じます 2
  • また同じ

したがって、異なる(まだ意味的に同等の)XOISCプログラムができあがります。

0 0 2 0 2 0 2 オンラインでお試しください!

X

正式な証明

SKI計算がチューリング完全であることを考えると、2つのことを示す必要があります。

  1. X
  2. XOISCは、ネーターで形成された任意の式を表すことができますX

最初の部分-導入部で3つの同等性を証明する-は非常に退屈でスペースを消費しますが、あまり面白くありません。そのため、この投稿に掲載する代わりに、ここにあります*

X

XXf gfg

0XF1FNG1GKfgf g

F1FN G1GK1 (GK+1)fggff g

通訳

入力

型付けされていないラムダ計算では、必要なものすべてに対して独自のデータ型を定義する必要があるため、インタープリターは教会の数字を認識します。これは、入力を提供すると、数字が対応する教会の数字に自動的に変換されることを意味します。

例として、2つの数値を乗算するプログラムを次に示します。オンラインで試してみてください!

De Bruijnインデックス、たとえばSコンビネータ\\\(3 1 (2 1))(またはλλλ(3 1 (2 1)))を使用して、引数として関数を指定することもできます。しかし、それはまた、認識しSKIそしてもちろんのXコンビネータを。

出力

デフォルトでは、インタープリターは、出力が整数をエンコードするかどうかを確認し、エンコードする場合は、結果に加えて対応する数値を出力します。便宜上-b、インタープリターに代わりにブール値のマッチングを試みるように指示するフラグがあります(最後の例を参照)。

アセンブラ

もちろん、低レベル言語には高レベル言語を変換するアセンブラが必要です。任意の入力(上記参照)を使用して、-aフラグを使用してXOISCプログラムに変換し、オンライン試すことができます。**


*リンクがダウンした場合、この投稿にはHTMLコメントとしてのコピーがあります。

**これにより、素数性をテストするプログラムが作成されます。オンライン試してください!


1
IotaコンビネーターではなくXコンビネーターを選んだ理由はありますか?
エソランジングフルーツ

1
@EsolangingFruit:ええ、他にもいくつかのオプションがあります。最終的には、SKを構築するのに最小限のアプリケーションを使用するため、そのオプションを選択しました。それは最高のパフォーマンスを発揮するように見えました(私は自分で比較していません)。
10:09に

1
ところで 興味がある場合は、リンクされた論文のいくつかのコンビネータの素晴らしい比較があります。
ბიმო

19

ドロー

Drawは2Dグリッドで動作するOISCであり、Wang B-machineと同様の方法で正方形にマークを付けます。ただし、言語をできるだけシンプルでOISC-yに保つために、すべての指示(合計で1つあります)は、踏み込んだばかりの正方形をマークし、停止できるように、マークされた正方形を踏みますプログラムを終了します。

プログラムは、行識別子(#または空白を含まない任意の文字列)、2つの整数(xおよびy)、さらに2つの行識別子(aおよびb)を含む一連の行で構成されます。

プログラムは次のように実行されます:位置(0、0)を指すポインターで
識別される行から開始し、とでstart指定された量だけポインターを移動し、ポインターがオンになっている正方形をマークします(正方形が既にマークされていない限り、その場合、実行は終了します)。次に、直接隣接する正方形の少なくとも1つもマークされている場合は行にジャンプし、そうでない場合は行にジャンプします。xyab

通訳者は、グリッドの最終結果を何らかの画像、キャンバスなどとして出力することが推奨されます。

チューリング完全性

Drawはチューリング完全です。Minskyマシンの修正バージョン(Alternateと呼ばれる)を言語にコンパイルできるためです。

Alternateは、2カウンターのMinskyマシンと同様に機能しますが、コマンドには大きな制限があります。コマンドは、1番目と2番目のカウンターをターゲットに切り替える必要があります。この変更を回避するために、追加のコマンドが追加されましたnop。このコマンドは、ターゲットカウンターをまったく変更しないため、上記の制限を満たす1つのカウンターへの連続した変更を「埋め込み」できます。また、これは、変更されるレジスタを指定する必要がなく、任意の命令について、実行がジャンプできる命令から直接推測できることも意味します。

例:このMinskyマシン

1 inc A 2
2 inc A 3
3 dec A 3 4
4 halt

この代替プログラムに変わります:

1 inc 2
2 nop 3
3 inc 4
4 nop 5
5 dec 6 8
6 nop 5
7 halt
8 halt

この制限は、最終的なDrawプログラムがレジスタを処理する方法のために必要です。つまり、レジスタをまったく区別しないということです。代わりに、Drawプログラムは、前の命令によって変更されていないレジスタを単にコピーし、実行中の命令に従って変更します。

次に、代替プログラムは次のように直接Drawに変換されます。

プログラムはこのブロックから始まります。

start 0 0 a a
a 3 0 b b
b -3 1 c c
c 3 0 d d
d -3 2 e e
e 3 0 f f
f 3 -3 i1_a i1_a

incdecおよびnopは、ほぼ同じ方法で翻訳されます。いずれの場合でも、最初のレジスタを変更しても2番目のレジスタを変更しても違いはありません(上記を参照)。増分はinc 2次のとおりです:

i1_y 0 -2 i1_z i1_y
i1_z 3 -1 i1_a i1_a
i1_a -5 1 i1_b i1_b
i1_b 0 2 i1_c i1_c
i1_c 0 2 i1_d i1_e
i1_d 0 2 i1_d i1_f

i1_e 5 0 i2_z i2_y
i1_f 5 0 i2_z i2_y

i1_xパーツの番号を現在の命令のインデックスに変更し、パーツの番号をi2_x次に実行する命令のインデックスに変更します。

nop命令は、次のような翻訳することができます。

i1_y 0 -2 i1_z i1_y
i1_z 3 -1 i1_a i1_a
i1_a -5 1 i1_b i1_b
i1_b 0 2 i1_c i1_c
i1_c 0 2 i1_d i1_e
i1_d 0 2 i1_d i1_f

i1_e 5 -2 i2_z i2_y
i1_f 5 -2 i2_z i2_y

これは減少です。

i1_y 0 -2 i1_z i1_y
i1_z 3 -1 i1_a i1_a
i1_a -5 1 i1_b i1_b
i1_b 0 2 i1_c i1_c
i1_c 0 2 i1_d i1_e
i1_d 0 2 i1_d i1_f

i1_e 5 -2 i3_z i3_y
i1_f 5 -4 i2_z i2_y

i3_x カウンタがすでに1の場合に呼び出される命令を指します。

停止:

i1_y 0 0 0 0
i1_z 0 0 0 0

ラベルを適切に変更し、すべてを単純に連結します。上記の例でこれを行うと、リポジトリ内のDrawプログラムが上から得られます。

通訳者

現在2つのインタープリターがあり、どちらもPythonで作成されています。それらはDrawのGitHubリポジトリにあります

  1. draw.py:このインタープリターはコマンドライン用であり、プログラムソースを引数として受け取ります。すべてのステップの後、実行されたコマンドと命令ポインターの位置を出力します。プログラムが停止すると、マークされたセルの数が出力されます。
  2. draw_golly.py:このバージョンでは、スクリプトの起動時にポップアップボックスを介してソースを取得し、正確に間違った目的でグラフィック出力を簡単に行うためGollyを使用します。GollyはPythonで少し扱いに​​くい場合があるため、Python 2がインストールされていることを確認してください(32ビットGollyと64ビットPythonを混在させたり、その逆を行ったりしないでください)。出力は、Gollyの組み込みセルグリッドを介して提供されます。

次の図は、2番目のインタープリターからの出力の例です。リポジトリでサンプルプログラムを実行すると、これが(または同様の)ものになります。


1
すごい!チャレンジを行うための非常にユニークな方法を見つけて、おめでとうございます。
MD XF

チューリングを完了するために、言語を停止する必要はまったくありません。ルール110は終了しませんが、それでもチューリングは完了しています。
アカンカ

Golly the Best Cellular Automata Simulator Everの+1。
高放射能

14

-3

ここに要点があります。

記憶

メモリはテープのマップであり、キーは文字列で、値は任意のサイズの整数です。

さらに、プログラムがジャンプできるラベルのセットがあります。

文字列であるオペランドを含むスタックがあります。

offestがあり、メモリのテープのどこにアクセスできるかを制御します。

一つの指示

-。まず、LABELスタックから文字列をポップします。それLABELがラベルとして定義されていない場合、ラベルを定義し、そのラベルのソース(つまり、プッシュ元)と現在の命令をクリアします。それ以外の場合は、上位2つの値を使用して、以下の計算を実行し、AそしてB

if mem[A] < mem[B]:
    jump to LABEL
if mem[A] != mem[B]:
    mem[A]--
else:
    mem[B]++

過剰な引数または不十分な引数がある場合、プログラムはエラー状態になり、プログラムの状態を示します。

の値にアクセスすることにより、オフセットを変更できます.

サンプルコード

X-

i i X-
i i X-
i i X-
i i X-
i i X-
i i X-
i i X-

これは、時間を増分iすること7により、変数をに設定します7

X-

i i X-
i i X-
i i X-
LOOP-
    a a X-
    a a X-
    j i LOOP-

これi+1は定数で乗算され2ます。

チューリングの完全性の証明

C ++のintサイズを無視する(つまり、無限であると仮定する)場合、-3は3-cell brainfuckへの縮小によりチューリング完了です。このサイズは無視できます。なぜなら、任意の大きさのセルを持つ無限のメモリーを備えたコンピューターで-3のインタープリターを作成できるからです。

また、BCTは-3プログラムとして作成できると考えています。


私は私のコンテンツを改善するのが大好きのように、ダウン投票に関する説明が理解されるだろうしてください
コナー・オブライエン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.