Quine (informatique)
Un quine (ou programme autoreproducteur, self-reproducing en anglais[1]) est un programme informatique qui imprime son propre code source. L'opération qui consiste à ouvrir le fichier source et à l'afficher est considérée comme une tricherie. Plus généralement, un programme qui utilise une quelconque entrée de données ne peut être considéré comme un quine valide. Dans beaucoup de langages de programmation, un quine est une variante de la commande suivante :
- Recopier puis placer entre guillemets la phrase « Recopier puis placer entre guillemets la phrase »
À titre de défi ou d'amusement, certains programmeurs essaient d'écrire le plus court quine dans un langage de programmation donné. Donald Knuth (Prix Turing 1974) et Ken Thompson (prix Turing 1983) expliquent dans leurs conférences Turing le rôle que ces programmes autoreproducteurs minimaux ont joué dans leurs formations et le pourquoi de ce rôle[2],[1].
Étymologie modifier
Les quines tirent leur nom du philosophe et logicien américain W. V. Quine (1908 – 2000), qui a étudié en profondeur l'autoréférence indirecte : il a entre autres forgé l'expression paradoxale :
« 'Yields falsehood when preceded by its quotation' yields falsehood when preceded by its quotation. »
c'est-à-dire : « 'est faux lorsque précédé par son propre énoncé' est faux lorsque précédé par son propre énoncé ».
Démonstration de l'existence modifier
Dans cette section, nous esquissons la démonstration de l'existence d'une machine de Turing QUINE qui ignore son entrée et qui écrit sa propre description[3]. Une machine de Turing est un modèle de calcul abstrait. Elle lit et écrit des caractères sur un ruban. Tout d'abord, pour tout mot w, on construit la machine printw qui ne tient pas compte de son entrée, efface son ruban et y écrit le mot w. Pour toute machine M, la description de M est notée <M>. Ensuite, on considère la machine descrPrint, qui, pour toute entrée w, retourne <printw>, la description de la machine de Turing printw. Informellement, descrPrint prend un mot en entrée, et retourne la machine qui imprime ce mot. Maintenant, on construit QUINE, la machine qui ignore son mot d'entrée u et qui imprime sa propre description :
QUINE(u) 1. lancer print<B> 2. lancer B
où B est la machine suivante :
B(<M>) 2a. lancer descrPrint(<M>) 2b. concaténer le résultat avec <M>
En exécutant, QUINE(u), l'étape 1 écrit <B> sur le ruban. L'étape 2 lance B(<B>). L'étape 2a lance descrPrint(<B>) et écrit <print<B>> sur le ruban. L'étape 2b finit avec <print<B>B> sur le ruban. Il s'agit de la description de QUINE.
Lien avec le théorème de récursion de Kleene modifier
On démontre le théorème de récursion de Kleene en remplaçant l'instruction 2b par <MR> où R est la suite du programme. D'autre part, le théorème de récursion de Kleene implique l'existence d'un quine pour tout langage de programmation Turing-complet.
Fichier vide modifier
Un fichier vide est acceptable comme solution, mais n'est pas accepté par tous les langages.
Pour les langages acceptant un fichier vide, aucune sortie ne doit être produite à l'exécution. Parmi les langages acceptant un fichier vide, ne produisant aucune sortie à l'exécution :
- BASIC (certains interpréteurs),
- Batch (MS-DOS),
- Brainfuck.
Ceux qui ne l'acceptent pas produisent une erreur, ne correspondant donc pas au code source. En général, ces langages de programmation requièrent un minimum de code : une fonction principale, une classe principale, une structure de programme...
Exemples modifier
Langages de programmation modifier
Ada modifier
Remarque : des sauts de ligne et des espaces ont été ajoutés pour faciliter la lecture.
with Ada.Text_Io;
procedure Quine is
S:String:="with Ada.Text_Io;procedure Quine is S:String:=X;G:Character:=Character'Val(34);
function F return String is begin for I in S'Range loop
if S(I)='X' then return S(S'First..I-1)&G&S&G&S(I+1..S'Last);end if;
end loop;end;begin Ada.Text_Io.Put_Line(F);end;";
G:Character:=Character'Val(34);
function F return String is
begin
for I in S'Range loop
if S(I)='X' then return S(S'First..I-1)&G&S&G&S(I+1..S'Last);end if;
end loop;
end;
begin
Ada.Text_Io.Put_Line(F);
end;
awk modifier
#!/usr/bin/awk -f
BEGIN{b="#!/usr/bin/awk -f";a="\"";s="\\";q="BEGIN{b=%c%s%c;a=%c%c%c%c;s=%c%c%c%c;q=%c%s%c;print b;printf q,a,b,a,a,s,a,a,a,s,s,a,a,q,a;print}";print b;printf q,a,b,a,a,s,a,a,a,s,s,a,a,q,a;print}
BASIC modifier
10 C=": PRINT CHR(49)+CHR(48)+CHR(32)+CHR(67)+CHR(61)+CHR(34)+C+CHR(34)+C":
PRINT CHR(49)+CHR(48)+CHR(32)+CHR(67)+CHR(61)+CHR(34)+C+CHR(34)+C
Batch (MS-DOS) modifier
Version 1 modifier
@echo off
%1 %2
call %0 goto e %%
call %0 goto e %%3 echo.%%4
echo :f
goto f
:e
echo.%4@echo off
echo.%4%31 %32
echo.%4call %30 goto e %3%3
echo.%4call %30 goto e %3%33 echo.%3%34
echo.%4echo :f
echo.%4goto f
echo.%4:e
:f
Version 2 modifier
Le fichier vide est également accepté : à l'exécution, rien n'est produit en sortie.
Bourne shell (sh) modifier
#!/bin/sh
quine () {
echo -e "#!/bin/sh\n$1"
echo "quine '$1'"
}
quine 'quine () {
echo -e "#!/bin/sh\\n$1"
echo "quine \047$1\047"
}
'
Brainfuck modifier
Remarque : il devrait s'agir d'une ligne de code continue, mais des retours à la ligne ont été ajoutés pour "faciliter" la lecture.
->+>+++>>+>++>+>+++>>+>++>>>+>+>+>++>+>>>>+++>+>>++>+>+++>>++>++>>+>>+>++>++>
+>>>>+++>+>>>>++>++>>>>+>>++>+>+++>>>++>>++++++>>+>>++>+>>>>+++>>+++++>>+>+++
>>>++>>++>>+>>++>+>+++>>>++>>+++++++++++++>>+>>++>+>+++>+>+++>>>++>>++++>>+>>
++>+>>>>+++>>+++++>>>>++>>>>+>+>++>>+++>+>>>>+++>+>>>>+++>+>>>>+++>>++>++>+>+
++>+>++>++>>>>>>++>+>+++>>>>>+++>>>++>+>+++>+>+>++>>>>>>++>>>+>>>++>+>>>>+++>
+>>>+>>++>+>++++++++++++++++++>>>>+>+>>>+>>++>+>+++>>>++>>++++++++>>+>>++>+>>
>>+++>>++++++>>>+>++>>+++>+>+>++>+>+++>>>>>+++>>>+>+>>++>+>+++>>>++>>++++++++
>>+>>++>+>>>>+++>>++++>>+>+++>>>>>>++>+>+++>>+>++>>>>+>+>++>+>>>>+++>>+++>>>+
[[->>+<<]<+]+++++[->+++++++++<]>.[+]>>[<<+++++++[->+++++++++<]>-
.------------------->-[-<.<+>>]<[+]<+>>>]<<<[-[-[-[>>+<++++++[->+++++<]]>++++
++++++++++<]>+++<]++++++[->+++++++<]>+<<<-[->>>++<<<]>[->>.<<]<<]
C modifier
#include <stdio.h>
int main(){
char*a="#include <stdio.h>%cint main(){char*a=%c%s%c;printf(a,10,34,a,34);}";
printf(a,10,34,a,34);
}
C++ modifier
Remarque : des sauts de ligne ont été ajoutés pour faciliter la lecture. Tout ce qui se trouve en dessous de #include <iostream>
s'écrit en une seule ligne.
#include <iostream>
int main(){
int i;
char t[2];
t[0]=0x00;
char *v,*w;
v=(char*)malloc(10);
w=(char*)malloc(9);
t[1]=v[0]=v[9]=w[0]=0x22;
v[1]=v[2]=v[7]=v[8]=w[1]=w[2]=0x3C;
v[3]=0x75;
w[4]=v[4]=0x5B;
w[5]=v[5]=0x69;
v[6]=w[6]=0x5D;
w[3]=0x78;
w[7]=0x3B;
w[8]=0x7D;std::string u[2],x[2];
u[0]=0x0A;
u[1]=v;
x[0]=t[0];
x[1]=w;
for(i=0;i<2;i++)std::cout<<t[i]<<"#include <iostream>"
<<u[i]<<"main(){int i;char t[2];t[0]=0x00;char *v,*w;v=(char*)malloc(10);w=(char*)malloc(9);
t[1]=v[0]=v[9]=w[0]=0x22;v[1]=v[2]=v[7]=v[8]=w[1]=w[2]=0x3C;v[3]=0x75;w[4]=v[4]=0x5B;w[5]=v[5]=0x69;
v[6]=w[6]=0x5D;w[3]=0x78;w[7]=0x3B;w[8]=0x7D;std::string u[2],x[2];u[0]=0x0A;u[1]=v;x[0]=t[0];
x[1]=w;for(i=0;i<2;i++){std::cout<<t[i]<<"<<x[i];}
Un autre exemple utilisant C++ 11 :
#include <iostream>
void f(char const*a){std::cout<<a<<a<<")\");}\n";} int main(){f(R"(#include <iostream>
void f(char const*a){std::cout<<a<<a<<")\");}\n";} int main(){f(R"()");}
C# modifier
Remarque : des sauts de ligne ont été ajoutés pour faciliter la lecture.
using System;
namespace quine
{
class Program
{
[STAThread]
static void Main(string[] args)
{
string s = "using System;{0}namespace quine{0}{2}{0}{1}class Program{0}
{1}{2}{0}{1}{1}[STAThread]{0}{1}{1}static void Main(string[] args){0}{1}{1}{2}{0}{1}{1}{1}
string s = {4}{6}{4};{0}{1}{1}{1}Console.Write(s, Environment.NewLine, {4}{5}t{4}, {4}{2}
{4}, {4}{3}{4}, {4}{5}{4}{4}, {4}{5}{5}{4}, s);{0}{1}{1}{3}{0}{1}{3}{0}{3}";
Console.Write(s, Environment.NewLine, "\t", "{", "}", "\"", "\\", s);
}
}
}
Caml Light modifier
let quine programme =
let guillemet = make_string 1 (char_of_int 34) and
pnt_virgule = make_string 1 (char_of_int 59) in
print_endline (programme ^ guillemet ^ programme ^ guillemet ^ pnt_virgule ^ pnt_virgule);
() in quine "let quine programme =
let guillemet = make_string 1 (char_of_int 34) and
pnt_virgule = make_string 1 (char_of_int 59) in
print_endline (programme ^ guillemet ^ programme ^ guillemet ^ pnt_virgule ^ pnt_virgule);
() in quine ";;
dc modifier
#!/usr/bin/dc [[#!/usr/bin/dc]P10an91ann93an[dx]p]dx
Common Lisp modifier
(funcall (lambda (x)
(append x (list (list 'quote x))))
'(funcall (lambda (x)
(append x (list (list 'quote x))))))
Forth modifier
Remarque : cette quine fonctionne sur tous les systèmes forth.
: q s" 2dup cr 115 emit 34 emit space type 34 emit space type cr"
2dup cr 115 emit 34 emit space type 34 emit space type cr ;
Haskell modifier
s="main=putStr (['s', '='] ++ show s ++ [';'] ++ s)";main=putStr (['s', '='] ++ show s ++ [';'] ++ s)
Java modifier
Remarque : des sauts de ligne ont été ajoutés pour faciliter la lecture.
public class r {public static void main(String[] args) {String p="public class r {
public static void main(String[] args) {",g="\"",n ="System.out.println(p+a+g+p+g+z
+c+g+s+g+g+z+b+g+n+g+z+d+g+s+s+g+z+e+g+z+g+z+'a'+'='+g+a+g+z+'b'+'='+g+b+g+z+'c'+'='
+g+c+g+z+'d'+'='+g+d+g+z+'e'+'='+g+e+g+z+'f'+'='+g+f+g+z+'v'+'='+g+v+g+v+n);}}",s="\\",
z=",",a="String p=",b="n =",c="g=",d="s=",e="z=",f="v=",v=";";System.out.println(
p+a+g+p+g+z+c+g+s+g+g+z+b+g+n+g+z+d+g+s+s+g+z+e+g+z+g+z+'a'+'='+g+a+g+z+'b'+'='+g+b+g+z
+'c'+'='+g+c+g+z+'d'+'='+g+d+g+z+'e'+'='+g+e+g+z+'f'+'='+g+f+g+z+'v'+'='+g+v+g+v+n);}}
Ou encore (la variable 'n' peut être remplacée par 'System.getProperty("line.separator")' pour plus de portabilité) :
class Quine{public static void main(String[] args){char n=10;char b='"';String a="class Quine{public static void main(String[] args){char n=10;char b='%c';String a=%c%s%c;System.out.format(a,b,b,a,b,n);}}%c";System.out.format(a,b,b,a,b,n);}}
JavaScript modifier
unescape(q="unescape(q=%22*%22).replace('*',q)").replace('*',q)
Les fonctionnalités du JavaScript permettent cependant de le faire directement :
(function a(){
return "("+a.toString()+")()";
})()
À partir de la version ES6 :
const f = () => "const f = " + f
LaTeX modifier
\documentclass{book}\pagestyle
{empty}\def\a{\ensuremath{\backslash}}\def\f
{\def\b{\a}\def\c{\{}\def\d{\}}\def
\e{\\}\noindent\g\b def\b g\c\def\b{\a b
}\def\c{\a c }\def\d{\a d}\def\e{\a e
\\}\g\}\a begin\{document\}\a f\a end
\{document\}}\def\g{ \b documentclass\c book\d\b pagestyle\e
\c empty\d\b def\b a\c \b ensuremath\c \b backslash\d\d\b def\b f\e
\c \b def\b b\c \b a\d\b def\b c\c \b \c \d\b def\b d\c \b \d\d\b def\e
\b e\c \b \b \d\b noindent\b g\b b def\b b g\b c\b def\b b\c \b a b\e
\d\b def\b c\c \b a c \d\b def\b d\c \b a d\d\b def\b e\c \b a e\e
\b \b \d\b g\b \d\b a begin\b \c document\b \d\b a f\b a end\e
\b \c document\b \d\d}\begin{document}\f\end{document}
OCaml modifier
(fun s -> Printf.printf "%s %S;;" s s) "(fun s -> Printf.printf \"%s %S;;\" s s)";;
Pascal modifier
const a='const a=';b='begin write(a,#39,a,#39#59#98#61#39,b,#39#59#10,b) end.';
begin write(a,#39,a,#39#59#98#61#39,b,#39#59#10,b) end.
En FreePascal :
PROCEDURE q(s:string);BEGIN write(s,#39,s,#39,#59,#69,#78,#68,#46);readln;END;BEGIN q('PROCEDURE q(s:string);BEGIN write(s,#39,s,#39,#59,#69,#78,#68,#46);readln;END;BEGIN q(');END.
Perl modifier
$_=q{$_=q{Q};s/Q/$_/;print};s/Q/$_/;print
Et un mélange shell/Perl :
perl -le '$n=q{perl -le a$n=q{$x};($_=$n)=~s/\141/\47/g;s/\$x/$n/;printa};($_=$n)=~s/\141/\47/g;s/\$x/$n/;print'
PHP modifier
<?php $q='<?php $q=\'%s\';printf($q,addslashes($q));';printf($q,addslashes($q));
PL1 modifier
Remarque : ce plus court[réf. souhaitée] quine écrit en PL/I compilera en utilisant la version OS PL/I V2.3.0 du compilateur, mais nécessite une marge à gauche de 1 et l'option COMPILE pour éviter un certain nombre d'erreurs ou d'avertissements.
%dcl z%z='put edit';proc options(main;q=''''put list(m;do i=1,2;z(q)skip;do j= 1to 78c=substr(m(i),j;if c=q z(c;z(c;end;z(q',';dcl(c,q)char,m(2)char(99)init( '%dcl z%z=''put edit'';proc options(main;q=''''''''put list(m;do i=1,2;z(q)skip;do j=', '1to 78c=substr(m(i),j;if c=q z(c;z(c;end;z(q'','';dcl(c,q)char,m(2)char(99)init(',
PostScript modifier
(dup == {dup cvx exec} pop 8 12 getinterval =)
dup cvx exec
Python modifier
En Python 2 :
a='a=%s;print a%%`a`';print a%`a`
En Python 3, print est une fonction :
a='a=%r;print(a%%a)';print(a%a)
Un autre exemple :
b='\\';g='"';p='%';s="b='%s%s';g='%s';p='%s';s=%s%s%s;print s%s(b,b,g,p,g,s,g,p)";print s%(b,b,g,p,g,s,g,p)
Un autre exemple dont les 61 derniers caractères sont communs avec le précédent :
b,g,p,s='\\','"','%',"b,g,p,s='%s%s','%s','%s',%s%s%s;print s%s(b,b,g,p,g,s,g,p)";print s%(b,b,g,p,g,s,g,p)
Ruby modifier
puts <<2*2,2
puts <<2*2,2
2
Fonctionnement[4] :
puts <<2
: affiche tout le texte suivant jusqu'au2
final ;*2
: fait ceci deux fois ;,2
: et imprime la valeur 2 ;- le second
puts <<2*2,2
est juste du texte, et le2
final est le délimiteur.
Rust modifier
fn main() {
let p:&[i8] = &[32, 0, 0, 0, 80, 2, -9, 5, 6, -83, 7, -6, 68, 8, -78, 77, -12, 8, 5, -70, 1, -9, 91, 0, -31, 18, -78, 0, 0, 0, 76, -7, 15, -84, 80, -54, -20, 53, 14, -49, 37, -61, 29, -29, 6, 85, -65, 5, 62, -66, 33, 18, -76, 10, -12, 80, -71, 18, -49, 22, 0, 0, 0, 76, -7, 15, -84, 77, 8, -1, -84, 67, -67, 29, -29, 16, 11, -49, 22, 0, 0, 0, 70, 9, 3, -82, 88, -88, 73, 5, -78, 80, -66, 59, 11, -15, 13, -74, 1, -9, 91, -113, 22, 0, 0, 0, 0, 0, 0, 0, 67, -67, 11, 18, -29, 10, 78, -61, -49, 22, 0, 0, 0, 0, 0, 0, 0, 80, 2, -9, 5, 6, -83, 7, -6, 89, 2, -91, 10, -12, 8, 59, -67, 65, 18, -83, 85, -61, -15, -9, 65, 18, -83, 67, 5, -7, 17, -73, 18, -49, 22, 0, 0, 0, 93, -115, 115, -115];
print!("fn main() {{\n let p:&[i8] = &{:?};\n", p);
let mut c = 0;
for x in p.iter() {
c += *x;
print!("{}", (c as u8) as char);
}
}
Source: [1]
Scheme modifier
((lambda (x)
(list x (list (quote quote) x)))
(quote
(lambda (x)
(list x (list (quote quote) x)))))
Tcl modifier
proc Quine {} {
set n [lindex [info level 0] 0]
append s [list proc $n [info args $n] [info body $n]] \n [list $n]
puts $s
}
Quine
Unlambda modifier
À écrire sur une seule ligne. Il est masqué car contient 12 538 caractères.
````s``s`ks``s`kk`k`d``````.`.`.s.i.`.k.i``s``s`ks``s``s`ks``s`kk`k.```s`kk`ki``
s``s`ks``s``s`ks``s`kk`kc``s``s`ks``s``s`ks``s``s`ks``s`kki``s`kki``s`kk`k``s``s
`ks``s``s`ks``s`kki`ki``s`kk`ki`ki``s``s`ks``s`kk`kc``s``s`ks``s``s`ks``s``s`ks`
`s`kki``s`kki``s`kk`k``s``s`ks``s``s`ks``s`kk`k`d```````.`.k.`.d.`.k.`..``s``s`k
s``s`kki`ki``s`kk`kk`ki``s``s`ks``s``s`ks``s`kk`ks``s``s`ks``s``s`ks``s`kk`ks``s
``s`ks``s`kk`kk``s`kk`ks``s``s`ks``s``s`ks``s`kk`ks``s``s`ks``s``s`ks``s`kk`ks``
s``s`ks``s`kk`kk``s`kk`ks``s``s`ks``s``s`ks``s`kk`ks``s``s`ks``s``s`ks``s`kk`ks`
`s``s`ks``s`kk`kk``s`kk`ks``s``s`ks``s``s`ks``s`kk`ks``s``s`ks``s``s`ks``s`kk`ks
``s``s`ks``s`kk`kk``s`kk`ks``s``s`ks``s``s`ks``s`kk`ks``s``s`ks``s`kk`kk``s`kk`k
k``s``s`ks``s`kk`kk``s`kki``s``s`ks``s``s`ks``s`kk`ks``s``s`ks``s`kk`kk``s`kk`kk
``s``s`ks``s`kk`kk``s`kki``s``s`ks``s``s`ks``s`kk`ks``s``s`ks``s`kk`kk``s`kk`kk`
`s``s`ks``s`kk`kk`ki``s``s`ks``s``s`ks``s`kk`ks``s``s`ks``s``s`ks``s`kk`ks``s``s
`ks``s`kk`kk``s`kk`ks``s``s`ks``s``s`ks``s`kk`ks``s``s`ks``s``s`ks``s`kk`ks``s``
s`ks``s`kk`kk``s`kk`ks``s``s`ks``s``s`ks``s`kk`ks``s``s`ks``s`kk`kk``s`kk`kk``s`
`s`ks``s`kk`kk`ki``s``s`ks``s``s`ks``s`kk`ks``s``s`ks``s`kk`kk``s`kk`kk``s`kk`ki
``s``s`ks``s`kk`kk``s`kk`ki``s``s`ks``s`kk`kk``s`kk`ki`k`d`k`.``k`d`k`.``k`d`k`.
``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`
.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.``k`d`k`.d`k`d`k
`.``k`d`k`.``k`d`k`.``k`d`k`.``k`d`k`.``k`d`k`.``k`d`k`..`k`d`k`.``k`d`k`..`k`d`
k`.``k`d`k`..`k`d`k`.s`k`d`k`..`k`d`k`.i`k`d`k`..`k`d`k`.``k`d`k`..`k`d`k`.k`k`d
`k`..`k`d`k`.i`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`
d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k
`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``
k`d`k`.k`k`d`k`..`k`d`k`.``k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k
`k`d`k`.``k`d`k`.k`k`d`k`.i`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.
s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`
.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k
`.k`k`d`k`.``k`d`k`.k`k`d`k`.c`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`
k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d
`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`
d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k
`d`k`.k`k`d`k`.i`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.i`
k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.`
`k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.
``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`
.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.i`k`d`k`.``k`d`k`.k`k`d`k
`.i`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`
k`.i`k`d`k`.``k`d`k`.k`k`d`k`.i`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d
`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`
d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.c`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k
`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``
k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.`
`k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.
k`k`d`k`.k`k`d`k`.i`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`
.i`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k
`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`
k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d
`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.``k`
d`k`.d`k`d`k`.``k`d`k`.``k`d`k`.``k`d`k`.``k`d`k`.``k`d`k`.``k`d`k`.``k`d`k`..`k
`d`k`.``k`d`k`..`k`d`k`.k`k`d`k`..`k`d`k`.``k`d`k`..`k`d`k`.d`k`d`k`..`k`d`k`.``
k`d`k`..`k`d`k`.k`k`d`k`..`k`d`k`.``k`d`k`..`k`d`k`..`k`d`k`.``k`d`k`.``k`d`k`.s
`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.
s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.i`k`d`k`.``k`d`k`.k`k`d`k`.i`k`d`k`.``k`d`k`
.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k
`.k`k`d`k`.i`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`
k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d
`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`
d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k
`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``
k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.`
`k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.
``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`
.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k
`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`
k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d
`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`
d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k
`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`
k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k
`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.
s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`
.k`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k
`.k`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`
k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d
`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`
d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k
`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``
k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k
`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.
``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`
.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k
`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`
k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d
`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`
d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k
`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``
k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.`
`k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.
``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`
.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k
`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`
k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d
`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`
d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k
`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`
k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.``k`d`k`.s
`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.``k`d`k`.
s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`
.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.``k`d`k
`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.i`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`
k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d
`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`
d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k
`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``
k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.`
`k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.
``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`
.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k
`.``k`d`k`.k`k`d`k`.k`k`d`k`.i`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`
k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d
`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`
d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k
`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`
k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k
`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.
``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`
.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.i`k`d`k`.``k`d`k
`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`
k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d
`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`
d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k
`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``
k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.`
`k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.
``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`
.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k
`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`
k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d
`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.s`k`
d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k
`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`
k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.s
`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.
s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`
.k`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k
`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`
k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d
`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`
d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k
`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`
k`d`k`.k`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k
`k`d`k`.k`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.
k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`
.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.i`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k
`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`
k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d
`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`
d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k
`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.``
k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.`
`k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.i`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`.
``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k`
.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`k
`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.i`k`d`k`.``k`d`k`.``k`d`k`.s`k`d`
k`.``k`d`k`.``k`d`k`.s`k`d`k`.``k`d`k`.k`k`d`k`.s`k`d`k`.``k`d`k`.``k`d`k`.s`k`d
`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.``k`d`k`.s`k`
d`k`.``k`d`k`.k`k`d`k`.k`k`d`k`.``k`d`k`.k`k`d`k`.i``si`ki
Vala modifier
var a="var a=\"%s\";\nprint(a,a.escape());";
print(a,a.escape());
Visual FoxPro modifier
CLEAR
SET TALK OFF
SET TEXTMERGE ON
\CLEAR
\SET TALK OFF
\SET TEXTMERGE ON
XProc modifier
<?xml version="1.0" encoding="UTF-8"?>
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" version="1.0">
<p:documentation>
<p>(c) Innovimax 2011 - The first XProc Quine</p>
</p:documentation>
<p:output port="result"/>
<p:identity>
<p:input port="source">
<p:inline>
<p:declare-step version="1.0">
<p:documentation>
<p>(c) Innovimax 2011 - The first XProc Quine</p>
</p:documentation>
<p:output port="result"/>
<p:identity>
<p:input port="source">
<p:inline/>
</p:input>
</p:identity>
<p:insert match="p:inline" position="first-child">
<p:input port="source"/>
<p:input port="insertion"/>
</p:insert>
</p:declare-step>
</p:inline>
</p:input>
</p:identity>
<p:insert match="p:inline" position="first-child">
<p:input port="source"/>
<p:input port="insertion"/>
</p:insert>
</p:declare-step>
XSLT modifier
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="2.0">
<!-- (c) Innovimax 2011 - XSLT 2.0 Quine without DOE -->
<xsl:variable name="code">
<xsl:element name="xsl:stylesheet">
<xsl:attribute name="version" select="'2.0'"/>
<xsl:comment> (c) Innovimax 2011 - XSLT 2.0 Quine without DOE
</xsl:comment>
<xsl:element name="xsl:variable">
<xsl:attribute name="name" select="'code'"/>
<xsl:element name="foo"/>
</xsl:element>
<xsl:element name="xsl:template">
<xsl:attribute name="match" select="'/'"/>
<xsl:element name="xsl:apply-templates">
<xsl:attribute name="select" select="'$code'"/>
<xsl:attribute name="mode" select="'copy'"/>
</xsl:element>
</xsl:element>
<xsl:element name="xsl:template">
<xsl:attribute name="match" select="'@*|node()'"/>
<xsl:attribute name="mode" select="'copy'"/>
<xsl:element name="xsl:copy">
<xsl:element name="xsl:apply-templates">
<xsl:attribute name="select" select="'@*|node()'"/>
<xsl:attribute name="mode" select="'copy'"/>
</xsl:element>
</xsl:element>
</xsl:element>
<xsl:element name="xsl:template">
<xsl:attribute name="match" select="'foo'"/>
<xsl:attribute name="mode" select="'copy'"/>
<xsl:element name="xsl:apply-templates">
<xsl:attribute name="select" select="'$code'"/>
<xsl:attribute name="mode" select="'el'"/>
</xsl:element>
</xsl:element>
<xsl:element name="xsl:template">
<xsl:attribute name="match" select="'*'"/>
<xsl:attribute name="mode" select="'el'"/>
<xsl:element name="xsl:element">
<xsl:attribute name="name" select="'xsl:element'"/>
<xsl:element name="xsl:attribute">
<xsl:attribute name="name" select="'name'"/>
<xsl:attribute name="select" select="'name()'"/>
</xsl:element>
<xsl:element name="xsl:apply-templates">
<xsl:attribute name="select" select="'@*|*|text()|comment()'"/>
<xsl:attribute name="mode" select="'el'"/>
</xsl:element>
</xsl:element>
</xsl:element>
<xsl:element name="xsl:template">
<xsl:attribute name="match" select="'@*'"/>
<xsl:attribute name="mode" select="'el'"/>
<xsl:element name="xsl:element">
<xsl:attribute name="name" select="'xsl:attribute'"/>
<xsl:element name="xsl:attribute">
<xsl:attribute name="name" select="'name'"/>
<xsl:attribute name="select" select="'name()'"/>
</xsl:element>
<xsl:element name="xsl:attribute">
<xsl:attribute name="name" select="'select'"/>
<xsl:text>'</xsl:text>
<xsl:element name="xsl:value-of">
<xsl:attribute name="select" select="'.'"/>
</xsl:element>
<xsl:text>'</xsl:text>
</xsl:element>
</xsl:element>
</xsl:element>
<xsl:element name="xsl:template">
<xsl:attribute name="match" select="'text()'"/>
<xsl:attribute name="mode" select="'el'"/>
<xsl:element name="xsl:element">
<xsl:attribute name="name" select="'xsl:text'"/>
<xsl:element name="xsl:value-of">
<xsl:attribute name="select" select="'.'"/>
</xsl:element>
</xsl:element>
</xsl:element>
<xsl:element name="xsl:template">
<xsl:attribute name="match" select="'comment()'"/>
<xsl:attribute name="mode" select="'el'"/>
<xsl:element name="xsl:element">
<xsl:attribute name="name" select="'xsl:comment'"/>
<xsl:element name="xsl:value-of">
<xsl:attribute name="select" select="'.'"/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:variable>
<xsl:template match="/">
<xsl:apply-templates select="$code" mode="copy"/>
</xsl:template>
<xsl:template match="@*|node()" mode="copy">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="copy"/>
</xsl:copy>
</xsl:template>
<xsl:template match="foo" mode="copy">
<xsl:apply-templates select="$code" mode="el"/>
</xsl:template>
<xsl:template match="*" mode="el">
<xsl:element name="xsl:element">
<xsl:attribute name="name" select="name()"/>
<xsl:apply-templates select="@*|*|text()|comment()" mode="el"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*" mode="el">
<xsl:element name="xsl:attribute">
<xsl:attribute name="name" select="name()"/>
<xsl:attribute name="select">'<xsl:value-of
select="."/>'</xsl:attribute>
</xsl:element>
</xsl:template>
<xsl:template match="text()" mode="el">
<xsl:element name="xsl:text">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
<xsl:template match="comment()" mode="el">
<xsl:element name="xsl:comment">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Extension modifier
Un quine est dit polyglotte quand il est valide dans plusieurs langages simultanément. Différents exemples de tels quines sont disponibles dans les liens externes en bas de page.
Références modifier
- (en) Ken Thompson, « Reflections on Trusting Trust », Communications of the ACM, vol. 27, no 8, , p. 761-763 (DOI 10.1145/358198.358210).
- (en) Donald Knuth, « Computer Programming as an Art », Communications of the ACM, vol. 17, no 12, , p. 667-673 (DOI 10.1145/361604.361612).
- (en) Michael Sipser, Introduction to the Theory of Computation, Boston, Cengage Learning, , 3e éd., 504 p. (ISBN 978-1-133-18779-0, lire en ligne).
- (en) « Shortest Ruby Quine [closed] ».