[Avida-SVN] r2030 - in branches/collect/source: classification cpu main script tools

blwalker at myxo.css.msu.edu blwalker at myxo.css.msu.edu
Thu Aug 30 12:04:02 PDT 2007


Author: blwalker
Date: 2007-08-30 15:04:02 -0400 (Thu, 30 Aug 2007)
New Revision: 2030

Modified:
   branches/collect/source/classification/cGenotypeControl.cc
   branches/collect/source/cpu/cHardwareCPU.cc
   branches/collect/source/cpu/cHardwareCPU.h
   branches/collect/source/cpu/cInstSet.cc
   branches/collect/source/cpu/cTestCPU.cc
   branches/collect/source/main/cAvidaConfig.h
   branches/collect/source/main/cOrganism.cc
   branches/collect/source/main/cOrganism.h
   branches/collect/source/main/cPopulation.cc
   branches/collect/source/main/cPopulationCell.cc
   branches/collect/source/main/cPopulationCell.h
   branches/collect/source/script/ASTree.cc
   branches/collect/source/script/ASTree.h
   branches/collect/source/script/cASTDumpVisitor.cc
   branches/collect/source/script/cASTDumpVisitor.h
   branches/collect/source/script/cASTVisitor.h
   branches/collect/source/script/cParser.cc
   branches/collect/source/tools/tArray.h
Log:

Porting development r2014:2016, r2017:2019, r2020:2026, and r2027:2028 to collect branch, thus making it current.

Translation: I am done spamming you now.  Sorry 'bout that.


