[Avida-SVN] r1066 - in branches/developers/avida-edward/source: cpu tools

kaben at myxo.css.msu.edu kaben at myxo.css.msu.edu
Wed Nov 1 13:03:18 PST 2006


Author: kaben
Date: 2006-11-01 16:03:18 -0500 (Wed, 01 Nov 2006)
New Revision: 1066

Modified:
   branches/developers/avida-edward/source/cpu/cHardwareCPU.cc
   branches/developers/avida-edward/source/cpu/cHardwareCPU.h
   branches/developers/avida-edward/source/tools/cMerit.cc
Log:

Backported Inst_TaskIO_Feedback for Jeff Clune's use in Avida-ED.
Backported Inst_Sense for Jeff Barrick's use in Avida-ED.



Modified: branches/developers/avida-edward/source/cpu/cHardwareCPU.cc
===================================================================
--- branches/developers/avida-edward/source/cpu/cHardwareCPU.cc	2006-11-01 20:24:18 UTC (rev 1065)
+++ branches/developers/avida-edward/source/cpu/cHardwareCPU.cc	2006-11-01 21:03:18 UTC (rev 1066)
@@ -202,7 +202,12 @@
     cInstEntryCPU("put",       &cHardwareCPU::Inst_TaskPut),
     cInstEntryCPU("IO",        &cHardwareCPU::Inst_TaskIO, true,
 		  "Output ?BX?, and input new number back into ?BX?"),
-
+    cInstEntryCPU("IO-Feedback",        &cHardwareCPU::Inst_TaskIO_Feedback, true,\
+                  "Output ?BX?, and input new number back into ?BX?,  and push 1,0,\
+                  or -1 onto stack1 if merit increased, stayed the same, or decreased"),
+    //cInstEntryCPU("match-strings", &cHardwareCPU::Inst_MatchStrings),
+  //cInstEntryCPU("sell", &cHardwareCPU::Inst_Sell),
+  //cInstEntryCPU("buy", &cHardwareCPU::Inst_Buy),
     cInstEntryCPU("send",      &cHardwareCPU::Inst_Send),
     cInstEntryCPU("receive",   &cHardwareCPU::Inst_Receive),
     cInstEntryCPU("sense",     &cHardwareCPU::Inst_Sense),
@@ -385,6 +390,7 @@
 , cur_thread(hardware_cpu.cur_thread)
 , mal_active(hardware_cpu.mal_active)
 , advance_ip(hardware_cpu.advance_ip)
+, m_executedmatchstrings(hardware_cpu.m_executedmatchstrings)
 #ifdef INSTRUCTION_COSTS
 , inst_cost(hardware_cpu.inst_cost)
 , inst_ft_cost(hardware_cpu.inst_ft_cost)
@@ -2826,7 +2832,75 @@
   organism->DoInput(value_in);
   return true;
 }
