[Avida-cvs] [avida-svn] r616 - in development: Avida.xcodeproj source/cpu

brysonda@myxo.css.msu.edu brysonda at myxo.css.msu.edu
Fri Apr 14 11:17:00 PDT 2006


Author: brysonda
Date: 2006-04-14 14:17:00 -0400 (Fri, 14 Apr 2006)
New Revision: 616

Modified:
   development/Avida.xcodeproj/project.pbxproj
   development/source/cpu/cHardware4Stack.cc
   development/source/cpu/cHardware4Stack.h
   development/source/cpu/cHardwareBase.cc
   development/source/cpu/cHardwareBase.h
   development/source/cpu/cHardwareCPU.cc
   development/source/cpu/cHardwareCPU.h
   development/source/cpu/cHardwareSMT.cc
   development/source/cpu/cHardwareSMT.h
Log:
Move various instances of duplicate hardware functionality into cHardwareBase.

Modified: development/Avida.xcodeproj/project.pbxproj
===================================================================
--- development/Avida.xcodeproj/project.pbxproj	2006-04-14 17:24:47 UTC (rev 615)
+++ development/Avida.xcodeproj/project.pbxproj	2006-04-14 18:17:00 UTC (rev 616)
@@ -40,6 +40,17 @@
 		702F52AA0992F8F600B2B507 /* cSymbolTable.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702F52A80992F8F600B2B507 /* cSymbolTable.cc */; };
 		702F52E10992FD8000B2B507 /* cScriptObject.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702F52DF0992FD8000B2B507 /* cScriptObject.cc */; };
 		702F532F0993060A00B2B507 /* avida-s in CopyFiles */ = {isa = PBXBuildFile; fileRef = 70DCAD1C097AF7CC002F8733 /* avida-s */; };
+		7039884C09F00CFE0052ACE7 /* avida-smt.cfg in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2D409EE8501001AEA89 /* avida-smt.cfg */; };
+		7039884D09F00D020052ACE7 /* analyze.cfg in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2D309EE8501001AEA89 /* analyze.cfg */; };
+		7039884E09F00D030052ACE7 /* avida.cfg in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2D509EE8501001AEA89 /* avida.cfg */; };
+		7039884F09F00D060052ACE7 /* environment.cfg in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2D709EE8501001AEA89 /* environment.cfg */; };
+		7039885009F00D080052ACE7 /* events.cfg in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2D809EE8501001AEA89 /* events.cfg */; };
+		7039885109F00D0D0052ACE7 /* inst_set.smt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2DC09EE8501001AEA89 /* inst_set.smt */; };
+		7039885209F00D0D0052ACE7 /* inst_set.sex in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2DB09EE8501001AEA89 /* inst_set.sex */; };
+		7039885309F00D0F0052ACE7 /* inst_set.default in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2DA09EE8501001AEA89 /* inst_set.default */; };
+		7039885409F00D150052ACE7 /* organism.default in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2F609EE8501001AEA89 /* organism.default */; };
+		7039885509F00D190052ACE7 /* organism.sex in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2F709EE8501001AEA89 /* organism.sex */; };
+		7039885609F00D1A0052ACE7 /* organism.smt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2F809EE8501001AEA89 /* organism.smt */; };
 		7040CF1C0906A52E00AA820F /* cEventManager.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7040CF1A0906A52E00AA820F /* cEventManager.cc */; };
 		7040CF1E0906A52E00AA820F /* cEventManager.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7040CF1A0906A52E00AA820F /* cEventManager.cc */; };
 		7040D3A6090964D100AA820F /* cMxCodeArray.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70B0865808F4974300FC65FE /* cMxCodeArray.cc */; };
@@ -444,6 +455,17 @@
 			dstSubfolderSpec = 16;
 			files = (
 				700E2996085A1F6000CF158A /* avida in CopyFiles */,
+				7039884C09F00CFE0052ACE7 /* avida-smt.cfg in CopyFiles */,
+				7039884D09F00D020052ACE7 /* analyze.cfg in CopyFiles */,
+				7039884E09F00D030052ACE7 /* avida.cfg in CopyFiles */,
+				7039884F09F00D060052ACE7 /* environment.cfg in CopyFiles */,
+				7039885009F00D080052ACE7 /* events.cfg in CopyFiles */,
+				7039885109F00D0D0052ACE7 /* inst_set.smt in CopyFiles */,
+				7039885209F00D0D0052ACE7 /* inst_set.sex in CopyFiles */,
+				7039885309F00D0F0052ACE7 /* inst_set.default in CopyFiles */,
+				7039885409F00D150052ACE7 /* organism.default in CopyFiles */,
+				7039885509F00D190052ACE7 /* organism.sex in CopyFiles */,
+				7039885609F00D1A0052ACE7 /* organism.smt in CopyFiles */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2383,7 +2405,6 @@
 					"-Wno-four-char-constants",
 					"-Wno-unknown-pragmas",
 				);
-				ZERO_LINK = YES;
 			};
 			name = Development;
 		};

Modified: development/source/cpu/cHardware4Stack.cc
===================================================================
--- development/source/cpu/cHardware4Stack.cc	2006-04-14 17:24:47 UTC (rev 615)
+++ development/source/cpu/cHardware4Stack.cc	2006-04-14 18:17:00 UTC (rev 616)
@@ -844,13 +844,13 @@
   // Make sure the creature will still be above the minimum size,
   // TEMPORARY!  INJECTED CODE CAN 
   if (end_pos <= 0) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
+    organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
     return false; // (inject fails)
   }
   
   if (end_pos < MIN_INJECT_SIZE) {
     GetMemory(mem_space_used)=cGenome(ConvertToInstruction(mem_space_used)); 
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
+    organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
     return false; // (inject fails)
   }
   
@@ -962,171 +962,7 @@
   return true; // (inject succeeds!)
 }
 
-void cHardware4Stack::Mutate(cAvidaContext& ctx, int mut_point)
-{
-  // Test if trying to mutate outside of genome...
-  assert(mut_point >= 0 && mut_point < GetMemory(0).GetSize());
-  
-  GetMemory(0)[mut_point] = m_inst_set->GetRandomInst(ctx);
-  GetMemory(0).SetFlagMutated(mut_point);
-  GetMemory(0).SetFlagPointMut(mut_point);
-  //organism->GetPhenotype().IsMutated() = true;
-  organism->CPUStats().mut_stats.point_mut_count++;
-}
 
-int cHardware4Stack::PointMutate(cAvidaContext& ctx, const double mut_rate)
-{
-  const int num_muts =
-  ctx.GetRandom().GetRandBinomial(GetMemory(0).GetSize(), mut_rate);
-  
-  for (int i = 0; i < num_muts; i++) {
-    const int pos = ctx.GetRandom().GetUInt(GetMemory(0).GetSize());
-    Mutate(ctx, pos);
-  }
-  
-  return num_muts;
-}
-
-
-// Trigger mutations of a specific type.  Outside triggers cannot specify
-// a head since hardware types are not known.
-
-bool cHardware4Stack::TriggerMutations(cAvidaContext& ctx, int trigger)
-{
-  // Only update triggers should happen from the outside!
-  assert(trigger == nMutation::TRIGGER_UPDATE);
-  
-  // Assume instruction pointer is the intended target (if one is even
-  // needed!
-  
-  return TriggerMutations(ctx, trigger, IP());
-}
-
-bool cHardware4Stack::TriggerMutations(cAvidaContext& ctx, int trigger, cHeadCPU& cur_head)
-{
-  // Collect information about mutations from the organism.
-  cLocalMutations & mut_info = organism->GetLocalMutations();
-  const tList<cMutation> & mut_list =
-    mut_info.GetMutationLib().GetMutationList(trigger);
-  
-  // If we have no mutations for this trigger, stop here.
-  if (mut_list.GetSize() == 0) return false;
-  bool has_mutation = false;
-  
-  // Determine what memory this mutation will be affecting.
-  cCPUMemory & target_mem = (trigger == nMutation::TRIGGER_DIVIDE) 
-    ? organism->ChildGenome() : GetMemory(0);
-  
-  // Loop through all mutations associated with this trigger and test them.
-  tConstListIterator<cMutation> mut_it(mut_list);
-  
-  while (mut_it.Next() != NULL) {
-    const cMutation * cur_mut = mut_it.Get();
-    const int mut_id = cur_mut->GetID();
-    const int scope = cur_mut->GetScope();
-    const double rate = mut_info.GetRate(mut_id);
-    switch (scope) {
-      case nMutation::SCOPE_GENOME:
-        if (TriggerMutations_ScopeGenome(ctx, cur_mut, target_mem, cur_head, rate)) {
-          has_mutation = true;
-          mut_info.IncCount(mut_id);
-        }
-        break;
-      case nMutation::SCOPE_LOCAL:
-      case nMutation::SCOPE_PROP:
-        if (TriggerMutations_ScopeLocal(ctx, cur_mut, target_mem, cur_head, rate)) {
-          has_mutation = true;
-          mut_info.IncCount(mut_id);
-        }
-        break;
-      case nMutation::SCOPE_GLOBAL:
-      case nMutation::SCOPE_SPREAD:
-        int num_muts =
-        TriggerMutations_ScopeGlobal(ctx, cur_mut, target_mem, cur_head, rate);
-        if (num_muts > 0) {
-          has_mutation = true;
-          mut_info.IncCount(mut_id, num_muts);
-        }
-          break;
-    }
-  }
-  
-  return has_mutation;
-}
-
-bool cHardware4Stack::TriggerMutations_ScopeGenome(cAvidaContext& ctx, const cMutation* cur_mut,
-                                                   cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate)
-{
-  // The rate we have stored indicates the probability that a single
-  // mutation will occur anywhere in the genome.
-  
-  if (ctx.GetRandom().P(rate) == true) {
-    // We must create a temporary head and use it to randomly determine the
-    // position in the genome to be mutated.
-    cHeadCPU tmp_head(cur_head);
-    tmp_head.AbsSet(ctx.GetRandom().GetUInt(target_memory.GetSize()));
-    TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, tmp_head);
-    return true;
-  }
-  return false;
-}
-
-bool cHardware4Stack::TriggerMutations_ScopeLocal(cAvidaContext& ctx, const cMutation* cur_mut,
-                                                  cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate)
-{
-  // The rate we have stored is the probability for a mutation at this single
-  // position in the genome.
-  
-  if (ctx.GetRandom().P(rate) == true) {
-    TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, cur_head);
-    return true;
-  }
-  return false;
-}
-
-int cHardware4Stack::TriggerMutations_ScopeGlobal(cAvidaContext& ctx, const cMutation* cur_mut,
-                                                  cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate)
-{
-  // The probability we have stored is per-site, so we can pull a random
-  // number from a binomial distribution to determine the number of mutations
-  // that should occur.
-  
-  const int num_mut =
-  ctx.GetRandom().GetRandBinomial(target_memory.GetSize(), rate);
-  
-  if (num_mut > 0) {
-    for (int i = 0; i < num_mut; i++) {
-      cHeadCPU tmp_head(cur_head);
-      tmp_head.AbsSet(ctx.GetRandom().GetUInt(target_memory.GetSize()));
-      TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, tmp_head);
-    }
-  }
-  
-  return num_mut;
-}
-
-void cHardware4Stack::TriggerMutations_Body(cAvidaContext& ctx, int type,
-                                            cCPUMemory& target_memory, cHeadCPU& cur_head)
-{
-  const int pos = cur_head.GetPosition();
-  
-  switch (type) {
-    case nMutation::TYPE_POINT:
-      target_memory[pos] = m_inst_set->GetRandomInst(ctx);
-      target_memory.SetFlagMutated(pos);
-      break;
-    case nMutation::TYPE_INSERT:
-    case nMutation::TYPE_DELETE:
-    case nMutation::TYPE_HEAD_INC:
-    case nMutation::TYPE_HEAD_DEC:
-    case nMutation::TYPE_TEMP:
-    case nMutation::TYPE_KILL:
-    default:
-      m_world->GetDriver().RaiseException("Mutation type not implemented!");
-      break;
-  };
-}
-
 void cHardware4Stack::ReadInst(const int in_inst)
 {
   if (m_inst_set->IsNop( cInstruction(in_inst) )) {
@@ -1254,178 +1090,16 @@
   return comp_stack%nHardware4Stack::NUM_STACKS;
 }
 
-inline void cHardware4Stack::Fault(int fault_loc, int fault_type, cString fault_desc)
+int cHardware4Stack::GetCopiedSize(const int parent_size, const int child_size)
 {
-  organism->Fault(fault_loc, fault_type, fault_desc);
-}
-
-bool cHardware4Stack::Divide_CheckViable(cAvidaContext& ctx, const int parent_size,
-                                         const int child_size, const int mem_space)
-{
-  // Make sure the organism is okay with dividing now...
-  if (organism->Divide_CheckViable() == false) return false; // (divide fails)
-  
-  // Make sure that neither parent nor child will be below the minimum size.
-  
-  const int genome_size = organism->GetGenome().GetSize();
-  const double size_range = m_world->GetConfig().CHILD_SIZE_RANGE.Get();
-  const int min_size = Max(MIN_CREATURE_SIZE, (int) (genome_size/size_range));
-  const int max_size = Min(MAX_CREATURE_SIZE, (int) (genome_size*size_range));
-  
-  if (child_size < min_size || child_size > max_size) {
-    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-          cStringUtil::Stringf("Invalid offspring length (%d)", child_size));
-    return false; // (divide fails)
-  }
-  
-  // Count the number of lines executed in the parent, and make sure the
-  // specified fraction has been reached.
-  
-  int executed_size = 0;
-  for (int i = 0; i < parent_size; i++) {
-    if (GetMemory(0).FlagExecuted(i)) executed_size++;
-  }
-  
-  const int min_exe_lines = (int) (parent_size * m_world->GetConfig().MIN_EXE_LINES.Get());
-  if (executed_size < min_exe_lines) {
-    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-          cStringUtil::Stringf("Too few executed lines (%d < %d)",
-                               executed_size, min_exe_lines));
-    return false; // (divide fails)
-  }
-	
-  // Count the number of lines which were copied into the child, and make
-  // sure the specified fraction has been reached.
-  
   int copied_size = 0;
