最近、フォン・ノイマンの『自己複製オートマトンの理論』の中国語訳を読み、自己複製オートマトンの理論に魅了されました!生命とは何か?この本は私に人生に対する新しい視点を与えてくれました。
熱力学の第二法則は、宇宙の死の法則です。システムのエントロピーは常に増大する傾向にあり、システムは常に秩序から無秩序へ、形態からカオスへ向かう傾向にあります。この法則から逃れられるものは、生命を除いて宇宙には存在しません。外界とエネルギーを交換することで、生命は内部の秩序を保つことができるのです。熱力学第二法則に逆らえるのは生命だけなのです。
熱力学は情報理論と本質的に結びついています。秩序があるシステムほど多くの情報を含み、秩序がないシステムほど情報は少なくなります。情報は常に減少する方向に流れます。この法則に逆らえるのは生命だけです。生命は情報を「創造」することができるのです。「創造」こそが生命を生命たらしめている本質なのです。
生命についてもうひとつ驚くべきことは、生命自身が自分自身に関するすべての情報を持っていて、自分と同じような新しい存在を生み出すことができるということです。このようなことができるのは生命だけです。
フォン・ノイマンによれば、単純な系は熱力学第二法則に逆らうことができず、そのような系はますます無秩序になり、エネルギーはますます低い方向に流れ、情報はますます少なくなる傾向があるだけです。システムがある程度複雑になって初めて、臨界点Cを設定することが可能になるのです。この臨界点を超えると、システムは自ら創造することができるようになり、熱力学第二法則に逆らってシステムがますます複雑になることができるのです。
ここでいう転換点Cとは、多くの人が提唱している「技術的特異点」と同じで、AIが自らを創造できる段階に達したとき、AIが本当に目覚めるときだと考えられています。シンギュラリティ」とは機械が自ら創造できるようになることであり、「シンギュラリティ」以降、機械は進化し、人間の理解の範疇を超えてますます複雑化し、ある程度生命の資質を持つようになり、それが人工知能の時代となるのです。人工知能の時代
要するに、生命が世界の他のすべてのものと違うのは、生命がそれ自身の情報をすべて含むことができるということです。そこで質問です:
問題:入力を読み込まず、自分のソースコードだけを出力するプログラムを書きなさい。
この質問は非常に基本的なもので、どのプログラミング言語を使うかとは関係ありません。
もし自分のソースコードを出力したいのなら、当然、プログラムの中に "print ... "ステートメントがあるはずです。しかし、何を出力するのでしょうか?もし堅苦しく書くとしたら、こうなるでしょう:
print "print "print ......""
***無限ループです。
一般に、プログラムAがプログラムBを生成できる場合、AにはBのすべての情報が含まれていなければならず、print文が追加されているため、Bよりも多くの情報が含まれていなければならないことが知られています。つまり、一般に、情報は減少します。そして、この自己生成プログラムは、それ自身がすべての情報を含んでいなければならず、ある意味で生命の意味を帯びているのです。
いくつかの自己生成手順とそのアイデアを以下に示します。
このbashスクリプトのように、プログラミング言語独自のリフレクション機能を使ったり、ファイルを読み込んだりするのは不正行為とみなされることに注意してください:
#!/bin/sh
cat $0
または、このようなjavascript:
function a() { console.log(a.toString(), "a()"); } a()
これは、自己生成プロシージャの再帰性や自己参照性が反映されていなかったり、結果がプログラミング言語の特定の実装に大きく依存していたりするためです。
言語のソースコードエスケープを出力
パイソン:
s = "'s = ' + repr(s) + '\
print(' + s + ')'"
print('s = ' + repr(s) + '
print(' + s + ')')
Lua 5.1:
s = "string.format('s = %q\
print(%s)', s, s)"
print(string.format('s = %q
print(%s)', s, s))
別のLuaバージョン:
s = "s = %q\
print(string.format(s, s))"
print(string.format(s, s))
スカラ:
def e(s: String) = (""" + s.replace("", "").replace(""", """) + """)
val s = """"def e(s: String) = (""" + s.replace("\", "\\\\\").replace(""", "\\\"") + """)""" + "\
val s = " + e(s) + "\
println(" + s + ")""
println("""def e(s: String) = (""" + s.replace("", "").replace(""", """) + """)""" + "
val s = " + e(s) + "
println(" + s + ")")
ソースコードに引用符が含まれないようにエンコードし、ソースコードを復元します。
バッシュ
#!/bin/sh
s='\x22#!/bin/sh
s=\x27$s\x27
echo $(echo -e $s)\x22'
echo "#!/bin/sh
s='$s'
echo $(echo -e $s)"
Lua 5.2ではload()を使用します:
s = "a,q,b=string.char(39),string.char(34),string.char(92) return a..'s = '..q..a..'..s..'..a..q..b..'nprint('..a..'..load(s)()..'..a..')'..a"
print('s = "'..s..'"
print('..load(s)()..')')
スカラ:
val s = "%22val+s+%3D+%5C%22%22+%2B+s+%2B+%22%5C%22%println%28%22+%2B+java.net.URLDecoder.decode%28s%2C+%22UTF-8%22%29+%2B+%22%29%22"
println("val s = "" + s + ""
println(" + java.net.URLDecoder.decode(s, "UTF-8") + ")")
eval の使用法:eval 文字列の中で自分自身を参照する
Lua load()のもう一つの使い方:
s = "print(string.format('s = %q load(s)()', s))" load(s)()
js eval():
s = "q = String.fromCharCode(34); console.log('s = ' + q + s + q + '; eval(s)')"; eval(s)
言語でより強力なエスケープ・メカニズムを使用
上の2番目のものと似ていますが、引用符はありません。
Luaの長い文字列:
x = [["x = [".."["..x.."]".."]
print("..x..")"]]
print("x = [".."["..x.."]".."]
print("..x..")")
Scalaのトリプルクォート:
val s = """"val s = """" + s + """"
println(" + s + ")""""
println("val s = """" + s + """"
println(" + s + ")")
Cマクロの使用
入力されたパラメータを最初に実行し、次にパラメータを文字列に変換します。
gcc :
#define p(a) int main(){a;puts("p("#a")");return 0;}
p(puts("#define p(a) int main(){a;puts("p("#a")");return 0;}"))