+bool cHardwareCPU::Inst_TaskIO_Feedback()
+{   
+  const int reg_used = FindModifiedRegister(nHardwareCPU::REG_BX);
+    
+  //check cur_bonus before the output
+  double preOutputBonus = organism->GetPhenotype().GetCurBonus();
+    
+  // Do the "put" component
+  const int value_out = Register(reg_used);
+  organism->DoOutput(value_out);  // Check for tasks completed.
+    
+  //check cur_merit after the output
+  double postOutputBonus = organism->GetPhenotype().GetCurBonus();
 
+    
+  //push the effect of the IO on merit (+,0,-) to the active stack
+    
+  if (preOutputBonus > postOutputBonus){
+    StackPush(-1);
+    }             
+  else if (preOutputBonus == postOutputBonus){
+    StackPush(0);
+    }
+  else if (preOutputBonus < postOutputBonus){
+    StackPush(1);
+    }
+  else {
+    assert(0);
+    //Bollocks. There was an error.
+    }
+
+  
+  
+
+  
+  
+  // Do the "get" component
+  const int value_in = organism->GetNextInput();
+  Register(reg_used) = value_in;
+  organism->DoInput(value_in);
+  return true;
+} 
+
+//bool cHardwareCPU::Inst_MatchStrings()
+//{
+//  if (m_executedmatchstrings)
+//    return false;  
+//  organism->DoOutput(357913941);
+//  m_executedmatchstrings = true;
+//  return true;
+//}
+//
+//bool cHardwareCPU::Inst_Sell()
+//{
+//  int search_label = GetLabel().AsInt(3) % MARKET_SIZE;
+//  int send_value = Register(nHardwareCPU::REG_BX);
+//  int sell_price = m_world->GetConfig().SELL_PRICE.Get();
+//  organism->SellValue(send_value, search_label, sell_price);
+//  return true;
+//}
+//
+//bool cHardwareCPU::Inst_Buy()
+//{
+//  int search_label = GetLabel().AsInt(3) % MARKET_SIZE;
+//  int buy_price = m_world->GetConfig().BUY_PRICE.Get();
+//  GetRegister(REG_BX) = organism->BuyValue(search_label, buy_price);
+//  return true;
+//}
+
 bool cHardwareCPU::Inst_Send()
 {
   const int reg_used = FindModifiedRegister(nHardwareCPU::REG_BX);
@@ -2844,19 +2918,77 @@
 
 bool cHardwareCPU::Inst_Sense()
 {
+  // Returns the log2 amount of a resource or resources
+  // specified by modifying NOPs into register BX
+
   const tArray<double> & res_count = organism->PopInterface().GetResources();
-  const int reg_used = FindModifiedRegister(nHardwareCPU::REG_BX);
 
-  // If there are no resources to measure, this instruction fails.
+  // Arbitrarily set to BX since the conditionals use this directly.
+  int reg_to_set = nHardwareCPU::REG_BX;
+
+  // If there are no resources, return
   if (res_count.GetSize() == 0) return false;
 
-  // Always get the first resource, and convert it to and int.
-  Register(reg_used) = (int) res_count[0];
+  // Only recalculate logs if these values have changed
+  static int last_num_resources = 0;
+  static int max_label_length = 0;
+  
+  if ((last_num_resources != res_count.GetSize()))
+  {
+      int max_label_length = (int) ceil(log(res_count.GetSize())/log(nHardwareCPU::NUM_NOPS));
+      last_num_resources = res_count.GetSize();
+  }
 
-  // @CAO Since resources are sometimes less than one, perhaps we should
-  // multiply it by some constant?  Or perhaps taking the log would be more
-  // useful so they can easily scan across orders of magnitude?
+  // Convert modifying NOPs to the index of the resource.
+  // If there are fewer than the number of NOPs required
+  // to uniquely specify a resource, then add together
+  // a subset of resources (motivation: regulation can evolve
+  // to be more specific if there is an advantage)
 
+  // Find the maximum number of NOPs needed to specify this number of resources
+  // Note: It's a bit wasteful to recalculate this every time and organisms will
+  // definitely be confused if the number of resources changes during a run
+  // because their mapping to resources will be disrupted
+
+  // Attempt to read a label with this maximum length
+  cHardwareCPU::ReadLabel(max_label_length);
+
+  // Find the length of the label that we actually obtained (max is max_reg_needed)
+  int real_label_length = GetLabel().GetSize();
+
+  // Start and end labels to define the start and end indices of  
+  // resources that we need to add together
+  cCodeLabel start_label = cCodeLabel(GetLabel());
+  cCodeLabel   end_label = cCodeLabel(GetLabel());
+
+  for (int i = 0; i < max_label_length - real_label_length; i++)
+  {
+    start_label.AddNop(0);
+    end_label.AddNop(nHardwareCPU::NUM_NOPS-1);
+  }
+
+  int start_index = start_label.AsInt(nHardwareCPU::NUM_NOPS);
+  int   end_index =   end_label.AsInt(nHardwareCPU::NUM_NOPS);
+
+  // If the label refers to ONLY resources that 
+  // do not exist, then the operation fails
+  if (start_index >= res_count.GetSize()) return false;
+
+  // Otherwise sum all valid resources that it might refer to
+  // (this will only be ONE if the label was of the maximum length).
+  int resource_result = 0;
+  for (int i = start_index; i <= end_index; i++)
+  {
+    // if it's a valid resource and not zero
+    // (alternately you could assign min_int for zero resources, but
+    // that would cause wierdness when adding sense values together)
+    if ((i < res_count.GetSize()) && (res_count[i] > 0)) resource_result += (int)(log(res_count[i])/0.69314718056);
+    // 0.69314718056 is log (2)
+  }
+
+  //Dump this value into an arbitrary register: BX
+  Register(reg_to_set) = (int) resource_result;
+
   return true;
 }
 

Modified: branches/developers/avida-edward/source/cpu/cHardwareCPU.h
===================================================================
--- branches/developers/avida-edward/source/cpu/cHardwareCPU.h	2006-11-01 20:24:18 UTC (rev 1065)
+++ branches/developers/avida-edward/source/cpu/cHardwareCPU.h	2006-11-01 21:03:18 UTC (rev 1066)
@@ -99,6 +99,7 @@
   // Flags...
   bool mal_active;         // Has an allocate occured since last divide?
   bool advance_ip;         // Should the IP advance after this instruction?
+  bool m_executedmatchstrings;  // Have we already executed the match strings instruction?
 
   // Instruction costs...
 #ifdef INSTRUCTION_COSTS
@@ -393,6 +394,10 @@
   bool Inst_TaskStackLoad();
   bool Inst_TaskPut();
   bool Inst_TaskIO();
+  bool Inst_TaskIO_Feedback();
+  //bool Inst_MatchStrings();
+  //bool Inst_Sell();
+  //bool Inst_Buy();
   bool Inst_Send();
   bool Inst_Receive();
   bool Inst_Sense();

Modified: branches/developers/avida-edward/source/tools/cMerit.cc
===================================================================
--- branches/developers/avida-edward/source/tools/cMerit.cc	2006-11-01 20:24:18 UTC (rev 1065)
+++ branches/developers/avida-edward/source/tools/cMerit.cc	2006-11-01 21:03:18 UTC (rev 1066)
@@ -16,8 +16,8 @@
   static double mult[max_bits];
   static bool mult_initilalized = false;
 
-  // Do not allow negative merits.
-  if (in_value < 0.0) in_value = 0.0;
+  // Do not allow negative merits. If less than 1, set to 0.
+  if (in_value < 1.0) in_value = 0.0;
 
   // Initilize multipliers only once
   if( mult_initilalized == false ){




More information about the Avida-cvs mailing list