anchor.diff:              lists:foreach(fun refit/1, Pop),
               ok
       end.
  +
  +
  +test() ->
  +    simulate_run((random_genotype_fn(nil))()).
  
positive.code: -module(cognitive).
  -import(genetica_utils, [clamp/3, rand_between/2]).
  -export([random_genotype_fn/1, phenotype_to_genotype_fn/1,
           genotype_to_phenotype_fn/1, fitness_fn/1, crossover_fn/1,
           mutation_fn/1, analyze_fn/2]).
  
  -record(ptype, {ref, gtype}).
  -record(vertex, {name, o = 0, y = 1, tau, sigma, gain}).
  -record(edge, {from, to, weight}).
  
  rand_node(Name) ->
      #vertex{name = Name, sigma = rand_between(-10, 0),
  
negative.code:             G
      end.
  
  
  %%% Fitness function stuff
  gen_fit(_G) ->
      rand_between(0, 100).
  
  new_block(Ets) ->
      ets:insert(Ets, #block{size = random:uniform(?BLOCK_MAX_SIZE),
                             x = random:uniform(?AREA_WIDTH),
                             y = ?AREA_HEIGHT}).
  
  %% Whether we can sense if we're at pos At, and the block is at spec. pos.
  senses(At, #block{size = S, x = X}) ->
      case At >= ?AREA_WIDTH of
          true -> At_m = At - ?AREA_WIDTH;
          false -> At_m = At
      end,
      Cmp =
          fun(A) when A >= ?AREA_WIDTH ->
                  A - ?AREA_WIDTH == At_m;
             (A) -> A == At_m
          end,
      lists:any(Cmp, lists:seq(X, X + S - 1)). %% - 1 to avoid blocksize+1
  
  sense(Ets) ->
      [Block] = ets:lookup(Ets, block),
      [{tpos, P}] = ets:lookup(Ets, tpos),
      ets:insert(Ets, {sensed, [senses(At, Block) ||
                                   At <- lists:seq(P,P + ?TRACKER_SIZE - 1)]}).
  
  %% Speed generated by a motor neuron
  speed(X) when 0.5 =< X, X < 0.9 -> 1;
  speed(X) when 0.9 =< X, X < 0.95 -> 2;
  speed(X) when 0.95 =< X -> 4;
  speed(_) -> 0.
  
  actuate(Ets) ->
      [{c, _, #vstate{o = C}}] = ets:lookup(Ets, c),
      [{d, _, #vstate{o = D}}] = ets:lookup(Ets, d),
      [{tpos, OldPos}] = ets:lookup(Ets, tpos),
      RawPos = OldPos + speed(D) - speed(C),
      if RawPos < 0 ->
              NewPos = RawPos + ?AREA_WIDTH;
         RawPos >= ?AREA_WIDTH ->
              NewPos = RawPos - ?AREA_WIDTH;
         true ->
              NewPos = RawPos
      end,
      ets:insert(Ets, {tpos, NewPos}).
  
  cognitive_step(_Ets) ->
      nil.
  
  move_block(_Ets) ->
      nil.
  
  step(Ets) ->
      sense(Ets),
      cognitive_step(Ets),
      actuate(Ets),
      move_block(Ets).
  
  simulate_run(G) ->
      io:format("whole:~n~p~n~n", [G]),
      Ets = ets:new(x, [set]),
      Firsts = lists:zip([#edge{from=F, to=T} || T <- [a, b],
                                                 F <- [1, 2, 3, 4, 5, a, b]],
                         lists:sublist(G, 2*7)),
      ets:insert(Ets, Firsts),
      io:format("first 14:~n~p~n~n", [Firsts]),
      OtherEdges = lists:zip([#edge{from=F, to=T} || T <- [c, d],
                                                     F <- [a, b, c, d]],
                             lists:sublist(G, 2*7 + 1, 2*4)),
      io:format("next 8:~n~p~n~n", [OtherEdges]),
      ets:insert(Ets, OtherEdges),
      Vertices = lists:sublist(G, 2*7 + 2*4 + 1, 4),
      io:format("and finally, vertices:~n~p~n~n", [Vertices]),
      ets:insert(Ets, [{Name, Vertex, #vstate{}} ||
                          Vertex = #vertex{name=Name} <- Vertices]),
      ets:insert(Ets, {tpos, 0}),
      ets:insert(Ets, {blocks_left, 39}),
      new_block(Ets),
      ets:insert(Ets, #block{size=6, x=27, y=15}),
      sense(Ets),
      All = ets:match_object(Ets, '_'),
      ets:delete(Ets),
      io:format("~P~n", [All, 100]).
  
  
  
  
  refit(#ptype{gtype = G, ref = Ref} = P) ->
      Fitness = gen_fit(G),
  