-  for (int i = 0; i < GetMemory(mem_space).GetSize(); i++) {
-    if (GetMemory(mem_space).FlagCopied(i)) copied_size++;
-  }
-  
-  const int min_copied =  (int) (child_size * m_world->GetConfig().MIN_COPIED_LINES.Get());
-  if (copied_size < min_copied) {
-    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-          cStringUtil::Stringf("Too few copied commands (%d < %d)",
-                               copied_size, min_copied));
-    return false; // (divide fails)
-  }
-  
-  // Save the information we collected here...
-  organism->GetPhenotype().SetLinesExecuted(executed_size);
-  organism->GetPhenotype().SetLinesCopied(copied_size);
-  
-  return true; // (divide succeeds!)
+  const cCPUMemory& memory = GetMemory(m_cur_child);
+  for (int i = 0; i < memory.GetSize(); i++) {
+    if (memory.FlagCopied(i)) copied_size++;
+	}
+  return copied_size;
 }
 
-void cHardware4Stack::Divide_DoMutations(cAvidaContext& ctx, double mut_multiplier)
-{
-  sCPUStats & cpu_stats = organism->CPUStats();
-  cCPUMemory & child_genome = organism->ChildGenome();
-  
-  organism->GetPhenotype().SetDivType(mut_multiplier);
-  
-  // Divide Mutations
-  if (organism->TestDivideMut(ctx)) {
-    const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize());
-    child_genome[mut_line] = m_inst_set->GetRandomInst(ctx);
-    cpu_stats.mut_stats.divide_mut_count++;
-  }
-  
-  // Divide Insertions
-  if (organism->TestDivideIns(ctx) && child_genome.GetSize() < MAX_CREATURE_SIZE){
-    const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize() + 1);
-    child_genome.Insert(mut_line, m_inst_set->GetRandomInst(ctx));
-    cpu_stats.mut_stats.divide_insert_mut_count++;
-  }
-  
-  // Divide Deletions
-  if (organism->TestDivideDel(ctx) && child_genome.GetSize() > MIN_CREATURE_SIZE){
-    const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize());
-    child_genome.Remove(mut_line);
-    cpu_stats.mut_stats.divide_delete_mut_count++;
-  }
-  
-  // Divide Mutations (per site)
-  if(organism->GetDivMutProb() > 0){
-    int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(), 
-                                                       organism->GetDivMutProb() / mut_multiplier);
-    // If we have lines to mutate...
-    if( num_mut > 0 ){
-      for (int i = 0; i < num_mut; i++) {
-        int site = ctx.GetRandom().GetUInt(child_genome.GetSize());
-        child_genome[site] = m_inst_set->GetRandomInst(ctx);
-        cpu_stats.mut_stats.div_mut_count++;
-      }
-    }
-  }
-  
-  
-  // Insert Mutations (per site)
-  if(organism->GetInsMutProb() > 0){
-    int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(),
-                                                       organism->GetInsMutProb());
-    // If would make creature to big, insert up to MAX_CREATURE_SIZE
-    if( num_mut + child_genome.GetSize() > MAX_CREATURE_SIZE ){
-      num_mut = MAX_CREATURE_SIZE - child_genome.GetSize();
-    }
-    // If we have lines to insert...
-    if( num_mut > 0 ){
-      // Build a list of the sites where mutations occured
-      static int mut_sites[MAX_CREATURE_SIZE];
-      for (int i = 0; i < num_mut; i++) {
-        mut_sites[i] = ctx.GetRandom().GetUInt(child_genome.GetSize() + 1);
-      }
-      // Sort the list
-      qsort( (void*)mut_sites, num_mut, sizeof(int), &IntCompareFunction );
-      // Actually do the mutations (in reverse sort order)
-      for(int i = num_mut-1; i >= 0; i--) {
-        child_genome.Insert(mut_sites[i], m_inst_set->GetRandomInst(ctx));
-        cpu_stats.mut_stats.insert_mut_count++;
-      }
-    }
-  }
-  
-  
-  // Delete Mutations (per site)
-  if( organism->GetDelMutProb() > 0 ){
-    int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(),
-                                                       organism->GetDelMutProb());
-    // If would make creature too small, delete down to MIN_CREATURE_SIZE
-    if (child_genome.GetSize() - num_mut < MIN_CREATURE_SIZE) {
-      num_mut = child_genome.GetSize() - MIN_CREATURE_SIZE;
-    }
-    
-    // If we have lines to delete...
-    for (int i = 0; i < num_mut; i++) {
-      int site = ctx.GetRandom().GetUInt(child_genome.GetSize());
-      child_genome.Remove(site);
-      cpu_stats.mut_stats.delete_mut_count++;
-    }
-  }
-  
-  // Mutations in the parent's genome
-  if (organism->GetParentMutProb() > 0) {
-    for (int i = 0; i < GetMemory(0).GetSize(); i++) {
-      if (organism->TestParentMut(ctx)) {
-        GetMemory(0)[i] = m_inst_set->GetRandomInst(ctx);
-        cpu_stats.mut_stats.parent_mut_line_count++;
-      }
-    }
-  }
-  
-  
-  // Count up mutated lines
-  for(int i = 0; i < GetMemory(0).GetSize(); i++){
-    if (GetMemory(0).FlagPointMut(i)) {
-      cpu_stats.mut_stats.point_mut_line_count++;
-    }
-  }
-  for(int i = 0; i < child_genome.GetSize(); i++){
-    if( child_genome.FlagCopyMut(i)) {
-      cpu_stats.mut_stats.copy_mut_line_count++;
-    }
-  }
-}
 
 void cHardware4Stack::Inject_DoMutations(cAvidaContext& ctx, double mut_multiplier, cCPUMemory & injected_code)
 {
@@ -1526,68 +1200,6 @@
 }
 
 
-// test whether the offspring creature contains an advantageous mutation.
-void cHardware4Stack::Divide_TestFitnessMeasures(cAvidaContext& ctx)
-{
-  cPhenotype & phenotype = organism->GetPhenotype();
-  phenotype.CopyTrue() = ( organism->ChildGenome() == organism->GetGenome() );
-  phenotype.ChildFertile() = true;
-  
-  // Only continue if we're supposed to do a fitness test on divide...
-  if (organism->GetTestOnDivide() == false) return;
-  
-  // If this was a perfect copy, then we don't need to worry about any other
-  // tests...  Theoretically, we need to worry about the parent changing,
-  // but as long as the child is always compared to the original genotype,
-  // this won't be an issue.
-  if (phenotype.CopyTrue() == true) return;
-  
-  const double parent_fitness = organism->GetTestFitness();
-  const double neut_min = parent_fitness * nHardware::FITNESS_NEUTRAL_MIN;
-  const double neut_max = parent_fitness * nHardware::FITNESS_NEUTRAL_MAX;
-  
-  cTestCPU* testcpu = m_world->GetHardwareManager().CreateTestCPU();
-  cCPUTestInfo test_info;
-  test_info.UseRandomInputs();
-  testcpu->TestGenome(ctx, test_info, organism->ChildGenome());
-  const double child_fitness = test_info.GetGenotypeFitness();
-  delete testcpu;
-  
-  bool revert = false;
-  bool sterilize = false;
-  
-  // If implicit mutations are turned off, make sure this won't spawn one.
-  if (organism->GetFailImplicit() == true) {
-    if (test_info.GetMaxDepth() > 0) sterilize = true;
-  }
-  
-  if (child_fitness == 0.0) {
-    // Fatal mutation... test for reversion.
-    if (ctx.GetRandom().P(organism->GetRevertFatal())) revert = true;
-    if (ctx.GetRandom().P(organism->GetSterilizeFatal())) sterilize = true;
-  } else if (child_fitness < neut_min) {
-    if (ctx.GetRandom().P(organism->GetRevertNeg())) revert = true;
-    if (ctx.GetRandom().P(organism->GetSterilizeNeg())) sterilize = true;
-  } else if (child_fitness <= neut_max) {
-    if (ctx.GetRandom().P(organism->GetRevertNeut())) revert = true;
-    if (ctx.GetRandom().P(organism->GetSterilizeNeut())) sterilize = true;
-  } else {
-    if (ctx.GetRandom().P(organism->GetRevertPos())) revert = true;
-    if (ctx.GetRandom().P(organism->GetSterilizePos())) sterilize = true;
-  }
-  
-  // Ideally, we won't have reversions and sterilizations turned on at the
-  // same time, but if we do, give revert the priority.
-  if (revert == true) {
-    organism->ChildGenome() = organism->GetGenome();
-  }
-  
-  if (sterilize == true) {
-    organism->GetPhenotype().ChildFertile() = false;
-  }
-}
-
-
 bool cHardware4Stack::Divide_Main(cAvidaContext& ctx, int mem_space_used, double mut_multiplier)
 {
   int write_head_pos = GetHead(nHardware::HEAD_WRITE).GetPosition();
@@ -1598,8 +1210,8 @@
     return false;
   
   // Make sure this divide will produce a viable offspring.
-  if(!Divide_CheckViable(ctx, GetMemory(IP().GetMemSpace()).GetSize(), 
-                         write_head_pos, mem_space_used)) 
+  m_cur_child = mem_space_used;
+  if(!Divide_CheckViable(ctx, GetMemory(IP().GetMemSpace()).GetSize(), write_head_pos)) 
     return false;
   
   // Since the divide will now succeed, set up the information to be sent
@@ -1740,11 +1352,11 @@
   const int stack_used = FindModifiedStack(nHardware4Stack::STACK_BX);
   if (Stack(nHardware4Stack::STACK_CX).Top() != 0) {
     if (0-INT_MAX > Stack(nHardware4Stack::STACK_BX).Top() && Stack(nHardware4Stack::STACK_CX).Top() == -1)
-      Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: Float exception");
+      organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: Float exception");
     else
       Stack(stack_used).Push(Stack(nHardware4Stack::STACK_BX).Top() / Stack(nHardware4Stack::STACK_CX).Top());
   } else {
-    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: dividing by 0");
+    organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: dividing by 0");
     return false;
   }
   return true;
@@ -2005,7 +1617,7 @@
 bool cHardware4Stack::Inst_ForkThread(cAvidaContext& ctx)
 {
   if (!ForkThread()) 
-    Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
+    organism->Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
   else
     IP().Advance();
   return true;
@@ -2048,7 +1660,7 @@
     else
       Stack(stack_used).Push(Stack(nHardware4Stack::STACK_BX).Top() % Stack(nHardware4Stack::STACK_CX).Top());
   } else {
-    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "mod: modding by 0");
+    organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "mod: modding by 0");
     return false;
   }
   return true;
@@ -2057,7 +1669,7 @@
 //35
 bool cHardware4Stack::Inst_KillThread(cAvidaContext& ctx)
 {
-  if (!KillThread()) Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);
+  if (!KillThread()) organism->Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);
   else AdvanceIP() = false;
   return true;
 }

