In a previous post a short introduction was done on automatic program generation.

This exercise was initiated as a further exploration of the visualization of these generated processes.

Besides visually stimulating images it also gives an idea of how complexity grows as the number of instructions grows.

Methods

In a previous experiment it was described how a tool was developed that can automatically create simple programs and execute them. This tool can do so at run-time, so no compiling is needed. This resulted in a convenient way of iterating over all these programs.

The amount of programs takes a quick rise as the amount of instructions grow. The exact amount of such programs can be reviewed in the initial post on this topic. Jump operators, which allow changing the control flow(see JMP instruction in assembler), were intentionally left out in an attempt to reduce complexity.

To visualize the ins & outs of the auto-generated processes programs with 3 registers is considered. To color the image we are going over all x,y coordinates  and calculate a r,g,b values for each of these pixels.The program has 3 outgoing registers named r0, r1, r2.

This means random programs start with x,y, 0 in the r0, r1, r2 register, get executed and at the end the values of these registers are used as r,g,b to color the pixel.

 

r0 r1 r2
x y 0
r g b

The code can be found on github here:

https://github.com/denshade/CodeGeneration

The huge space of generated programs is examined by generating random programs and visually inspecting the result.

Results

Programs with a low instruction count usually express themselves as gradients which limit themselves at a 256×256 position.

2016-11-13 18_37_50-Message.png

The above picture is

[Sin r2].

As soon as #instructions goes up so does the complexity of the outcome.

2016-11-13 18_41_39-Message.png

The above picture is

[Cos r0, Sqrt r2, Div r0 -> r2, Mod r1 -> r2].

More complex patterns are showing.

Is there a limit to how far can be gone with creating complex images?  There will be faulty programs or programs that are show no patterns at all. These generate black images. The amount of black images boosts as the amount of instructions goes up.

But as complexity grows so does on occasion aesthetics. It is assumed here that what is found ‘beautiful’ depends on the simple grasp of what is a pattern and what is not. Too complex patterns cannot be detected by the human eye and are discarded as noise.

Here are a few interesting patterns that were found.

2016-11-13 11_24_54-program specifics.png

 

Space like patterns

2016-11-13 11_33_38-Message.png

 

 

2016-11-12 10_35_29-CodeGeneration - [C__Users_Lieven_Documents_GitHub_CodeGeneration] - [CodeGenera.png

Some look like what we sent Voyager Golden Record.

2016-11-12 10_28_47-CodeGeneration - [C__Users_Lieven_Documents_GitHub_CodeGeneration] - [CodeGenera.png

2016-11-13 11_42_09-Message.png

 

 

Here is a pattern that comes back a lot at a complexity of 10. What creates this pattern is still to be examined.

2016-11-12 08_06_18-program specifics.png

2016-11-12 08_13_56-program specifics.png

As things get more complicated they tend to look alien.

2016-11-13 19_03_35-Message.png

The above picture is rendered by

[Sqrt r2, Invert r0, Cos r1, Cos r1, Sqrt r2, Cos r1, Sin r0, Cos r0, Cos r0, 
Sin r2, Invert r2, Cos r1, Cos r2, Invert r0, Invert r2, Div r2 -> r1, 
Sub r0 -> r2, r0+= r2, Div r0 -> r2, Mul r1 -> r1, Mul r1 -> r0, Div r0 -> r2, 
Mul r0 -> r0, Mod r1 -> r0, Mod r1 -> r0, Mul r2 -> r2, Div r2 -> r2, 
Move r0 -> r2, Div r1 -> r1, Mod r2 -> r0, r0+= r0, r0+= r1, Div r1 -> r2,
 r1+= r0, Sub r0 -> r1, r0+= r2, Mul r2 -> r0, r1+= r1, Mul r0 -> r2, 
Move r0 -> r0, Mul r1 -> r0, Mod r2 -> r1, Div r2 -> r0, Mul r2 -> r1, 
Sub r1 -> r0, Sub r0 -> r0, r0+= r1, Mul r0 -> r1, r1+= r1, Sub r2 -> r2, 
Mod r1 -> r2]

Other complex programs can still demonstrate simple structures like very dark grey lines.

[Sin r0, Invert r1, Invert r2, Sin r1, Sqrt r1, Sin r2, Sin r2, Sin r0, Sin r2, 
Sin r1, Cos r1, Sqrt r2, Sqrt r2, Sin r2, Sin r0, Sin r1, Sin r1, Sqrt r2, 
Invert r1, Sin r2, Invert r1, Div r0 -> r2, Div r2 -> r0, Mul r1 -> r2, 
Mod r1 -> r2, Div r0 -> r0, Move r0 -> r2, Sub r0 -> r2, Div r0 -> r1, 
Sub r2 -> r0, Move r0 -> r2, r1+= r0, Sub r2 -> r1, Mod r0 -> r1, Sub r0 -> r2, 
Div r0 -> r0, Mod r1 -> r1, Mod r0 -> r1, Div r0 -> r1, Move r0 -> r2, 
Move r2 -> r2, r1+= r0, Sub r2 -> r1, Div r0 -> r0, Sub r0 -> r1, Div r1 -> r0, 
Move r2 -> r0, Move r1 -> r2, r0+= r2, Mul r2 -> r0, r1+= r1]

Conclusion

As the amount of programs grows so does complexity. Programs soon grow too complex to appreciate. The amount of black images also becomes bigger as the amount of instructions grows.

Complexity doesn’t imply usefulness because more programs .

Most complex programs have a small spectrum of values and are shown as nearly black images which isn’t very visually exciting.

Further investigation

A new converter can be implemented to reach for a bigger spectrum. By multiplying the r,g,b values with the 255/maximumValueOfChannel of the image new patterns may be discovered.

The reason why so many programs have black values needs further investigation.