CSSでチューリングマシンを実装するその他のアプローチ:プリプロセッサやJavaScriptとの組み合わせ
CSSはチューリング完全なのか? プログラミング初心者向け解説
CSSは、Webページの見た目やレイアウトを装飾するために使用されるスタイルシート言語です。一方、チューリング完全性とは、ある言語でチューリングマシンと同等の計算を実行できるかどうかを指します。チューリングマシンは、理論的にどんな計算でも実行できる抽象的なコンピュータモデルです。
近年、CSSがチューリング完全であることを示唆する研究や議論が活発になっています。しかし、CSSが真の意味でチューリング完全であるかどうか、専門家の間でも意見が分かれています。
CSSがチューリング完全であると主張する人たちは、主に以下の点を根拠として挙げています。
- 疑似要素と疑似クラスの組み合わせ: CSSには、
::before
や::after
のような疑似要素や、:hover
や:focus
のような疑似クラスと呼ばれる機能があります。これらの機能を組み合わせることで、有限状態オートマトンを実装することができ、有限状態オートマトンはチューリングマシンの等価なモデルであることが知られています。 - 計算量的な表現力: CSSには、計算量的な表現力を持つセレクタやプロパティがいくつか存在します。例えば、
calc()
関数やvar()
関数などは、算術演算や変数操作を実行することができます。これらの機能を組み合わせることで、より複雑な計算を実行することが可能になります。 - 自己参照と再帰: CSSには、
@import
ルールやメディアクエリなど、自己参照や再帰的な構造を記述できる機能がいくつか存在します。これらの機能を組み合わせることで、より複雑な制御ロジックを実装することが可能になります。
- 実装の制限: 多くのブラウザエンジンは、CSSの仕様を完全に実装していないため、CSSだけで複雑な計算を実行することは困難です。また、ブラウザエンジンの挙動は、ハードウェアやOSによって異なる場合があるため、CSSプログラムの移植性が制限されます。
- 意図的な設計ではない: CSSはもともと、Webページの見た目やレイアウトを装飾することを目的とした言語であり、計算を実行することを目的とした言語ではありません。そのため、CSSには計算に必要な機能が十分に備わっていないという指摘があります。
- 実用性のなさ: 就算式が実行できるとしても、CSSだけで複雑なプログラムを書くことは非常に困難であり、実用的ではないという意見もあります。
現時点では、CSSが真の意味でチューリング完全であるかどうかは、決定的ではありません。理論的には可能であるという示唆はありますが、実用的な観点からは疑問が残ります。
今後、CSSの機能が拡張されたり、ブラウザエンジンの実装が改善されたりすることで、CSSがより強力な計算ツールとして進化する可能性も考えられます。しかし、現時点では、CSSを汎用的なプログラミング言語として考えるのは時期尚早と言えるでしょう。
補足
この解説は、プログラミング初心者向けに分かりやすく説明するために、専門用語や詳細な技術説明を省略しています。より深い理解を求める場合は、上記の参考情報などを参照してください。
CSSでチューリングマシンを実装するサンプルコード
以下のサンプルコードは、CSSでチューリングマシンを実装する例の一つです。しかし、これはあくまでも理論的な実験であり、実用的なプログラムではありません。また、このコードは完全ではなく、バグや誤動作がある可能性があります。
/* 状態遷移表 */
.state-0 .symbol-0 {
transition: to-state-1;
output: 1;
write: 1;
move: right;
}
.state-0 .symbol-1 {
transition: to-state-3;
output: 0;
write: 1;
move: left;
}
.state-1 .symbol-0 {
transition: to-state-2;
output: 1;
write: 1;
move: left;
}
.state-1 .symbol-1 {
transition: to-state-0;
output: 1;
write: 1;
move: right;
}
.state-2 .symbol-0 {
transition: to-state-1;
output: 1;
write: 1;
move: right;
}
.state-2 .symbol-1 {
transition: to-state-3;
output: 0;
write: 1;
move: left;
}
.state-3 .symbol-0 {
transition: to-state-4;
output: 1;
write: 1;
move: left;
}
.state-3 .symbol-1 {
transition: to-state-0;
output: 1;
write: 1;
move: right;
}
.state-4 .symbol-0 {
halt;
output: 1;
}
.state-4 .symbol-1 {
halt;
output: 1;
}
/* 初期状態 */
.tape {
content: "000000";
position: absolute;
top: 0;
left: 0;
}
.head {
position: absolute;
top: 0;
left: 0;
}
/* 遷移処理 */
.tape [data-state],
.head {
transition: all 0.5s;
}
[data-state].state-0 {
background-color: red;
}
[data-state].state-1 {
background-color: green;
}
[data-state].state-2 {
background-color: blue;
}
[data-state].state-3 {
background-color: purple;
}
[data-state].state-4 {
background-color: yellow;
}
.head {
width: 10px;
height: 10px;
background-color: black;
}
/* 動作 */
.tape [data-symbol="0"] {
width: 10px;
height: 10px;
background-color: white;
}
.tape [data-symbol="1"] {
width: 10px;
height: 10px;
background-color: black;
}
[data-state] {
display: inline-block;
}
.tape {
white-space: nowrap;
}
.tape [data-symbol] {
margin: 0 5px;
}
/* デモ */
.tape [data-symbol]:nth-child(1) {
background-color: black;
}
.head {
left: 50px;
}
説明
このコードは、3つの状態を持つ単純なチューリングマシンを実装しています。テープには0と1のシンボルが並び、ヘッドはテープ上の位置を読み書きします。各状態には、シンボル0とシンボル1に対する遷移ルールが定義されています。遷移ルールには、次の状態、出力するシンボル、テープに書き込むシンボル、ヘッドを移動する方向が指定されています。
このコードはあくまでもデモであり、実用的なプログラムではありません。実際には、より複雑なチューリングマシンを実装するには、もっと多くの状態や遷移ルールが必要になります。
このサンプルコードは、CSSの疑似要素、疑似クラス、アニメーション
CSSでチューリングマシンを実装するその他のアプローチ
CSSプリプロセッサは、CSSコードをより強力で表現力豊かなものにするためのツールです。代表的なCSSプリプロセッサとして、SassやLessなどがあります。これらのプリプロセッサを利用することで、変数、関数、ループなどの機能を利用して、より複雑なチューリングマシンを実装することができます。
例:Sassを使ったチューリングマシン実装
$states = (0, 1, 2, 3, 4);
$symbols = (0, 1);
$tape = "000000";
$head = 0;
@mixin transition($from, $to, $symbol, $output, $write, $move) {
&.#{$from} .#{$symbol} {
transition: to-state-#{$to};
output: $output;
write: $write;
move: $move;
}
}
@each $state in $states {
@each $symbol in $symbols {
@include transition($state, $transitions[$state][$symbol][0], $symbol, $transitions[$state][$symbol][1], $transitions[$state][$symbol][2], $transitions[$state][$symbol][3]);
}
}
.tape {
content: $tape;
position: absolute;
top: 0;
left: 0;
}
.head {
position: absolute;
top: 0;
left: ($head * 10px);
width: 10px;
height: 10px;
background-color: black;
}
.tape [data-symbol="0"] {
width: 10px;
height: 10px;
background-color: white;
}
.tape [data-symbol="1"] {
width: 10px;
height: 10px;
background-color: black;
}
[data-state] {
display: inline-block;
}
.tape {
white-space: nowrap;
}
.tape [data-symbol] {
margin: 0 5px;
}
JavaScriptと組み合わせる
CSSだけではチューリングマシンの実装が困難な場合、JavaScriptと組み合わせて実装することもできます。JavaScriptを利用することで、より複雑な制御ロジックを実装したり、外部データを読み込んだりすることができます。
例:JavaScriptとCSSを組み合わせたチューリングマシン実装
<!DOCTYPE html>
<html>
<head>
<title>Turing Machine</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="tape"></div>
<div class="head"></div>
<script src="script.js"></script>
</body>
</html>
/* style.css */
.tape {
content: "000000";
position: absolute;
top: 0;
left: 0;
}
.head {
position: absolute;
top: 0;
left: 0;
width: 10px;
height: 10px;
background-color: black;
}
.tape [data-symbol="0"] {
width: 10px;
height: 10px;
background-color: white;
}
.tape [data-symbol="1"] {
width: 10px;
height: 10px;
background-color: black;
}
[data-state] {
display: inline-block;
}
.tape {
white-space: nowrap;
}
.tape [data-symbol] {
margin: 0 5px;
}
// script.js
const tape = document.querySelector('.tape');
const head = document.querySelector('.head');
const states = [0, 1, 2, 3, 4];
const symbols = [0, 1];
let currentState = 0;
let currentPosition =
css turing-complete