Modified: development/source/cpu/cHardware4Stack.h
===================================================================
--- development/source/cpu/cHardware4Stack.h	2006-04-14 17:24:47 UTC (rev 615)
+++ development/source/cpu/cHardware4Stack.h	2006-04-14 18:17:00 UTC (rev 616)
@@ -67,7 +67,7 @@
 {
 public:
   typedef bool (cHardware4Stack::*tHardware4StackMethod)(cAvidaContext& ctx);
-private:
+protected:
   static cInstLib4Stack* s_inst_slib;
   static cInstLib4Stack* initInstLib(void);
   
@@ -95,6 +95,8 @@
 
   // Keeps track of fractional instructions that carry over into next update
   float inst_remainder; 
+  
+  int m_cur_child;
 
   
   bool SingleProcess_PayCosts(cAvidaContext& ctx, const cInstruction & cur_inst);
@@ -124,32 +126,21 @@
   cCodeLabel & GetReadLabel() { return threads[cur_thread].read_label; }
   
 
-  bool TriggerMutations_ScopeGenome(cAvidaContext& ctx, const cMutation* cur_mut, cCPUMemory& target_memory,
-                                    cHeadCPU& cur_head, const double rate);
-  bool TriggerMutations_ScopeLocal(cAvidaContext& ctx, const cMutation* cur_mut, cCPUMemory& target_memory,
-                                   cHeadCPU& cur_head, const double rate);
-  int TriggerMutations_ScopeGlobal(cAvidaContext& ctx, const cMutation* cur_mut, cCPUMemory& target_memory,
-                                   cHeadCPU& cur_head, const double rate);
-  void TriggerMutations_Body(cAvidaContext& ctx, int type, cCPUMemory & target_memory, cHeadCPU& cur_head);
-
   // ---------- Instruction Helpers -----------
   int FindModifiedStack(int default_stack);
   int FindModifiedHead(int default_head);
   int FindComplementStack(int base_stack);
   
-  void Fault(int fault_loc, int fault_type, cString fault_desc=""); 
   bool Allocate_Necro(const int new_size);
   bool Allocate_Random(const int old_size, const int new_size);
   bool Allocate_Default(const int new_size);
   bool Allocate_Main(const int allocated_size);
   
-  bool Divide_Main(cAvidaContext& ctx, const int mem_space_used, double mut_multiplier=1);
-  bool Divide_CheckViable(cAvidaContext& ctx, const int parent_size, const int child_size, const int mem_space);
-  void Divide_DoMutations(cAvidaContext& ctx, double mut_multiplier = 1);
-  void Inject_DoMutations(cAvidaContext& ctx, double mut_multiplier, cCPUMemory & injected_code);
-  void Divide_TestFitnessMeasures(cAvidaContext& ctx);
-  void Mutate(cAvidaContext& ctx, const int mut_point);
+  int GetCopiedSize(const int parent_size, const int child_size);
   
+  bool Divide_Main(cAvidaContext& ctx, const int mem_space_used, double mut_multiplier = 1.0);
+  void Inject_DoMutations(cAvidaContext& ctx, double mut_multiplier, cCPUMemory& injected_code);
+  
   bool HeadCopy_ErrorCorrect(double reduction);
 
   bool InjectParasite(cAvidaContext& ctx, double mut_multiplier);
@@ -241,12 +232,6 @@
   }
 	
   
-  // --------  Mutation  --------
-  int PointMutate(cAvidaContext& ctx, const double mut_rate);  
-  bool TriggerMutations(cAvidaContext& ctx, int trigger);
-  bool TriggerMutations(cAvidaContext& ctx, int trigger, cHeadCPU& cur_head);
-  
-
 private:
   // ---------- Instruction Library -----------
   bool Inst_ShiftR(cAvidaContext& ctx);

Modified: development/source/cpu/cHardwareBase.cc
===================================================================
--- development/source/cpu/cHardwareBase.cc	2006-04-14 17:24:47 UTC (rev 615)
+++ development/source/cpu/cHardwareBase.cc	2006-04-14 18:17:00 UTC (rev 616)
@@ -10,6 +10,432 @@
 
 #include "cHardwareBase.h"
 
+#include "cAvidaContext.h"
+#include "cCPUTestInfo.h"
+#include "cHardwareManager.h"
+#include "cHeadCPU.h"
+#include "cInstSet.h"
+#include "cMutation.h"
+#include "cMutationLib.h"
+#include "nMutation.h"
+#include "cOrganism.h"
+#include "cPhenotype.h"
+#include "cRandom.h"
+#include "cTestCPU.h"
+#include "cWorld.h"
+#include "cWorldDriver.h"
+#include "nHardware.h"
+
+#include "functions.h"
+
+
+int cHardwareBase::GetExecutedSize(const int parent_size)
+{
+  int executed_size = 0;
+  const cCPUMemory& memory = GetMemory();
+  for (int i = 0; i < parent_size; i++) {
+    if (memory.FlagExecuted(i)) executed_size++;
+  }  
+  return executed_size;
+}
+
+bool cHardwareBase::Divide_CheckViable(cAvidaContext& ctx, const int parent_size, const int child_size)
+{
+  // Make sure the organism is okay with dividing now...
+  if (organism->Divide_CheckViable() == false) return false; // (divide fails)
+  
+  // Make sure that neither parent nor child will be below the minimum size.  
+  const int genome_size = organism->GetGenome().GetSize();
+  const double size_range = m_world->GetConfig().CHILD_SIZE_RANGE.Get();
+  const int min_size = Max(MIN_CREATURE_SIZE, static_cast<int>(genome_size / size_range));
+  const int max_size = Min(MAX_CREATURE_SIZE, static_cast<int>(genome_size * size_range));
+  
+  if (child_size < min_size || child_size > max_size) {
+    organism->Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
+                    cStringUtil::Stringf("Invalid offspring length (%d)", child_size));
+    return false; // (divide fails)
+  }
+  if (parent_size < min_size || parent_size > max_size) {
+    organism->Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
+                    cStringUtil::Stringf("Invalid post-divide length (%d)",parent_size));
+    return false; // (divide fails)
+  }
+  
+  // Count the number of lines executed in the parent, and make sure the
+  // specified fraction has been reached.
+  
+  const int executed_size = GetExecutedSize(parent_size);
+  const int min_exe_lines = static_cast<int>(parent_size * m_world->GetConfig().MIN_EXE_LINES.Get());
+  if (executed_size < min_exe_lines) {
+    organism->Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
+          cStringUtil::Stringf("Too few executed lines (%d < %d)", executed_size, min_exe_lines));
+    return false; // (divide fails)
+  }
+	
+  const int copied_size = GetCopiedSize(parent_size, child_size);
+  const int min_copied = static_cast<int>(child_size * m_world->GetConfig().MIN_COPIED_LINES.Get());
+  if (copied_size < min_copied) {
+    organism->Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
+          cStringUtil::Stringf("Too few copied commands (%d < %d)", copied_size, min_copied));
+    return false; // (divide fails)
+  }
+  
+  // Save the information we collected here...
+  cPhenotype& phenotype = organism->GetPhenotype();
+  phenotype.SetLinesExecuted(executed_size);
+  phenotype.SetLinesCopied(copied_size);
+  
+  // Determine the fitness of this organism as compared to its parent...
+  if (m_world->GetTestSterilize() && !phenotype.IsInjected()) {
+    const int merit_base = phenotype.CalcSizeMerit();
+    const double cur_fitness = merit_base * phenotype.GetCurBonus() / phenotype.GetTimeUsed();
+    const double fitness_ratio = cur_fitness / phenotype.GetLastFitness();
+    
+    bool sterilize = false;
+    
+    if (fitness_ratio < nHardware::FITNESS_NEUTRAL_MIN) {
+      if (ctx.GetRandom().P(organism->GetSterilizeNeg())) sterilize = true;
+    } else if (fitness_ratio <= nHardware::FITNESS_NEUTRAL_MAX) {
+      if (ctx.GetRandom().P(organism->GetSterilizeNeut())) sterilize = true;
+    } else {
+      if (ctx.GetRandom().P(organism->GetSterilizePos())) sterilize = true;
+    }
+    
+    if (sterilize) {
+      // Don't let this organism have this or any more children!
+      phenotype.IsFertile() = false;
+      return false;
+    }    
+  }
+  
+  return true; // (divide succeeds!)
+}
+
+
+void cHardwareBase::Divide_DoMutations(cAvidaContext& ctx, double mut_multiplier)
+{
+  sCPUStats& cpu_stats = organism->CPUStats();
+  cCPUMemory& child_genome = organism->ChildGenome();
+  
+  organism->GetPhenotype().SetDivType(mut_multiplier);
+  
+  // Divide Mutations
+  if (organism->TestDivideMut(ctx)) {
+    const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize());
+    child_genome[mut_line] = m_inst_set->GetRandomInst(ctx);
+    cpu_stats.mut_stats.divide_mut_count++;
+  }
+  
+  // Divide Insertions
+  if (organism->TestDivideIns(ctx) && child_genome.GetSize() < MAX_CREATURE_SIZE) {
+    const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize() + 1);
+    child_genome.Insert(mut_line, m_inst_set->GetRandomInst(ctx));
+    cpu_stats.mut_stats.divide_insert_mut_count++;
+  }
+  
+  // Divide Deletions
+  if (organism->TestDivideDel(ctx) && child_genome.GetSize() > MIN_CREATURE_SIZE) {
+    const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize());
+    child_genome.Remove(mut_line);
+    cpu_stats.mut_stats.divide_delete_mut_count++;
+  }
+  
+  // Divide Mutations (per site)
+  if (organism->GetDivMutProb() > 0) {
+    int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(), 
+                                                  organism->GetDivMutProb() / mut_multiplier);
+    // If we have lines to mutate...
+    if (num_mut > 0) {
+      for (int i = 0; i < num_mut; i++) {
+        int site = ctx.GetRandom().GetUInt(child_genome.GetSize());
+        child_genome[site] = m_inst_set->GetRandomInst(ctx);
+        cpu_stats.mut_stats.div_mut_count++;
+      }
+    }
+  }
+  
+  
+  // Insert Mutations (per site)
+  if (organism->GetInsMutProb() > 0) {
+    int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(),
+                                                  organism->GetInsMutProb());
+    // If would make creature to big, insert up to MAX_CREATURE_SIZE
+    if (num_mut + child_genome.GetSize() > MAX_CREATURE_SIZE) {
+      num_mut = MAX_CREATURE_SIZE - child_genome.GetSize();
+    }
+    // If we have lines to insert...
+    if (num_mut > 0) {
+      // Build a list of the sites where mutations occured
+      static int mut_sites[MAX_CREATURE_SIZE];
+      for (int i = 0; i < num_mut; i++) {
+        mut_sites[i] = ctx.GetRandom().GetUInt(child_genome.GetSize() + 1);
+      }
+      // Sort the list
+      qsort( (void*)mut_sites, num_mut, sizeof(int), &IntCompareFunction );
+      // Actually do the mutations (in reverse sort order)
+      for (int i = num_mut-1; i >= 0; i--) {
+        child_genome.Insert(mut_sites[i], m_inst_set->GetRandomInst(ctx));
+        cpu_stats.mut_stats.insert_mut_count++;
+      }
+    }
+  }
+  
+  
+  // Delete Mutations (per site)
+  if (organism->GetDelMutProb() > 0) {
+    int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(),
+                                                  organism->GetDelMutProb());
+    // If would make creature too small, delete down to MIN_CREATURE_SIZE
+    if (child_genome.GetSize() - num_mut < MIN_CREATURE_SIZE) {
+      num_mut = child_genome.GetSize() - MIN_CREATURE_SIZE;
+    }
+    
+    // If we have lines to delete...
+    for (int i = 0; i < num_mut; i++) {
+      int site = ctx.GetRandom().GetUInt(child_genome.GetSize());
+      child_genome.Remove(site);
+      cpu_stats.mut_stats.delete_mut_count++;
+    }
+  }
+  
+  // Mutations in the parent's genome
+  if (organism->GetParentMutProb() > 0) {
+    for (int i = 0; i < GetMemory().GetSize(); i++) {
+      if (organism->TestParentMut(ctx)) {
+        GetMemory()[i] = m_inst_set->GetRandomInst(ctx);
+        cpu_stats.mut_stats.parent_mut_line_count++;
+      }
+    }
+  }
+  
+  
+  // Count up mutated lines
+  for (int i = 0; i < GetMemory().GetSize(); i++) {
+    if (GetMemory().FlagPointMut(i)) {
+      cpu_stats.mut_stats.point_mut_line_count++;
+    }
+  }
+  for (int i = 0; i < child_genome.GetSize(); i++) {
+    if (child_genome.FlagCopyMut(i)) {
+      cpu_stats.mut_stats.copy_mut_line_count++;
+    }
+  }
+}
+
+
+// test whether the offspring creature contains an advantageous mutation.
+void cHardwareBase::Divide_TestFitnessMeasures(cAvidaContext& ctx)
+{
+  cPhenotype & phenotype = organism->GetPhenotype();
+  phenotype.CopyTrue() = ( organism->ChildGenome() == organism->GetGenome() );
+  phenotype.ChildFertile() = true;
+	
+  // Only continue if we're supposed to do a fitness test on divide...
+  if (organism->GetTestOnDivide() == false) return;
+	
+  // If this was a perfect copy, then we don't need to worry about any other
+  // tests...  Theoretically, we need to worry about the parent changing,
+  // but as long as the child is always compared to the original genotype,
+  // this won't be an issue.
+  if (phenotype.CopyTrue() == true) return;
+	
+  const double parent_fitness = organism->GetTestFitness();
+  const double neut_min = parent_fitness * nHardware::FITNESS_NEUTRAL_MIN;
+  const double neut_max = parent_fitness * nHardware::FITNESS_NEUTRAL_MAX;
+  
+  cTestCPU* testcpu = m_world->GetHardwareManager().CreateTestCPU();
+  cCPUTestInfo test_info;
+  test_info.UseRandomInputs();
+  testcpu->TestGenome(ctx, test_info, organism->ChildGenome());
+  const double child_fitness = test_info.GetGenotypeFitness();
+  delete testcpu;
+  
+  bool revert = false;
+  bool sterilize = false;
+  
+  // If implicit mutations are turned off, make sure this won't spawn one.
+  if (organism->GetFailImplicit() == true) {
+    if (test_info.GetMaxDepth() > 0) sterilize = true;
+  }
+  
+  if (child_fitness == 0.0) {
+    // Fatal mutation... test for reversion.
+    if (ctx.GetRandom().P(organism->GetRevertFatal())) revert = true;
+    if (ctx.GetRandom().P(organism->GetSterilizeFatal())) sterilize = true;
+  } else if (child_fitness < neut_min) {
+    if (ctx.GetRandom().P(organism->GetRevertNeg())) revert = true;
+    if (ctx.GetRandom().P(organism->GetSterilizeNeg())) sterilize = true;
+  } else if (child_fitness <= neut_max) {
+    if (ctx.GetRandom().P(organism->GetRevertNeut())) revert = true;
+    if (ctx.GetRandom().P(organism->GetSterilizeNeut())) sterilize = true;
+  } else {
+    if (ctx.GetRandom().P(organism->GetRevertPos())) revert = true;
+    if (ctx.GetRandom().P(organism->GetSterilizePos())) sterilize = true;
+  }
+  
+  // Ideally, we won't have reversions and sterilizations turned on at the
+  // same time, but if we do, give revert the priority.
+  if (revert == true) {
+    organism->ChildGenome() = organism->GetGenome();
+  }
+	
+  if (sterilize == true) {
+    organism->GetPhenotype().ChildFertile() = false;
+  }
+}
+
+int cHardwareBase::PointMutate(cAvidaContext& ctx, const double mut_rate)
+{
+  cCPUMemory& memory = GetMemory();
+  const int num_muts = ctx.GetRandom().GetRandBinomial(memory.GetSize(), mut_rate);
+  
+  for (int i = 0; i < num_muts; i++) {
+    const int pos = ctx.GetRandom().GetUInt(memory.GetSize());
+    memory[pos] = m_inst_set->GetRandomInst(ctx);
+    memory.SetFlagMutated(pos);
+    memory.SetFlagPointMut(pos);
+    organism->CPUStats().mut_stats.point_mut_count++;
+  }
+  
+  return num_muts;
+}
+
+void cHardwareBase::TriggerMutations_Body(cAvidaContext& ctx, int type, cCPUMemory & target_memory, cHeadCPU& cur_head)
+{
+  const int pos = cur_head.GetPosition();
+	
+  switch (type) {
+		case nMutation::TYPE_POINT:
+			target_memory[pos] = m_inst_set->GetRandomInst(ctx);
+			target_memory.SetFlagMutated(pos);
+			break;
+		case nMutation::TYPE_INSERT:
+		case nMutation::TYPE_DELETE:
+		case nMutation::TYPE_HEAD_INC:
+		case nMutation::TYPE_HEAD_DEC:
+		case nMutation::TYPE_TEMP:
+		case nMutation::TYPE_KILL:
+		default:
+      m_world->GetDriver().RaiseException("Mutation type not implemented!");
+			break;
+  };
+}
+
+
+bool cHardwareBase::TriggerMutations_ScopeGenome(cAvidaContext& ctx, const cMutation* cur_mut,
+                                                 cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate)
+{
+  // The rate we have stored indicates the probability that a single
+  // mutation will occur anywhere in the genome.
+  
+  if (ctx.GetRandom().P(rate) == true) {
+    // We must create a temporary head and use it to randomly determine the
+    // position in the genome to be mutated.
+    cHeadCPU tmp_head(cur_head);
+    tmp_head.AbsSet(ctx.GetRandom().GetUInt(target_memory.GetSize()));
+    TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, tmp_head);
+    return true;
+  }
+  return false;
+}
+
+bool cHardwareBase::TriggerMutations_ScopeLocal(cAvidaContext& ctx, const cMutation* cur_mut,
+                                                cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate)
+{
+  // The rate we have stored is the probability for a mutation at this single
+  // position in the genome.
+	
+  if (ctx.GetRandom().P(rate) == true) {
+    TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, cur_head);
+    return true;
+  }
+  return false;
+}
+
+int cHardwareBase::TriggerMutations_ScopeGlobal(cAvidaContext& ctx, const cMutation * cur_mut,
+                                                cCPUMemory & target_memory, cHeadCPU& cur_head, const double rate)
+{
+  // The probability we have stored is per-site, so we can pull a random
+  // number from a binomial distribution to determine the number of mutations
+  // that should occur.
+	
+  const int num_mut =
+	ctx.GetRandom().GetRandBinomial(target_memory.GetSize(), rate);
+	
+  if (num_mut > 0) {
+    for (int i = 0; i < num_mut; i++) {
+      cHeadCPU tmp_head(cur_head);
+      tmp_head.AbsSet(ctx.GetRandom().GetUInt(target_memory.GetSize()));
+      TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, tmp_head);
+    }
+  }
+	
+  return num_mut;
+}
+
+// Trigger mutations of a specific type.  Outside triggers cannot specify
+// a head since hardware types are not known.
+bool cHardwareBase::TriggerMutations(cAvidaContext& ctx, int trigger)
+{
+  // Only update triggers should happen from the outside!
+  assert(trigger == nMutation::TRIGGER_UPDATE);
+	
+  // Assume instruction pointer is the intended target (if one is even
+  // needed!
+	
+  return TriggerMutations(ctx, trigger, IP());
+}
+
+bool cHardwareBase::TriggerMutations(cAvidaContext& ctx, int trigger, cHeadCPU& cur_head)
+{
+  // Collect information about mutations from the organism.
+  cLocalMutations& mut_info = organism->GetLocalMutations();
+  const tList<cMutation>& mut_list = mut_info.GetMutationLib().GetMutationList(trigger);
+	
+  // If we have no mutations for this trigger, stop here.
+  if (mut_list.GetSize() == 0) return false;
+  bool has_mutation = false;
+	
+  // Determine what memory this mutation will be affecting.
+  cCPUMemory& target_mem = (trigger == nMutation::TRIGGER_DIVIDE) ? organism->ChildGenome() : GetMemory();
+	
+  // Loop through all mutations associated with this trigger and test them.
+  tConstListIterator<cMutation> mut_it(mut_list);
+	
+  while (mut_it.Next() != NULL) {
+    const cMutation* cur_mut = mut_it.Get();
+    const int mut_id = cur_mut->GetID();
+    const int scope = cur_mut->GetScope();
+    const double rate = mut_info.GetRate(mut_id);
+    switch (scope) {
+			case nMutation::SCOPE_GENOME:
+				if (TriggerMutations_ScopeGenome(ctx, cur_mut, target_mem, cur_head, rate)) {
+					has_mutation = true;
+					mut_info.IncCount(mut_id);
+				}
+				break;
+			case nMutation::SCOPE_LOCAL:
+			case nMutation::SCOPE_PROP:
+				if (TriggerMutations_ScopeLocal(ctx, cur_mut, target_mem, cur_head, rate)) {
+					has_mutation = true;
+					mut_info.IncCount(mut_id);
+				}
+				break;
+			case nMutation::SCOPE_GLOBAL:
+			case nMutation::SCOPE_SPREAD:
+				int num_muts = TriggerMutations_ScopeGlobal(ctx, cur_mut, target_mem, cur_head, rate);
+				if (num_muts > 0) {
+					has_mutation = true;
+					mut_info.IncCount(mut_id, num_muts);
+				}
+        break;
+    }
+  }
+	
+  return has_mutation;
+}
+
+
 bool cHardwareBase::Inst_Nop(cAvidaContext& ctx)          // Do Nothing.
 {
   return true;

Modified: development/source/cpu/cHardwareBase.h
===================================================================
--- development/source/cpu/cHardwareBase.h	2006-04-14 17:24:47 UTC (rev 615)
+++ development/source/cpu/cHardwareBase.h	2006-04-14 18:17:00 UTC (rev 616)
@@ -25,6 +25,7 @@
 class cInjectGenotype;
 class cInstruction;
 class cInstSet;
+class cMutation;
 class cOrganism;
 class cString;
 class cWorld;
@@ -34,10 +35,24 @@
 protected:
   cWorld* m_world;
   cOrganism* organism;       // Organism using this hardware.
-  cInstSet* m_inst_set;        // Instruction set being used.
+  cInstSet* m_inst_set;      // Instruction set being used.
   cHardwareTracer* m_tracer; // Set this if you want execution traced.
 
-
+  virtual int GetExecutedSize(const int parent_size);
+  virtual int GetCopiedSize(const int parent_size, const int child_size) = 0;  
+  
+  bool Divide_CheckViable(cAvidaContext& ctx, const int parent_size, const int child_size);
+  void Divide_DoMutations(cAvidaContext& ctx, double mut_multiplier = 1.0);
+  void Divide_TestFitnessMeasures(cAvidaContext& ctx);
+  
+  void TriggerMutations_Body(cAvidaContext& ctx, int type, cCPUMemory& target_memory, cHeadCPU& cur_head);
+  bool TriggerMutations_ScopeGenome(cAvidaContext& ctx, const cMutation* cur_mut,
+																		cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate);
+  bool TriggerMutations_ScopeLocal(cAvidaContext& ctx, const cMutation* cur_mut,
+																	 cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate);
+  int TriggerMutations_ScopeGlobal(cAvidaContext& ctx, const cMutation* cur_mut,
+																	 cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate);
+  
   cHardwareBase(); // @not_implemented
   cHardwareBase(const cHardwareBase&); // @not_implemented
   cHardwareBase& operator=(const cHardwareBase&); // @not_implemented
@@ -126,9 +141,9 @@
   
   
   // --------  Mutation  --------
-  virtual int PointMutate(cAvidaContext& ctx, const double mut_rate) = 0;
-  virtual bool TriggerMutations(cAvidaContext& ctx, int trigger) = 0;
-  virtual bool TriggerMutations(cAvidaContext& ctx, int trigger, cHeadCPU& cur_head) = 0;
+  virtual int PointMutate(cAvidaContext& ctx, const double mut_rate);
+  virtual bool TriggerMutations(cAvidaContext& ctx, int trigger);
+  virtual bool TriggerMutations(cAvidaContext& ctx, int trigger, cHeadCPU& cur_head);
   
   
 protected:

Modified: development/source/cpu/cHardwareCPU.cc
===================================================================
--- development/source/cpu/cHardwareCPU.cc	2006-04-14 17:24:47 UTC (rev 615)
+++ development/source/cpu/cHardwareCPU.cc	2006-04-14 18:17:00 UTC (rev 616)
@@ -1002,175 +1002,7 @@
   }
 }
 
