Skip to content
Clifford Bohm edited this page Jul 27, 2017 · 15 revisions

Brains are provided with input values (continuous values delivered from a world) and then run some process to produce output values. There is no limit to the methods employed by the process. A simply brain, for example, could ignore inputs and simply deliver fixed output values. More complex brains may use memory, run internal simulations or execute complex logic. When a brain is constructed, it is passed a number of inputs and number of outputs, which is determined by the world in which the brain will run. A brain must have at least as many inputs and outputs as the world in which it will run.

Worlds / Brains

There is a wall between brains and worlds, such that, brains do not have information about the worlds they are running in. This separation is an important distinction as it ensures that any brain can be used in combination with world. It is possible to break this separation (some experiments need to) by use of dynamic type casting. Consider, for example, a world designed to test the effects of single gate knockouts on Markov Brains. Since not all brains have gates, and even other brains that have gates do not implement them in the same way, one must know that they are interacting with Markov Brains. These worlds should be written with checks to ensure that they fail gracefully (with a meaningful error) if there is a type mismatch.

Value Ranges

While inputs and output are continuous values, some brains or sub-brain units may work on inputs which are in a different range. For example, Deterministic Gates in Markov Brains only work with binary input. In these cases the continuous value is converted by some predetermined rule (e.g. the bit() operation converts any value greater then 0 to 1 and all other values to 0). This type of conversion allows elements that require different types of input to coexist.
It is worth noting at this point that some worlds may be written in such a way that they deliver or expect values which are not within the range of a given brain. For example, think of a world that generates a positive score when organisms successfully add two positive integers. If a brain were used in this adding world that can only receive and deliver bit values, the brain would run, but would not be able to score points!

Brain Types

Markov Brain
Markov Brain are collections of gates (which behave like mini-brains).
Wire Brain
Wire Brains are cellular automatons that approximate electrical current flowing though wires.
Human Brain
Human Brains ask a human for input. These can be very helpful when designing and debugging worlds.
Cartesian Genetic Programming Brain
CGPs define a list of equations (one for each output).
Iterated Prisoner's Dilemma Brains
A special purposed brain designed to be used with IPD World.
Genetic Programing Brain
A Direct encoded (no genome) brain which defines a tree based formula for each output.
Long Short-Term Memory Brain
An implimentation of the LSTM algorithm.

Using Brains

As an end user, using brains should be as simple as reading parameters descriptions from the settings files and then setting parameters.

If you are writing a world, you will need to be familiar with a few brain functions.

  • resetBrain() - clears any values set in a brain. Each brain defines it's own reset behavior. For example, in markov brains, the brain reset function also calls reset functions on each gate.
  • setInput(address, value) - sets an input, indexed by address, with value.
  • readOutput(address) - get the output value indexed by address.
  • update() - run the brains process.

Programming Brains

If you wish to write your own brain, you will need to be aware of a few more details.

  • Brain Construction - brain constructors are generally used to a) localize parameters, b) set up elements of brains (allocated space for memory, defining internal logic or wiring) and, c) set popFileColumns
  • description() - this is a function which returns a human readable description of a brain.
  • getStats() - is called when an organism is constructed to collect information about this brain which is integrated into the organism DataMap.
  • makeBrainFromGenome() - returns a (shared pointer to a) brain built from a given genome
  • initalizeGenome() - sometimes when you are building a brain from a genome, you will want to seed that brain with some data (i.e. in markov brains we seed the brain with gate start codons).
  • recordActivity - it may be useful to record activity from a brain so that it can be analyzed. Since you will not want to data to be recorded at all times and it is not known at construction, it does not make sense to use the standard DataMap methods to save this data. setRecordActivity() and setRecordFileName() allow you to determine whether to save this additional data and a filename in which to save the data.
Clone this wiki locally