Desain Satu Instruksi Mengatur Komputer!

31

Perhatikan: Saya bersedia memberikan hadiah untuk setiap jawaban yang menurut saya menarik.

Tantangan Anda adalah merancang komputer set instruksi (TIS) yang lengkap-Turing :

OISC adalah mesin abstrak yang hanya menggunakan satu instruksi - menghindari kebutuhan untuk opcode bahasa mesin. Dengan pilihan yang bijaksana untuk instruksi tunggal dan sumber daya yang diberikan tak terbatas, OISC mampu menjadi komputer universal dengan cara yang sama seperti komputer tradisional yang memiliki banyak instruksi.

Berikut adalah beberapa contoh perintah tunggal yang membuat TIS-lengkap OISC.

Aturan:

Anda harus memberikan interpretasi atau bukti daripadanya

Anda harus menyediakan juru bahasa untuk bahasa Anda. Penerjemah ini hanya boleh dibatasi oleh memori / waktu (mis. Tidak boleh memiliki batasan yang dikenakan pengguna) Jika Anda tidak menyediakan juru bahasa untuk bahasa Anda (untuk alasan apa pun selain kemalasan), Anda harus membuktikan bahwa mungkin saja satu untuk ditulis. Seorang juru bahasa harus dimungkinkan .

Anda harus membuktikan kelengkapan Turing-nya

Anda harus menyertakan bukti resmi bahwa bahasa Anda Turing-lengkap. Cara sederhana untuk melakukan ini adalah dengan membuktikan bahwa itu dapat menafsirkan atau memiliki perilaku yang sama dengan bahasa Turing-lengkap lainnya. Bahasa yang paling dasar untuk ditafsirkan adalah Brainf ** k .

Misalnya, bahasa normal yang memiliki semua perintah yang sama dengan Brainf ** k (dan kurangnya batasan memori yang dipaksakan oleh pengguna) adalah Turing-complete karena apa pun yang dapat diimplementasikan dalam Brainf ** k dapat diimplementasikan dalam bahasa .

Berikut adalah daftar bahasa Turing-lengkap yang sangat mudah diimplementasikan.

Persyaratan OISC tambahan

  • OISC ini seharusnya hanya memiliki satu instruksi - itu tidak dapat memiliki banyak instruksi dengan salah satu dari mereka membuatnya Turing-lengkap.

  • OISC Anda dapat menggunakan sintaksis yang Anda suka. Anda harus menentukan dalam jawaban Anda apa itu instruksi, apa itu data, dan apa itu no-op (mis. Spasi kosong). Jadilah kreatif!

  • Argumen tidak hanya perlu bilangan bulat. Sebagai contoh, /// adalah contoh indah dari OISC Turing-complete.

  • Bagaimana dan jika input dan output diambil dan diberikan diserahkan kepada Anda. Sebagian besar OISC menerapkan I / O melalui lokasi memori tertentu, tetapi mungkin ada cara lain untuk melakukannya, dan Anda dianjurkan untuk menemukannya.

  • Jawaban yang valid harus memberikan beberapa kode contoh dalam OISC Anda, baik dengan memasukkannya dalam pos atau menghubungkan ke tantangan sederhana yang diselesaikan dalam bahasa.

Pemungutan suara

Pemilih, harap diingat untuk tidak membatalkan pengiriman yang membosankan. Contoh:

  • Bahasa -setara
  • Implementasi OISC yang ada (penjawab, silakan buat sendiri!)
  • "OISC" di mana argumen pertama menentukan perintah untuk memanggil ( contoh )

Namun, Anda harus mengambil alih pengiriman yang menarik dan kreatif, seperti:

  • OISC didasarkan pada persamaan matematika
  • ZISC Turing-complete berdasarkan pada jaringan saraf
  • OISC di mana output I / O terjadi dengan cara lain selain lokasi memori tertentu

Kemenangan

Seperti halnya , jawaban dengan suara terbanyak menang! Semoga berhasil!

