Recipe

A recipe to create a self reproducing program

Actually, the recipe is to create a program that, when run, will produce a self reproducing version of itself.

Some definitions:

  • S0: the source of original program, for example the famous 'hello world' program (example in C++):
#include <iostream>
using namespace std;
int main()
{
   cout << "Hello world!" << endl;
   return 0;
}
  • S0m: the original program, that can run in three modes (see later), for example:
#include <iostream>
using namespace std;
int main(int argc, char*argv[])
{
   switch (atoi(argv[1]))
   {
      case(0): cout << "Hello world!" << endl; break;
      case(1): selfreplicate(0); break;
      case(2): selfreplicate(1); break;
      case(3): makeselfrep(); break;
      return 0;
   }
}
  • S1: the source of the program that will produce a self reproducing program. This program source is constructed from S0m by adding some code.
  • S2: the source of the self reproducing program. This program source is produced by compiling and running S1.

Choose a method to represent a program source

It is necessary to represent program source the one way or the other in your program. The program source will be read from file and has to be stored in a variable. In C++ we can choose to represent every line of the program source as a string, and put these strings in a vector or array. Another way would be to store the ASCII value of each character in an array.

Choose a suitable unique marker

We need to insert in the code somewhere an unique marker to separate the program source in to parts: A and B. Most conveniently is to choose a comment line with an unique text.

In the remainder of this text:

  • A: the representation of the program source until and including a marker
  • B: the representation of the rest of the program source
  • MARKER: the marker

Create function PRINT1

PRINT1 prints A or B to standard output in ASCII. In most cases, the definition of this function can be:

   PRINT1(x)

The output of PRINT1(), using C++, could be something like:

   #include <iostream>
   int main()
   ...
   ...

PRINT1() will be called with A or B as actual argument.

Create function PRINT2

PRINT2 must print instructions in the language of S0 to create A or B to standard output. In most cases,the definition of this function can be:

   PRINT2(name,x)

This function will be called as PRINT2('A',A) and PRINT2('B',B). Part of a typical output could be, using C++ and vector as representation::

   A.push_back("#include <iostream>");
   A.push_back("int main()");
   ...
   ...

Create function printselfrepprog

This function should look like this:

printselfrepprog(x,y,int mode)
{
   ... possibly some initialization code ...
   PRINT1(x)
   if(mode == 0)
   {
      PRINT2('A',x)
      PRINT2('B',y)
   }
   PRINT1(y)
}

Create function selfreplicate

This function should look like this:

selfreplicate(int mode)
{
   ... code to declare/define A and B ...
   MARKER
   printselfrepprog(A,B,mode)
}

Notes:

  • this function contains the marker.
  • this function will be called in S0m.

Create function makeselfrep

This function should look like this:

makeselfrep()
{
   ... code to declare/define A and B ...
   ... code to read a file (S1) until and including MARKER into A ...
   ... code to read the rest of the file into B ...

   printselfrepprog(A,B,0)
}

Notes:

  • this function will be called in S0m.
  • in general it is convenient to define one parameter for makeselfrep: the name of the file to be read.

Modify S0 to obtain S0m

The original program, S0, has to be modified into S0m, so that it can run in the following modes:

  1. normal mode: the program fullfills it's original task
  2. S2 producing mode: the program calls function selfreplicate(0)
  3. S1 producing mode: the program calls function selfreplicate(1)
  4. Create S2 from S1: the program calls function makeselfrep()

How to determine the desired mode, depends on the facilities of the language used and the way the S0 program is used. Probably the easiest way is to use an environment variable.

Putting it together

In most languages something like this will be possible to create S1 like this:

   define MARKER. (Note: take care that this line will
                   not be seen as MARKER by selfreplicate() )
   source code of PRINT1()
   source code of PRINT2()
   source code of printselfrepprog()
   source code of selfreplicate()
   source code of makeselfrep()
   S0m

Creating the self reproducing program

To create the self reproducing program:

  • compile and run S1, such that makeselfrep() is called, store the output in S2.
    • S1 has to be read by the program
  • compile and run S2 in one of these modes:
    • calling selfreplicate(0) to produce S2
    • calling selfreplicate(1) to produce S1
    • running to fullfill it's original task