-void cHardwareCPU::InjectCodeThread(const cGenome & inject_code, const int line_num)
-{
-}
 
-void cHardwareCPU::Mutate(cAvidaContext& ctx, int mut_point)
-{
-  // Test if trying to mutate outside of genome...
-  assert(mut_point >= 0 && mut_point < GetMemory().GetSize());
-  
-  GetMemory()[mut_point] = m_inst_set->GetRandomInst(ctx);
-  GetMemory().SetFlagMutated(mut_point);
-  GetMemory().SetFlagPointMut(mut_point);
-  //organism->GetPhenotype().IsMutated() = true;
-  organism->CPUStats().mut_stats.point_mut_count++;
-}
-
-int cHardwareCPU::PointMutate(cAvidaContext& ctx, const double mut_rate)
-{
-  const int num_muts =
-  ctx.GetRandom().GetRandBinomial(GetMemory().GetSize(), mut_rate);
-  
-  for (int i = 0; i < num_muts; i++) {
-    const int pos = ctx.GetRandom().GetUInt(GetMemory().GetSize());
-    Mutate(ctx, pos);
-  }
-  
-  return num_muts;
-}
-
-
-// Trigger mutations of a specific type.  Outside triggers cannot specify
-// a head since hardware types are not known.
-
-bool cHardwareCPU::TriggerMutations(cAvidaContext& ctx, int trigger)
-{
-  // Only update triggers should happen from the outside!
-  assert(trigger == nMutation::TRIGGER_UPDATE);
-  
-  // Assume instruction pointer is the intended target (if one is even
-  // needed!
-  
-  return TriggerMutations(ctx, trigger, IP());
-}
-
-bool cHardwareCPU::TriggerMutations(cAvidaContext& ctx, int trigger, cHeadCPU & cur_head)
-{
-  // Collect information about mutations from the organism.
-  cLocalMutations & mut_info = organism->GetLocalMutations();
-  const tList<cMutation> & mut_list =
-    mut_info.GetMutationLib().GetMutationList(trigger);
-  
-  // If we have no mutations for this trigger, stop here.
-  if (mut_list.GetSize() == 0) return false;
-  bool has_mutation = false;
-  
-  // Determine what memory this mutation will be affecting.
-  cCPUMemory & target_mem = (trigger == nMutation::TRIGGER_DIVIDE) 
-    ? organism->ChildGenome() : GetMemory();
-  
-  // Loop through all mutations associated with this trigger and test them.
-  tConstListIterator<cMutation> mut_it(mut_list);
-  
-  while (mut_it.Next() != NULL) {
-    const cMutation * cur_mut = mut_it.Get();
-    const int mut_id = cur_mut->GetID();
-    const int scope = cur_mut->GetScope();
-    const double rate = mut_info.GetRate(mut_id);
-    switch (scope) {
-      case nMutation::SCOPE_GENOME:
-        if (TriggerMutations_ScopeGenome(ctx, cur_mut, target_mem, cur_head, rate)) {
-          has_mutation = true;
-          mut_info.IncCount(mut_id);
-        }
-        break;
-      case nMutation::SCOPE_LOCAL:
-      case nMutation::SCOPE_PROP:
-        if (TriggerMutations_ScopeLocal(ctx, cur_mut, target_mem, cur_head, rate)) {
-          has_mutation = true;
-          mut_info.IncCount(mut_id);
-        }
-        break;
-      case nMutation::SCOPE_GLOBAL:
-      case nMutation::SCOPE_SPREAD:
-        int num_muts =
-        TriggerMutations_ScopeGlobal(ctx, cur_mut, target_mem, cur_head, rate);
-        if (num_muts > 0) {
-          has_mutation = true;
-          mut_info.IncCount(mut_id, num_muts);
-        }
-          break;
-    }
-  }
-  
-  return has_mutation;
-}
-
-bool cHardwareCPU::TriggerMutations_ScopeGenome(cAvidaContext& ctx, const cMutation* cur_mut,
-                                                cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate)
-{
-  // The rate we have stored indicates the probability that a single
-  // mutation will occur anywhere in the genome.
-  
-  if (ctx.GetRandom().P(rate) == true) {
-    // We must create a temporary head and use it to randomly determine the
-    // position in the genome to be mutated.
-    cHeadCPU tmp_head(cur_head);
-    tmp_head.AbsSet(ctx.GetRandom().GetUInt(target_memory.GetSize()));
-    TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, tmp_head);
-    return true;
-  }
-  return false;
-}
-
-bool cHardwareCPU::TriggerMutations_ScopeLocal(cAvidaContext& ctx, const cMutation* cur_mut,
-                                               cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate)
-{
-  // The rate we have stored is the probability for a mutation at this single
-  // position in the genome.
-  
-  if (ctx.GetRandom().P(rate) == true) {
-    TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, cur_head);
-    return true;
-  }
-  return false;
-}
-
-int cHardwareCPU::TriggerMutations_ScopeGlobal(cAvidaContext& ctx, const cMutation* cur_mut,
-                                               cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate)
-{
-  // The probability we have stored is per-site, so we can pull a random
-  // number from a binomial distribution to determine the number of mutations
-  // that should occur.
-  
-  const int num_mut =
-  ctx.GetRandom().GetRandBinomial(target_memory.GetSize(), rate);
-  
-  if (num_mut > 0) {
-    for (int i = 0; i < num_mut; i++) {
-      cHeadCPU tmp_head(cur_head);
-      tmp_head.AbsSet(ctx.GetRandom().GetUInt(target_memory.GetSize()));
-      TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, tmp_head);
-    }
-  }
-  
-  return num_mut;
-}
-
-void cHardwareCPU::TriggerMutations_Body(cAvidaContext& ctx, int type, cCPUMemory & target_memory,
-                                         cHeadCPU & cur_head)
-{
-  const int pos = cur_head.GetPosition();
-  
-  switch (type) {
-    case nMutation::TYPE_POINT:
-      target_memory[pos] = m_inst_set->GetRandomInst(ctx);
-      target_memory.SetFlagMutated(pos);
-      break;
-    case nMutation::TYPE_INSERT:
-    case nMutation::TYPE_DELETE:
-    case nMutation::TYPE_HEAD_INC:
-    case nMutation::TYPE_HEAD_DEC:
-    case nMutation::TYPE_TEMP:
-    case nMutation::TYPE_KILL:
-    default:
-      m_world->GetDriver().RaiseException("Mutation type not implemented!");
-      break;
-  };
-}
-
 void cHardwareCPU::ReadInst(const int in_inst)
 {
   if (m_inst_set->IsNop( cInstruction(in_inst) )) {
@@ -1308,12 +1140,6 @@
 }
 
 
-inline void cHardwareCPU::Fault(int fault_loc, int fault_type, cString fault_desc)
-{
-  organism->Fault(fault_loc, fault_type, fault_desc);
-}
-
-
 bool cHardwareCPU::Allocate_Necro(const int new_size)
 {
   GetMemory().ResizeOld(new_size);
@@ -1343,11 +1169,11 @@
 {
   // must do divide before second allocate & must allocate positive amount...
   if (m_world->GetConfig().REQUIRE_ALLOCATE.Get() && mal_active == true) {
-    Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR, "Allocate already active");
+    organism->Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR, "Allocate already active");
     return false;
   }
   if (allocated_size < 1) {
-    Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
+    organism->Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
           cStringUtil::Stringf("Allocate of %d too small", allocated_size));
     return false;
   }
