170 likes | 309 Views
Herbert G. Mayer, PSU CS Status 8/6/2013. CS 410 Mastery in Programming Chapter 9 Self-Reproducing Programs. Syllabus. Goal First Try Second Try Exercise 1 Third Try Success Exercise 2 More Complex Self-Reproducer Haskel Solution References. Goal.
E N D
Herbert G. Mayer, PSU CS Status 8/6/2013 CS 410Mastery in ProgrammingChapter 9Self-Reproducing Programs
Syllabus • Goal • First Try • Second Try • Exercise 1 • Third Try • Success • Exercise 2 • More Complex Self-Reproducer • Haskel Solution • References
Goal • Write a program p in C, C++, Python, Haskell, or Java that requires no input, but produces an output string o, with o being textually identical to the source program p!
First Try C Source Attempt 1, assuming C-flavor that does not require: #include <stdio.h> Program source: char*s="char*s=main(){printf(c);}";main(){printf(s);} Program Output: char*s=main(){printf(c);} Verdict: Goal obviously not accomplished!
Second Try C/C++ Source Attempt 2: main(){char*s="main(){char*s=%c%s%c";printf(s,34,s,34);} Program Output: main(){char*s="main(){char*s=%c%s%c" Verdict: Goal also not accomplished!
Exercise 1 Without reading ahead, students should try to design a self-reproducing program on their own The rules are: • Write a C, C++, . . . or Java program that reads no input and produces 1 output, which is identical to its own source • With zero compiler issues, i.e. also no warnings • Compiled best on 2 different compilers, for example: • For the first compiler use C++ • For the second use gcc • Best NOT to use 2 Microsoft or 2 GNU compilers! Coming from the same background, they may have identical, inherited flaws • The Unix diff command must find zero differences, no blanks, no \n, nothing to be flagged!! Total diff silence! Shorter is better, but there is no requirement to stay below a certain number of lines
Third Try • C/C++ Source Attempt 3: • main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34);";printf(s,34,s,34);} • Program Output: main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34);";printf(s,34,s,34); • Note: Warp-around is a pure PowerPoint issue; the line is one long single C source line • Verdict: Goal almost accomplished! Except missing ‘}’
Success at Try 4 Final Attempt: main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34);}";printf(s,34,s,34);} Program Output: main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34);}";printf(s,34,s,34);} Verdict: Finally accomplished! All 1 single line of C++ source
Exercise 2 • Students should replace the parameterized double quotes 34 “ with ‘\”’ • main(){char*s="main(){char*s=%c%s%c;printf(s,34,s,34);}";printf(s,34,s,34);}
More Complex Self-Reproducer • Build the following programs • part1.c is the core of a C program to become self-reproducing • chop.c chops an incoming source string to char constants of the kind ’x’, with the comma , • part2.c is a copy of part1.c but minus the first line, holding the C++ code char s[]={ • Next come initial source programs to create the self-replicator • Then I explain in detail, how to make part2.c
part1.c to be deleted for part2.c char s[]={ 0}; int main() { // main inti; printf("char s[]={\n"); for(i=0;s[i];i++){ if(i%20==0)printf("\n"); switch(s[i]){ case'\'':printf("'\\\'',");break; case'\n':printf("'\\n',");break; case'\\':printf("'\\\\',");break; default:printf("'%c',",s[i]); } } printf("%s",s); }
chop.c #include <stdio.h> int main() { // main char c; int count = 0; while( ( c = getchar() ) != EOF ) { if( 0 == ( count % 20 ) ) { printf( "\n" ); } //end if switch ( c ){ case '\'': printf( "'\\\''," ); break; case '\n': printf( "'\\n'," ); break; case '\\': printf( "'\\\\'," ); break; default: printf( "'%c',", c ); } //end switch count++; } //end while } //end main
part1.c Chopped, not line 1 • '0','}',';','\n','i','n','t',' ','m','a','i','n','(',')','\n','{',' ','/','/',' ', • 'm','a','i','n','\n',' ',' ','i','n','t',' ','i',';','\n',' ',' ','p','r','i','n', • 't','f','(','"','c','h','a','r',' ','s','[',']','=','{','\\','n','"',')',';','\n', • ' ',' ','f','o','r','(','i','=','0',';','s','[','i',']',';','i','+','+',')','{', • '\n',' ',' ',' ',' ','i','f','(','i','%','2','0','=','=','0',')','p','r','i','n', • 't','f','(','"','\\','n','"',')',';','\n',' ',' ',' ',' ','s','w','i','t','c','h', • '(','s','[','i',']',')','{','\n',' ',' ',' ',' ',' ',' ','c','a','s','e','\'','\\', • '\'','\'',':','p','r','i','n','t','f','(','"','\'','\\','\\',’\'\'','\'',',','"',')', • ';','b','r','e','a','k',';','\n',' ',' ',' ',' ',' ',' ','c','a','s','e','\'','\\', • 'n','\'',':','p','r','i','n','t','f','(','"','\'','\\','\\','n','\'',',','"',')',';', • 'b','r','e','a','k',';','\n',' ',' ',' ',' ',' ',' ','c','a','s','e','\'','\\','\\', • '\'',':','p','r','i','n','t','f','(','"','\'','\\','\\','\\',’\,'\'',',','"',')',';', • 'b','r','e','a','k',';','\n',' ',' ',' ',' ',' ',' ','d','e','f','a','u','l','t', • ':','p','r','i','n','t','f','(','"','\'','%','c','\'',',','"',',','s','[','i',']', • ')',';','\n',' ',' ',' ',' ','}','\n',' ',' ','}','\n',' ',' ','p','r','i','n','t', • 'f','(','"','%','s','"',',','s',')',';','\n','}','\n', add 0}; here
Detailed Instructions Create part1.c Compile and run for kicks. Output: char s[]={ cp part1.ctemp1, delete first line, which is char s[]={ Run chop.o < temp1 > temp2 cp part1.c part2.c Insert temp2 into the part2.c char array s[] At end of char array in part2.c: move 0}; to end of previous line, i.e. exchange the place of the \n In part2.c to avoid duplication, delete the original line 0}; Now compile part2.c and run part2.o > output diff output part2.c is null
part2.c • char s[]={ • '0','}',';','\n','i','n','t',' ','m','a','i','n','(',')','\n','{',' ','/','/',' ', • 'm','a','i','n','\n',' ',' ','i','n','t',' ','i',';','\n',' ',' ','p','r','i','n', • 't','f','(','"','c','h','a','r',' ','s','[',']','=','{','\\','n','"',')',';','\n', • ' ',' ','f','o','r','(','i','=','0',';','s','[','i',']',';','i','+','+',')','{', • '\n',' ',' ',' ',' ','i','f','(','i','%','2','0','=','=','0',')','p','r','i','n', • 't','f','(','"','\\','n','"',')',';','\n',' ',' ',' ',' ','s','w','i','t','c','h', • '(','s','[','i',']',')','{','\n',' ',' ',' ',' ',' ',' ','c','a','s','e','\'','\\', • '\'','\'',':','p','r','i','n','t','f','(','"','\'','\\','\\','\\','\'','\'',',','"',')', • ';','b','r','e','a','k',';','\n',' ',' ',' ',' ',' ',' ','c','a','s','e','\'','\\', • 'n','\'',':','p','r','i','n','t','f','(','"','\'','\\','\\','n','\'',',','"',')',';', • 'b','r','e','a','k',';','\n',' ',' ',' ',' ',' ',' ','c','a','s','e','\'','\\','\\', • '\'',':','p','r','i','n','t','f','(','"','\'','\\','\\','\\','\\','\'',',','"',')',';', • 'b','r','e','a','k',';','\n',' ',' ',' ',' ',' ',' ','d','e','f','a','u','l','t', • ':','p','r','i','n','t','f','(','"','\'','%','c','\'',',','"',',','s','[','i',']', • ')',';','\n',' ',' ',' ',' ','}','\n',' ',' ','}','\n',' ',' ','p','r','i','n','t', • 'f','(','"','%','s','"',',','s',')',';','\n','}','\n',0}; • int main() • { // main • int i; • printf("char s[]={\n"); • for(i=0;s[i];i++){ • if(i%20==0)printf("\n"); • switch(s[i]){ • case'\'':printf("'\\\'',");break; • case'\n':printf("'\\n',");break; • case'\\':printf("'\\\\',");break; • default:printf("'%c',",s[i]); • } • } • printf("%s",s); • }
Haskell Solution During the summer 2012 course of CS 510 a student provided the following complete solution in Haskell: main = putStr s >> print s s = "main = putStr s >> print s\ns = "
References • Quine Page for Self-Producing Programs: http://www.nyx.net/~gthompso/quine.htm • Wiki Page for quine program: http://en.wikipedia.org/wiki/Quine_(computing) • Quine’s Paradox: http://en.wikipedia.org/wiki/Quine%27s_paradox • Ken Thompson’s “Reflections on Trust”: http://cm.bell-labs.com/who/ken/trust.html