Modified: branches/collect/source/classification/cGenotypeControl.cc
===================================================================
--- branches/collect/source/classification/cGenotypeControl.cc	2007-08-30 18:26:42 UTC (rev 2029)
+++ branches/collect/source/classification/cGenotypeControl.cc	2007-08-30 19:04:02 UTC (rev 2030)
@@ -204,29 +204,22 @@
 
 bool cGenotypeControl::Adjust(cGenotype & in_genotype)
 {
-  cGenotype * cur_genotype = in_genotype.GetPrev();
+  cGenotype* cur_genotype = in_genotype.GetPrev();
 
   // Check to see if this genotype should be removed completely.
-
-  if (in_genotype.GetNumOrganisms() == 0 &&
-      in_genotype.GetDeferAdjust() == false) {
+  if (in_genotype.GetNumOrganisms() == 0 && in_genotype.GetDeferAdjust() == false) {
     m_world->GetClassificationManager().RemoveGenotype(in_genotype);
     return false;
   }
 
   // Do not adjust the position of this genotype if it was and still is the
   // best genotype, or if it is otherwise in the proper spot...
+  if (CheckPos(in_genotype)) return true;
 
-  if (CheckPos(in_genotype)) {
-    return true;
-  }
-
   // Otherwise, remove it from the queue (for just the moment).
-
   Remove(in_genotype);
 
   // If this genotype is the best, put it there.
-
   if (in_genotype.GetNumOrganisms() > best->GetNumOrganisms()) {
     Insert(in_genotype, best->GetPrev());
     best = &in_genotype;

Modified: branches/collect/source/cpu/cHardwareCPU.cc
===================================================================
--- branches/collect/source/cpu/cHardwareCPU.cc	2007-08-30 18:26:42 UTC (rev 2029)
+++ branches/collect/source/cpu/cHardwareCPU.cc	2007-08-30 19:04:02 UTC (rev 2030)
@@ -355,9 +355,10 @@
     tInstLibEntry<tMethod>("time", &cHardwareCPU::Inst_GetUpdate),
     
     // Promoter Model
+    tInstLibEntry<tMethod>("promoter", &cHardwareCPU::Inst_Promoter),
     tInstLibEntry<tMethod>("terminate", &cHardwareCPU::Inst_Terminate),
-    tInstLibEntry<tMethod>("promoter", &cHardwareCPU::Inst_Promoter),
     tInstLibEntry<tMethod>("regulate", &cHardwareCPU::Inst_Regulate),
+    tInstLibEntry<tMethod>("numberate", &cHardwareCPU::Inst_Numberate),
     
     // Energy usage
     tInstLibEntry<tMethod>("double-energy-usage", &cHardwareCPU::Inst_DoubleEnergyUsage),
@@ -466,20 +467,22 @@
   }
 #endif   
 
+  // Promoter model
   if (m_world->GetConfig().PROMOTERS_ENABLED.Get())
   {
     // Ideally, this shouldn't be hard-coded
     cInstruction promoter_inst = m_world->GetHardwareManager().GetInstSet().GetInst(cStringUtil::Stringf("promoter"));
-    promoter_search_pos = 0;
-    promoter_inst_executed = 0;
-    promoter_pos.Resize(0);
-    promoter_active.Resize(0);
+
+    m_promoter_index = -1; // Meaning the last promoter was nothing
+    m_promoter_offset = 0;
+    m_promoter_regulation = 0;
+    m_promoters.Resize(0);
     for (int i=0; i<GetMemory().GetSize(); i++)
     {
       if ( (GetMemory())[i] == promoter_inst)
       {
-        promoter_pos.Push(i);
-        promoter_active.Push(true);
+        int code = Numberate(i-1, -1);
+        m_promoters.Push( cPromoter(i,code) );
       }
     }
   }
@@ -505,27 +508,27 @@
   cur_head = nHardware::HEAD_IP;
   read_label.Clear();
   next_label.Clear();
+  
+  // Promoter model
+  m_promoter_inst_executed = 0;
 }
 
-
-
 // This function processes the very next command in the genome, and is made
 // to be as optimized as possible.  This is the heart of avida.
 
 void cHardwareCPU::SingleProcess(cAvidaContext& ctx)
 {
   int last_IP_pos = IP().GetPosition();
-
+  
   // Mark this organism as running...
   organism->SetRunning(true);
+  cPhenotype& phenotype = organism->GetPhenotype();
   
-  cPhenotype & phenotype = organism->GetPhenotype();
+  // First instruction - check whether we should be starting at a promoter, when enabled.
+  if (phenotype.GetCPUCyclesUsed() == 0 && m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1)
+    Inst_Terminate(m_world->GetDefaultContext());
   
-  if (m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1) {
-    //First instruction - check whether we should be starting at a promoter.
-    if (phenotype.GetCPUCyclesUsed() == 0) Inst_Terminate(m_world->GetDefaultContext());
-  }
-  
+  // Count the cpu cycles used
   phenotype.IncCPUCyclesUsed();
   if (!m_world->GetConfig().NO_CPU_CYCLE_TIME.Get()) phenotype.IncTimeUsed();
 
@@ -557,6 +560,14 @@
     // Test if costs have been paid and it is okay to execute this now...
     bool exec = SingleProcess_PayCosts(ctx, cur_inst);
 
+    // If there are no active promoters and a certain mode is set, then don't execute any further instructions
+    if ((m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1) 
+      && (m_world->GetConfig().NO_ACTIVE_PROMOTER_EFFECT.Get() == 2) 
+      && (m_promoter_index == -1) ) 
+    { 
+      exec = false;
+    }
+    
     // Now execute the instruction...
     if (exec == true) {
       // NOTE: This call based on the cur_inst must occur prior to instruction
@@ -571,7 +582,7 @@
       
       //Add to the promoter inst executed count before executing the inst (in case it is a terminator)
       if (m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1) {
-        promoter_inst_executed++;
+        m_threads[m_cur_thread].IncPromoterInstExecuted();
       }
 
       if (exec == true) SingleProcess_ExecuteInst(ctx, cur_inst);
@@ -582,29 +593,19 @@
       
       // Pay the time cost of the instruction now
       phenotype.IncTimeUsed(time_cost);
-      
-      // In the promoter model, there may be a chance of termination
-      // that causes execution to start at a new instruction (per instruction executed)
-      if ( m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1 ) {
-        const double processivity = m_world->GetConfig().PROMOTER_PROCESSIVITY_INST.Get();
-        if ( ctx.GetRandom().P(1-processivity) ) Inst_Terminate(ctx);
+            
+      // In the promoter model, we may force termination after a certain number of inst have been executed
+      if ( m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1 )
+      {
+        const double processivity = m_world->GetConfig().PROMOTER_PROCESSIVITY.Get();
+        if ( ctx.GetRandom().P(1-processivity) ) 
+          Inst_Terminate(ctx);
+        if ( m_world->GetConfig().PROMOTER_INST_MAX.Get() && (m_threads[m_cur_thread].GetPromoterInstExecuted() >= m_world->GetConfig().PROMOTER_INST_MAX.Get()) ) 
+          Inst_Terminate(ctx);
       }
-      
+
     } // if exec
-    
-    // In the promoter model, there may be a chance of termination
-    // that causes execution to start at a new instruction (per cpu cycle executed)
-    // @JEB - since processivities usually v. close to 1 it doesn't
-    // improve speed much to combine with "per instruction" block
-    if ( m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1 )
-    {
-      const double processivity = m_world->GetConfig().PROMOTER_PROCESSIVITY.Get();
-      if ( ctx.GetRandom().P(1-processivity) ) 
-        Inst_Terminate(ctx);
-      if ( m_world->GetConfig().PROMOTER_MAX_INST.Get() && (promoter_inst_executed >= m_world->GetConfig().PROMOTER_MAX_INST.Get()) ) 
-        Inst_Terminate(ctx);
-    }
-    
+        
   } // Previous was executed once for each thread...
   
   // Kill creatures who have reached their max num of instructions executed
@@ -723,13 +724,16 @@
       
   if (m_world->GetConfig().PROMOTERS_ENABLED.Get())
   {
-    fp << "Promoters:";
-    for (int i=0; i<promoter_pos.GetSize(); i++)
+    fp << "Promoters: index=" << m_promoter_index << " offset=" << m_promoter_offset;
+    fp << " exe_inst=" << m_threads[m_cur_thread].GetPromoterInstExecuted();
+    fp << " regulation=0x" << setbase(16) << setfill('0') << setw(8) << m_promoter_regulation << endl;
+    for (int i=0; i<m_promoters.GetSize(); i++)
     {
-      fp << " " << promoter_pos[i] << "-" << (promoter_active[i] ? "on" : "off"); 
+      fp << setfill(' ') << setbase(10) << i << "(" << m_promoters[i].m_pos << "):";
+      fp << "Ox" << setbase(16) << setfill('0') << setw(8) << (m_promoters[i].m_bit_code ^ m_promoter_regulation) << " "; 
     }
-    fp << endl;
-    fp << "Instructions executed past promoter: " << promoter_inst_executed << endl;
+    fp << endl;    
+    fp << setfill(' ') << setbase(10) << endl;
   }    
   fp.flush();
 }
@@ -4371,56 +4375,188 @@
   return true;
 }
 
