[Avida-SVN] r1152 - in development/source: cpu main

barrick at myxo.css.msu.edu barrick at myxo.css.msu.edu
Mon Dec 25 09:22:39 PST 2006


Author: barrick
Date: 2006-12-25 12:22:39 -0500 (Mon, 25 Dec 2006)
New Revision: 1152

Modified:
   development/source/cpu/cHardwareCPU.cc
   development/source/cpu/cHardwareCPU.h
   development/source/main/cInstSet.cc
   development/source/main/cInstSet.h
   development/source/main/cPhenotype.h
Log:
Merry X-mas!

1. THROW/CATCH

Corrected the behavior of the 'throw/catch' instructions
to my original intent. A 'throw' instruction jumps to
the next 'catch' instruction followed by a modifying
label that matches the 'throw' label OR ANY TRUNCATION OF
THAT LABEL, i.e. a catch without any modifying NOPs will
capture any 'throw' instruction, no matter what it's
label. 

(Note: I've never seen the label on 'throw' used by an
evolved organism, though it works correctly in tests. It
might be worth trying the opposite -- where a 'catch'
stops only 'throw's modified by truncations or substrings 
of the 'catch' label.)

2. GOTO/LABEL

Added a similar 'goto/label' suite of instructions (goto,
goto-if=0, goto-if!=0). A 'goto' instruction jumps to the
next 'label' instruction after it with an IDENTICAL 
modifying label.

(I'm starting runs to compare these alternate methods
of flow control.)

3. TRANSPOSON

Added a first-generation 'transposon' instruction that
adds insertions of itself with some probability to a
child genome when it has been executed in the parent. This
only works with 'repro' organisms. 



Modified: development/source/cpu/cHardwareCPU.cc
===================================================================
--- development/source/cpu/cHardwareCPU.cc	2006-12-20 23:09:39 UTC (rev 1151)
+++ development/source/cpu/cHardwareCPU.cc	2006-12-25 17:22:39 UTC (rev 1152)
@@ -123,6 +123,11 @@
     cInstEntryCPU("throwif!=0",&cHardwareCPU::Inst_ThrowIfNot0),
     cInstEntryCPU("catch",     &cHardwareCPU::Inst_Catch),
     