MD XF
sumber
10
Apa itu "instruksi"? Dan bagaimana kita menghitungnya?
Wheat Wizard
1
@NoOneIsHere saya berharap saya tahu cukup hanya untuk memilih xD
Brian H.
2
Saya menurunkan ini. Saya pikir ini adalah ide yang sangat menarik, tetapi Anda tidak menjelaskan apa itu OISC dan bagaimana cara mengkonfirmasi sesuatu itu satu. Saya menjadikan BF sebagai OISC, tetapi itu jelas bertentangan dengan semangat pertanyaan, tetapi secara teknis valid.
NoOneIsHere
1
@ MDXF saya tidak berpikir Anda mendapatkan ///: ia memiliki perintah substitusi, dan ia memiliki perintah cetak, yang bukan hanya efek samping dari perintah substitusi
Destructible Lemon
1
@NoOneIsHere Karena popularitas-kontes . Ya, itu valid, tetapi memiliki skor buruk (penghitungan suara), sehingga tidak akan menang.
user202729

Jawaban:

20

XOISC

OISC ini didasarkan pada X-combinator Fokker yang didefinisikan sebagai berikut:

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

Jika kita mengakui fakta bahwa SKI-kalkulus adalah Turing lengkap, kobinator di atas juga Turing lengkap. Ini karena S , K dan saya dapat ditulis dalam bentuk X , seperti ini:XSKIX

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

Cara kerja XOISC

Secara internal XOISC memiliki tumpukan (awalnya kosong), dari sana instruksi mengambil sebagai argumen melakukan hal berikut:n

  • Pop elemen (fungsi f 1 ... f N ) dari stack, tekan f 1 ( f 2 ( ... ( f N X ) ... ) )nf1fNf1 (f2 ((fN X)))

Setelah tidak ada instruksi lagi yang tersisa XOISC akan mendorong semua argumen baris perintah (jika ada) ke stack, misalnya:

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

Perhitungan akhir akan .((((s1 s2)) sM) a1))aN


Karena satu instruksi dalam XOISC hanya membutuhkan satu argumen (memory offset), tidak ada alasan untuk menggunakan nama untuk instruksi tersebut. Jadi file sumber yang valid hanya akan terdiri dari bilangan bulat yang dipisahkan oleh baris baru atau spasi putih, seperti misalnya:

0 0 2 0 1 0 1

Cobalah online!

Contoh

Mari kita ambil contoh di atas (tumpukan tumbuh ke kanan):

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]

Akhirnya mengevaluasi tumpukan: atau dengan kurang kurung X ( X X ) ( X X ) ( X X ) yang kita kenal sebagai tua yang baik S K K identitas fungsi.((X (X X)) (X X)) (X X)X (X X) (X X) (X X)S K K

Turing kelengkapan

Ide bukti

X

X

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

  • X0
  • selanjutnya kita berada di level kurung yang baru, jadi kita hanya perlu a 0
  • sekarang dua kurung tutup, jadi kita perlu memunculkan 2 elemen: 2
  • lagi kita berada di tingkat tanda kurung baru, jadi kita perlu a 0
  • dua tanda kurung, tutup lagi jadi a 2
  • dan sama lagi

Jadi kita berakhir dengan program XOISC yang berbeda (namun sama-sama semantik):

0 0 2 0 2 0 2 Cobalah online!

X

Bukti formal

Mengingat bahwa SKI-kalkulus sudah selesai Turing, kita perlu menunjukkan dua hal:

  1. X
  2. X

Bagian pertama - membuktikan ketiga persamaan dalam pendahuluan - sangat membosankan dan memakan tempat, juga tidak terlalu menarik. Jadi alih-alih meletakkannya di pos ini, Anda dapat menemukannya di sini * .

X

XXf gfg