-// Move execution to a new promoter
+// Move the instruction ptr to the next active promoter
 bool cHardwareCPU::Inst_Terminate(cAvidaContext& ctx)
 {
-  // Reset the CPU, clearing everything except R/W head positions.
-  const int write_head_pos = GetHead(nHardware::HEAD_WRITE).GetPosition();
-  const int read_head_pos = GetHead(nHardware::HEAD_READ).GetPosition();
-  m_threads[m_cur_thread].Reset(this, m_threads[m_cur_thread].GetID());
-  GetHead(nHardware::HEAD_WRITE).Set(write_head_pos);
-  GetHead(nHardware::HEAD_READ).Set(read_head_pos);
+  // Optionally,
+  // Reset the thread.
+  if (m_world->GetConfig().TERMINATION_RESETS.Get())
+  {
+    //const int write_head_pos = GetHead(nHardware::HEAD_WRITE).GetPosition();
+    //const int read_head_pos = GetHead(nHardware::HEAD_READ).GetPosition();
+    m_threads[m_cur_thread].Reset(this, m_threads[m_cur_thread].GetID());
+    //GetHead(nHardware::HEAD_WRITE).Set(write_head_pos);
+    //GetHead(nHardware::HEAD_READ).Set(read_head_pos);
+    
+    //Setting this makes it harder to do things. You have to be modular.
+    organism->GetOrgInterface().ResetInputs(ctx);   // Re-randomize the inputs this organism sees
+    organism->ClearInput();                         // Also clear their input buffers, or they can still claim
+                                                    // rewards for numbers no longer in their environment!
+  }
+  
+  // Reset our count
+  m_threads[m_cur_thread].ResetPromoterInstExecuted();
+  m_advance_ip = false;
+  const int reg_used = REG_BX; // register to put chosen promoter code in, for now always BX
 
-  // We want to execute the promoter that we land on.
-  promoter_inst_executed = 0;
-  m_advance_ip = false;
+  // Search for an active promoter  
+  int start_offset = m_promoter_offset;
+  int start_index  = m_promoter_index;
   
-  //Setting this makes it harder to do things. You have to be modular.
-  organism->GetOrgInterface().ResetInputs(ctx);   // Re-randomize the inputs this organism sees
-  organism->ClearInput();                         // Also clear their input buffers, or they can still claim
-                                                  // rewards for numbers no longer in their environment!
-  
-  // Find the next active promoter
-  int started_search_pos = promoter_search_pos;
-  
-  while (promoter_pos.GetSize() > 0) // conditional infinite loop, breaks out
+  bool no_promoter_found = true;
+  if ( m_promoters.GetSize() > 0 ) 
   {
-    promoter_search_pos++;
-    promoter_search_pos %= promoter_active.GetSize();
-    if (promoter_active[promoter_search_pos]) break;
-    if (started_search_pos == promoter_search_pos) break;
-  } 
+    while( true )
+    {
+      // If the next promoter is active, then break out
+      NextPromoter();
+      if (IsActivePromoter()) 
+      {
+        no_promoter_found = false;
+        break;
+      }
+      
+      // If we just checked the promoter that we were originally on, then there
+      // are no active promoters.
+      if ( (start_offset == m_promoter_offset) && (start_index == m_promoter_index) ) break;
+
+      // If we originally were not on a promoter, then stop once we check the
+      // first promoter and an offset of zero
+      if (start_index == -1)
+      {
+          start_index = 0;
+      }
+    } 
+  }
   
-  //Can't find a promoter -- start at the beginning of the genome (or die! or sleep!)
-  if ((promoter_pos.GetSize() == 0) || ((promoter_search_pos == started_search_pos) && (!promoter_active[promoter_search_pos])))
+  if (no_promoter_found)
   {
-    IP().Set(0);
+    if ((m_world->GetConfig().NO_ACTIVE_PROMOTER_EFFECT.Get() == 0) || (m_world->GetConfig().NO_ACTIVE_PROMOTER_EFFECT.Get() == 2))
+    {
+      // Set defaults for when no active promoter is found
+      m_promoter_index = -1;
+      IP().Set(0);
+      GetRegister(reg_used) = 0;
+      
+      // @JEB HACK! -- All kinds of bad stuff happens if execution length is zero. For now:
+      if (m_world->GetConfig().NO_ACTIVE_PROMOTER_EFFECT.Get() == 2) GetMemory().SetFlagExecuted(0);
+    }
+    // Death to organisms that refuse to use promoters!
+    else if (m_world->GetConfig().NO_ACTIVE_PROMOTER_EFFECT.Get() == 1)
+    {
+      organism->Die();
+    }
+    else
+    {
+      cout << "Unrecognized NO_ACTIVE_PROMOTER_EFFECT setting: " << m_world->GetConfig().NO_ACTIVE_PROMOTER_EFFECT.Get() << endl;
+    }
   }
   else
   {
-    IP().Set(promoter_pos[promoter_search_pos]);
+    // We found an active match, offset to just after it.
+    // and put its bit code in BX for the organism to have
+      // cHeadCPU will do the mod genome size for us
+    IP().Set(m_promoters[m_promoter_index].m_pos + 1);
+    GetRegister(reg_used) = m_promoters[m_promoter_index].m_bit_code;
   }
-  
   return true;
 }
 
