• 1.摘要
  • 2.基本信息
  • 3.起源
  • 4.原理
  • 5.例子
  • 5.1.Perl
  • 5.2.Python

自产生程序

自产生程序(Quine),它以哲学家奎恩命名,指的是输出结果为程序自身源码的程序。

能够直接读取自己源码、读入用户输入或空白的程序一般都不视为自产生程序。

基本信息

  • 中文名

    自产生程序

  • 外文名

    Quine

  • 范畴

    电子工程术语

起源

这种编程思想在计算机刚刚兴起的时候就已经出现了。Paul Bratley发表的文章"Computer Recreations: Self-Reproducing Automata"也对此进行了讨论。而已知最早的这类程序在1960年代于爱丁堡大学出现,由Hamish Dewar以Atlas Autocode编写:

%BEGIN !THIS IS A SELF-REPRODUCING PROGRAM %ROUTINESPEC R R PRINT SYMBOL(39) R PRINT SYMBOL(39) NEWLINE %CAPTION %END~ %CAPTION %ENDOFPROGRAM~ %ROUTINE R %PRINTTEXT ' %BEGIN !THIS IS A SELF-REPRODUCING PROGRAM %ROUTINESPEC R R PRINT SYMBOL(39) R PRINT SYMBOL(39) NEWLINE %CAPTION %END~ %CAPTION %ENDOFPROGRAM~ %ROUTINE R %PRINTTEXT ' %END %ENDOFPROGRAM

原理

我们先定义一个函数q {\displaystyle q} ,对于一个字符串 w a {\displaystyle w_{a}} , q ( w a ) {\displaystyle q(w_{a})} 经过编程语言的解释会变成 w b {\displaystyle w_{b}} 。

对于一个程序 P {\displaystyle P} 而言,以下会使用 ⟨ P ⟩ {\displaystyle \langle P\rangle } 来表示程序P的描述(即代码)。

创建一个程序SELF,SELF由A、B所组成。换言之 ⟨ S E L F ⟩ = ⟨ A ⟩ ⟨ B ⟩ {\displaystyle \langle SELF\rangle =\langle A\rangle \langle B\rangle } 。且会先运行A再运行B。

A=“储存 ⟨ B ⟩ {\displaystyle \langle B\rangle } ”

B=“对於输入 ,而M为一段程式码。一、计算出q() 二、把计算结果和结合起来 三、印出所出求出描述。”

而自生实际运行的过程为:

一、首先A先运行,会得到 ⟨ B ⟩ {\displaystyle \langle B\rangle } 。

二、B开始运行,然后被输入 ⟨ B ⟩ {\displaystyle \langle B\rangle } (即 M = B {\displaystyle M=B} )。

三、B利用 ⟨ B ⟩ {\displaystyle \langle B\rangle } ,可以计算出 q ( ⟨ B ⟩ ) {\displaystyle q(\langle B\rangle )} ,并以此计算出 ⟨ A ⟩ {\displaystyle \langle A\rangle } 。将 ⟨ A ⟩ {\displaystyle \langle A\rangle } 与 ⟨ B ⟩ {\displaystyle \langle B\rangle } 组合成一个新的程序的描述 ⟨ S E L F ⟩ {\displaystyle \langle SELF\rangle } 。

四、输出 ⟨ S E L F ⟩ {\displaystyle \langle SELF\rangle } 。

例子

在Quine的定义里,程序不能有任何形式的输入,否则将被视为“作弊”。例如,一个程序读取该程序自身的源代码然后打印出来,利用这种方法的程序属于作弊的Quine。

Perl

一个用Perl编写的无作弊的Quine:

$_=q{print"\$_=q{$_};eval"};eval