@@ -1357,7 +1183,7 @@
   
   // Make sure that the new size is in range.
   if (new_size > MAX_CREATURE_SIZE  ||  new_size < MIN_CREATURE_SIZE) {
-    Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
+    organism->Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
           cStringUtil::Stringf("Invalid post-allocate size (%d)",
                                new_size));
     return false;
@@ -1365,7 +1191,7 @@
   
   const int max_alloc_size = (int) (old_size * m_world->GetConfig().CHILD_SIZE_RANGE.Get());
   if (allocated_size > max_alloc_size) {
-    Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
+    organism->Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
           cStringUtil::Stringf("Allocate too large (%d > %d)",
                                allocated_size, max_alloc_size));
     return false;
@@ -1374,7 +1200,7 @@
   const int max_old_size =
     (int) (allocated_size * m_world->GetConfig().CHILD_SIZE_RANGE.Get());
   if (old_size > max_old_size) {
-    Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
+    organism->Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
           cStringUtil::Stringf("Allocate too small (%d > %d)",
                                old_size, max_old_size));
     return false;
@@ -1397,287 +1223,24 @@
   return true;
 }
 
-
-bool cHardwareCPU::Divide_CheckViable(cAvidaContext& ctx, const int child_size,
-                                      const int parent_size)
+int cHardwareCPU::GetCopiedSize(const int parent_size, const int child_size)
 {
-  // Make sure the organism is okay with dividing now...
-  if (organism->Divide_CheckViable() == false) return false; // (divide fails)
-  
-  // If required, make sure an allocate has occured.
-  if (m_world->GetConfig().REQUIRE_ALLOCATE.Get() && mal_active == false) {
-    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR, "Must allocate before divide");
-    return false; //  (divide fails)
-  }
-  
-  // Make sure that neither parent nor child will be below the minimum size.
-  
-  const int genome_size = organism->GetGenome().GetSize();
-  const double size_range = m_world->GetConfig().CHILD_SIZE_RANGE.Get();
-  const int min_size = Max(MIN_CREATURE_SIZE, (int) (genome_size/size_range));
-  const int max_size = Min(MAX_CREATURE_SIZE, (int) (genome_size*size_range));
-  
-  if (child_size < min_size || child_size > max_size) {
-    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-          cStringUtil::Stringf("Invalid offspring length (%d)", child_size));
-    return false; // (divide fails)
-  }
-  if (parent_size < min_size || parent_size > max_size) {
-    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-          cStringUtil::Stringf("Invalid post-divide length (%d)",parent_size));
-    return false; // (divide fails)
-  }
-  
-  // Count the number of lines executed in the parent, and make sure the
-  // specified fraction has been reached.
-  
-  int executed_size = 0;
-  for (int i = 0; i < parent_size; i++) {
-    if (GetMemory().FlagExecuted(i)) executed_size++;
-  }
-  
-  const int min_exe_lines = (int) (parent_size * m_world->GetConfig().MIN_EXE_LINES.Get());
-  if (executed_size < min_exe_lines) {
-    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-          cStringUtil::Stringf("Too few executed lines (%d < %d)",
-                               executed_size, min_exe_lines));
-    return false; // (divide fails)
-  }
-	
-  // Count the number of lines which were copied into the child, and make
-  // sure the specified fraction has been reached.
-  
   int copied_size = 0;
+  const cCPUMemory& memory = GetMemory();
   for (int i = parent_size; i < parent_size + child_size; i++) {
-    if (GetMemory().FlagCopied(i)) copied_size++;
+    if (memory.FlagCopied(i)) copied_size++;
   }
-  
-  const int min_copied =  (int) (child_size * m_world->GetConfig().MIN_COPIED_LINES.Get());
-  if (copied_size < min_copied) {
-    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-          cStringUtil::Stringf("Too few copied commands (%d < %d)",
-                               copied_size, min_copied));
-    return false; // (divide fails)
-  }
-  
-  // Save the information we collected here...
-  cPhenotype & phenotype = organism->GetPhenotype();
-  phenotype.SetLinesExecuted(executed_size);
-  phenotype.SetLinesCopied(copied_size);
-  
-  // Determine the fitness of this organism as compared to its parent...
-  if (m_world->GetTestSterilize() == true &&
-      phenotype.IsInjected() == false) {
-    const int merit_base = phenotype.CalcSizeMerit();
-    const double cur_fitness =
-      merit_base * phenotype.GetCurBonus() / phenotype.GetTimeUsed();
-    const double fitness_ratio = cur_fitness / phenotype.GetLastFitness();
-    
-    
-    //  const double neut_min = parent_fitness * nHardware::FITNESS_NEUTRAL_MIN;
-    //  const double neut_max = parent_fitness * nHardware::FITNESS_NEUTRAL_MAX;
-    
-    bool sterilize = false;
-    
-    if (fitness_ratio < nHardware::FITNESS_NEUTRAL_MIN) {
-      if (ctx.GetRandom().P(organism->GetSterilizeNeg())) sterilize = true;
-    } else if (fitness_ratio <= nHardware::FITNESS_NEUTRAL_MAX) {
-      if (ctx.GetRandom().P(organism->GetSterilizeNeut())) sterilize = true;
-    } else {
-      if (ctx.GetRandom().P(organism->GetSterilizePos())) sterilize = true;
-    }
-    
-    if (sterilize == true) {
-      //Don't let this organism have this or any more children!
-      phenotype.IsFertile() = false;
-      return false;
-    }    
-  }
-  
-  return true; // (divide succeeds!)
-}
+  return copied_size;
+}  
 
 
-void cHardwareCPU::Divide_DoMutations(cAvidaContext& ctx, double mut_multiplier)
-{
-  sCPUStats & cpu_stats = organism->CPUStats();
-  cCPUMemory & child_genome = organism->ChildGenome();
-  
-  organism->GetPhenotype().SetDivType(mut_multiplier);
-  
-  // Divide Mutations
-  if (organism->TestDivideMut(ctx)) {
-    const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize());
-    child_genome[mut_line] = m_inst_set->GetRandomInst(ctx);
-    cpu_stats.mut_stats.divide_mut_count++;
-  }
-  
-  // Divide Insertions
-  if (organism->TestDivideIns(ctx) && child_genome.GetSize() < MAX_CREATURE_SIZE){
-    const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize() + 1);
-    child_genome.Insert(mut_line, m_inst_set->GetRandomInst(ctx));
-    cpu_stats.mut_stats.divide_insert_mut_count++;
-  }
-  
-  // Divide Deletions
-  if (organism->TestDivideDel(ctx) && child_genome.GetSize() > MIN_CREATURE_SIZE){
-    const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize());
-    child_genome.Remove(mut_line);
-    cpu_stats.mut_stats.divide_delete_mut_count++;
-  }
-  
-  // Divide Mutations (per site)
-  if(organism->GetDivMutProb() > 0){
-    int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(), 
-                                                       organism->GetDivMutProb() / mut_multiplier);
-    // If we have lines to mutate...
-    if( num_mut > 0 ){
-      for (int i = 0; i < num_mut; i++) {
-        int site = ctx.GetRandom().GetUInt(child_genome.GetSize());
-        child_genome[site] = m_inst_set->GetRandomInst(ctx);
-        cpu_stats.mut_stats.div_mut_count++;
-      }
-    }
-  }
-  
-  
-  // Insert Mutations (per site)
-  if(organism->GetInsMutProb() > 0){
-    int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(),
-                                                       organism->GetInsMutProb());
-    // If would make creature to big, insert up to MAX_CREATURE_SIZE
-    if( num_mut + child_genome.GetSize() > MAX_CREATURE_SIZE ){
-      num_mut = MAX_CREATURE_SIZE - child_genome.GetSize();
-    }
-    // If we have lines to insert...
-    if( num_mut > 0 ){
-      // Build a list of the sites where mutations occured
-      static int mut_sites[MAX_CREATURE_SIZE];
-      for (int i = 0; i < num_mut; i++) {
-        mut_sites[i] = ctx.GetRandom().GetUInt(child_genome.GetSize() + 1);
-      }
-      // Sort the list
-      qsort( (void*)mut_sites, num_mut, sizeof(int), &IntCompareFunction );
-      // Actually do the mutations (in reverse sort order)
-      for(int i = num_mut-1; i >= 0; i--) {
-        child_genome.Insert(mut_sites[i], m_inst_set->GetRandomInst(ctx));
-        cpu_stats.mut_stats.insert_mut_count++;
-      }
-    }
-  }
-  
-  
-  // Delete Mutations (per site)
-  if( organism->GetDelMutProb() > 0 ){
-    int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(),
-                                                       organism->GetDelMutProb());
-    // If would make creature too small, delete down to MIN_CREATURE_SIZE
-    if (child_genome.GetSize() - num_mut < MIN_CREATURE_SIZE) {
-      num_mut = child_genome.GetSize() - MIN_CREATURE_SIZE;
-    }
-    
-    // If we have lines to delete...
-    for (int i = 0; i < num_mut; i++) {
-      int site = ctx.GetRandom().GetUInt(child_genome.GetSize());
-      child_genome.Remove(site);
-      cpu_stats.mut_stats.delete_mut_count++;
-    }
-  }
-  
-  // Mutations in the parent's genome
-  if (organism->GetParentMutProb() > 0) {
-    for (int i = 0; i < GetMemory().GetSize(); i++) {
-      if (organism->TestParentMut(ctx)) {
-        GetMemory()[i] = m_inst_set->GetRandomInst(ctx);
-        cpu_stats.mut_stats.parent_mut_line_count++;
-      }
-    }
-  }
-  
-  
-  // Count up mutated lines
-  for(int i = 0; i < GetMemory().GetSize(); i++){
-    if (GetMemory().FlagPointMut(i)) {
-      cpu_stats.mut_stats.point_mut_line_count++;
-    }
-  }
-  for(int i = 0; i < child_genome.GetSize(); i++){
-    if( child_genome.FlagCopyMut(i)) {
-      cpu_stats.mut_stats.copy_mut_line_count++;
-    }
-  }
-}
-
-
-// test whether the offspring creature contains an advantageous mutation.
-void cHardwareCPU::Divide_TestFitnessMeasures(cAvidaContext& ctx)
-{
-  cPhenotype & phenotype = organism->GetPhenotype();
-  phenotype.CopyTrue() = ( organism->ChildGenome() == organism->GetGenome() );
-  phenotype.ChildFertile() = true;
-  
-  // Only continue if we're supposed to do a fitness test on divide...
-  if (organism->GetTestOnDivide() == false) return;
-  
-  // If this was a perfect copy, then we don't need to worry about any other
-  // tests...  Theoretically, we need to worry about the parent changing,
-  // but as long as the child is always compared to the original genotype,
-  // this won't be an issue.
-  if (phenotype.CopyTrue() == true) return;
-  
-  const double parent_fitness = organism->GetTestFitness();
-  const double neut_min = parent_fitness * nHardware::FITNESS_NEUTRAL_MIN;
-  const double neut_max = parent_fitness * nHardware::FITNESS_NEUTRAL_MAX;
-  
-  cTestCPU* testcpu = m_world->GetHardwareManager().CreateTestCPU();
-  cCPUTestInfo test_info;
-  test_info.UseRandomInputs();
-  testcpu->TestGenome(ctx, test_info, organism->ChildGenome());
-  const double child_fitness = test_info.GetGenotypeFitness();
-  delete testcpu;
-  
-  bool revert = false;
-  bool sterilize = false;
-  
-  // If implicit mutations are turned off, make sure this won't spawn one.
-  if (organism->GetFailImplicit() == true) {
-    if (test_info.GetMaxDepth() > 0) sterilize = true;
-  }
-  
-  if (child_fitness == 0.0) {
-    // Fatal mutation... test for reversion.
-    if (ctx.GetRandom().P(organism->GetRevertFatal())) revert = true;
-    if (ctx.GetRandom().P(organism->GetSterilizeFatal())) sterilize = true;
-  } else if (child_fitness < neut_min) {
-    if (ctx.GetRandom().P(organism->GetRevertNeg())) revert = true;
-    if (ctx.GetRandom().P(organism->GetSterilizeNeg())) sterilize = true;
-  } else if (child_fitness <= neut_max) {
-    if (ctx.GetRandom().P(organism->GetRevertNeut())) revert = true;
-    if (ctx.GetRandom().P(organism->GetSterilizeNeut())) sterilize = true;
-  } else {
-    if (ctx.GetRandom().P(organism->GetRevertPos())) revert = true;
-    if (ctx.GetRandom().P(organism->GetSterilizePos())) sterilize = true;
-  }
-  
-  // Ideally, we won't have reversions and sterilizations turned on at the
-  // same time, but if we do, give revert the priority.
-  if (revert == true) {
-    organism->ChildGenome() = organism->GetGenome();
-  }
-  
-  if (sterilize == true) {
-    organism->GetPhenotype().ChildFertile() = false;
-  }
-}
-
-
 bool cHardwareCPU::Divide_Main(cAvidaContext& ctx, const int div_point,
                                const int extra_lines, double mut_multiplier)
 {
   const int child_size = GetMemory().GetSize() - div_point - extra_lines;
   
   // Make sure this divide will produce a viable offspring.
-  const bool viable = Divide_CheckViable(ctx, child_size, div_point);
+  const bool viable = Divide_CheckViable(ctx, div_point, child_size);
   if (viable == false) return false;
   
   // Since the divide will now succeed, set up the information to be sent
@@ -2195,7 +1758,7 @@
   const int value = GetRegister(reg_used);
   if (value > 1) GetRegister(reg_used) = (int) sqrt((double) value);
   else if (value < 0) {
-    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "sqrt: value is negative");
+    organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "sqrt: value is negative");
     return false;
   }
   return true;