Yang pertama adalah sepele karena 0akan meninggalkan di tumpukan sebagai satu ekspresi. Sekarang kita anggap ada dua program ( F 1 ... FXF1...FNG1...GKfgf g

Program F1...FN G1...GK-1 (GK+1)fggff g

Penerjemah

Input

Karena kalkulus lambda yang tidak diketik mengharuskan kita untuk menentukan tipe data kita sendiri untuk semua yang kita inginkan dan ini rumit penafsir menyadari angka - angka Gereja - ini berarti ketika Anda memberikan input, maka secara otomatis akan mengubah angka menjadi angka Gereja yang sesuai.

Sebagai contoh, inilah program yang mengalikan dua angka: Coba online!

Anda juga dapat menyediakan fungsi sebagai argumen dengan menggunakan indeks De Bruijn , misalnya Skombinator \\\(3 1 (2 1))(atau λλλ(3 1 (2 1))). Namun itu juga mengakui S, K, Idan tentu saja Xcombinator.

Keluaran

Secara default, interpreter memeriksa apakah output mengkodekan integer, jika itu akan menampilkan nomor yang sesuai (di samping hasilnya). Untuk kenyamanan ada -bbendera yang memberitahu penerjemah untuk mencoba mencocokkan boolean sebagai gantinya (lihat contoh terakhir).

Assembler

Tentu saja bahasa tingkat rendah mana pun memerlukan assembler yang mengubah bahasa tingkat tinggi ke bahasa itu, Anda cukup menggunakan input apa pun (lihat di atas) dan menerjemahkannya ke program XOISC dengan menggunakan -abendera, coba online! **


* Jika tautannya tidak aktif, ada salinan sebagai komentar HTML di pos ini.

** Ini menghasilkan program yang menguji keutamaan, coba online!

ბიმო
sumber
1
Apakah ada alasan Anda memilih X combinator daripada Iota combinator?
Buah Esolanging
1
@EsolangingFruit: Ya, ada beberapa opsi lain juga, pada akhirnya saya memilih yang itu karena menggunakan aplikasi yang paling sedikit untuk membangun SK. Sepertinya itu akan melakukan yang terbaik (tbh saya belum melakukan perbandingan sendiri).
ბიმო
1
Btw. ada perbandingan yang bagus dari beberapa combinator di kertas yang tertaut jika Anda tertarik.
ბიმო
19

Seri

Draw adalah OISC yang bekerja pada grid 2D, menandai kotak dengan cara yang mirip dengan mesin Wang B. Namun, untuk menjaga bahasa sesederhana dan OISC-y mungkin, semua instruksi (yang jumlahnya sangat banyak) menandai kotak yang baru saja diinjak, dan, agar dapat berhenti, menginjak sebuah kotak yang ditandai mengakhiri program.

Program ini terdiri dari urutan garis yang berisi pengenal garis (string arbitrer tidak termasuk # atau spasi putih), dua bilangan bulat ( xdan y) dan dua pengidentifikasi garis lainnya ( adan b).

Program berjalan sebagai berikut:
Mulai dari garis yang diidentifikasi startdengan penunjuk yang menunjuk ke posisi (0, 0), gerakkan penunjuk dengan jumlah yang diberikan oleh xdan ydan tandai kotak dengan penunjuk sekarang (kecuali kotak sudah ditandai, dalam hal eksekusi berakhir). Kemudian, lompat ke garis ajika setidaknya salah satu dari kotak yang berbatasan langsung juga ditandai, dan berbaris bsebaliknya.

Penerjemah didorong untuk menampilkan hasil akhir dari grid seperti semacam gambar, kanvas, dll.

Turing-Kelengkapan

Draw adalah Turing-complete karena memungkinkan untuk mengkompilasi versi yang dimodifikasi (disebut Alternate) dari mesin Minsky ke dalam bahasa.

Tindakan alternatif mirip dengan mesin Minsky dua-penghitung, tetapi ada batasan besar pada perintah: perintah harus bergantian antara menargetkan penghitung pertama dan kedua. Untuk menyiasati modifikasi ini, perintah tambahan telah ditambahkan: nop. Perintah ini tidak mengubah penghitung yang ditargetkan sama sekali, yang memungkinkan untuk "pad" perubahan berurutan ke satu penghitung, memenuhi batasan yang diuraikan di atas. Ini juga berarti bahwa register yang akan diubah tidak harus diberikan dan, untuk setiap instruksi yang diberikan, dapat disimpulkan secara langsung dari instruksi dari mana eksekusi dapat melompat ke sana.

Contoh: mesin Minsky ini

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

berubah menjadi program Alternatif ini:

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

Pembatasan ini diperlukan karena cara program Draw yang terakhir menangani register, yang mengatakan bahwa itu tidak membedakan mereka sama sekali. Sebaliknya, program Draw hanya menyalin register yang belum diubah oleh instruksi sebelumnya, memodifikasinya sesuai dengan instruksi yang dieksekusi.

Kemudian, program Alternate langsung diterjemahkan ke dalam Draw sebagai berikut:

Program dimulai dengan blok ini.

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

inc, decdan nopditerjemahkan dengan cara yang hampir sama satu sama lain. Dalam semua kasus, tidak ada perbedaan antara mengubah register pertama atau kedua (seperti yang dijelaskan di atas). Ini kenaikan, setara dengan 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

Ubah angka di i1_xbagian ke indeks instruksi saat ini, dan dii2_x bagian ke indeks instruksi berikutnya yang akan dieksekusi.

The nopinstruksi dapat diterjemahkan seperti:

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

Ini adalah penurunan:

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 mengacu pada instruksi yang akan dipanggil jika penghitung sudah 1.

Berhenti:

i1_y 0 0 0 0
i1_z 0 0 0 0

Ubah label dengan tepat dan rangkai semuanya menjadi satu. Melakukan ini untuk contoh dari atas memberikan program Draw di repositori dari atas.

Penerjemah

Saat ini ada dua penerjemah, keduanya ditulis dalam Python. Mereka dapat ditemukan di repositori Draw's GitHub .

  1. draw.py : Penerjemah ini dimaksudkan untuk baris perintah dan menggunakan sumber program sebagai argumen. Setelah setiap langkah, itu output perintah yang dieksekusi dan lokasi pointer instruksi; setelah program terhenti, ia mencetak jumlah sel yang ditandai.
  2. draw_golly.py : Versi ini menggunakan Golly untuk tujuan grafis yang lebih mudah dan salah , mengambil sumber melalui kotak sembulan saat memulai skrip. Golly bisa sedikit rewel dengan Python, jadi pastikan Anda telah menginstal Python 2 (dan jangan campur 32-bit Golly dengan 64-bit Python atau sebaliknya). Output disediakan melalui grid sel bawaan Golly.

Gambar berikut adalah contoh untuk output dari juru bahasa kedua. Menjalankan contoh program di repositori memberikan ini (atau yang serupa):

ivzem
sumber
1
Luar biasa! Selamat telah menemukan cara yang sangat unik untuk melakukan tantangan.
MD XF
Bahasa Anda tidak perlu berhenti sama sekali untuk menyelesaikan turing. Aturan 110 tidak berakhir, tetapi tetap saja lengkap.
Akangka
1 untuk Golly Simulator Seluler Automata Terbaik.
HighlyRadioactive
14

-3

Inilah intinya.

Ingatan

Memori adalah peta kaset, di mana kuncinya adalah string dan nilainya adalah bilangan bulat berukuran arbitrer.

Selain itu, ada satu set label, tempat program dapat melompat ke.

Ada tumpukan, yang berisi operan, yang merupakan string.

Ada offest, yang mengontrol di mana dalam kaset memori itu dapat diakses.

Instruksi Satu

-. Pertama, ia mengeluarkan string LABELdari stack. Jika itu LABELtidak didefinisikan sebagai label, itu mendefinisikan label, dan membersihkan sumber label itu (yaitu dari mana ia didorong dari) dan instruksi saat ini. Kalau tidak, ia melakukan perhitungan berikut, menggunakan dua nilai teratas, Adan B:

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

Perhatikan bahwa jika ada argumen berlebih atau argumen tidak mencukupi, program akan kesalahan keluar, menunjukkan status program.

Offset dapat dimodifikasi dengan mengakses nilai ..

Kode contoh

X-

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

Ini menetapkan variabel imenjadi 7, dengan menambah 7waktu.

X-

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

Ini dikalikan i+1dengan konstanta 2.

Bukti Kelengkapan Turing

Mengabaikan ukuran int C ++ (yaitu, dengan asumsi mereka tak terbatas), -3 adalah Turing Lengkap dengan reduksi ke brainfuck 3-sel . Saya dapat mengabaikan ukuran ini karena dapat ditulis interpreter untuk -3 pada komputer dengan memori tak terbatas yang memiliki sel-sel besar yang sewenang-wenang.

Saya juga percaya bahwa BCT dapat ditulis sebagai program -3.

Conor O'Brien
sumber
Karena saya senang memperbaiki konten saya, mohon, penjelasan mengenai suara turun akan dihargai
Conor O'Brien