+    cInstEntryCPU("goto",      &cHardwareCPU::Inst_Goto),
+    cInstEntryCPU("goto-if=0", &cHardwareCPU::Inst_GotoIf0),    
+    cInstEntryCPU("goto-if!=0",&cHardwareCPU::Inst_GotoIfNot0),
+    cInstEntryCPU("label",     &cHardwareCPU::Inst_Label),
+    
     cInstEntryCPU("pop",       &cHardwareCPU::Inst_Pop, true,
                   "Remove top number from stack and place into ?BX?"),
     cInstEntryCPU("push",      &cHardwareCPU::Inst_Push, true,
@@ -204,6 +209,7 @@
     cInstEntryCPU("c-divide",  &cHardwareCPU::Inst_CDivide),
     cInstEntryCPU("inject",    &cHardwareCPU::Inst_Inject),
     cInstEntryCPU("inject-r",  &cHardwareCPU::Inst_InjectRand),
+    cInstEntryCPU("transposon",&cHardwareCPU::Inst_Transposon),
     cInstEntryCPU("search-f",  &cHardwareCPU::Inst_SearchF),
     cInstEntryCPU("search-b",  &cHardwareCPU::Inst_SearchB),
     cInstEntryCPU("mem-size",  &cHardwareCPU::Inst_MemSize),
@@ -1756,40 +1762,46 @@
   // Only initialize this once to save some time...
   static cInstruction catch_inst = GetInstSet().GetInst(cStringUtil::Stringf("catch"));
 
-  //What label complement are we looking for?
-  //If the size is zero then we just find the first example of a catch
+  //Look for the label directly (no complement)
   ReadLabel();
-  GetLabel().Rotate(1, NUM_NOPS);
-  
+    
   cHeadCPU search_head(IP());
   int start_pos = search_head.GetPosition();
   search_head++;
   
-  while (start_pos != search_head.GetPosition()) {
-    
+  while (start_pos != search_head.GetPosition()) 
+  {
     // If we find a catch instruction, compare the NOPs following it
     if (search_head.GetInst() == catch_inst)
     {
       int catch_pos = search_head.GetPosition();
       search_head++;
-      int size_matched = 0;
-      while ( GetLabel().GetSize() > size_matched )
+
+      // Continue to examine the label after the catch
+      //  (1) It ends (=> use the catch!)
+      //  (2) It becomes longer than the throw label (=> use the catch!)
+      //  (3) We find a NOP that doesnt match the throw (=> DON'T use the catch...)
+      
+      bool match = true;
+      int size_matched = 0;      
+      while ( match && m_inst_set->IsNop(search_head.GetInst()) && (GetLabel().GetSize() > size_matched) )
       {
-        if ( !m_inst_set->IsNop( search_head.GetInst()) ) break;
-        if ( GetLabel()[size_matched] != m_inst_set->GetNopMod( search_head.GetInst()) ) break;
+        if ( GetLabel()[size_matched] != m_inst_set->GetNopMod( search_head.GetInst()) ) match = false;
         search_head++;
         size_matched++;
       }
       
       // We found a matching catch instruction
-      // set the catch to execute 
-      if (GetLabel().GetSize() == size_matched)
+      if (match)
       {
         IP().Set(catch_pos);
         m_advance_ip = false; // Don't automatically move the IP
                               // so we mark the catch as executed.
         return true;
       }
+      
+      //If we advanced past NOPs during testing, retreat
+      if ( !m_inst_set->IsNop(search_head.GetInst()) ) search_head--;
     }
     search_head.Advance();
   }
@@ -1810,6 +1822,66 @@
   return Inst_Throw(ctx);
 }
 
+bool cHardwareCPU::Inst_Goto(cAvidaContext& ctx)
+{
+  // Only initialize this once to save some time...
+  static cInstruction label_inst = GetInstSet().GetInst(cStringUtil::Stringf("label"));
+
+  //Look for an EXACT label match after a 'label' instruction
+  ReadLabel();
+  
+  cHeadCPU search_head(IP());
+  int start_pos = search_head.GetPosition();
+  search_head++;
+  
+  while (start_pos != search_head.GetPosition()) 
+  {
+    if (search_head.GetInst() == label_inst)
+    {
+      int label_pos = search_head.GetPosition();
+      search_head++;
+      int size_matched = 0;
+      bool match = true;
+      while ( match && m_inst_set->IsNop(search_head.GetInst()) && (GetLabel().GetSize() > size_matched) )
+      {
+        if ( GetLabel()[size_matched] != m_inst_set->GetNopMod( search_head.GetInst()) ) match = false;
+        search_head++;
+        size_matched++;
+      }
+      
+      // We found a matching 'label' instruction only if the next 
+      // instruction (at the search head now) is not a NOP
+      if ( match && !m_inst_set->IsNop(search_head.GetInst()) )
+      {
+        IP().Set(label_pos);
+        m_advance_ip = false; // Don't automatically move the IP
+                              // so we mark the catch as executed.
+        return true;
+      }
+
+      //If we advanced past NOPs during testing, retreat
+      if ( !m_inst_set->IsNop(search_head.GetInst()) ) search_head--;
+    }
+    search_head++;
+  }
+
+  return false;
+}
+
+
+bool cHardwareCPU::Inst_GotoIfNot0(cAvidaContext& ctx)
+{
+  if (GetRegister(REG_BX) == 0) return false;
+  return Inst_Goto(ctx);
+}
+
+bool cHardwareCPU::Inst_GotoIf0(cAvidaContext& ctx)
+{
+  if (GetRegister(REG_BX) != 0) return false;
+  return Inst_Goto(ctx);
+}
+
+
 bool cHardwareCPU::Inst_Pop(cAvidaContext& ctx)
 {
   const int reg_used = FindModifiedRegister(REG_BX);
@@ -2485,7 +2557,53 @@
   } else return false;
 }
 