@@ -2207,7 +1770,7 @@
   const int value = GetRegister(reg_used);
   if (value >= 1) GetRegister(reg_used) = (int) log((double) value);
   else if (value < 0) {
-    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "log: value is negative");
+    organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "log: value is negative");
     return false;
   }
   return true;
@@ -2219,7 +1782,7 @@
   const int value = GetRegister(reg_used);
   if (value >= 1) GetRegister(reg_used) = (int) log10((double) value);
   else if (value < 0) {
-    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "log10: value is negative");
+    organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "log10: value is negative");
     return false;
   }
   return true;
@@ -2258,11 +1821,11 @@
   const int reg_used = FindModifiedRegister(nHardwareCPU::REG_BX);
   if (GetRegister(nHardwareCPU::REG_CX) != 0) {
     if (0-INT_MAX > GetRegister(nHardwareCPU::REG_BX) && GetRegister(nHardwareCPU::REG_CX) == -1)
-      Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: Float exception");
+      organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: Float exception");
     else
       GetRegister(reg_used) = GetRegister(nHardwareCPU::REG_BX) / GetRegister(nHardwareCPU::REG_CX);
   } else {
-    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: dividing by 0");
+    organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: dividing by 0");
     return false;
   }
   return true;
@@ -2274,7 +1837,7 @@
   if (GetRegister(nHardwareCPU::REG_CX) != 0) {
     GetRegister(reg_used) = GetRegister(nHardwareCPU::REG_BX) % GetRegister(nHardwareCPU::REG_CX);
   } else {
-    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "mod: modding by 0");
+    organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "mod: modding by 0");
     return false;
   }
   return true;
@@ -2569,11 +2132,11 @@
   
   // Make sure the creature will still be above the minimum size,
   if (inject_size <= 0) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
+    organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
     return false; // (inject fails)
   }
   if (start_pos < MIN_CREATURE_SIZE) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
+    organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
     return false; // (inject fails)
   }
   
@@ -2590,7 +2153,7 @@
   
   // If there is no label, abort.
   if (GetLabel().GetSize() == 0) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: label required");
+    organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: label required");
     return false; // (inject fails)
   }
   
@@ -2599,7 +2162,7 @@
   
   const bool inject_signal = host_organism->GetHardware().InjectHost(GetLabel(), inject_code);
   if (inject_signal) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_WARNING, "inject: host too large.");
+    organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_WARNING, "inject: host too large.");
     return false; // Inject failed.
   }
   
@@ -2636,11 +2199,11 @@
   
   // Make sure the creature will still be above the minimum size,
   if (inject_size <= 0) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
+    organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
     return false; // (inject fails)
   }
   if (start_pos < MIN_CREATURE_SIZE) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
+    organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
     return false; // (inject fails)
   }
   
@@ -2657,7 +2220,7 @@
   
   // If there is no label, abort.
   if (GetLabel().GetSize() == 0) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: label required");
+    organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: label required");
     return false; // (inject fails)
   }
   
@@ -3036,13 +2599,13 @@
 bool cHardwareCPU::Inst_ForkThread(cAvidaContext& ctx)
 {
   IP().Advance();
-  if (!ForkThread()) Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
+  if (!ForkThread()) organism->Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
   return true;
 }
 
 bool cHardwareCPU::Inst_KillThread(cAvidaContext& ctx)
 {
-  if (!KillThread()) Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);
+  if (!KillThread()) organism->Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);
   else advance_ip = false;
   return true;
 }

Modified: development/source/cpu/cHardwareCPU.h
===================================================================
--- development/source/cpu/cHardwareCPU.h	2006-04-14 17:24:47 UTC (rev 615)
+++ development/source/cpu/cHardwareCPU.h	2006-04-14 18:17:00 UTC (rev 616)
@@ -67,7 +67,7 @@
 public:
   typedef bool (cHardwareCPU::*tHardwareCPUMethod)(cAvidaContext& ctx);
 
-private:
+protected:
   static cInstLibCPU* s_inst_slib;
   static cInstLibCPU* initInstLib(void);
 
@@ -92,7 +92,57 @@
   tArray<int> inst_ft_cost;
 #endif
   
+  
+  bool SingleProcess_PayCosts(cAvidaContext& ctx, const cInstruction& cur_inst);
+  bool SingleProcess_ExecuteInst(cAvidaContext& ctx, const cInstruction& cur_inst);
+  
+  // --------  Stack Manipulation...  --------
+  inline void StackPush(int value);
+  inline int StackPop();
+  inline void StackFlip();
+  inline void StackClear();
+  inline void SwitchStack();
+  
+  
+  // --------  Head Manipulation (including IP)  --------
+  cHeadCPU& GetActiveHead() { return threads[cur_thread].heads[threads[cur_thread].cur_head]; }
+  void AdjustHeads();
+  
+  
+  // --------  Label Manipulation  -------
+  void ReadLabel(int max_size=nHardware::MAX_LABEL_SIZE);
+  cHeadCPU FindLabel(int direction);
+  int FindLabel_Forward(const cCodeLabel & search_label, const cGenome& search_genome, int pos);
+  int FindLabel_Backward(const cCodeLabel & search_label, const cGenome& search_genome, int pos);
+  cHeadCPU FindLabel(const cCodeLabel & in_label, int direction);
+  cHeadCPU FindFullLabel(const cCodeLabel & in_label);
+  const cCodeLabel& GetReadLabel() const { return threads[cur_thread].read_label; }
+  cCodeLabel& GetReadLabel() { return threads[cur_thread].read_label; }
+  
+  
+  
+  // ---------- Instruction Helpers -----------
+  int FindModifiedRegister(int default_register);
+  int FindModifiedHead(int default_head);
+  int FindComplementRegister(int base_reg);
+  
+  bool Allocate_Necro(const int new_size);
+  bool Allocate_Random(cAvidaContext& ctx, const int old_size, const int new_size);
+  bool Allocate_Default(const int new_size);
+  bool Allocate_Main(cAvidaContext& ctx, const int allocated_size);
+  
+  int GetCopiedSize(const int parent_size, const int child_size);
+  
+  bool Divide_Main(cAvidaContext& ctx, const int divide_point, const int extra_lines=0, double mut_multiplier=1);
+  
+  void InjectCode(const cGenome& injection, const int line_num);
+  
+  bool HeadCopy_ErrorCorrect(cAvidaContext& ctx, double reduction);
+  bool Inst_HeadDivideMut(cAvidaContext& ctx, double mut_multiplier = 1);
+  
+  void ReadInst(const int in_inst);
 
+  
   cHardwareCPU& operator=(const cHardwareCPU&); // @not_implemented
 
 public:
@@ -173,12 +223,6 @@
   }
 
 
-  // --------  Mutation  --------
-  int PointMutate(cAvidaContext& ctx, const double mut_rate);  
-  bool TriggerMutations(cAvidaContext& ctx, int trigger);
-  bool TriggerMutations(cAvidaContext& ctx, int trigger, cHeadCPU& cur_head);
-  
-  
   // Non-Standard Methods
   
   int GetActiveStack() const { return threads[cur_thread].cur_stack; }
@@ -385,71 +429,6 @@
 
   //// Placebo ////
   bool Inst_Skip(cAvidaContext& ctx);
