1632
правки
Изменения
Квайны
,rollbackEdits.php mass rollback
{{Определение
|definition='''Квайном''' (англ. ''quine'')<ref name=quineName/> называется программа, которая выводит свой исходный код. При этом, программа не должна использовать внешние данные (например, читать файл со своим исходным кодом).
}}
Формально общий принцип написания квайнов содержится в доказательстве [[Теорема о рекурсии|теоремы о рекурсии]]. Далее будет рассмотрено понятие мультиквайна. ==ИнтроныМультиквайны=====Связанные определения===
{{Определение
|definition='''Интроном''' (англ. ''intron'')<ref name=intronName/> называется часть сегмента данных, которая не используется для вывода кода, но сохраняющаяся сохраняется в процессе саморепликации квайна.
}}
{{Определение
|definition='''Би-квайномБиквайном''' (англ. ''bi-quinebiquine'') называется программа, которая делает одно из двух:
*при обычном запуске она выводит свой исходный код,
*при запуске с особым аргументом она выводит исходный код своего "брата" на другом языке программирования.
Её "брат " делает то же самое: выводит свой код при запуске без аргументов и выводит код оригинальной программы при запуске с переданным специальным аргументом.
}}
{{Определение
|definition='''<tex>R</tex>-квайном''' (англ. <tex>R</tex>-''quine'') называется программа, способная вывести исходный код <tex>R-1</tex> программ на других языках программирования в зависимости от переданного ей аргумента, а так же также свой исходный код при вызове без аргументов.
}}
Заметим, что требование, чтобы программы были на разных языках программирования , важно, т.к. иначе все программы смогут иметь один и тот же код.
{{
Теорема
|about=о существовании мульти-квайновмультиквайнов|statement= На любом языке программирования можно написать мульти-квайнмультиквайн.|proof= Докажем утверждение для би-квайна, для биквайна. Для большего количества языков доказательство будет выглядеть аналогично.
Рассмотрим программу с двумя параметрами на языке <tex>L_1</tex>, которая выводит первый параметр при обычном запуске и второй {{- --}} при запуске со спец. аргументом. По [[Теорема о рекурсии|теореме о рекурсии]] мы можем зафиксировать первый параметр и сказать, что он будет равен исходному коду нашей программы. Таким образом, мы получим программу с одним параметром, которая выводит свой код при запуске без аргументов и выводит параметр при запуске со спец. аргументом. Проделаем то же самое для программы на языке <tex>L_2</tex>. И , наконец, зафиксируем как параметр первой программы исходный код второй и наоборот.
}}
===Принцип написания===
Будем следовать доказательству и напишем мульти-квайн мультиквайн для двух языков. Далее покажем, как добавить новый язык.* напишем для каждого языка "полу-квайнполуквайн":
<table>
<tr>
<td><centerfont size = "2em"> <tex>P_1(p,arg)</tex></center></td>:<td><center><tex>P_2(p,arg)</tex></center></td></tr><tr><td><code><font size = "2em"> '''if ''' (arg == "print second!") '''print'''(p) '''else''' '''print'''(getSrc()) </font></code></td><td><code><font size = "2em"> if (arg == "print first!") print(p) else print(getSrc()) </font></code></td></tr></table>* добавим код каждой из программ интроном в код другой* модифицируем каждую из программ, чтобы вместо <tex>p</tex> она выводила интрон: <table><tr><td><center><tex>P_1(arg)</tex></center></td><td><center><tex>P_2(p,arg)</tex></center></td></tr><tr><td><code><font size = "2em"> if (arg == "print second!"): print(p2_intron) else print(getSrc()) </font></code></td><td><code><font size = "2em"> '''if ''' (arg == "print first!") '''print'''(p1_intronp) '''else''' '''print'''(getSrc()) </font></code></td>
</tr>
</table>
* подставим код второй программы в первую:
<font size = "2em">
<tex>P_1(p,arg)</tex>:
'''if''' (arg == "print second!")
'''print'''(<tex>P_2</tex>(p, arg).getSrc())
'''else'''
'''print'''(getSrc())
</font>
* применим [[Теорема о рекурсии|теорему о рекурсии]] и заменим параметр на исходный код программы:
<font size = "2em">
<tex>P_1(arg)</tex>:
'''if''' (arg == "print second!")
'''print'''(<tex>P_2</tex>(getSrc(), arg).getSrc())
'''else'''
'''print'''(getSrc())
</font>
Вторая программа может быть получена запуском первой с нужным аргументом.
Теперь добавим третий язык:
* напишем для него "полу-квайнполуквайн", но уже с двумя параметрами и тремя возможными выводами:<code><font size = "2em">
<tex>P_3(p1,p2,arg)</tex>:
'''if ''' (arg == "print first!") '''print'''(p1) '''elseif ''' (arg == "print second!") '''print'''(p2) '''else''' '''print'''(getSrc()) </font></code>* добавим третье условие параметр в два уже существующих квайна:
<table>
<tr>
<td><centerfont size = "2em"> <tex>P_1(p,arg)</tex></center></td>:<td><center><tex>P_2(p,arg)</tex></center></td></tr><tr><td><code><font size = "2em"> '''if ''' (arg == "print second!") '''print'''(p2_intron) elseif (arg == "print third!") print(p) else print(getSrc())</fonttex>P_2</codetex></td><td><code><font size = "2em"> if (p, getSrc(), arg == "print first!") print.getSrc(p1_intron)) '''elseif ''' (arg == "print third!") '''print'''(p) '''else''' '''print'''(getSrc())</font></code></td></tr></table>* подставим код первых двух интронами в третью, а код третьей - вторым интроном в каждую из двух первых:<table><tr><td><center><tex>P_1(arg)</tex></center></tdfont size = "2em"><td><center> <tex>P_2(p,arg)</tex></center></td>:<td><center><tex>P_3(arg)</tex></center></td></tr><tr><td><code><font size = "2em"> '''if ''' (arg == "print second!") print(p2_intron) elseif (arg == "print thirdfirst!") '''print'''(p3_intron) else print(getSrc())</fonttex>P_1</codetex></td><td><code><font size = "2em"> if (arg == "print first!") printp, getSrc(p1_intron) elseif (, arg == "print third!") print(p3_intron) else print(.getSrc())</font></code></td><td><code><font size = "2em"> if (arg == "print first!") print(p1_intron) '''elseif ''' (arg == "print secondthird!") '''print'''(p2_intronp) '''else''' '''print'''(getSrc())</font></code></td>
</tr>
</table>
* подставим код первых двух в третью:
<font size = "2em">
<tex>P_3(p1,p2,arg)</tex>:
'''if''' (arg == "print first!")
'''print'''(<tex>P_1</tex>(p1, arg).getSrc())
'''elseif''' (arg == "print second!")
'''print'''(<tex>P_2</tex>(p2, arg).getSrc())
'''else'''
'''print'''(getSrc())
</font>
* применим [[Теорема о рекурсии|теорему о рекурсии]] и заменим оба параметра на исходный код программы:
<font size = "2em">
<tex>P_3(arg)</tex>:
'''if''' (arg == "print first!")
'''print'''(<tex>P_1</tex>(getSrc(), arg).getSrc())
'''elseif''' (arg == "print second!")
'''print'''(<tex>P_2</tex>(getSrc(), arg).getSrc())
'''else'''
'''print'''(getSrc())
</font>
Две оставшиеся программы будут выглядеть аналогично и смогут быть получены путём запуска третьей с каждым из возможных аргументов.
== Примечания ==