-// To be implemented...
+// Get a new regulation code (which is XOR'ed with promoter codes).
 bool cHardwareCPU::Inst_Regulate(cAvidaContext& ctx)
 {
+  const int reg_used = FindModifiedRegister(REG_BX);
+  m_promoter_regulation = GetRegister(reg_used);
   return true;
 }
 
+// Create a number from inst bit codes
+bool cHardwareCPU::Inst_Numberate(cAvidaContext& ctx)
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  
+  // advance the IP now, so that it rests on the beginning of our number
+  IP().Advance();
+  m_advance_ip = false;
+  
+  int num = Numberate(IP().GetPosition(), +1);
+  GetRegister(reg_used) = num;
+  return true;
+}
 
+// Move to the next promoter.
+void cHardwareCPU::NextPromoter()
+{
+  // Move promoter index, rolling over if necessary
+  m_promoter_index++;
+  if (m_promoter_index == m_promoters.GetSize())
+  {
+    m_promoter_index = 0;
+    
+    // Move offset, rolling over when there are not enough bits before we would have to wrap around left
+    m_promoter_offset+=m_world->GetConfig().PROMOTER_EXE_LENGTH.Get();
+    if (m_promoter_offset + m_world->GetConfig().PROMOTER_EXE_LENGTH.Get() >= cHardwareCPU::PROMOTER_CODE_SIZE)
+    {
+      m_promoter_offset = 0;
+    }
+  }
+}
+
+
+// Check whether the current promoter is active.
+bool cHardwareCPU::IsActivePromoter()
+{
+  assert( m_promoters.GetSize() != 0 );
+  int count = 0;
+  unsigned int code = m_promoters[m_promoter_index].m_bit_code ^ m_promoter_regulation;
+  for(int i=0; i<m_world->GetConfig().PROMOTER_EXE_LENGTH.Get(); i++)
+  {
+    int offset = m_promoter_offset + i;
+    offset %= cHardwareCPU::PROMOTER_CODE_SIZE;
+    int state = code >> offset;
+    count += (state & 1);
+  }
+
+  return (count >= m_world->GetConfig().PROMOTER_EXE_THRESHOLD.Get());
+}
+
+// Construct a promoter bit code from instruction bit codes
+int cHardwareCPU::Numberate(int _pos, int _dir)
+{  
+  int code_size = 0;
+  unsigned int code = 0;
+  int j = _pos;
+  j %= GetMemory().GetSize();
+  while (code_size < cHardwareCPU::PROMOTER_CODE_SIZE)
+  {
+    unsigned int inst_code = (unsigned int) GetInstSet().GetInstructionCode( (GetMemory())[j] );
+    // shift bits in, one by one ... excuse the counter pun
+    for (int code_on = 0; (code_size < cHardwareCPU::PROMOTER_CODE_SIZE) && (code_on < m_world->GetConfig().INST_CODE_LENGTH.Get()); code_on++)
+    {
+      if (_dir < 0)
+      {
+        code >>= 1; // shift first so we don't go one too far at the end
+        code += (1 << (cHardwareCPU::PROMOTER_CODE_SIZE - 1)) * (inst_code & 1);
+        inst_code >>= 1; 
+      }
+      else
+      {
+        code <<= 1; // shift first so we don't go one too far at the end;        
+        code += (inst_code >> (m_world->GetConfig().INST_CODE_LENGTH.Get() - 1)) & 1;
+        inst_code <<= 1; 
+      }
+      code_size++;
+    }
+    
+     // move back one inst
+    j += GetMemory().GetSize() + _dir;
+    j %= GetMemory().GetSize();
+
+  }
+  return code;
+}
+
+
 /*! Send a message to the organism that is currently faced by this cell,
 where the label field of sent message is from register ?BX?, and the data field
 is from register ~?BX?.
@@ -4436,7 +4572,6 @@
   return organism->SendMessage(ctx, msg);
 }
 
-
 /*! This method /attempts/ to retrieve a message -- It may not be possible, as in
 the case of an empty receive buffer.
 
@@ -4457,7 +4592,6 @@
   return true;
 }
 
-
 //// Placebo insts ////
 bool cHardwareCPU::Inst_Skip(cAvidaContext& ctx)
 {

Modified: branches/collect/source/cpu/cHardwareCPU.h
===================================================================
--- branches/collect/source/cpu/cHardwareCPU.h	2007-08-30 18:26:42 UTC (rev 2029)
+++ branches/collect/source/cpu/cHardwareCPU.h	2007-08-30 19:04:02 UTC (rev 2030)
@@ -89,13 +89,14 @@
   static const int NUM_HEADS = nHardware::NUM_HEADS >= NUM_REGISTERS ? nHardware::NUM_HEADS : NUM_REGISTERS;
   enum tRegisters { REG_AX = 0, REG_BX, REG_CX, REG_DX, REG_EX, REG_FX };
   static const int NUM_NOPS = 3;
+  static const int PROMOTER_CODE_SIZE = sizeof(int) * 8; // Number of bits in promoter codes
   
   // --------  Data Structures  --------
   struct cLocalThread
   {
   private:
     int m_id;
-    
+    int m_promoter_inst_executed;
   public:
     int reg[NUM_REGISTERS];
     cHeadCPU heads[NUM_HEADS];
@@ -115,6 +116,9 @@
     void Reset(cHardwareBase* in_hardware, int in_id);
     int GetID() const { return m_id; }
     void SetID(int in_id) { m_id = in_id; }
+    int GetPromoterInstExecuted() { return m_promoter_inst_executed; }
+    void IncPromoterInstExecuted() { m_promoter_inst_executed++; }
+    void ResetPromoterInstExecuted() { m_promoter_inst_executed = 0; }
   };
 
     
@@ -137,13 +141,24 @@
   bool m_mal_active;         // Has an allocate occured since last divide?
   bool m_advance_ip;         // Should the IP advance after this instruction?
   bool m_executedmatchstrings;	// Have we already executed the match strings instruction?
+
+  // <-- Promoter model
+  int m_promoter_index;       //site to begin looking for the next active promoter from
+  int m_promoter_offset;      //bit offset when testing whether a promoter is on
+  int m_promoter_regulation;  //bit code that modifies current execution, via an XOR
   
-  // Promoter model
-  int promoter_search_pos;      //site to begin looking for the next active promoter from
-  int promoter_inst_executed;   //num inst executed since last termination
-  tArray<int> promoter_pos;     //positions with promoter instructions
-  tArray<bool> promoter_active; //whether each promoter is active (same size as promoter_pos)
-  
+  struct cPromoter 
+  {
+  public:
+    int m_pos;      //position within genome
+    int m_bit_code; //bit code of promoter
+  public:
+    cPromoter(int _pos = 0, int _bit_code = 0) { m_pos = _pos; m_bit_code = _bit_code; }
+    ~cPromoter() { ; }
+  };
+  tArray<cPromoter> m_promoters;
+  // Promoter Model -->
+
   bool SingleProcess_ExecuteInst(cAvidaContext& ctx, const cInstruction& cur_inst);
   
   // --------  Stack Manipulation...  --------
@@ -536,7 +551,13 @@
   bool Inst_Promoter(cAvidaContext& ctx);
   bool Inst_Terminate(cAvidaContext& ctx);
   bool Inst_Regulate(cAvidaContext& ctx);
+  bool Inst_Numberate(cAvidaContext& ctx);
 
+    // Helper functions //
+  bool IsActivePromoter();
+  void NextPromoter();
+  int Numberate(int _pos, int _dir);
+
   //// Messaging ////
   bool Inst_SendMessage(cAvidaContext& ctx);
   bool Inst_RetrieveMessage(cAvidaContext& ctx);

Modified: branches/collect/source/cpu/cInstSet.cc
===================================================================
--- branches/collect/source/cpu/cInstSet.cc	2007-08-30 18:26:42 UTC (rev 2029)
+++ branches/collect/source/cpu/cInstSet.cc	2007-08-30 19:04:02 UTC (rev 2030)
@@ -249,12 +249,11 @@
           break;
       }
     } else {
-      const int iclidx = inst_code.GetSize() - 1;
       int inst_code_val = 0;
-      for (int i = 0; i < inst_code_len && i <= iclidx; i++) {
+      for (int i = 0; i < inst_code_len && i < inst_code.GetSize(); i++) {
         inst_code_val <<= 1;
-        if (inst_code[iclidx - i] == '1') inst_code_val |= 1;
-        else if (inst_code[iclidx - i] != '0') {
+        if (inst_code[i] == '1') inst_code_val |= 1;
+        else if (inst_code[i] != '0') {
           errors.PushRear(new cString("Invalid character in instruction code, must be 0 or 1."));
           success = false;
           break;

Modified: branches/collect/source/cpu/cTestCPU.cc
===================================================================
--- branches/collect/source/cpu/cTestCPU.cc	2007-08-30 18:26:42 UTC (rev 2029)
+++ branches/collect/source/cpu/cTestCPU.cc	2007-08-30 19:04:02 UTC (rev 2030)
@@ -221,7 +221,7 @@
   
   organism.GetHardware().SetTrace(tracer);
   while (time_used < time_allocated && organism.GetHardware().GetMemory().GetSize() &&
-         organism.GetPhenotype().GetNumDivides() == 0)
+         organism.GetPhenotype().GetNumDivides() == 0 && !organism.IsDead())
   {
     time_used++;
     

Modified: branches/collect/source/main/cAvidaConfig.h
===================================================================
--- branches/collect/source/main/cAvidaConfig.h	2007-08-30 18:26:42 UTC (rev 2029)
+++ branches/collect/source/main/cAvidaConfig.h	2007-08-30 19:04:02 UTC (rev 2030)
@@ -474,14 +474,15 @@
 
   CONFIG_ADD_GROUP(PROMOTER_GROUP, "Promoters");
   CONFIG_ADD_VAR(PROMOTERS_ENABLED, int, 0, "Use the promoter/terminator execution scheme.\nCertain instructions must also be included.");
-  CONFIG_ADD_VAR(PROMOTER_MAX_INST, int, 20, "Maximum number of instructions to execute before terminating.");
+  CONFIG_ADD_VAR(PROMOTER_INST_MAX, int, 0, "Maximum number of instructions to execute before terminating. 0 = off");
   CONFIG_ADD_VAR(PROMOTER_PROCESSIVITY, double, 1.0, "Chance of not terminating after each cpu cycle.");
   CONFIG_ADD_VAR(PROMOTER_PROCESSIVITY_INST, double, 1.0, "Chance of not terminating after each instruction.");
-  CONFIG_ADD_VAR(PROMOTER_BG_STRENGTH, double, 0, "Probability of positions that are not promoter\ninstructions initiating execution (promoters are 1).");
-  CONFIG_ADD_VAR(REGULATION_STRENGTH, double, 1, "Strength added or subtracted to a promoter by regulation.");
-  CONFIG_ADD_VAR(REGULATION_DECAY_FRAC, double, 0.1, "Fraction of regulation that decays away. \nMax regulation = 2^(REGULATION_STRENGTH/REGULATION_DECAY_FRAC)");
+  CONFIG_ADD_VAR(TERMINATION_RESETS, int, 0, "Does termination reset the thread's state?");
+  CONFIG_ADD_VAR(NO_ACTIVE_PROMOTER_EFFECT, int, 0, "What happens when there are no active promoters?\n0 = Start execution at the beginning of the genome.\n1 = Kill the organism.\n2 = Stop the organism from executing any further instructions.");
+  CONFIG_ADD_VAR(PROMOTER_EXE_LENGTH, int, 4, "Length of promoter windows used to determine execution.");
+  CONFIG_ADD_VAR(PROMOTER_EXE_THRESHOLD, int, 3, "Minimum number of bits that must be set in a promoter window to allow execution.");
   CONFIG_ADD_VAR(INST_CODE_LENGTH, int, 4, "Instruction binary code length (number of bits)");
-  CONFIG_ADD_VAR(INST_CODE_DEFAULT_TYPE, int, 0, "Default value of instruction binary code value.\n0 = All zeros\n1 = Based of the instruction number");
+  CONFIG_ADD_VAR(INST_CODE_DEFAULT_TYPE, int, 0, "Default value of instruction binary code value.\n0 = All zeros\n1 = Based off the instruction number");
 
   CONFIG_ADD_GROUP(COLORS_GROUP, "Output colors for when data files are printed in HTML mode.\nThere are two sets of these; the first are for lineages,\nand the second are for mutation tests.");
   CONFIG_ADD_VAR(COLOR_DIFF, cString, "CCCCFF", "Color to flag stat that has changed since parent.");

Modified: branches/collect/source/main/cOrganism.cc
===================================================================
--- branches/collect/source/main/cOrganism.cc	2007-08-30 18:26:42 UTC (rev 2029)
+++ branches/collect/source/main/cOrganism.cc	2007-08-30 19:04:02 UTC (rev 2030)
@@ -70,6 +70,7 @@
   , m_max_executed(-1)
   , m_is_running(false)
   , m_is_sleeping(false)
+  , m_is_dead(false)
   , m_net(NULL)
   , m_msg(0)
 {

Modified: branches/collect/source/main/cOrganism.h
===================================================================
--- branches/collect/source/main/cOrganism.h	2007-08-30 18:26:42 UTC (rev 2029)
+++ branches/collect/source/main/cOrganism.h	2007-08-30 19:04:02 UTC (rev 2030)
@@ -123,6 +123,7 @@
   int m_max_executed;      // Max number of instruction executed before death.  
   bool m_is_running;       // Does this organism have the CPU?
   bool m_is_sleeping;      // Is this organisms sleeping?
+  bool m_is_dead;          // Is this organism dead?
   
   class cNetSupport
   {
@@ -190,6 +191,7 @@
   void SetSleeping(bool in_sleeping) { m_is_sleeping = in_sleeping; }
   bool IsSleeping() { return m_is_sleeping; }
   
+  bool IsDead() { return m_is_dead; }
   
   // --------  cOrgInterface Methods  --------
   cHardwareBase& GetHardware() { return *m_hardware; }
@@ -202,7 +204,7 @@
   int GetNextInput(int& in_input_pointer) { return m_interface->GetInputAt(in_input_pointer); } //@JEB alternate for GX
   tBuffer<int>& GetInputBuf() { return m_input_buf; }
   tBuffer<int>& GetOutputBuf() { return m_output_buf; }
-  void Die() { m_interface->Die(); }
+  void Die() { m_interface->Die(); m_is_dead = true; }
   void Kaboom(int dist) { m_interface->Kaboom(dist);}
   void SpawnDeme() { m_interface->SpawnDeme(); }
   int GetCellID() { return m_interface->GetCellID(); }

Modified: branches/collect/source/main/cPopulation.cc
===================================================================
--- branches/collect/source/main/cPopulation.cc	2007-08-30 18:26:42 UTC (rev 2029)
+++ branches/collect/source/main/cPopulation.cc	2007-08-30 19:04:02 UTC (rev 2030)
@@ -2040,7 +2040,7 @@
   cPopulationCell& cell = GetCell(cell_id);
   assert(cell.IsOccupied()); // Unoccupied cell getting processor time!
   cOrganism* cur_org = cell.GetOrganism();
-  cur_org->GetHardware().SingleProcess(ctx);
+  cell.GetHardware()->SingleProcess(ctx);
   if (cur_org->GetPhenotype().GetToDelete() == true) {
     delete cur_org;
   }

Modified: branches/collect/source/main/cPopulationCell.cc
===================================================================
--- branches/collect/source/main/cPopulationCell.cc	2007-08-30 18:26:42 UTC (rev 2029)
+++ branches/collect/source/main/cPopulationCell.cc	2007-08-30 19:04:02 UTC (rev 2030)
@@ -40,6 +40,7 @@
 cPopulationCell::cPopulationCell(const cPopulationCell& in_cell)
   : m_world(in_cell.m_world)
   , m_organism(in_cell.m_organism)
+  , m_hardware(in_cell.m_hardware)
   , m_inputs(in_cell.m_inputs)
   , m_cell_id(in_cell.m_cell_id)
   , m_deme_id(in_cell.m_deme_id)
@@ -58,6 +59,7 @@
 {
   m_world = in_cell.m_world;
   m_organism = in_cell.m_organism;
+  m_hardware = in_cell.m_hardware;
   m_inputs = in_cell.m_inputs;
   m_cell_id = in_cell.m_cell_id;
   m_deme_id = in_cell.m_deme_id;
@@ -164,6 +166,7 @@
 
   // Adjust this cell's attributes to account for the new organism.
   m_organism = new_org;
+  m_hardware = &new_org->GetHardware();
   m_organism_count++;
 
   // Adjust the organism's attributes to match this cell.
@@ -191,6 +194,7 @@
     m_world->GetPopulation().GetDeme(m_deme_id).GiveBackCellEnergy(m_cell_id, m_organism->GetPhenotype().GetStoredEnergy() * m_world->GetConfig().FRAC_ENERGY_TRANSFER.Get());
   }
   m_organism = NULL;
+  m_hardware = NULL;
   return out_organism;
 }
 

Modified: branches/collect/source/main/cPopulationCell.h
===================================================================
--- branches/collect/source/main/cPopulationCell.h	2007-08-30 18:26:42 UTC (rev 2029)
+++ branches/collect/source/main/cPopulationCell.h	2007-08-30 19:04:02 UTC (rev 2030)
@@ -38,6 +38,7 @@
 #include "tList.h"
 #endif
 
+class cHardwareBase;
 class cPopulation;
 class cOrganism;
 class cPopulationCell;
@@ -50,6 +51,7 @@
 private:
   cWorld* m_world;
   cOrganism* m_organism;                    // The occupent of this cell.
+  cHardwareBase* m_hardware;
   tList<cPopulationCell> m_connections;  // A list of neighboring cells.
   cMutationRates* m_mut_rates;           // Mutation rates at this cell.
   tArray<int> m_inputs;                 // Environmental Inputs...
@@ -68,7 +70,7 @@
 
   
 public:
-  cPopulationCell() : m_world(NULL), m_organism(NULL), m_mut_rates(NULL), m_organism_count(0) { ; }
+  cPopulationCell() : m_world(NULL), m_organism(NULL), m_hardware(NULL), m_mut_rates(NULL), m_organism_count(0) { ; }
   cPopulationCell(const cPopulationCell& in_cell);
   ~cPopulationCell() { delete m_mut_rates; }
 
@@ -79,6 +81,7 @@
   void Rotate(cPopulationCell& new_facing);
 
   inline cOrganism* GetOrganism() const { return m_organism; }
+  inline cHardwareBase* GetHardware() const { return m_hardware; }
   inline tList<cPopulationCell>& ConnectionList() { return m_connections; }
   inline cPopulationCell& GetCellFaced() { return *(m_connections.GetFirst()); }
   int GetFacing();  // Returns the facing of this cell.

Modified: branches/collect/source/script/ASTree.cc
===================================================================
--- branches/collect/source/script/ASTree.cc	2007-08-30 18:26:42 UTC (rev 2029)
+++ branches/collect/source/script/ASTree.cc	2007-08-30 19:04:02 UTC (rev 2030)
@@ -48,6 +48,7 @@
 void cASTLiteral::Accept(cASTVisitor& visitor) { visitor.visitLiteral(*this); }
 void cASTLiteralArray::Accept(cASTVisitor& visitor) { visitor.visitLiteralArray(*this); }
 void cASTVariableReference::Accept(cASTVisitor& visitor) { visitor.visitVariableReference(*this); }
+void cASTUnpackTarget::Accept(cASTVisitor& visitor) { visitor.visitUnpackTarget(*this); }
 
 
 cASTStatementList::~cASTStatementList()

Modified: branches/collect/source/script/ASTree.h
===================================================================
--- branches/collect/source/script/ASTree.h	2007-08-30 18:26:42 UTC (rev 2029)
+++ branches/collect/source/script/ASTree.h	2007-08-30 19:04:02 UTC (rev 2030)
@@ -37,6 +37,9 @@
 #ifndef tList_h
 #include "tList.h"
 #endif
+#ifndef tManagedPointerArray_h
+#include "tManagedPointerArray.h"
+#endif
 
 
 class cASTVisitor;
@@ -88,6 +91,7 @@
 class cASTLiteral;
 class cASTLiteralArray;
 class cASTVariableReference;
+class cASTUnpackTarget;
 
 
 
@@ -436,4 +440,33 @@
 };
 
 
+class cASTUnpackTarget : public cASTNode
+{
+private:
+  tManagedPointerArray<cString> m_nodes;
+  bool m_last_wild;
+  bool m_last_named;
+  cASTNode* m_expr;
+  
+public:
+  cASTUnpackTarget() : m_last_wild(false), m_last_named(false), m_expr(NULL) { ; }
+  ~cASTUnpackTarget() { delete m_expr; }
+  
+  inline void AddVar(const cString& name) { m_nodes.Push(name); }
+  inline int GetSize() const { return m_nodes.GetSize(); }
+  inline const cString& GetVar(int idx) const { return m_nodes[idx]; }
+  
+  inline bool IsLastNamed() const { return m_last_named; }
+  inline bool IsLastWild() const { return m_last_wild; }
+  
+  inline void SetLastNamed() { m_last_wild = true; m_last_named = true; }
+  inline void SetLastWild() { m_last_wild = true; m_last_named = false; }
+  
+  cASTNode* GetExpression() const { return m_expr; }
+  void SetExpression(cASTNode* expr) { delete m_expr; m_expr = expr; }
+  
+  void Accept(cASTVisitor& visitor);
+};
+
+
 #endif

Modified: branches/collect/source/script/cASTDumpVisitor.cc
===================================================================
--- branches/collect/source/script/cASTDumpVisitor.cc	2007-08-30 18:26:42 UTC (rev 2029)
+++ branches/collect/source/script/cASTDumpVisitor.cc	2007-08-30 19:04:02 UTC (rev 2030)
@@ -384,3 +384,42 @@
   indent();
   cout << node.GetName() << endl;
 }
+
+
+void cASTDumpVisitor::visitUnpackTarget(cASTUnpackTarget& node)
+{
+  m_depth++;
+  
+  // Array unpack portion
+  indent();
+  cout << "@{";
+  m_depth++;
+  
+  for (int i = 0; i < node.GetSize(); i++) {
+    cout << endl;
+    indent();
+    cout << node.GetVar(i);
+  }
+  if (node.IsLastNamed()) {
+    cout << "..";
+  } else if (node.IsLastWild()) {
+    cout << endl;
+    indent();
+    cout << "..";
+  }
+  cout << endl;
+  m_depth--;
+  indent();
+  cout << "}" << endl;
+  
+  // Equals
+  m_depth--;
+  indent();
+  cout << "=" << endl;
+  m_depth++;
+  
+  // Expression portion
+  node.GetExpression()->Accept(*this);
+  
+  m_depth--;
+}

Modified: branches/collect/source/script/cASTDumpVisitor.h
===================================================================
--- branches/collect/source/script/cASTDumpVisitor.h	2007-08-30 18:26:42 UTC (rev 2029)
+++ branches/collect/source/script/cASTDumpVisitor.h	2007-08-30 19:04:02 UTC (rev 2030)
@@ -59,6 +59,7 @@
   void visitLiteral(cASTLiteral&);
   void visitLiteralArray(cASTLiteralArray&);
   void visitVariableReference(cASTVariableReference&);
+  void visitUnpackTarget(cASTUnpackTarget&);
 
 private:
   inline void indent();

Modified: branches/collect/source/script/cASTVisitor.h
===================================================================
--- branches/collect/source/script/cASTVisitor.h	2007-08-30 18:26:42 UTC (rev 2029)
+++ branches/collect/source/script/cASTVisitor.h	2007-08-30 19:04:02 UTC (rev 2030)
@@ -58,6 +58,7 @@
   virtual void visitLiteral(cASTLiteral&) = 0;
   virtual void visitLiteralArray(cASTLiteralArray&) = 0;
   virtual void visitVariableReference(cASTVariableReference&) = 0;
+  virtual void visitUnpackTarget(cASTUnpackTarget&) = 0;
 };
 
 #endif

Modified: branches/collect/source/script/cParser.cc
===================================================================
--- branches/collect/source/script/cParser.cc	2007-08-30 18:26:42 UTC (rev 2029)
+++ branches/collect/source/script/cParser.cc	2007-08-30 19:04:02 UTC (rev 2030)
@@ -265,31 +265,40 @@
 cASTNode* cParser::parseArrayUnpack()
 {
   PARSE_TRACE("parseArrayUnpack");
-  cASTNode* au = NULL;
   
-  // @todo - array unpack
-  
   if (nextToken() != TOKEN(ID)) PARSE_UNEXPECT();
+
+  tAutoRelease<cASTUnpackTarget> ut(new cASTUnpackTarget());
+  (*ut).AddVar(currentText());
   
   while (nextToken()) {
     if (currentToken() == TOKEN(COMMA)) {
       nextToken();
       if (currentToken() == TOKEN(ID)) {
+        (*ut).AddVar(currentText());
         continue;
       } else if (currentToken() == TOKEN(ARR_WILD)) {
+        (*ut).SetLastWild();
         break;
       } else {
         PARSE_ERROR(UNEXPECTED_TOKEN);
         break;
       }
     } else if (currentToken() == TOKEN(ARR_WILD)) {
+      (*ut).SetLastNamed();
       break;
     } else {
       PARSE_UNEXPECT();
     }
   }
+  
+  if (nextToken() != TOKEN(ARR_CLOSE)) PARSE_UNEXPECT();
+  if (nextToken() != TOKEN(ASSIGN)) PARSE_UNEXPECT();
+  nextToken(); // consume '='
+  
+  (*ut).SetExpression(parseExpression());
 
-  return au;
+  return ut.Release();
 }
 
 cASTArgumentList* cParser::parseArgumentList()

Modified: branches/collect/source/tools/tArray.h
===================================================================
--- branches/collect/source/tools/tArray.h	2007-08-30 18:26:42 UTC (rev 2029)
+++ branches/collect/source/tools/tArray.h	2007-08-30 19:04:02 UTC (rev 2030)
@@ -83,15 +83,15 @@
     return tmp;
   }
   
-  tArray Subset(int start, int end) {
+  inline tArray Subset(int start, int end) const {
     assert(start <= end);
     assert(0 <= start && start <= GetSize());
     assert(0 <= end && end <= GetSize());
     
-    tArray tmp(0);
-    for(int i = start; i < end; i++) {
-      tmp.Push(m_data[i]);
-    }
+    const int new_size = end - start;
+    tArray tmp(end - start);
+    for(int i = 0; i < new_size; i++) tmp[i] = m_data[i + start];
+
     return tmp;
   }
   




More information about the Avida-cvs mailing list