-
-
-  // Internal Implementation
-
-  bool SingleProcess_PayCosts(cAvidaContext& ctx, const cInstruction& cur_inst);
-  bool SingleProcess_ExecuteInst(cAvidaContext& ctx, const cInstruction& cur_inst);
-  
-  // --------  Stack Manipulation...  --------
-  inline void StackPush(int value);
-  inline int StackPop();
-  inline void StackFlip();
-  inline void StackClear();
-  inline void SwitchStack();
-  
-  
-  // --------  Head Manipulation (including IP)  --------
-  cHeadCPU& GetActiveHead() { return threads[cur_thread].heads[threads[cur_thread].cur_head]; }
-  void AdjustHeads();
-  
-  
-  // --------  Label Manipulation  -------
-  void ReadLabel(int max_size=nHardware::MAX_LABEL_SIZE);
-  cHeadCPU FindLabel(int direction);
-  int FindLabel_Forward(const cCodeLabel & search_label, const cGenome& search_genome, int pos);
-  int FindLabel_Backward(const cCodeLabel & search_label, const cGenome& search_genome, int pos);
-  cHeadCPU FindLabel(const cCodeLabel & in_label, int direction);
-  cHeadCPU FindFullLabel(const cCodeLabel & in_label);
-  const cCodeLabel& GetReadLabel() const { return threads[cur_thread].read_label; }
-  cCodeLabel& GetReadLabel() { return threads[cur_thread].read_label; }
-  
-  
-  bool TriggerMutations_ScopeGenome(cAvidaContext& ctx, const cMutation* cur_mut,
-                                    cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate);
-  bool TriggerMutations_ScopeLocal(cAvidaContext& ctx, const cMutation* cur_mut,
-                                   cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate);
-  int TriggerMutations_ScopeGlobal(cAvidaContext& ctx, const cMutation* cur_mut, 
-                                   cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate);
-  void TriggerMutations_Body(cAvidaContext& ctx, int type, cCPUMemory& target_memory, cHeadCPU& cur_head);
-  
-  
-  // ---------- Instruction Helpers -----------
-  int FindModifiedRegister(int default_register);
-  int FindModifiedHead(int default_head);
-  int FindComplementRegister(int base_reg);
-  
-  void Fault(int fault_loc, int fault_type, cString fault_desc="");
-  
-  bool Allocate_Necro(const int new_size);
-  bool Allocate_Random(cAvidaContext& ctx, const int old_size, const int new_size);
-  bool Allocate_Default(const int new_size);
-  bool Allocate_Main(cAvidaContext& ctx, const int allocated_size);
-  
-  bool Divide_Main(cAvidaContext& ctx, const int divide_point, const int extra_lines=0, double mut_multiplier=1);
-  bool Divide_CheckViable(cAvidaContext& ctx, const int child_size, const int parent_size);
-  void Divide_DoMutations(cAvidaContext& ctx, double mut_multiplier=1);
-  void Divide_TestFitnessMeasures(cAvidaContext& ctx);
-  void Mutate(cAvidaContext& ctx, const int mut_point);
-  
-  void InjectCode(const cGenome& injection, const int line_num);
-  void InjectCodeThread(const cGenome& injection, const int line_num);
-  
-  bool HeadCopy_ErrorCorrect(cAvidaContext& ctx, double reduction);
-  bool Inst_HeadDivideMut(cAvidaContext& ctx, double mut_multiplier = 1);
-  
-  void ReadInst(const int in_inst);
 };
 
 

Modified: development/source/cpu/cHardwareSMT.cc
===================================================================
--- development/source/cpu/cHardwareSMT.cc	2006-04-14 17:24:47 UTC (rev 615)
+++ development/source/cpu/cHardwareSMT.cc	2006-04-14 18:17:00 UTC (rev 616)
@@ -700,12 +700,12 @@
   
   // Make sure the creature will still be above the minimum size
   if (end_pos <= 0) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
+    organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
     return false; // (inject fails)
   }
   if (end_pos < MIN_INJECT_SIZE) {
     m_mem_array[mem_space_used] = cGenome("a"); 
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
+    organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
     return false; // (inject fails)
   }  
   
@@ -742,168 +742,7 @@
   return true;
 }
 
-void cHardwareSMT::Mutate(cAvidaContext& ctx, int mut_point)
-{
-  // Test if trying to mutate outside of genome...
-  assert(mut_point >= 0 && mut_point < m_mem_array[0].GetSize());
-	
-  m_mem_array[0][mut_point] = m_inst_set->GetRandomInst(ctx);
-  m_mem_array[0].SetFlagMutated(mut_point);
-  m_mem_array[0].SetFlagPointMut(mut_point);
-  organism->CPUStats().mut_stats.point_mut_count++;
-}
 
-int cHardwareSMT::PointMutate(cAvidaContext& ctx, const double mut_rate)
-{
-  const int num_muts = ctx.GetRandom().GetRandBinomial(m_mem_array[0].GetSize(), mut_rate);
-	
-  for (int i = 0; i < num_muts; i++) {
-    const int pos = ctx.GetRandom().GetUInt(m_mem_array[0].GetSize());
-    Mutate(ctx, pos);
-  }
-	
-  return num_muts;
-}
-
-
-// Trigger mutations of a specific type.  Outside triggers cannot specify
-// a head since hardware types are not known.
-
-bool cHardwareSMT::TriggerMutations(cAvidaContext& ctx, int trigger)
-{
-  // Only update triggers should happen from the outside!
-  assert(trigger == nMutation::TRIGGER_UPDATE);
-	
-  // Assume instruction pointer is the intended target (if one is even
-  // needed!
-	
-  return TriggerMutations(ctx, trigger, IP());
-}
-
-bool cHardwareSMT::TriggerMutations(cAvidaContext& ctx, int trigger, cHeadCPU& cur_head)
-{
-  // Collect information about mutations from the organism.
-  cLocalMutations& mut_info = organism->GetLocalMutations();
-  const tList<cMutation> & mut_list =
-    mut_info.GetMutationLib().GetMutationList(trigger);
-	
-  // If we have no mutations for this trigger, stop here.
-  if (mut_list.GetSize() == 0) return false;
-  bool has_mutation = false;
-	
-  // Determine what memory this mutation will be affecting.
-  cCPUMemory & target_mem = (trigger == nMutation::TRIGGER_DIVIDE) 
-    ? organism->ChildGenome() : m_mem_array[0];
-	
-  // Loop through all mutations associated with this trigger and test them.
-  tConstListIterator<cMutation> mut_it(mut_list);
-	
-  while (mut_it.Next() != NULL) {
-    const cMutation * cur_mut = mut_it.Get();
-    const int mut_id = cur_mut->GetID();
-    const int scope = cur_mut->GetScope();
-    const double rate = mut_info.GetRate(mut_id);
-    switch (scope) {
-			case nMutation::SCOPE_GENOME:
-				if (TriggerMutations_ScopeGenome(ctx, cur_mut, target_mem, cur_head, rate)) {
-					has_mutation = true;
-					mut_info.IncCount(mut_id);
-				}
-				break;
-			case nMutation::SCOPE_LOCAL:
-			case nMutation::SCOPE_PROP:
-				if (TriggerMutations_ScopeLocal(ctx, cur_mut, target_mem, cur_head, rate)) {
-					has_mutation = true;
-					mut_info.IncCount(mut_id);
-				}
-				break;
-			case nMutation::SCOPE_GLOBAL:
-			case nMutation::SCOPE_SPREAD:
-				int num_muts =
-				TriggerMutations_ScopeGlobal(ctx, cur_mut, target_mem, cur_head, rate);
-				if (num_muts > 0) {
-					has_mutation = true;
-					mut_info.IncCount(mut_id, num_muts);
-				}
-					break;
-    }
-  }
-	
-  return has_mutation;
-}
-
-bool cHardwareSMT::TriggerMutations_ScopeGenome(cAvidaContext& ctx, const cMutation* cur_mut,
-                                                cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate)
-{
-  // The rate we have stored indicates the probability that a single
-  // mutation will occur anywhere in the genome.
-  
-  if (ctx.GetRandom().P(rate) == true) {
-    // We must create a temporary head and use it to randomly determine the
-    // position in the genome to be mutated.
-    cHeadCPU tmp_head(cur_head);
-    tmp_head.AbsSet(ctx.GetRandom().GetUInt(target_memory.GetSize()));
-    TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, tmp_head);
-    return true;
-  }
-  return false;
-}
-
-bool cHardwareSMT::TriggerMutations_ScopeLocal(cAvidaContext& ctx, const cMutation* cur_mut,
-                                               cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate)
-{
-  // The rate we have stored is the probability for a mutation at this single
-  // position in the genome.
-	
-  if (ctx.GetRandom().P(rate) == true) {
-    TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, cur_head);
-    return true;
-  }
-  return false;
-}
-
-int cHardwareSMT::TriggerMutations_ScopeGlobal(cAvidaContext& ctx, const cMutation * cur_mut,
-                                               cCPUMemory & target_memory, cHeadCPU& cur_head, const double rate)
-{
-  // The probability we have stored is per-site, so we can pull a random
-  // number from a binomial distribution to determine the number of mutations
-  // that should occur.
-	
-  const int num_mut =
-	ctx.GetRandom().GetRandBinomial(target_memory.GetSize(), rate);
-	
-  if (num_mut > 0) {
-    for (int i = 0; i < num_mut; i++) {
-      cHeadCPU tmp_head(cur_head);
-      tmp_head.AbsSet(ctx.GetRandom().GetUInt(target_memory.GetSize()));
-      TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, tmp_head);
-    }
-  }
-	
-  return num_mut;
-}
-
-void cHardwareSMT::TriggerMutations_Body(cAvidaContext& ctx, int type, cCPUMemory & target_memory, cHeadCPU& cur_head)
-{
-  const int pos = cur_head.GetPosition();
-	
-  switch (type) {
-		case nMutation::TYPE_POINT:
-			target_memory[pos] = m_inst_set->GetRandomInst(ctx);
-			target_memory.SetFlagMutated(pos);
-			break;
-		case nMutation::TYPE_INSERT:
-		case nMutation::TYPE_DELETE:
-		case nMutation::TYPE_HEAD_INC:
-		case nMutation::TYPE_HEAD_DEC:
-		case nMutation::TYPE_TEMP:
-		case nMutation::TYPE_KILL:
-		default:
-      m_world->GetDriver().RaiseException("Mutation type not implemented!");
-			break;
-  };
-}
-
 void cHardwareSMT::ReadInst(const int in_inst)
 {
   if (m_inst_set->IsNop( cInstruction(in_inst) )) {
@@ -1069,179 +908,17 @@
   return (base_stack + 2) % nHardwareSMT::NUM_STACKS;
 }
 
-inline void cHardwareSMT::Fault(int fault_loc, int fault_type, cString fault_desc)
-{
-  organism->Fault(fault_loc, fault_type, fault_desc);
-}
 
-bool cHardwareSMT::Divide_CheckViable(cAvidaContext& ctx, const int parent_size,
-                                      const int child_size, const int mem_space)
+int cHardwareSMT::GetCopiedSize(const int parent_size, const int child_size)
 {
-  // Make sure the organism is okay with dividing now...
-  if (organism->Divide_CheckViable() == false) return false; // (divide fails)
-
-  // Make sure that neither parent nor child will be below the minimum size.
-	
-  const int genome_size = organism->GetGenome().GetSize();
-  const double size_range = m_world->GetConfig().CHILD_SIZE_RANGE.Get();
-  const int min_size = Max(MIN_CREATURE_SIZE, (int) (genome_size/size_range));
-  const int max_size = Min(MAX_CREATURE_SIZE, (int) (genome_size*size_range));
-  
-  if (child_size < min_size || child_size > max_size) {
-    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-					cStringUtil::Stringf("Invalid offspring length (%d)", child_size));
-    return false; // (divide fails)
-  }
-	
-  // Count the number of lines executed in the parent, and make sure the
-  // specified fraction has been reached.
-	
-  int executed_size = 0;
-  for (int i = 0; i < parent_size; i++) {
-    if (m_mem_array[0].FlagExecuted(i)) executed_size++;
-  }
-	
-  const int min_exe_lines = (int) (parent_size * m_world->GetConfig().MIN_EXE_LINES.Get());
-  if (executed_size < min_exe_lines) {
-    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-					cStringUtil::Stringf("Too few executed lines (%d < %d)",
-															 executed_size, min_exe_lines));
-    return false; // (divide fails)
-  }
-	
-  // Count the number of lines which were copied into the child, and make
-  // sure the specified fraction has been reached.
-	
   int copied_size = 0;
-  for (int i = 0; i < m_mem_array[mem_space].GetSize(); i++) {
-    if (m_mem_array[mem_space].FlagCopied(i)) copied_size++;
+  const cCPUMemory& memory = m_mem_array[m_cur_child];
+  for (int i = 0; i < memory.GetSize(); i++) {
+    if (memory.FlagCopied(i)) copied_size++;
 	}
-	
-  const int min_copied = static_cast<int>(child_size * m_world->GetConfig().MIN_COPIED_LINES.Get());
-  if (copied_size < min_copied) {
-    Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-					cStringUtil::Stringf("Too few copied commands (%d < %d)",
-															 copied_size, min_copied));
-    return false; // (divide fails)
-  }
-	
-  // Save the information we collected here...
-  organism->GetPhenotype().SetLinesExecuted(executed_size);
-  organism->GetPhenotype().SetLinesCopied(copied_size);
-	
-  return true; // (divide succeeds!)
+  return copied_size;
 }
 