+bool cHardwareCPU::Inst_Transposon(cAvidaContext& ctx)
+{
+  ReadLabel();
+  //organism->GetPhenotype().ActivateTransposon(GetLabel());
+}
 
+void cHardwareCPU::Divide_DoTransposons(cAvidaContext& ctx)
+{
+  // This only works if 'transposon' is in the current instruction set
+  static bool transposon_in_use = GetInstSet().InstInSet(cStringUtil::Stringf("transposon"));
+  if (!transposon_in_use) return;
+  
+  static cInstruction transposon_inst = GetInstSet().GetInst(cStringUtil::Stringf("transposon"));
+  cCPUMemory& child_genome = organism->ChildGenome();
+
+  // Count the number of transposons that are marked as executed
+  int tr_count = 0;
+  for (int i=0; i < child_genome.GetSize(); i++) 
+  {
+    if (child_genome.FlagExecuted(i) && (child_genome[i] == transposon_inst)) tr_count++;
+  }
+  
+  for (int i=0; i < tr_count; i++) 
+  {
+    if (ctx.GetRandom().P(0.01))
+    {
+      const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize() + 1);
+      child_genome.Insert(mut_line, transposon_inst);
+    }
+  }
+  
+  
+/*
+  const tArray<cCodeLabel> tr = organism->GetPhenotype().GetActiveTransposons();
+  cCPUMemory& child_genome = organism->ChildGenome();
+  
+  for (int i=0; i < tr.GetSize(); i++) 
+  {
+    if (ctx.GetRandom().P(0.1))
+    {
+      const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize() + 1);
+      child_genome.Insert(mut_line, transposon_inst);
+    }
+  }
+*/  
+}
+
 bool cHardwareCPU::Inst_Repro(cAvidaContext& ctx)
 {
   // const bool viable = Divide_CheckViable(ctx, div_point, child_size);
@@ -2510,6 +2628,9 @@
   }
   organism->GetPhenotype().SetLinesExecuted(lines_executed);
   
