Квайны — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Общий принцип написания квайнов)
Строка 1: Строка 1:
 
{{Определение
 
{{Определение
|definition='''Квайном''' (англ. <i>quine</i>)<ref name=quineName/> называется программа, которая выводит свой исходный код. При этом, программа не должна использовать внешние данные (например, читать файл со своим исходным кодом)<ref name=quineExists/>.
+
|definition='''Квайном''' (англ. ''quine'')<ref name=quineName/> называется программа, которая выводит свой исходный код. При этом, программа не должна использовать внешние данные (например, читать файл со своим исходным кодом).
 
}}
 
}}
  
Строка 6: Строка 6:
 
Квайн состоит из двух сегментов: <b>кода</b> и <b>данных</b>. Данные представляют собой текстовую версию кода, и, как правило, получаются из кода простым добавлением обрамляющих кавычек. Код, в свою очередь, сначала использует данные, чтобы вывести код(содержащийся в них), а затем, просто выводит данные.
 
Квайн состоит из двух сегментов: <b>кода</b> и <b>данных</b>. Данные представляют собой текстовую версию кода, и, как правило, получаются из кода простым добавлением обрамляющих кавычек. Код, в свою очередь, сначала использует данные, чтобы вывести код(содержащийся в них), а затем, просто выводит данные.
  
Формально общий принцип написания квайнов содержит доказательство [[Теорема о рекурсии|теоремы о рекурсии]]. Далее будет рассмотрено понятие мульти-квайна.
+
Формально общий принцип написания квайнов содержится в доказательстве [[Теорема о рекурсии|теоремы о рекурсии]]. Далее будет рассмотрено понятие мульти-квайна.
  
==Связанные определения==
+
==Интроны==
===Интроны===
 
 
{{Определение
 
{{Определение
|definition='''Интроном''' (intron) называется часть сегмента данных, которая не используется для вывода кода, но сохраняющаяся в процессе саморепликации квайна.
+
|definition='''Интроном''' (англ. ''intron'') называется часть сегмента данных, которая не используется для вывода кода, но сохраняющаяся в процессе саморепликации квайна.
 
}}
 
}}
 
Название пришло из биологии, где интронами называются части ДНК, не участвующие в синтезе протеинов.
 
Название пришло из биологии, где интронами называются части ДНК, не участвующие в синтезе протеинов.
Строка 19: Строка 18:
 
Интроны активно используются при создании мульти-квайнов.
 
Интроны активно используются при создании мульти-квайнов.
  
===Мульти-квайны===
+
==Мульти-квайны==
 
{{Определение
 
{{Определение
|definition='''Би-квайном''' (bi-quine) называется программа, которая делает одно из двух:
+
|definition='''Би-квайном''' (англ. ''bi-quine'') называется программа, которая делает одно из двух:
 
*при обычном запуске она выводит свой исходный код,
 
*при обычном запуске она выводит свой исходный код,
 
*при запуске с особым аргументом она выводит исходный код своего "брата" на другом языке программирования.
 
*при запуске с особым аргументом она выводит исходный код своего "брата" на другом языке программирования.
Строка 27: Строка 26:
 
}}
 
}}
 
{{Определение
 
{{Определение
|definition='''<tex>R</tex>-квайном''' называется программа, способная вывести исходный код <tex>R-1</tex> программ на других языках программирования в зависимости от переданного ей аргумента, а так же свой исходный код при вызове без аргументов.
+
|definition='''<tex>R</tex>-квайном''' (англ. <tex>R</tex>-''quine'') называется программа, способная вывести исходный код <tex>R-1</tex> программ на других языках программирования в зависимости от переданного ей аргумента, а так же свой исходный код при вызове без аргументов.
 
}}
 
}}
 
Заметим, что требование, чтобы программы были на разных языках программирования важно, т.к. иначе все программы смогут иметь один и тот же код.
 
Заметим, что требование, чтобы программы были на разных языках программирования важно, т.к. иначе все программы смогут иметь один и тот же код.
Строка 40: Строка 39:
 
}}
 
}}
  