-void cHardwareSMT::Divide_DoMutations(cAvidaContext& ctx, double mut_multiplier)
-{
-  sCPUStats& cpu_stats = organism->CPUStats();
-  cCPUMemory& child_genome = organism->ChildGenome();
-  
-  organism->GetPhenotype().SetDivType(mut_multiplier);
-	
-  // Divide Mutations
-  if (organism->TestDivideMut(ctx)) {
-    const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize());
-    child_genome[mut_line] = m_inst_set->GetRandomInst(ctx);
-    cpu_stats.mut_stats.divide_mut_count++;
-  }
-	
-  // Divide Insertions
-  if (organism->TestDivideIns(ctx) && child_genome.GetSize() < MAX_CREATURE_SIZE){
-    const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize() + 1);
-    child_genome.Insert(mut_line, m_inst_set->GetRandomInst(ctx));
-    cpu_stats.mut_stats.divide_insert_mut_count++;
-  }
-	
-  // Divide Deletions
-  if (organism->TestDivideDel(ctx) && child_genome.GetSize() > MIN_CREATURE_SIZE){
-    const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize());
-    child_genome.Remove(mut_line);
-    cpu_stats.mut_stats.divide_delete_mut_count++;
-  }
-	
-  // Divide Mutations (per site)
-  if(organism->GetDivMutProb() > 0){
-    int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(), 
-																					 organism->GetDivMutProb() / mut_multiplier);
-    // If we have lines to mutate...
-    if( num_mut > 0 ){
-      for (int i = 0; i < num_mut; i++) {
-				int site = ctx.GetRandom().GetUInt(child_genome.GetSize());
-				child_genome[site] = m_inst_set->GetRandomInst(ctx);
-				cpu_stats.mut_stats.div_mut_count++;
-      }
-    }
-  }
-	
-	
-  // Insert Mutations (per site)
-  if(organism->GetInsMutProb() > 0){
-    int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(),
-																					 organism->GetInsMutProb());
-    // If would make creature to big, insert up to MAX_CREATURE_SIZE
-    if( num_mut + child_genome.GetSize() > MAX_CREATURE_SIZE ){
-      num_mut = MAX_CREATURE_SIZE - child_genome.GetSize();
-    }
-    // If we have lines to insert...
-    if( num_mut > 0 ){
-      // Build a list of the sites where mutations occured
-      static int mut_sites[MAX_CREATURE_SIZE];
-      for (int i = 0; i < num_mut; i++) {
-				mut_sites[i] = ctx.GetRandom().GetUInt(child_genome.GetSize() + 1);
-      }
-      // Sort the list
-      qsort( (void*)mut_sites, num_mut, sizeof(int), &IntCompareFunction );
-      // Actually do the mutations (in reverse sort order)
-      for(int i = num_mut-1; i >= 0; i--) {
-				child_genome.Insert(mut_sites[i], m_inst_set->GetRandomInst(ctx));
-				cpu_stats.mut_stats.insert_mut_count++;
-      }
-    }
-  }
-	
-	
-  // Delete Mutations (per site)
-  if( organism->GetDelMutProb() > 0 ){
-    int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(),
-																					 organism->GetDelMutProb());
-    // If would make creature too small, delete down to MIN_CREATURE_SIZE
-    if (child_genome.GetSize() - num_mut < MIN_CREATURE_SIZE) {
-      num_mut = child_genome.GetSize() - MIN_CREATURE_SIZE;
-    }
-		
-    // If we have lines to delete...
-    for (int i = 0; i < num_mut; i++) {
-      int site = ctx.GetRandom().GetUInt(child_genome.GetSize());
-      child_genome.Remove(site);
-      cpu_stats.mut_stats.delete_mut_count++;
-    }
-  }
-	
-  // Mutations in the parent's genome
-  if (organism->GetParentMutProb() > 0) {
-    for (int i = 0; i < m_mem_array[0].GetSize(); i++) {
-      if (organism->TestParentMut(ctx)) {
-				m_mem_array[0][i] = m_inst_set->GetRandomInst(ctx);
-				cpu_stats.mut_stats.parent_mut_line_count++;
-      }
-    }
-  }
-	
-	
-  // Count up mutated lines
-  for(int i = 0; i < m_mem_array[0].GetSize(); i++){
-    if (m_mem_array[0].FlagPointMut(i)) {
-      cpu_stats.mut_stats.point_mut_line_count++;
-    }
-  }
-  for(int i = 0; i < child_genome.GetSize(); i++){
-    if( child_genome.FlagCopyMut(i)) {
-      cpu_stats.mut_stats.copy_mut_line_count++;
-    }
-  }
-}
-
 void cHardwareSMT::Inject_DoMutations(cAvidaContext& ctx, double mut_multiplier, cCPUMemory & injected_code)
 {
   organism->GetPhenotype().SetDivType(mut_multiplier);
@@ -1331,82 +1008,20 @@
 }
 
 
-// test whether the offspring creature contains an advantageous mutation.
-void cHardwareSMT::Divide_TestFitnessMeasures(cAvidaContext& ctx)
-{
-  cPhenotype & phenotype = organism->GetPhenotype();
-  phenotype.CopyTrue() = ( organism->ChildGenome() == organism->GetGenome() );
-  phenotype.ChildFertile() = true;
-	
-  // Only continue if we're supposed to do a fitness test on divide...
-  if (organism->GetTestOnDivide() == false) return;
-	
-  // If this was a perfect copy, then we don't need to worry about any other
-  // tests...  Theoretically, we need to worry about the parent changing,
-  // but as long as the child is always compared to the original genotype,
-  // this won't be an issue.
-  if (phenotype.CopyTrue() == true) return;
-	
-  const double parent_fitness = organism->GetTestFitness();
-  const double neut_min = parent_fitness * nHardware::FITNESS_NEUTRAL_MIN;
-  const double neut_max = parent_fitness * nHardware::FITNESS_NEUTRAL_MAX;
-  
-  cTestCPU* testcpu = m_world->GetHardwareManager().CreateTestCPU();
-  cCPUTestInfo test_info;
-  test_info.UseRandomInputs();
-  testcpu->TestGenome(ctx, test_info, organism->ChildGenome());
-  const double child_fitness = test_info.GetGenotypeFitness();
-  delete testcpu;
-  
-  bool revert = false;
-  bool sterilize = false;
-  
-  // If implicit mutations are turned off, make sure this won't spawn one.
-  if (organism->GetFailImplicit() == true) {
-    if (test_info.GetMaxDepth() > 0) sterilize = true;
-  }
-  
-  if (child_fitness == 0.0) {
-    // Fatal mutation... test for reversion.
-    if (ctx.GetRandom().P(organism->GetRevertFatal())) revert = true;
-    if (ctx.GetRandom().P(organism->GetSterilizeFatal())) sterilize = true;
-  } else if (child_fitness < neut_min) {
-    if (ctx.GetRandom().P(organism->GetRevertNeg())) revert = true;
-    if (ctx.GetRandom().P(organism->GetSterilizeNeg())) sterilize = true;
-  } else if (child_fitness <= neut_max) {
-    if (ctx.GetRandom().P(organism->GetRevertNeut())) revert = true;
-    if (ctx.GetRandom().P(organism->GetSterilizeNeut())) sterilize = true;
-  } else {
-    if (ctx.GetRandom().P(organism->GetRevertPos())) revert = true;
-    if (ctx.GetRandom().P(organism->GetSterilizePos())) sterilize = true;
-  }
-  
-  // Ideally, we won't have reversions and sterilizations turned on at the
-  // same time, but if we do, give revert the priority.
-  if (revert == true) {
-    organism->ChildGenome() = organism->GetGenome();
-  }
-	
-  if (sterilize == true) {
-    organism->GetPhenotype().ChildFertile() = false;
-  }
-}
-
-
 bool cHardwareSMT::Divide_Main(cAvidaContext& ctx, int mem_space_used, double mut_multiplier)
 {
   int write_head_pos = GetHead(nHardware::HEAD_WRITE).GetPosition();
   
-  // @DMB - change to allow ???
   // We're going to disallow division calls from memory spaces other than zero for right now @law
+  // @DMB - change to allow ???
   if(IP().GetMemSpace() != 0) return false;
 
   // Make sure the memory space we're using exists
   if (m_mem_array.GetSize() <= mem_space_used) return false;
-	
+  	
   // Make sure this divide will produce a viable offspring.
-  if(!Divide_CheckViable(ctx, m_mem_array[IP().GetMemSpace()].GetSize(), write_head_pos, mem_space_used)) 
-    return false;
+  m_cur_child = mem_space_used; // save current child memory space for use by dependent functions (e.g. GetCopiedSize())
+  if (!Divide_CheckViable(ctx, m_mem_array[IP().GetMemSpace()].GetSize(), write_head_pos)) return false;
   
   // Since the divide will now succeed, set up the information to be sent to the new organism
   m_mem_array[mem_space_used].Resize(write_head_pos);
@@ -1574,11 +1189,11 @@
 #endif
   if (Stack(op2).Top() != 0) {
     if (0-INT_MAX > Stack(op1).Top() && Stack(op2).Top() == -1)
-      Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: Float exception");
+      organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: Float exception");
     else
       Stack(dst).Push(Stack(op1).Top() / Stack(op2).Top());
   } else {
-    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: dividing by 0");
+    organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: dividing by 0");
     return false;
   }
   return true;
@@ -1629,7 +1244,7 @@
     else
       Stack(dst).Push(Stack(op1).Top() % Stack(op2).Top());
   } else {
-    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "mod: modding by 0");
+    organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "mod: modding by 0");
 		return false;
   }
   return true;
@@ -1938,7 +1553,7 @@
 bool cHardwareSMT::Inst_ThreadCreate(cAvidaContext& ctx)
 {
   if (!ForkThread()) 
-    Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
+    organism->Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
   else
     IP().Advance();
   return true;
@@ -1956,7 +1571,7 @@
 //35
 bool cHardwareSMT::Inst_ThreadExit(cAvidaContext& ctx)
 {
-  if (!KillThread()) Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);
+  if (!KillThread()) organism->Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);
   else AdvanceIP() = false;
   return true;
 }

Modified: development/source/cpu/cHardwareSMT.h
===================================================================
--- development/source/cpu/cHardwareSMT.h	2006-04-14 17:24:47 UTC (rev 615)
+++ development/source/cpu/cHardwareSMT.h	2006-04-14 18:17:00 UTC (rev 616)
@@ -66,7 +66,7 @@
 public:
   typedef bool (cHardwareSMT::*tMethod)(cAvidaContext& ctx);
 
-private:
+protected:
   static tInstLib<cHardwareSMT::tMethod>* s_inst_slib;
   static tInstLib<cHardwareSMT::tMethod>* initInstLib(void);
 
@@ -89,6 +89,8 @@
   tArray<int> inst_cost;
   tArray<int> inst_ft_cost;
 #endif
+  
+  int m_cur_child;
 
   
   bool SingleProcess_PayCosts(cAvidaContext& ctx, const cInstruction& cur_inst);
@@ -117,16 +119,7 @@
   const cCodeLabel& GetReadLabel() const { return m_threads[m_cur_thread].read_label; }
   cCodeLabel& GetReadLabel() { return m_threads[m_cur_thread].read_label; }
 
-  
-  bool TriggerMutations_ScopeGenome(cAvidaContext& ctx, const cMutation* cur_mut,
-																		cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate);
-  bool TriggerMutations_ScopeLocal(cAvidaContext& ctx, const cMutation* cur_mut,
-																	 cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate);
-  int TriggerMutations_ScopeGlobal(cAvidaContext& ctx, const cMutation* cur_mut,
-																	 cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate);
-  void TriggerMutations_Body(cAvidaContext& ctx, int type, cCPUMemory& target_memory,
-														 cHeadCPU& cur_head);
-	
+  	
   // ---------- Instruction Helpers -----------
   int FindModifiedStack(int default_stack);
   int FindModifiedNextStack(int default_stack);
@@ -139,18 +132,15 @@
   int FindMemorySpaceLabel(const cCodeLabel& label, int mem_space);
   bool MemorySpaceExists(const cCodeLabel& label);
 	
-  void Fault(int fault_loc, int fault_type, cString fault_desc=""); 
   bool Allocate_Necro(const int new_size);
   bool Allocate_Random(const int old_size, const int new_size);
   bool Allocate_Default(const int new_size);
   bool Allocate_Main(const int allocated_size);
-	
-  bool Divide_Main(cAvidaContext& ctx, const int mem_space_used, double mut_multiplier=1);
-  bool Divide_CheckViable(cAvidaContext& ctx, const int parent_size, const int child_size, const int mem_space);
-  void Divide_DoMutations(cAvidaContext& ctx, double mut_multiplier = 1);
+
+	int GetCopiedSize(const int parent_size, const int child_size);
+  
+  bool Divide_Main(cAvidaContext& ctx, const int mem_space_used, double mut_multiplier = 1.0);
   void Inject_DoMutations(cAvidaContext& ctx, double mut_multiplier, cCPUMemory& injected_code);
-  void Divide_TestFitnessMeasures(cAvidaContext& ctx);
-  void Mutate(cAvidaContext& ctx, const int mut_point);
 
   bool InjectParasite(cAvidaContext& ctx, double mut_multiplier);
 
@@ -239,12 +229,6 @@
   }
 	
   
-  // --------  Mutation  --------
-  int PointMutate(cAvidaContext& ctx, const double mut_rate);  
-  bool TriggerMutations(cAvidaContext& ctx, int trigger);
-  bool TriggerMutations(cAvidaContext& ctx, int trigger, cHeadCPU& cur_head);
-
-
 private:
   // ---------- Instruction Library -----------
   bool Inst_ShiftR(cAvidaContext& ctx);




More information about the Avida-cvs mailing list