[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