==Принцип написания==
+
===Принцип написания===
 
Будем следовать доказательству и напишем мульти-квайн для двух языков. Далее покажем, как добавить новый язык.
 
Будем следовать доказательству и напишем мульти-квайн для двух языков. Далее покажем, как добавить новый язык.
 
# напишем для каждого языка "полу-квайн": <tex>P(p,arg):  
 
# напишем для каждого языка "полу-квайн": <tex>P(p,arg):  
Строка 88: Строка 87:
 
\right.
 
\right.
 
</tex>
 
</tex>
 +
 +
== Примечания ==
 +
<references>
 +
<ref name=quineName>Название "квайн" было предложено [http://ru.wikipedia.org/wiki/Хофштадтер,_Дуглас Дугласом Хофштадтером], в его известной книге "Гёдель, Эшер, Бах: Эта бесконечная гирлянда" в честь американского логика и философа  [http://ru.wikipedia.org/wiki/Куайн,_Уиллард_Ван_Орман Уилларда Ван Ормана Квайна], который углублённо изучал явление [http://en.wikipedia.org/wiki/Indirect_self-reference косвенного самоупоминания].</ref>
 +
</references>
  
 
== Источники информации ==
 
== Источники информации ==
Строка 94: Строка 98:
 
* [http://habrahabr.ru/post/188378/ Хабрахабр - Мультиязыковые квайны]
 
* [http://habrahabr.ru/post/188378/ Хабрахабр - Мультиязыковые квайны]
 
* [http://habrahabr.ru/post/128191/ Хабрахабр - Как писать квайны]
 
* [http://habrahabr.ru/post/128191/ Хабрахабр - Как писать квайны]
 
== Примечания ==
 
<references>
 
<ref name=quineName>Название "квайн" было предложено [http://ru.wikipedia.org/wiki/Хофштадтер,_Дуглас Дугласом Хофштадтером], в его известной книге "Гёдель, Эшер, Бах: Эта бесконечная гирлянда" в честь американского логика и философа  [http://ru.wikipedia.org/wiki/Куайн,_Уиллард_Ван_Орман Уилларда Ван Ормана Квайна], который углублённо изучал явление [http://en.wikipedia.org/wiki/Indirect_self-reference косвенного самоупоминания].</ref>
 
<ref name=quineExists>Из [http://neerc.ifmo.ru/wiki/index.php?title=%D0%A2%D0%B5%D0%BE%D1%80%D0%B5%D0%BC%D0%B0_%D0%BE_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D0%B8#.D0.A2.D0.B5.D0.BE.D1.80.D0.B5.D0.BC.D0.B0_.D0.BE_.D1.80.D0.B5.D0.BA.D1.83.D1.80.D1.81.D0.B8.D0.B8 теоремы Клини о рекурсии] очевидно следует, что квайн можно написать на любом Тьюринг-полном языке.</ref>
 
</references>
 
 
  
 
[[Категория: Теория формальных языков]]
 
[[Категория: Теория формальных языков]]
 
[[Категория: Теория вычислимости]]
 
[[Категория: Теория вычислимости]]

Версия 15:04, 6 января 2015

Определение:
Квайном (англ. quine)[1] называется программа, которая выводит свой исходный код. При этом, программа не должна использовать внешние данные (например, читать файл со своим исходным кодом).


Общий принцип написания квайнов

Квайн состоит из двух сегментов: кода и данных. Данные представляют собой текстовую версию кода, и, как правило, получаются из кода простым добавлением обрамляющих кавычек. Код, в свою очередь, сначала использует данные, чтобы вывести код(содержащийся в них), а затем, просто выводит данные.

Формально общий принцип написания квайнов содержится в доказательстве теоремы о рекурсии. Далее будет рассмотрено понятие мульти-квайна.

Интроны

Определение:
Интроном (англ. intron) называется часть сегмента данных, которая не используется для вывода кода, но сохраняющаяся в процессе саморепликации квайна.

Название пришло из биологии, где интронами называются части ДНК, не участвующие в синтезе протеинов. В вышеприведённый квайн можно легко добавить интрон, написав перед объявлением функции

const unsigned char intron[] = "--Hello! I am an intron!---";

и добавив в код (а значит, и модифицировав данные) строчки для вывода интрона. Интроны активно используются при создании мульти-квайнов.

Мульти-квайны

Определение:
Би-квайном (англ. bi-quine) называется программа, которая делает одно из двух:
  • при обычном запуске она выводит свой исходный код,
  • при запуске с особым аргументом она выводит исходный код своего "брата" на другом языке программирования.
Её брат делает то же самое: выводит свой код при запуске без аргументов и выводит код оригинальной программы при запуске с переданным спец. аргументом.


Определение:
[math]R[/math]-квайном (англ. [math]R[/math]-quine) называется программа, способная вывести исходный код [math]R-1[/math] программ на других языках программирования в зависимости от переданного ей аргумента, а так же свой исходный код при вызове без аргументов.

Заметим, что требование, чтобы программы были на разных языках программирования важно, т.к. иначе все программы смогут иметь один и тот же код.

Теорема (о существовании мульти-квайнов):
На любом языке программирования можно написать мульти-квайн
Доказательство:
[math]\triangleright[/math]

Докажем утверждение для би-квайна, для большего количества языков доказательство будет выглядеть аналогично.

Рассмотрим программу с двумя параметрами на языке [math]L_1[/math], которая выводит первый параметр при обычном запуске и второй - при запуске со спец. аргументом. По теореме о неподвижной точке мы можем зафиксировать первый параметр и сказать, что он будет равен исходному коду нашей программы. Таким образом, мы получим программу с одним параметром, которая выводит свой код при запуске без аргументов и выводит параметр при запуске со спец. аргументом. Проделаем то же самое для программы на языке [math]L_2[/math]. И наконец, зафиксируем как параметр первой исходник второй и наоборот.
[math]\triangleleft[/math]

Принцип написания

Будем следовать доказательству и напишем мульти-квайн для двух языков. Далее покажем, как добавить новый язык.

  1. напишем для каждого языка "полу-квайн": [math]P(p,arg): \left\{ \begin{array}{l l} P(p,"shazam!") \rightarrow print(p); \\ P(p,null) \rightarrow print(P.getSrc()); \end{array} \right. [/math]
  2. добавим код каждой из программ интроном в код другой
  3. модифицируем каждую из программ, чтобы вместо [math]p[/math] она выводила интрон: [math]P(arg): \left\{ \begin{array}{l l} P("shazam!") \rightarrow print(intron); \\ P(null) \rightarrow print(P.getSrc()); \end{array} \right. [/math]

Теперь добавим третий язык:

  1. напишем для него "полу-квайн", но уже с двумя параметрами и тремя возможными выводами:[math]P_3(p,arg): \left\{ \begin{array}{l l} P_3(p1,p2,"shazam!") \rightarrow print(p1); \\ P_3(p1,p2,"cadabra!") \rightarrow print(p2); \\ P_3(p1,p2,null) \rightarrow print(P_3.getSrc()); \end{array} \right. [/math]
  2. добавим третье условие в два уже существующих квайна: [math]P(p,arg): \left\{ \begin{array}{l l} P(p,"shazam!") \rightarrow print(intron); \\ P(p,"cadabra!") \rightarrow print(p); \\ P(p,null) \rightarrow print(P.getSrc()); \end{array} \right. [/math]
  3. подставим код первых двух интронами в третью, а код третьей - вторым интроном в каждую из двух первых:
[math]P(arg): 
\left\{
	\begin{array}{l l}
		P("shazam!") \rightarrow print(intron1);  \\
                P("cadabra!") \rightarrow print(intron2); \\
                P(null) \rightarrow print(P.getSrc());
	\end{array}
	\right.
[/math]

Примечания

  1. Название "квайн" было предложено Дугласом Хофштадтером, в его известной книге "Гёдель, Эшер, Бах: Эта бесконечная гирлянда" в честь американского логика и философа Уилларда Ван Ормана Квайна, который углублённо изучал явление косвенного самоупоминания.

Источники информации