[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