Квайны
Определение: |
Квайном (англ. quine)[1] называется программа, которая выводит свой исходный код. При этом, программа не должна использовать внешние данные (например, читать файл со своим исходным кодом). |
Квайн состоит из двух сегментов: кода и данных. Данные представляют собой текстовую версию кода, и, как правило, получаются из кода простым добавлением обрамляющих кавычек. Код, в свою очередь, сначала использует данные, чтобы вывести код(содержащийся в них), а затем, просто выводит данные.
Формально общий принцип написания квайнов содержится в доказательстве теоремы о рекурсии. Далее будет рассмотрено понятие мульти-квайна.
Интроны
Определение: |
Интроном (англ. intron)[2] называется часть сегмента данных, которая не используется для вывода кода, но сохраняющаяся в процессе саморепликации квайна. |
Мульти-квайны
Определение: |
Би-квайном (англ. bi-quine) называется программа, которая делает одно из двух:
|
Определение: |
-квайном (англ. -quine) называется программа, способная вывести исходный код программ на других языках программирования в зависимости от переданного ей аргумента, а так же свой исходный код при вызове без аргументов. |
Заметим, что требование, чтобы программы были на разных языках программирования важно, т.к. иначе все программы смогут иметь один и тот же код.
Теорема (о существовании мульти-квайнов): |
На любом языке программирования можно написать мульти-квайн |
Доказательство: |
Докажем утверждение для би-квайна, для большего количества языков доказательство будет выглядеть аналогично. Рассмотрим программу с двумя параметрами на языке , которая выводит первый параметр при обычном запуске и второй - при запуске со спец. аргументом. По теореме о рекурсии мы можем зафиксировать первый параметр и сказать, что он будет равен исходному коду нашей программы. Таким образом, мы получим программу с одним параметром, которая выводит свой код при запуске без аргументов и выводит параметр при запуске со спец. аргументом. Проделаем то же самое для программы на языке . И наконец, зафиксируем как параметр первой исходный код второй и наоборот. |
Принцип написания
Будем следовать доказательству и напишем мульти-квайн для двух языков. Далее покажем, как добавить новый язык.
- напишем для каждого языка "полу-квайн":
|
|
- добавим код каждой из программ интроном в код другой
- модифицируем каждую из программ, чтобы вместо она выводила интрон:
|
|
Теперь добавим третий язык:
- напишем для него "полу-квайн", но уже с двумя параметрами и тремя возможными выводами:
:
if (arg == "print first!")
print(p1)
elseif (arg == "print second!")
print(p2)
else
print(getSrc())
- добавим третье условие в два уже существующих квайна:
|
|
- подставим код первых двух интронами в третью, а код третьей - вторым интроном в каждую из двух первых:
|
|
|
Примечания
- ↑ Название "квайн" было предложено Дугласом Хофштадтером, в его известной книге "Гёдель, Эшер, Бах: Эта бесконечная гирлянда" в честь американского логика и философа Уилларда Ван Ормана Квайна, который углублённо изучал явление косвенного самоупоминания.
- ↑ Название пришло из биологии, где интронами называются части ДНК, не участвующие в синтезе протеинов.