+  // Do transposon movement and copying before other mutations
+  Divide_DoTransposons(ctx);
+  
   // Perform Copy Mutations...
   if (organism->GetCopyMutProb() > 0) { // Skip this if no mutations....
     for (int i = 0; i < GetMemory().GetSize(); i++) {

Modified: development/source/cpu/cHardwareCPU.h
===================================================================
--- development/source/cpu/cHardwareCPU.h	2006-12-20 23:09:39 UTC (rev 1151)
+++ development/source/cpu/cHardwareCPU.h	2006-12-25 17:22:39 UTC (rev 1152)
@@ -175,6 +175,7 @@
   bool Divide_Main1RS(cAvidaContext& ctx, const int divide_point, const int extra_lines=0, double mut_multiplier=1); //AWC 07/28/06
   bool Divide_Main2RS(cAvidaContext& ctx, const int divide_point, const int extra_lines=0, double mut_multiplier=1); //AWC 07/28/06
 
+  void Divide_DoTransposons(cAvidaContext& ctx);
   
   void InjectCode(const cGenome& injection, const int line_num);
   
@@ -292,8 +293,13 @@
   bool Inst_Throw(cAvidaContext& ctx);
   bool Inst_ThrowIf0(cAvidaContext& ctx);
   bool Inst_ThrowIfNot0(cAvidaContext& ctx);  
-  bool Inst_Catch(cAvidaContext& ctx) { return true; };
-  
+  bool Inst_Catch(cAvidaContext& ctx) { ReadLabel(); return true; };
+ 
+  bool Inst_Goto(cAvidaContext& ctx);
+  bool Inst_GotoIf0(cAvidaContext& ctx);
+  bool Inst_GotoIfNot0(cAvidaContext& ctx);  
+  bool Inst_Label(cAvidaContext& ctx) { ReadLabel(); return true; };
+    
   // Stack and Register Operations
   bool Inst_Pop(cAvidaContext& ctx);
   bool Inst_Push(cAvidaContext& ctx);
@@ -372,6 +378,7 @@
   bool Inst_Inject(cAvidaContext& ctx);
   bool Inst_InjectRand(cAvidaContext& ctx);
   bool Inst_InjectThread(cAvidaContext& ctx);
+  bool Inst_Transposon(cAvidaContext& ctx);
   bool Inst_Repro(cAvidaContext& ctx);
   bool Inst_SpawnDeme(cAvidaContext& ctx);
   bool Inst_Kazi(cAvidaContext& ctx);

Modified: development/source/main/cInstSet.cc
===================================================================
--- development/source/main/cInstSet.cc	2006-12-20 23:09:39 UTC (rev 1151)
+++ development/source/main/cInstSet.cc	2006-12-25 17:22:39 UTC (rev 1152)
@@ -106,3 +106,14 @@
   return best_name;
 }
 
+bool cInstSet::InstInSet(const cString& in_name) const
+{
+  cString best_name("");
+  
+  for (int i = 0; i < m_lib_name_map.GetSize(); i++) {
+    const cString & cur_name = m_inst_lib->GetName(m_lib_name_map[i].lib_fun_id);
+    if (cur_name == in_name) return true;
+  }
+  return false;
+}
+

Modified: development/source/main/cInstSet.h
===================================================================
--- development/source/main/cInstSet.h	2006-12-20 23:09:39 UTC (rev 1151)
+++ development/source/main/cInstSet.h	2006-12-25 17:22:39 UTC (rev 1152)
@@ -114,6 +114,7 @@
 
   inline cInstruction GetInst(const cString& in_name) const;
   cString FindBestMatch(const cString& in_name) const;
+  bool InstInSet(const cString& in_name) const;
 
   // Static methods..
   static const cInstruction& GetInstDefault() { return inst_default2; }

Modified: development/source/main/cPhenotype.h
===================================================================
--- development/source/main/cPhenotype.h	2006-12-20 23:09:39 UTC (rev 1151)
+++ development/source/main/cPhenotype.h	2006-12-25 17:22:39 UTC (rev 1152)
@@ -22,6 +22,9 @@
 #ifndef tArray_h
 #include "tArray.h"
 #endif
+#ifndef cCodeLabel_h
+#include "cCodeLabel.h"
+#endif
 
 
 /*************************************************************************
@@ -83,6 +86,7 @@
   tArray<int> cur_inst_count;	    // Intsruction exection counter
   tArray<int> cur_sense_count;     // Total times resource combinations have been sensed; JEB 10-22-06 
   tArray<double> sensed_resources; // Resources of which the organism is explictly aware
+  tArray<cCodeLabel> active_transposons; // Transposons that are active
   
   // 3. These mark the status of "in progess" variables at the last divide.
   double last_merit_base;         // Either constant or based on genome length.
@@ -199,8 +203,8 @@
   const tArray<int>& GetCurReactionCount() const { assert(initialized == true); return cur_reaction_count;}
   const tArray<int>& GetCurInstCount() const { assert(initialized == true); return cur_inst_count; }
   const tArray<int>& GetCurSenseCount() const { assert(initialized == true); return cur_sense_count; }
-  
   double GetSensedResource(int _in) { assert(initialized == true); return sensed_resources[_in]; }
+  const tArray<cCodeLabel>& GetActiveTransposons() { assert(initialized == true); return active_transposons; }
 
   double GetLastMeritBase() const { assert(initialized == true); return last_merit_base; }
   double GetLastBonus() const { assert(initialized == true); return last_bonus; }
@@ -266,6 +270,8 @@
 
   void IncCurInstCount(int _inst_num)  { assert(initialized == true); cur_inst_count[_inst_num]++; } 
   void DecCurInstCount(int _inst_num)  { assert(initialized == true); cur_inst_count[_inst_num]--; } 
+  
+  void ActivateTransposon(cCodeLabel & in_label) { assert(initialized == true); active_transposons.Push(in_label); }
 
   void IncAge()      { assert(initialized == true); age++; }
   void IncTimeUsed(int i=1) { assert(initialized == true); time_used+=i; }




More information about the Avida-cvs mailing list