[Avida-SVN] r1589 - in branches/collect: . Avida.xcodeproj source/actions source/classification source/cpu source/main source/targets source/targets/avida source/targets/avida-viewer support/config tests
blwalker at myxo.css.msu.edu
blwalker at myxo.css.msu.edu
Tue May 22 09:50:55 PDT 2007
Author: blwalker
Date: 2007-05-22 12:50:55 -0400 (Tue, 22 May 2007)
New Revision: 1589
Added:
branches/collect/source/targets/unit-tests/
branches/collect/tests/_avida_GA_lim_res/
branches/collect/tests/_task_optimize_lim_res/
branches/collect/tests/string_match_embed3/
Modified:
branches/collect/Avida.vcproj
branches/collect/Avida.xcodeproj/project.pbxproj
branches/collect/CMakeLists.txt
branches/collect/source/actions/PopulationActions.cc
branches/collect/source/actions/PrintActions.cc
branches/collect/source/classification/cClassificationManager.cc
branches/collect/source/classification/cClassificationManager.h
branches/collect/source/classification/cLineage.cc
branches/collect/source/classification/cLineage.h
branches/collect/source/cpu/cCPUMemory.h
branches/collect/source/cpu/cHardwareGX.cc
branches/collect/source/cpu/cHardwareGX.h
branches/collect/source/main/cAvidaConfig.h
branches/collect/source/main/cEnvironment.cc
branches/collect/source/main/cMutationRates.h
branches/collect/source/main/cOrganism.h
branches/collect/source/main/cPhenotype.cc
branches/collect/source/main/cPhenotype.h
branches/collect/source/main/cPopulation.cc
branches/collect/source/main/cPopulation.h
branches/collect/source/main/cReactionResult.cc
branches/collect/source/main/cReactionResult.h
branches/collect/source/main/cTaskContext.h
branches/collect/source/main/cTaskLib.cc
branches/collect/source/main/cWorld.cc
branches/collect/source/targets/avida-viewer/viewer.cc
branches/collect/source/targets/avida/primitive.cc
branches/collect/support/config/avida.cfg
branches/collect/support/config/default-gx.org
Log:
Ported r1524:1587 from development. Resolved some purely textual conflicts involving cclade and task_value; I don't know why they didn't merge cleanly in the first place.
Modified: branches/collect/Avida.vcproj
===================================================================
--- branches/collect/Avida.vcproj 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/Avida.vcproj 2007-05-22 16:50:55 UTC (rev 1589)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
@@ -39,7 +39,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories=""$(ProjectDir)source\tools";"$(ProjectDir)source\targets\avida-viewer";"$(ProjectDir)source\platform\msvc2005";"$(ProjectDir)source\platform\msvc2005\pdcurses";"$(ProjectDir)source\main";"$(ProjectDir)source\drivers";"$(ProjectDir)source\cpu";"$(ProjectDir)source\classification";"$(ProjectDir)source\analyze";"$(ProjectDir)source\actions";"$(ProjectDir)source""
+ AdditionalIncludeDirectories=""$(ProjectDir)source\tools";"$(ProjectDir)source\targets\avida-viewer";"$(ProjectDir)source\platform\msvc2005";"$(ProjectDir)source\platform\msvc2005\pdcurses";"$(ProjectDir)source\main";"$(ProjectDir)source\drivers";"$(ProjectDir)source\cpu";"$(ProjectDir)source\classification";"$(ProjectDir)source\analyze";"$(ProjectDir)source\actions";"$(ProjectDir)source";"$(ProjectDir)source\platform""
PreprocessorDefinitions="NOMACROS;DEBUG;WIN32;_WIN32"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -121,7 +121,7 @@
FavorSizeOrSpeed="1"
OmitFramePointers="true"
WholeProgramOptimization="true"
- AdditionalIncludeDirectories=""$(ProjectDir)source\tools";"$(ProjectDir)source\targets\avida-viewer";"$(ProjectDir)source\platform\msvc2005";"$(ProjectDir)source\platform\msvc2005\pdcurses";"$(ProjectDir)source\main";"$(ProjectDir)source\drivers";"$(ProjectDir)source\cpu";"$(ProjectDir)source\classification";"$(ProjectDir)source\analyze";"$(ProjectDir)source\actions";"$(ProjectDir)source""
+ AdditionalIncludeDirectories=""$(ProjectDir)source\tools";"$(ProjectDir)source\targets\avida-viewer";"$(ProjectDir)source\platform\msvc2005";"$(ProjectDir)source\platform\msvc2005\pdcurses";"$(ProjectDir)source\main";"$(ProjectDir)source\drivers";"$(ProjectDir)source\cpu";"$(ProjectDir)source\classification";"$(ProjectDir)source\analyze";"$(ProjectDir)source\actions";"$(ProjectDir)source";"$(ProjectDir)source\platform""
PreprocessorDefinitions="NOMACROS;NDEBUG;WIN32;_WIN32"
ExceptionHandling="1"
RuntimeLibrary="0"
@@ -449,6 +449,14 @@
>
</File>
<File
+ RelativePath=".\source\cpu\cHardwareGX.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\source\cpu\cHardwareGX.h"
+ >
+ </File>
+ <File
RelativePath=".\source\cpu\cHardwareManager.h"
>
</File>
@@ -869,6 +877,10 @@
>
</File>
<File
+ RelativePath=".\source\platform\FloatingPoint.h"
+ >
+ </File>
+ <File
RelativePath=".\source\tools\functions.h"
>
</File>
Modified: branches/collect/Avida.xcodeproj/project.pbxproj
===================================================================
--- branches/collect/Avida.xcodeproj/project.pbxproj 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/Avida.xcodeproj/project.pbxproj 2007-05-22 16:50:55 UTC (rev 1589)
@@ -97,6 +97,7 @@
706C6FFF0B83F265003174C1 /* cInstSet.cc in Sources */ = {isa = PBXBuildFile; fileRef = 706C6FFE0B83F265003174C1 /* cInstSet.cc */; };
706C70000B83F265003174C1 /* cInstSet.cc in Sources */ = {isa = PBXBuildFile; fileRef = 706C6FFE0B83F265003174C1 /* cInstSet.cc */; };
706C70010B83F265003174C1 /* cInstSet.cc in Sources */ = {isa = PBXBuildFile; fileRef = 706C6FFE0B83F265003174C1 /* cInstSet.cc */; };
+ 707045F00BCEA0D9000F9B9A /* cHardwareGX.cc in Sources */ = {isa = PBXBuildFile; fileRef = 423335880BC067E3000DF681 /* cHardwareGX.cc */; };
7073165D097C6C8F00815164 /* cParser.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7073165B097C6C8F00815164 /* cParser.cc */; };
70731665097C6DF500815164 /* cASLibrary.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70731663097C6DF500815164 /* cASLibrary.cc */; };
7073166B097C6E0C00815164 /* cASSymbol.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70731669097C6E0C00815164 /* cASSymbol.cc */; };
@@ -216,6 +217,8 @@
70B1A6520B7E237F00067486 /* cHardwareExperimental.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70B1A64F0B7E237F00067486 /* cHardwareExperimental.cc */; };
70B1A7430B7E3FFD00067486 /* instset-experimental.cfg in CopyFiles */ = {isa = PBXBuildFile; fileRef = 70B1A7420B7E3FFD00067486 /* instset-experimental.cfg */; };
70B1A75A0B7E431F00067486 /* experimental.org in CopyFiles */ = {isa = PBXBuildFile; fileRef = 70B1A7590B7E431F00067486 /* experimental.org */; };
+ 70B6514F0BEA6FCC002472ED /* main.cc in Sources */ = {isa = PBXBuildFile; fileRef = 701EF27E0BEA5D2300DAE168 /* main.cc */; };
+ 70B651B70BEA9AEC002472ED /* unit-tests in CopyFiles */ = {isa = PBXBuildFile; fileRef = 70B6514C0BEA6FAD002472ED /* unit-tests */; };
70BCB22E0AB7B23D003FF331 /* cArgContainer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70BCB21C0AB7ADA6003FF331 /* cArgContainer.cc */; };
70BCB2350AB7B26B003FF331 /* cArgContainer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70BCB21C0AB7ADA6003FF331 /* cArgContainer.cc */; };
70C054ED0A4F6FD2002703C1 /* PopulationActions.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70C054C90A4F6E19002703C1 /* PopulationActions.cc */; };
@@ -427,6 +430,16 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 70B651B50BEA9AC2002472ED /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = work;
+ dstSubfolderSpec = 16;
+ files = (
+ 70B651B70BEA9AEC002472ED /* unit-tests in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
70DCAD08097AF7CC002F8733 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@@ -472,6 +485,7 @@
701D9382094CBA69008B845F /* cDriverManager.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cDriverManager.cc; sourceTree = "<group>"; };
701D93E6094CBF71008B845F /* cDefaultAnalyzeDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cDefaultAnalyzeDriver.h; sourceTree = "<group>"; };
701D93E7094CBF71008B845F /* cDefaultAnalyzeDriver.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cDefaultAnalyzeDriver.cc; sourceTree = "<group>"; };
+ 701EF27E0BEA5D2300DAE168 /* main.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = main.cc; sourceTree = "<group>"; };
7027621909D73E5900741717 /* cOrgSourceMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cOrgSourceMessage.h; sourceTree = "<group>"; };
7027621A09D73E7700741717 /* cOrgSinkMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cOrgSinkMessage.h; sourceTree = "<group>"; };
702D4EF508DA5328007BA469 /* cEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cEnvironment.h; sourceTree = "<group>"; };
@@ -600,6 +614,7 @@
707CE51D0A9E49A50022D19C /* config.html */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.html.documentation; path = config.html; sourceTree = "<group>"; };
707CE7490AA333060022D19C /* actions.html */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.html.documentation; path = actions.html; sourceTree = "<group>"; };
707CE7500AA334120022D19C /* analyze.html */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.html.documentation; path = analyze.html; sourceTree = "<group>"; };
+ 707D71280C00B9B300DD4D49 /* FloatingPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FloatingPoint.h; sourceTree = "<group>"; };
708051A70A1F65FE00CBB8B6 /* SaveLoadActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SaveLoadActions.h; sourceTree = "<group>"; };
708051A80A1F65FE00CBB8B6 /* SaveLoadActions.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SaveLoadActions.cc; sourceTree = "<group>"; };
708051BA0A1F66B400CBB8B6 /* cActionLibrary.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cActionLibrary.cc; sourceTree = "<group>"; };
@@ -787,6 +802,7 @@
70B1A7420B7E3FFD00067486 /* instset-experimental.cfg */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = "instset-experimental.cfg"; sourceTree = "<group>"; };
70B1A7590B7E431F00067486 /* experimental.org */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = experimental.org; sourceTree = "<group>"; };
70B3984E0947B29D0018F09D /* tManagedPointerArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tManagedPointerArray.h; sourceTree = "<group>"; };
+ 70B6514C0BEA6FAD002472ED /* unit-tests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "unit-tests"; sourceTree = BUILT_PRODUCTS_DIR; };
70BCB21B0AB7ADA6003FF331 /* cArgContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cArgContainer.h; sourceTree = "<group>"; };
70BCB21C0AB7ADA6003FF331 /* cArgContainer.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cArgContainer.cc; sourceTree = "<group>"; };
70BCB2470AB7B634003FF331 /* cArgSchema.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cArgSchema.h; sourceTree = "<group>"; };
@@ -910,7 +926,7 @@
DCC315CE076253A5008F7A48 /* environment.rotate */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = environment.rotate; sourceTree = "<group>"; };
DCC315D0076253A5008F7A48 /* task_event_gen.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = task_event_gen.cc; sourceTree = "<group>"; };
DCC315D1076253A5008F7A48 /* task_event_gen.old.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = task_event_gen.old.cc; sourceTree = "<group>"; };
- DCC3164D07626CF3008F7A48 /* avida */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = avida; sourceTree = BUILT_PRODUCTS_DIR; };
+ DCC3164D07626CF3008F7A48 /* avida */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = avida; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -929,6 +945,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 70B6514A0BEA6FAD002472ED /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
70DCAD07097AF7CC002F8733 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -965,6 +988,14 @@
path = drivers;
sourceTree = "<group>";
};
+ 701EF27D0BEA5D2300DAE168 /* unit-tests */ = {
+ isa = PBXGroup;
+ children = (
+ 701EF27E0BEA5D2300DAE168 /* main.cc */,
+ );
+ path = "unit-tests";
+ sourceTree = "<group>";
+ };
70422A1B091B141000A5E67F /* analyze */ = {
isa = PBXGroup;
children = (
@@ -1131,6 +1162,7 @@
70DCAC55097AF730002F8733 /* avida */,
70DCAC56097AF730002F8733 /* avida-s */,
70DCAC58097AF730002F8733 /* avida-viewer */,
+ 701EF27D0BEA5D2300DAE168 /* unit-tests */,
703CA3710A50734500AB4DB4 /* SConscript */,
);
path = targets;
@@ -1226,8 +1258,9 @@
70DCF4FF09CF81E400924128 /* platform */ = {
isa = PBXGroup;
children = (
+ 70DCF50009CF823500924128 /* tcmalloc */,
703CA3700A5072E600AB4DB4 /* SConscript */,
- 70DCF50009CF823500924128 /* tcmalloc */,
+ 707D71280C00B9B300DD4D49 /* FloatingPoint.h */,
);
path = platform;
sourceTree = "<group>";
@@ -1616,6 +1649,7 @@
700E2B83085DE50C00CF158A /* avida-viewer */,
70DCAD1C097AF7CC002F8733 /* avida-s */,
70AA941909D486AE006A24C8 /* libtcmalloc.a */,
+ 70B6514C0BEA6FAD002472ED /* unit-tests */,
);
name = Products;
sourceTree = "<group>";
@@ -1668,6 +1702,23 @@
productReference = 70AA941909D486AE006A24C8 /* libtcmalloc.a */;
productType = "com.apple.product-type.library.static";
};
+ 70B6514B0BEA6FAD002472ED /* unit-tests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 70B651570BEA700B002472ED /* Build configuration list for PBXNativeTarget "unit-tests" */;
+ buildPhases = (
+ 70B651490BEA6FAD002472ED /* Sources */,
+ 70B6514A0BEA6FAD002472ED /* Frameworks */,
+ 70B651B50BEA9AC2002472ED /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "unit-tests";
+ productName = "unit-tests";
+ productReference = 70B6514C0BEA6FAD002472ED /* unit-tests */;
+ productType = "com.apple.product-type.tool";
+ };
70DCAC9D097AF7CC002F8733 /* avida-s */ = {
isa = PBXNativeTarget;
buildConfigurationList = 70DCAD17097AF7CC002F8733 /* Build configuration list for PBXNativeTarget "avida-s" */;
@@ -1721,6 +1772,7 @@
70DCAC9D097AF7CC002F8733 /* avida-s */,
700E2AF3085DE50C00CF158A /* avida-viewer */,
70AA941809D486AE006A24C8 /* tcmalloc */,
+ 70B6514B0BEA6FAD002472ED /* unit-tests */,
);
};
/* End PBXProject section */
@@ -1894,6 +1946,7 @@
7099EF580B2FBC86001269F6 /* cTextViewerDriver_Base.cc in Sources */,
70B1A6520B7E237F00067486 /* cHardwareExperimental.cc in Sources */,
706C70010B83F265003174C1 /* cInstSet.cc in Sources */,
+ 707045F00BCEA0D9000F9B9A /* cHardwareGX.cc in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1907,6 +1960,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 70B651490BEA6FAD002472ED /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 70B6514F0BEA6FCC002472ED /* main.cc in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
70DCAC9F097AF7CC002F8733 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -2428,6 +2489,70 @@
};
name = Profile;
};
+ 70B651580BEA700B002472ED /* Development */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INSTALL_PATH = "$(HOME)/bin";
+ PREBINDING = NO;
+ PRODUCT_NAME = "unit-tests";
+ ZERO_LINK = YES;
+ };
+ name = Development;
+ };
+ 70B651590BEA700B002472ED /* Deployment-G4 */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_MODEL_TUNING = G5;
+ INSTALL_PATH = "$(HOME)/bin";
+ PREBINDING = NO;
+ PRODUCT_NAME = "unit-tests";
+ ZERO_LINK = YES;
+ };
+ name = "Deployment-G4";
+ };
+ 70B6515A0BEA700B002472ED /* Deployment-G5 */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_MODEL_TUNING = G5;
+ INSTALL_PATH = "$(HOME)/bin";
+ PREBINDING = NO;
+ PRODUCT_NAME = "unit-tests";
+ ZERO_LINK = YES;
+ };
+ name = "Deployment-G5";
+ };
+ 70B6515B0BEA700B002472ED /* Deployment-Universal */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_MODEL_TUNING = G5;
+ INSTALL_PATH = "$(HOME)/bin";
+ PREBINDING = NO;
+ PRODUCT_NAME = "unit-tests";
+ ZERO_LINK = YES;
+ };
+ name = "Deployment-Universal";
+ };
+ 70B6515C0BEA700B002472ED /* Profile */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_MODEL_TUNING = G5;
+ INSTALL_PATH = "$(HOME)/bin";
+ PREBINDING = NO;
+ PRODUCT_NAME = "unit-tests";
+ ZERO_LINK = YES;
+ };
+ name = Profile;
+ };
70DCAD18097AF7CC002F8733 /* Development */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -2595,6 +2720,18 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = "Deployment-G4";
};
+ 70B651570BEA700B002472ED /* Build configuration list for PBXNativeTarget "unit-tests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 70B651580BEA700B002472ED /* Development */,
+ 70B651590BEA700B002472ED /* Deployment-G4 */,
+ 70B6515A0BEA700B002472ED /* Deployment-G5 */,
+ 70B6515B0BEA700B002472ED /* Deployment-Universal */,
+ 70B6515C0BEA700B002472ED /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = "Deployment-G4";
+ };
70DCAD17097AF7CC002F8733 /* Build configuration list for PBXNativeTarget "avida-s" */ = {
isa = XCConfigurationList;
buildConfigurations = (
Modified: branches/collect/CMakeLists.txt
===================================================================
--- branches/collect/CMakeLists.txt 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/CMakeLists.txt 2007-05-22 16:50:55 UTC (rev 1589)
@@ -30,8 +30,13 @@
# This section defines default builtin compiler options
# ------------------------------------------------------------------------------
IF(UNIX)
- SET(COMPILER_WARNING_FLAGS "-Wextra -Wno-unknown-pragmas -Wconversion -Wno-trigraphs")
- SET(COMPILER_OPTIMIZATION_FLAGS "-ffast-math -fno-rtti -funroll-loops -fstrict-aliasing -ftree-vectorize -fvisibility-inlines-hidden")
+ IF (CMAKE_CXX_COMPILER MATCHES ".*pathCC.*")
+ SET(COMPILER_WARNING_FLAGS "")
+ SET(COMPILER_OPTIMIZATION_FLAGS "-ffast-math -fno-rtti -funroll-loops -fstrict-aliasing -OPT:Olimit=0")
+ ELSE (CMAKE_CXX_COMPILER MATCHES ".*pathCC.*")
+ SET(COMPILER_WARNING_FLAGS "-Wextra -Wno-unknown-pragmas -Wconversion -Wno-trigraphs")
+ SET(COMPILER_OPTIMIZATION_FLAGS "-ffast-math -fno-rtti -funroll-loops -fstrict-aliasing -ftree-vectorize -fvisibility-inlines-hidden")
+ ENDIF (CMAKE_CXX_COMPILER MATCHES ".*pathCC.*")
# Four types of c++ compilations:
# - debug (Debug)
@@ -205,6 +210,11 @@
LIST(APPEND ALL_INC_DIRS ${MAIN_DIR})
+# The platform directory
+SET(PLATFORM_DIR ${PROJECT_SOURCE_DIR}/source/platform)
+LIST(APPEND ALL_INC_DIRS ${PLATFORM_DIR})
+
+
# The tools directory
SET(TOOLS_DIR ${PROJECT_SOURCE_DIR}/source/tools)
SET(TOOLS_SOURCES
@@ -379,7 +389,20 @@
ENDIF(AVD_TASK_EVENT_GEN)
+OPTION(AVD_UNIT_TESTS
+ "Enable the unit-tests executable. Running this target will test various low level functionality."
+ OFF
+)
+IF(AVD_UNIT_TESTS)
+ SET(UNIT_TESTS_DIR source/targets/unit-tests)
+ SET(UNIT_TESTS_SOURCES
+ ${UNIT_TESTS_DIR}/main.cc
+ )
+ ADD_EXECUTABLE(unit-tests ${UNIT_TESTS_SOURCES})
+ INSTALL_TARGETS(/work unit-tests)
+ENDIF(AVD_UNIT_TESTS)
+
# Default Configuration Files
# - Installed into the work directory alongside selected targets
# ------------------------------------------------------------------------------
@@ -455,20 +478,20 @@
# By default, compile all unit tests of primitive Avida classes. Tests
# are run via 'make test' under unix.
-OPTION(AVD_UNIT_TESTS
+OPTION(AVD_CMAKE_UNIT_TESTS
"Enable building primitive unit test suites."
OFF
)
-IF(AVD_UNIT_TESTS)
+IF(AVD_CMAKE_UNIT_TESTS)
SET(UNIT_TESTS TRUE)
INCLUDE (${CMAKE_ROOT}/Modules/Dart.cmake)
ADD_DEFINITIONS(-DENABLE_UNIT_TESTS)
ADD_DEFINITIONS(-DUSE_tMemTrack=1)
ENABLE_TESTING()
-ELSE(AVD_UNIT_TESTS)
+ELSE(AVD_CMAKE_UNIT_TESTS)
REMOVE_DEFINITIONS(-DENABLE_UNIT_TESTS)
REMOVE_DEFINITIONS(-DUSE_tMemTrack=1)
-ENDIF(AVD_UNIT_TESTS)
+ENDIF(AVD_CMAKE_UNIT_TESTS)
IF(BUILD_AvidaSupportLibs)
Modified: branches/collect/source/actions/PopulationActions.cc
===================================================================
--- branches/collect/source/actions/PopulationActions.cc 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/actions/PopulationActions.cc 2007-05-22 16:50:55 UTC (rev 1589)
@@ -34,6 +34,7 @@
#include "cPopulationCell.h"
#include "cStats.h"
#include "cWorld.h"
+#include "cOrganism.h"
/*
@@ -542,13 +543,9 @@
{
private:
public:
- cActionToggleRewardInstruction(cWorld* world, const cString& args) : cAction(world, args)
- {
- //pass
- //@JMC: m_killprob (and other code) is a meme that hitchiked when I used gabe's event as an example. need to clean it up.
- }
+ cActionToggleRewardInstruction(cWorld* world, const cString& args) : cAction(world, args) {}
- static const cString GetDescription() { return "Arguments: [double probability=0.9]"; }
+ static const cString GetDescription() { return "No Arguments"; }
void Process(cAvidaContext& ctx)
{
@@ -570,19 +567,14 @@
{
private:
public:
- cActionToggleFitnessValley(cWorld* world, const cString& args) : cAction(world, args)
- {
- //pass
- //@JMC: m_killprob (and other code) is a meme that hitchiked when I used gabe's event as an example. need to clean it up.
- }
+ cActionToggleFitnessValley(cWorld* world, const cString& args) : cAction(world, args) {}
- static const cString GetDescription() { return "Arguments: [double probability=0.9]"; }
+ static const cString GetDescription() { return "No Arguments"; }
void Process(cAvidaContext& ctx)
{
if(m_world->GetConfig().FITNESS_VALLEY.Get()) {m_world->GetConfig().FITNESS_VALLEY.Set(0);}
else{m_world->GetConfig().FITNESS_VALLEY.Set(1);}
-// m_world->GetConfig().FITNESS_VALLEY.Set(-1* m_world->GetConfig().FITNESS_VALLEY.Get());
}
};
@@ -1439,7 +1431,7 @@
void Process(cAvidaContext& ctx)
{
for (int i = 0; i < m_world->GetPopulation().GetSize(); i++) {
- m_world->GetPopulation().GetCell(i).GetOrganism();
+ (m_world->GetPopulation().GetCell(i).GetOrganism())->GetPhenotype();
}
}
};
Modified: branches/collect/source/actions/PrintActions.cc
===================================================================
--- branches/collect/source/actions/PrintActions.cc 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/actions/PrintActions.cc 2007-05-22 16:50:55 UTC (rev 1589)
@@ -687,6 +687,92 @@
/*
+ This function requires that TRACK_CCLADES be enabled and avida is
+ not in analyze mode.
+
+ Parameters
+ filename (cString)
+ Where the clade information should be stored.
+
+ Please note the structure to this file is not a matrix.
+ Each line is formatted as follows:
+ update number_cclades ccladeID0 ccladeID0_count ccladeID1
+
+ @MRR May 2007
+ */
+class cActionPrintCCladeCounts : public cAction
+{
+private:
+ cString filename;
+ bool first_time;
+
+public:
+ cActionPrintCCladeCounts(cWorld* world, const cString& args)
+ : cAction(world, args)
+ {
+ cString largs(args);
+ filename = (!largs.GetSize()) ? "cclade_count.dat" : largs.PopWord();
+ first_time = true;
+ }
+
+ static const cString GetDescription() { return "Arguments: [filename = \"cclade_count.dat\"]"; }
+
+ void Process(cAvidaContext& ctx)
+ {
+ //Handle possible errors
+ if (ctx.GetAnalyzeMode())
+ m_world->GetDriver().RaiseFatalException(1, "PrintCCladeCount requires avida to be in run mode.");
+
+ if (m_world->GetConfig().TRACK_CCLADES.Get() == 0)
+ m_world->GetDriver().RaiseFatalException(1, "PrintCCladeCount requires coalescence clade tracking to be enabled.");
+
+
+ tHashTable<int, int> cclade_count; //A count for each clade in the population
+ set<int> clade_ids;
+
+ cPopulation& pop = m_world->GetPopulation();
+ const int update = m_world->GetStats().GetUpdate();
+
+ //For each organism in the population, find what coalescence clade it belongs to and count
+ for (int k = 0; k < pop.GetSize(); k++)
+ {
+ if (!pop.GetCell(k).IsOccupied())
+ continue;
+ int cclade_id = pop.GetCell(k).GetOrganism()->GetCCladeLabel();
+ int count = 0;
+ if (!cclade_count.Find(cclade_id,count))
+ clade_ids.insert(cclade_id);
+ cclade_count.SetValue(cclade_id, ++count);
+ }
+
+ ofstream& fp = m_world->GetDataFileManager().GetOFStream(filename);
+ if (!fp.is_open())
+ m_world->GetDriver().RaiseFatalException(1, "PrintCCladeCount: Unable to open output file.");
+ if (first_time)
+ {
+ fp << "# Each line is formatted as follows:" << endl;
+ fp << "# update number_cclades ccladeID0 ccladeID0_count ccladeID1" << endl;
+ fp << endl;
+ first_time = false;
+ }
+ fp << update << " "
+ << clade_ids.size() << " ";
+
+ set<int>::iterator sit = clade_ids.begin();
+ while(sit != clade_ids.end())
+ {
+ int count = 0;
+ cclade_count.Find(*sit, count);
+ fp << *sit << " " << count << " ";
+ sit++;
+ }
+ fp << endl;
+
+ }
+};
+
+
+/*
@MRR March 2007
This function prints out fitness data. The main point is that it
calculates the average fitness from info from the testCPU + the actual
@@ -1812,6 +1898,8 @@
action_lib->Register<cActionPrintPhenotypeData>("PrintPhenotypeData");
action_lib->Register<cActionPrintPhenotypeStatus>("PrintPhenotypeStatus");
action_lib->Register<cActionPrintDemeStats>("PrintDemeStats");
+ action_lib->Register<cActionPrintCCladeCounts>("PrintCCladeCounts");
+
// Processed Data
action_lib->Register<cActionPrintData>("PrintData");
Modified: branches/collect/source/classification/cClassificationManager.cc
===================================================================
--- branches/collect/source/classification/cClassificationManager.cc 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/classification/cClassificationManager.cc 2007-05-22 16:50:55 UTC (rev 1589)
@@ -1260,7 +1260,29 @@
fp << endl;
}
+//@MRR Coalescence Clades
+void cClassificationManager::LoadCCladeFounders(const cString& filename)
+{
+ ifstream fin(filename);
+ if (!fin.is_open())
+ m_world->GetDriver().RaiseFatalException(1, "Unable to open coalescence clade ids.");
+ int id;
+ fin >> id;
+ while(!fin.eof())
+ {
+ m_cclade_ids.insert(id);
+ fin >> id;
+ }
+ fin.close();
+}
+bool cClassificationManager::IsCCladeFounder(const int id) const
+{
+ set<int>::const_iterator it = m_cclade_ids.find(id);
+ return (it == m_cclade_ids.end()) ? false : true;
+}
+
+
unsigned int cClassificationManager::FindCRC(const cGenome & in_genome) const
{
unsigned int total = 0;
Modified: branches/collect/source/classification/cClassificationManager.h
===================================================================
--- branches/collect/source/classification/cClassificationManager.h 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/classification/cClassificationManager.h 2007-05-22 16:50:55 UTC (rev 1589)
@@ -27,6 +27,7 @@
#define cClassificationManager_h
#include <list>
+#include <set>
#ifndef defs_h
#include "defs.h"
@@ -96,6 +97,9 @@
cLineage* m_max_fitness_lineage; // lineage with the single highest fitness
cLineage* m_dominant_lineage; // the lineage with the largest number of creatures.
int m_lineage_next_id;
+
+ // CClade @MRR
+ std::set<int> m_cclade_ids;
// Private Helper Functions
@@ -206,7 +210,10 @@
void PrintLineageTotals(const cString& filename, bool verbose=false);
void PrintLineageCurCounts(const cString& filename);
-
+ // Coalescence Clade
+ void LoadCCladeFounders(const cString& filename);
+ bool IsCCladeFounder(const int id) const;
+
// Utility Functions
bool SaveClone(std::ofstream& fp);
bool LoadClone(std::ifstream & fp);
Modified: branches/collect/source/classification/cLineage.cc
===================================================================
--- branches/collect/source/classification/cLineage.cc 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/classification/cLineage.cc 2007-05-22 16:50:55 UTC (rev 1589)
@@ -150,3 +150,11 @@
}
+tArray<const cGenotype*> cLineage::GetCurrentGenotypes(cAvidaContext& ctx) const
+{
+ tArray<const cGenotype*> genotypes;
+ map<const cGenotype*, int, gt_gentype>::const_iterator it = m_genotype_map.begin();
+ for(; it != m_genotype_map.end(); it++)
+ genotypes.Push(it->first);
+ return genotypes;
+}
Modified: branches/collect/source/classification/cLineage.h
===================================================================
--- branches/collect/source/classification/cLineage.h 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/classification/cLineage.h 2007-05-22 16:50:55 UTC (rev 1589)
@@ -27,6 +27,7 @@
#define cLineage_h
#include <map>
+#include "tArray.h"
class cAvidaContext;
class cGenotype;
@@ -150,6 +151,8 @@
* the creation of this lineage
**/
double GetLineageStat2 () const { return m_lineage_stat2; }
+
+ tArray<const cGenotype*> GetCurrentGenotypes(cAvidaContext& ctx) const;
};
Modified: branches/collect/source/cpu/cCPUMemory.h
===================================================================
--- branches/collect/source/cpu/cCPUMemory.h 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/cpu/cCPUMemory.h 2007-05-22 16:50:55 UTC (rev 1589)
@@ -60,7 +60,7 @@
cCPUMemory(const cGenome& in_genome) : cGenome(in_genome), flag_array(in_genome.GetSize()) { ; }
cCPUMemory(const cString& in_string) : cGenome(in_string), flag_array(in_string.GetSize()) { ; }
//! Construct a cCPUMemory object from a cInstruction range.
- cCPUMemory(cInstruction* begin, cInstruction* end) : cGenome(begin, end), flag_array(GetSize()) { }
+ cCPUMemory(cInstruction* begin, cInstruction* end) : cGenome(begin, end), flag_array(GetSize()) { ClearFlags(); }
~cCPUMemory() { ; }
void operator=(const cCPUMemory& other_memory);
@@ -103,6 +103,8 @@
void ClearFlagCopyMut(int pos) { flag_array[pos] &= ~MASK_COPYMUT; }
void ClearFlagInjected(int pos) { flag_array[pos] &= ~MASK_INJECTED; }
+ void Append(const cInstruction& in_inst) { Insert(GetSize(), in_inst); }
+ void Append(const cGenome& in_genome) { Insert(GetSize(), in_genome); }
void Insert(int pos, const cInstruction& in_inst);
void Insert(int pos, const cGenome& in_genome);
void Remove(int pos, int num_insts=1);
Modified: branches/collect/source/cpu/cHardwareGX.cc
===================================================================
--- branches/collect/source/cpu/cHardwareGX.cc 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/cpu/cHardwareGX.cc 2007-05-22 16:50:55 UTC (rev 1589)
@@ -21,6 +21,7 @@
*/
#include <climits>
#include <fstream>
+#include <algorithm>
#include "cHardwareGX.h"
#include "cAvidaContext.h"
#include "cCPUTestInfo.h"
@@ -44,7 +45,12 @@
using namespace std;
+//! A small helper struct to make deleting a little easier.
+struct delete_functor {
+ template <typename T> void operator()(T *ptr) { delete ptr; }
+};
+
tInstLib<cHardwareGX::tMethod>* cHardwareGX::s_inst_slib = cHardwareGX::initInstLib();
tInstLib<cHardwareGX::tMethod>* cHardwareGX::initInstLib(void)
@@ -237,7 +243,29 @@
tInstLibEntry<tMethod>("die", &cHardwareGX::Inst_Die),
// Placebo instructions
- tInstLibEntry<tMethod>("skip", &cHardwareGX::Inst_Skip)
+ tInstLibEntry<tMethod>("skip", &cHardwareGX::Inst_Skip),
+
+ // Gene Expression Instructions
+ tInstLibEntry<tMethod>("p-alloc", &cHardwareGX::Inst_NewExecutableProgramid),
+ tInstLibEntry<tMethod>("g-alloc", &cHardwareGX::Inst_NewGenomeProgramid),
+ tInstLibEntry<tMethod>("p-copy", &cHardwareGX::Inst_ProgramidCopy),
+ tInstLibEntry<tMethod>("p-divide", &cHardwareGX::Inst_ProgramidDivide),
+
+ tInstLibEntry<tMethod>("site", &cHardwareGX::Inst_Site),
+ tInstLibEntry<tMethod>("bind", &cHardwareGX::Inst_Bind),
+ tInstLibEntry<tMethod>("bind2", &cHardwareGX::Inst_Bind2),
+ tInstLibEntry<tMethod>("if-bind", &cHardwareGX::Inst_IfBind),
+ tInstLibEntry<tMethod>("if-bind2", &cHardwareGX::Inst_IfBind2),
+ tInstLibEntry<tMethod>("num-sites", &cHardwareGX::Inst_NumSites),
+
+ // These are dummy instructions used for making mutiple programids
+ // look like one genome (for purposes of passing to offspring and printing).
+ // They need to be included but should have ZERO probabilities!!!
+ tInstLibEntry<tMethod>("PROGRAMID", &cHardwareGX::Inst_Nop),
+ tInstLibEntry<tMethod>("READABLE", &cHardwareGX::Inst_Nop),
+ tInstLibEntry<tMethod>("BINDABLE", &cHardwareGX::Inst_Nop),
+ tInstLibEntry<tMethod>("EXECUTABLE", &cHardwareGX::Inst_Nop)
+
};
const int n_size = sizeof(s_n_array)/sizeof(cNOPEntryCPU);
@@ -266,35 +294,58 @@
cHardwareGX::cHardwareGX(cWorld* world, cOrganism* in_organism, cInstSet* in_m_inst_set)
: cHardwareBase(world, in_organism, in_m_inst_set)
{
+ m_last_unique_id_assigned = 0;
m_functions = s_inst_slib->GetFunctions();
- m_programids.push_back(programid_ptr(new cProgramid(in_organism->GetGenome(), this)));
- m_current = m_programids.back();
- Reset(); // Setup the rest of the hardware...
+ Reset(); // Setup the rest of the hardware...also creates initial programid(s) from genome
}
/*! Destructor; delete all programids. */
cHardwareGX::~cHardwareGX()
{
- for(programid_list::iterator i=m_programids.begin(); i!=m_programids.end(); ++i) {
- delete *i;
- }
+ std::for_each(m_programids.begin(), m_programids.end(), delete_functor());
}
-/*! Reset this cHardwareGX to a known state. Removes all the cProgramids, creates
-a new cProgramid from the germ.
+/*! Reset this cHardwareGX to a known state.
+Removes all the current cProgramids, and creates new cProgramids from the germ.
*/
void cHardwareGX::Reset()
{
+ // Clear the current list of programids.
+ std::for_each(m_programids.begin(), m_programids.end(), delete_functor());
+ m_programids.clear();
+
+ // And add any programids specified by the "genome."
+ cGenome genome = organism->GetGenome();
+
+ // These specify the range of instructions that will be used to create a new
+ // programid. The range of instructions used to create a programid is:
+ // [begin, end), that is, the instruction pointed to by end is *not* copied.
+ cInstruction* begin=&genome[0];
+ cInstruction* end=&begin[genome.GetSize()];
+ cInstruction* i=0;
+ // Find the first instance of a PROGRAMID instruction.
+ begin = std::find_if(begin, end, bind2nd(equal_to<cInstruction>(), GetInstSet().GetInst("PROGRAMID")));
+ while(begin!=end) {
+ // Find the boundary of this programid.
+ i = std::find_if(begin+1, end, bind2nd(equal_to<cInstruction>(), GetInstSet().GetInst("PROGRAMID")));
+ AddProgramid(new cProgramid(cGenome(begin, i), this));
+ begin = i;
+ }
+
+ assert(m_programids.size()>0);
+
+ // Sanity, oh, where is my sanity?
+ bool has_executable=false;
+ bool has_bindable=false;
for(programid_list::iterator i=m_programids.begin(); i!=m_programids.end(); ++i) {
- delete *i;
+ has_executable = has_executable || (*i)->GetExecutable();
+ has_bindable = has_bindable || (*i)->GetBindable();
}
+ assert(has_bindable && has_executable);
- m_programids.clear();
- m_programids.push_back(programid_ptr(new cProgramid(organism->GetGenome(), this)));
m_current = m_programids.back();
-
m_mal_active = false;
m_executedmatchstrings = false;
@@ -308,36 +359,10 @@
inst_cost[i] = m_inst_set->GetCost(cInstruction(i));
inst_ft_cost[i] = m_inst_set->GetFTCost(cInstruction(i));
}
-#endif
-
+#endif
}
-//void cHardwareGX::cLocalThread::operator=(const cLocalThread& in_thread)
-//{
-// m_id = in_thread.m_id;
-// for (int i = 0; i < NUM_REGISTERS; i++) reg[i] = in_thread.reg[i];
-// for (int i = 0; i < NUM_HEADS; i++) heads[i] = in_thread.heads[i];
-// stack = in_thread.stack;
-//}
-//
-//void cHardwareGX::cLocalThread::Reset(cHardwareBase* in_hardware, int in_id)
-//{
-// m_id = in_id;
-//
-// for (int i = 0; i < NUM_REGISTERS; i++) reg[i] = 0;
-// for (int i = 0; i < NUM_HEADS; i++) heads[i].Reset(in_hardware);
-//
-// stack.Clear();
-// cur_stack = 0;
-// cur_head = nHardware::HEAD_IP;
-// read_label.Clear();
-// next_label.Clear();
-//}
-
-
-// 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.
/*! In cHardwareGX, SingleProcess is something of a misnomer. Each time this method
is called, each cProgramid executes a single instruction.
*/
@@ -346,25 +371,59 @@
cPhenotype& phenotype = organism->GetPhenotype();
organism->SetRunning(true);
+ m_just_divided = false;
phenotype.IncTimeUsed();
- for(programid_list::iterator i=m_programids.begin(); i!=m_programids.end(); ++i) {
- // Set the currently-executing cProgramid.
+ // A temporary list of the current programids in this organism.
+ programid_list runnable(m_programids.begin(), m_programids.end());
+
+ // Execute one instruction for each programid.
+ for(programid_list::iterator i=runnable.begin(); i!=runnable.end(); ++i) {
+ // Currently executing programid.
m_current = *i;
- // Find the instruction to be executed.
- const cInstruction& cur_inst = IP().GetInst();
-
- m_advance_ip = true;
- SingleProcess_ExecuteInst(ctx, cur_inst);
- if (m_advance_ip == true) {
- IP().Advance();
+ // Print the status of this CPU at each step...
+ if (m_tracer != NULL) m_tracer->TraceHardware(*this);
+
+ if(m_current->GetExecute()) {
+ // In case the IP is modified by this instruction, make sure that it wraps
+ // around to the beginning of the genome.
+ IP().Adjust();
+
+ // Find the instruction to be executed.
+ const cInstruction& cur_inst = IP().GetInst();
+
+ m_advance_ip = true;
+ SingleProcess_ExecuteInst(ctx, cur_inst);
+
+ // Break out if we just divided b/c the number of programids
+ // will have changed and it won't be obvious how to continue
+ if (m_just_divided) break;
+ if (m_advance_ip == true) {
+ IP().Advance();
+ }
+
+ // Update this programid stat
+ m_current->IncCPUCyclesUsed();
}
-
- // Update phenotype.
- phenotype.IncCPUCyclesUsed();
}
+ m_current = 0;
+
+ // Now kill old programids.
+ unsigned int on_p = 0;
+ while(on_p < m_programids.size()) {
+ if(m_programids[on_p]->GetCPUCyclesUsed() > MAX_PROGRAMID_AGE) {
+ RemoveProgramid(on_p);
+ } else {
+ on_p++;
+ }
+ }
+ m_current = m_programids.back(); // m_current must always point to a programid!
+
+ // Update phenotype. Note the difference between these cpu cycles and the per-programid ones...
+ phenotype.IncCPUCyclesUsed();
+
// Kill creatures who have reached their max num of instructions executed.
const int max_executed = organism->GetMaxExecuted();
if ((max_executed > 0 && phenotype.GetTimeUsed() >= max_executed)
@@ -467,11 +526,11 @@
return true;
}
-// This method will handle the actuall execution of an instruction
-// within single process, once that function has been finalized.
+
+/*! This method executes one instruction for one programid. */
bool cHardwareGX::SingleProcess_ExecuteInst(cAvidaContext& ctx, const cInstruction& cur_inst)
{
- // Copy Instruction locally to handle stochastic effects
+ // Copy the instruction in case of execution errors.
cInstruction actual_inst = cur_inst;
#ifdef EXECUTION_ERRORS
@@ -479,12 +538,11 @@
if (organism->TestExeErr()) actual_inst = m_inst_set->GetRandomInst(ctx);
#endif /* EXECUTION_ERRORS */
- // Get a pointer to the corrisponding method...
+ // Get the index for the instruction.
int inst_idx = m_inst_set->GetLibFunctionIndex(actual_inst);
// Mark the instruction as executed
IP().SetFlagExecuted();
-
#if INSTRUCTION_COUNT
// instruction execution count incremeneted
@@ -533,6 +591,16 @@
*/
void cHardwareGX::PrintStatus(ostream& fp)
{
+ //\todo clean up references
+
+ // Extra information about this programid
+ fp << "MemSpace:" << m_current->GetID() << " Programid ID:" << m_current->m_unique_id;
+ if (m_current->GetExecute()) fp << " EXECUTING";
+ if (m_current->GetExecutable()) fp << " EXECUTABLE";
+ if (m_current->GetBindable()) fp << " BINDABLE";
+ if (m_current->GetReadable()) fp << " READABLE";
+ fp << endl;
+
fp << organism->GetPhenotype().GetCPUCyclesUsed() << " ";
fp << "IP:" << IP().GetPosition() << " ";
@@ -540,18 +608,11 @@
fp << static_cast<char>('A' + i) << "X:" << GetRegister(i) << " ";
fp << setbase(16) << "[0x" << GetRegister(i) << "] " << setbase(10);
}
-
- // Add some extra information if additional time costs are used for instructions,
- // leave this out if there are no differences to keep it cleaner
- if ( organism->GetPhenotype().GetTimeUsed() != organism->GetPhenotype().GetCPUCyclesUsed() )
- {
- fp << " EnergyUsed:" << organism->GetPhenotype().GetTimeUsed();
- }
fp << endl;
- fp << " R-Head:" << GetHead(nHardware::HEAD_READ).GetPosition() << " "
- << "W-Head:" << GetHead(nHardware::HEAD_WRITE).GetPosition() << " "
- << "F-Head:" << GetHead(nHardware::HEAD_FLOW).GetPosition() << " "
+ fp << " R-Head:" << GetHead(nHardware::HEAD_READ).GetMemSpace() << ":" << GetHead(nHardware::HEAD_READ).GetPosition() << " "
+ << "W-Head:" << GetHead(nHardware::HEAD_WRITE).GetMemSpace() << ":" << GetHead(nHardware::HEAD_WRITE).GetPosition() << " "
+ << "F-Head:" << GetHead(nHardware::HEAD_FLOW).GetMemSpace() << ":" << GetHead(nHardware::HEAD_FLOW).GetPosition() << " "
<< "RL:" << GetReadLabel().AsString() << " "
<< endl;
@@ -564,17 +625,15 @@
// fp << " Ox" << setw(8) << GetStack(i, stack_id, 0);
// fp << setfill(' ') << setbase(10) << endl;
// }
-
+
fp << " Mem (" << GetMemory().GetSize() << "):"
- << " " << GetMemory().AsString()
- << endl;
+ << " " << GetMemory().AsString()
+ << endl;
fp.flush();
}
-
-
/////////////////////////////////////////////////////////////////////////
// Method: cHardwareGX::FindLabel(direction)
//
@@ -838,20 +897,22 @@
*/
void cHardwareGX::InjectCode(const cGenome & inject_code, const int line_num)
{
- m_programids.push_back(programid_ptr(new cProgramid(inject_code, this)));
- programid_ptr injected = m_programids.back();
-
+ programid_ptr injected = new cProgramid(inject_code, this);
+
// Set instruction flags on the injected code
for(int i=0; i<injected->m_memory.GetSize(); ++i) {
injected->m_memory.SetFlagInjected(i);
}
+
+ AddProgramid(injected);
+
organism->GetPhenotype().IsModified() = true;
}
void cHardwareGX::ReadInst(const int in_inst)
{
- if (m_inst_set->IsNop( cInstruction(in_inst) )) {
+ if(m_inst_set->IsNop(cInstruction(in_inst))) {
GetReadLabel().AddNop(in_inst);
} else {
GetReadLabel().Clear();
@@ -2818,6 +2879,69 @@
}
+/*! This instruction allocates a new programid with a zero length genome
+and moves the write head of the current programid to it.
+*/
+bool cHardwareGX::Inst_NewProgramid(cAvidaContext& ctx, bool executable, bool bindable, bool readable)
+{
+ // Do some maintenance on the programid where the write head was previously.
+ // (1) Adjust the number of heads on it; this could make it executable!
+ // (2) \todo Delete if it has no instructions or is below a certain size?
+ int write_head_contacted = GetHead(nHardware::HEAD_WRITE).GetMemSpace();
+ m_programids[write_head_contacted]->RemoveContactingHead(GetHead(nHardware::HEAD_WRITE));
+ GetHead(nHardware::HEAD_WRITE).Set(0, m_current->m_id); // Immediately set the write head back to itself
+
+ // If we've reached the programid limit, then deal with that
+ if(m_programids.size() >= MAX_PROGRAMIDS) {
+ //Decide on a programid to destroy, currently highest number of cpu cycles executed
+ //\todo more methods of choosing..
+
+ if (PROGRAMID_REPLACEMENT_METHOD == 0) {
+ // Don't replace (they can still die of old age!)
+ return false;
+ } else if(PROGRAMID_REPLACEMENT_METHOD == 1) {
+ // Replace oldest programid
+ int destroy_index = -1;
+ int max_cpu_cycles_used = -1;
+ for (unsigned int i=0; i<m_programids.size(); i++) {
+ if (m_programids[i]->GetCPUCyclesUsed() > max_cpu_cycles_used) {
+ max_cpu_cycles_used = m_programids[i]->GetCPUCyclesUsed();
+ destroy_index = i;
+ }
+ }
+ assert(destroy_index>=0);
+ RemoveProgramid(destroy_index);
+
+ // Also replace anything that its WRITE head contacted (unless itself)...
+ // to prevent accumulating partially copied programids
+ if(write_head_contacted != destroy_index) {
+ RemoveProgramid(write_head_contacted);
+ }
+ }
+ }
+
+ // Create the new programid and add it to the list
+ cGenome new_genome(1);
+ programid_ptr new_programid = new cProgramid(new_genome, this);
+ new_programid->m_executable = executable;
+ new_programid->m_bindable = bindable;
+ new_programid->m_readable = readable;
+ AddProgramid(new_programid);
+
+ // Set the write head to the newly allocated programid
+ new_programid->AddContactingHead(GetHead(nHardware::HEAD_WRITE));
+ GetHead(nHardware::HEAD_WRITE).Set(0, new_programid->GetID());
+
+ return true;
+}
+
+bool cHardwareGX::Inst_Site(cAvidaContext& ctx)
+{
+ // Do nothing except move past the label
+ ReadLabel();
+ return true;
+}
+
/*! This instruction reads the trailing label and tries to match it against other
programids in the CPU. Note: labels that follow a match instruction in the
programid to be matched against are *ignored*. Note that match should be a
@@ -2828,58 +2952,497 @@
\todo Have to determine the correct placement of the heads on Bind. If we're not
careful, we'll allow two RNAPs to bind to each other and start copying each other's
-genome. Probably a bad idea.
+genome. Probably a bad idea. @JEB Well, at least those selfish solutions would die.
+Temp Soln @JEB -- added a flag to programids so that only certain programids are bindable
*/
-bool cHardwareGX::Inst_Match(cAvidaContext& ctx) {
+bool cHardwareGX::Inst_Bind(cAvidaContext& ctx)
+{
// Get the label that we're trying to match.
+ // Do this first to advance IP past it.
ReadLabel();
- // Now, select another programid to match against. To start with, let's
- // look at all our programids and pick the first one that matches. This will
- // need to be revisited.
+ // Binding fails if we are already bound!
+ cHeadProgramid& read = GetHead(nHardware::HEAD_READ);
+ if(read.GetMemSpace() != m_current->GetID()) return false;
+ cHeadProgramid& write = GetHead(nHardware::HEAD_WRITE);
+
+ // Now, select another programid to match against.
+ // Go through all *other* programids looking for matches
+ std::vector<cMatchSite> all_matches;
for(programid_list::iterator i=m_programids.begin(); i!=m_programids.end(); ++i) {
- std::pair<bool, cMatchSite> match = (*i)->Matches(GetLabel());
+ // Don't bind to ourself, or to whatever programid our write head is attached to.
+ if((*i != m_current) && ((*i)->GetID() != write.GetMemSpace())) {
+ std::vector<cMatchSite> matches = (*i)->Sites(GetLabel());
+ all_matches.insert(all_matches.end(), matches.begin(), matches.end());
+ }
+ }
+
+ // The instruction failed if there were no matches
+ if(all_matches.size() == 0) return false;
+
+ // Otherwise set the read head to a random match
+ unsigned int c = ctx.GetRandom().GetUInt(all_matches.size());
+
+ // Ok, it matched. Bind the current programid's read head to the matched site.
+ m_current->Bind(nHardware::HEAD_READ, all_matches[c]);
+
+ // And we're done.
+ return true;
+}
+
+
+/*! This instruction attempts to locate two programids that have the same site.
+If two such programids are found, BX is set to 2, otherwise BX is set to 0.
+
+This instruction is well-suited for finding two genomes. For example, the following
+instruction sequence may be used to locate two genomes with an origin of replication,
+and if found, trigger a cell division:
+bind2
+nop-B
+nop-C
+if-not-0
+p-divide
+*/
+bool cHardwareGX::Inst_Bind2(cAvidaContext& ctx)
+{
+ // Get the label we're searching for.
+ ReadLabel();
+
+ // Search for matches to this label.
+ std::vector<cMatchSite> bindable;
+ for(programid_list::iterator i=m_programids.begin(); i!=m_programids.end(); ++i) {
+ if(*i != m_current) {
+ std::vector<cMatchSite> matches = (*i)->Sites(GetLabel());
+ // Now, we only want one match from each programid; we'll take a random one.
+ if(matches.size()>0) {
+ bindable.push_back(matches[ctx.GetRandom().GetInt(matches.size())]);
+ }
+ }
+ }
+
+ // Select two of the matches at random.
+ if(bindable.size()>=2) {
+ int first = ctx.GetRandom().GetInt(bindable.size());
+ int second = ctx.GetRandom().GetInt(bindable.size());
+ while(first == second) { second = ctx.GetRandom().GetUInt(bindable.size()); }
+ assert(bindable[first].m_programid->GetID() != bindable[second].m_programid->GetID());
+ assert(bindable[first].m_programid->GetBindable());
+ assert(bindable[second].m_programid->GetBindable());
+ assert(bindable[first].m_programid->GetReadable());
+ assert(bindable[second].m_programid->GetReadable());
+
+ // If the caller is already bound to other programids, detach.
+ m_current->Detach();
- if(match.first == true) {
- // Ok, it matched. Bind the current programid to the matched site.
- // For right now, we only support read-head binding.
- m_current->Bind(nHardware::HEAD_READ, match.second);
+ // And attach this programid's read and write heads to the indexed organisms.
+ // It *is* possible that the caller could do "bad things" now.
+ m_current->Bind(nHardware::HEAD_READ, bindable[first]);
+ m_current->Bind(nHardware::HEAD_WRITE, bindable[second]);
+
+ // Finally, set BX to indicate that bind2 worked, and return.
+ GetRegister(REG_BX) = 2;
+ return true;
+ }
+
+ // Bind2 didn't work.
+ GetRegister(REG_BX) = 0;
+ return false;
+}
+
+
+bool cHardwareGX::Inst_IfBind(cAvidaContext& ctx)
+{
+ // Normal Bind
+ bool ret = Inst_Bind(ctx);
+
+ //Skip the next instruction if binding was not successful
+ if (!ret) IP().Advance();
+
+ return ret;
+}
+
+
+bool cHardwareGX::Inst_IfBind2(cAvidaContext& ctx)
+{
+ // Normal Bind2
+ bool ret = Inst_Bind2(ctx);
+
+ //Skip the next instruction if binding was not successful
+ if (!ret) IP().Advance();
+
+ return ret;
+}
+
+
+/*! This instruction puts the total number of binding sites found in BX
+Currently it is used to keep track of whether genome division has completed.*/
+bool cHardwareGX::Inst_NumSites(cAvidaContext& ctx)
+{
+ // Get the label that we're trying to match.
+ ReadLabel();
+
+ // Go through all *other* programids counting matches
+ int num_sites = 0;
+ for(programid_list::iterator i=m_programids.begin(); i!=m_programids.end(); ++i) {
+ if (*i != m_current) {
+ num_sites += (*i)->Sites(GetLabel()).size();
+ }
+ }
+
+ GetRegister(REG_BX) = num_sites;
+ return true;
+}
+
+
+/*! This instruction is like h-copy, except:
+(1) It does nothing if the read and write head are not on OTHER programids
+(2) It dissociates the read head if it encounters the complement of the label that was used in the
+ match instruction that put the read head on its current target
+*/
+bool cHardwareGX::Inst_ProgramidCopy(cAvidaContext& ctx)
+{
+ cHeadProgramid& write = GetHead(nHardware::HEAD_WRITE);
+ cHeadProgramid& read = GetHead(nHardware::HEAD_READ);
+ read.Adjust(); // Strange things can happen (like we're reading from a programid that was being written).
+
+ // Don't copy if this programid's write or read head is on itself
+ if(read.GetMemSpace() == m_current->GetID()) return false;
+ if(write.GetMemSpace() == m_current->GetID()) return false;
+
+ // Don't copy if the source is not readable
+ if(!m_programids[read.GetMemSpace()]->GetReadable()) return false;
+
+ // If a copy is mutated in after a bind2, then the read head could be at the
+ // end of a genome. The copy fails, and we should probably break the bind, too.
+ if(read.GetPosition() >= read.GetMemory().GetSize()) {
+ m_current->Detach();
+ return false;
+ }
+
+ // Keep track of whether the last non-NOP we copied was a site
+ if(GetInstSet().IsNop(read.GetInst())) {
+ m_current->m_copying_label.AddNop(GetInstSet().GetNopMod(read.GetInst()));
+ } else {
+ m_current->m_copying_site = (read.GetInst() == GetInstSet().GetInst("site"));
+ m_current->m_copying_label.Clear();
+ }
+
+ // Allocate space for one additional instruction if the write head is at the end
+ // Otherwise the write head will improperly
+ if(write.GetMemory().GetSize() == write.GetPosition() + 1) {
+ write.GetMemory().Resize(write.GetMemory().GetSize() + 1);
+ }
+
+ // \todo The timing of deletion, change, insertion mutation checks matters
+ // I'm not sure this is right @JEB
+
+ // Normal h-copy, unless a deletion occured
+ if (!organism->TestCopyDel(ctx)) {
+ // Normal h-copy
+ bool ret = Inst_HeadCopy(ctx);
+ }
+
+ // Divide Insertion
+ if (organism->TestCopyIns(ctx)) {
+ write.GetMemory().Insert(write.GetPosition(), GetInstSet().GetRandomInst(ctx));
+ // Advance the write head;
+ write++;
+ }
+
+ // Peek at the next inst to see if it is a NOP
+ // If it isn't, then we can compare the label and possibly fall off
+ if(m_current->m_copying_site) {
+ if((!GetInstSet().IsNop(read.GetInst()) && (m_current->m_terminator_label == m_current->m_copying_label))) {
+ // Move read head off of old target and back to itself
+ read.GetProgramid()->RemoveContactingHead(read);
+ read.Set(0, m_current->m_id);
- // And we're done.
+ //Shrink the programid we were on by one inst
+ if (write.GetMemory().GetSize()>1)
+ {
+ write.GetMemory().Resize( write.GetMemory().GetSize() - 1 );
+ }
+
+ // \to do, we would apply insertion/deletion on divide instructions here
+ // if we want them to happen for each new programid that is produced
+ // // Handle Divide Mutations...
+
+ // This would be equivalent to
+ // Divide_DoMutations(ctx, mut_multiplier);
+ // But that operates on m_child_genome, currently
+
return true;
}
}
+
+ return true;
+}
+
+
+/*! This instruction creates a new organism by randomly dividing the programids with
+the daughter cell. Currently we convert the daughter genomes back into one list with pseudo-instructions
+telling us where new programids start and some of their properties. This is pretty inefficient.
+*/
+bool cHardwareGX::Inst_ProgramidDivide(cAvidaContext& ctx)
+{
+ //This stuff is usually set by Divide_CheckViable, leaving it zero causes problems
+ cPhenotype& phenotype = organism->GetPhenotype();
+ organism->GetPhenotype().SetLinesExecuted(1);
+ organism->GetPhenotype().SetLinesCopied(1);
- // If nothing matched, we're done; but the instruction didn't really work.
- return false;
+ // Let's make sure that things seem sane.
+ cHeadProgramid& read = GetHead(nHardware::HEAD_READ); // The parent.
+ cHeadProgramid& write = GetHead(nHardware::HEAD_WRITE); // The offspring.
+
+ // If either of these heads are on m_current, this instruction fails.
+ if(read.GetMemSpace() == m_current->GetID()) return false;
+ if(write.GetMemSpace() == m_current->GetID()) return false;
+
+ // It should never be the case that the read and write heads are on the same programid.
+ assert(read.GetMemSpace() != write.GetMemSpace());
+ // Actually, it can happen with bind2 @JEB
+
+ // If the read and write heads are on the same programid, then fail
+ if (read.GetMemSpace() == write.GetMemSpace()) return false;
+
+ // If we're not bound to two bindable programids, this instruction fails.
+ if(!m_programids[read.GetMemSpace()]->GetBindable()) return false;
+ if(!m_programids[write.GetMemSpace()]->GetBindable()) return false;
+
+ // Now, let's keep track of two different lists of programids, one for the parent,
+ // and one for the offspring.
+ programid_list parent;
+ programid_list offspring;
+ // We're also going to do all our work on a temporary list, so that we can fail
+ // without affecting the state of the caller.
+ programid_list all(m_programids);
+ // This is a list of fragments, to be deleted once we've passed the viability check.
+ programid_list fragments;
+
+ // The currently executing programid called the divide instruction. The caller
+ // is (hopefully) a DNA polymerase, therefore it knows which genome fragments go where.
+ parent.push_back(m_programids[read.GetMemSpace()]); // The parent's genome.
+ all[read.GetMemSpace()] = 0;
+ offspring.push_back(m_programids[write.GetMemSpace()]); // The offspring's genome.
+ //offspring.back()->SetBindable(true);
+ all[write.GetMemSpace()] = 0;
+
+ // Locate and remove all incomplete genomes, identified by programids that have
+ // write heads on them.
+ for(programid_list::iterator i=all.begin(); i!=all.end(); ++i) {
+ // Does this programid currently have it's write head somewhere?
+ if((*i != 0) && ((*i)->GetHead(nHardware::HEAD_WRITE).GetMemSpace() != (*i)->GetID())) {
+ // Yes - It is likely an incomplete genome fragment, so don't
+ // allow it to propagate.
+ fragments.push_back(all[(*i)->GetHead(nHardware::HEAD_WRITE).GetMemSpace()]);
+ all[(*i)->GetHead(nHardware::HEAD_WRITE).GetMemSpace()] = 0;
+ }
+ }
+
+ // Divvy up the programids.
+ for(programid_list::iterator i=all.begin(); i!=all.end(); ++i) {
+ if(*i != 0) {
+ if(ctx.GetRandom().GetUInt(2) == 0) {
+ // Offspring!
+ offspring.push_back(*i);
+ } else {
+ // Parent!
+ parent.push_back(*i);
+ }
+ }
+ }
+
+ ///// Failure conditions (custom divide_check_viable)
+ // It is possible that the divide kills the child and the parent
+ // Each must have genomic programids of some minimum length
+ // and an executable programid (otherwise it is inviable)
+ // For now we leave a zombie mother to die of old age
+ // but do not permit creating an inviable daughter
+
+ // Conditions for successful replication
+ int num_daughter_programids = 0;
+ int daughter_genome_length = 0;
+ bool daughter_has_executable = false;
+ bool daughter_has_bindable = false;
+
+ // Calculate these conditions.
+ for(programid_list::iterator i=offspring.begin(); i!=offspring.end(); ++i) {
+ ++num_daughter_programids;
+ if((*i)->GetReadable()) {
+ daughter_genome_length += (*i)->GetMemory().GetSize();
+ }
+ daughter_has_executable = daughter_has_executable || (*i)->GetExecutable();
+ daughter_has_bindable = daughter_has_bindable || (*i)->GetBindable();
+ }
+ assert(daughter_has_bindable); // We know this should be there...
+
+ // And check them. Note that if this check fails, we have *not* modified the
+ // state of the calling programid.
+ if((num_daughter_programids == 0)
+ || (!daughter_has_executable)
+ || (daughter_genome_length < 50)) {
+ // \todo link to original genome length
+ return false;
+ }
+
+ // Ok, we're good to go. We have to create the offspring's genome and delete the
+ // offspring's programids from m_programids.
+ cCPUMemory& child_genome = organism->ChildGenome();
+ child_genome.Resize(1);
+ if (m_world->GetVerbosity() >= VERBOSE_DETAILS) std::cout << "-=OFFSPRING=-" << endl;
+ for(programid_list::iterator i=offspring.begin(); i!=offspring.end(); ++i) {
+ (*i)->AppendLinearGenome(child_genome);
+ if (m_world->GetVerbosity() >= VERBOSE_DETAILS) (*i)->PrintGenome(std::cout);
+ delete *i;
+ *i = 0;
+ }
+
+ // Now clean up the parent.
+ m_programids.clear();
+ if (m_world->GetVerbosity() >= VERBOSE_DETAILS) std::cout << "-=PARENT=-" << endl;
+ for(programid_list::iterator i=parent.begin(); i!=parent.end(); ++i) {
+ AddProgramid(*i);
+ if (m_world->GetVerbosity() >= VERBOSE_DETAILS) (*i)->PrintGenome(std::cout);
+ }
+
+ // And delete the fragments.
+ for(programid_list::iterator i=fragments.begin(); i!=fragments.end(); ++i) {
+ delete *i;
+ }
+
+ // Activate the child
+ bool parent_alive = organism->ActivateDivide(ctx);
+
+ // Mother viability checks could go here.
+ m_just_divided = true;
+ return true;
}
-/*! This instruction runs asynchronously compared to the rest of the cProgramid,
-and it is exectued ONLY when a cProgramid disassociates from another. cProgramids
-are not required to have this instruction in their genome.
+//! Adds a new programid to the current cHardwareGX.
+void cHardwareGX::AddProgramid(programid_ptr programid)
+{
+ programid->m_id = m_programids.size();
+ programid->ResetHeads();
+// programid->ResetCPUCyclesUsed();
+ programid->m_contacting_heads = 0;
+ m_programids.push_back(programid);
+}
-IF a cProgramid disassociates AND it has this instruction, then its HEAD_IP is
-updated to point to this instruction.
-\todo What if a cProgramid has multiple Inst_OnDisassociates?
-*/
-bool cHardwareGX::Inst_OnDisassociate(cAvidaContext& ctx) {
- return false;
+void cHardwareGX::RemoveProgramid(unsigned int remove_index)
+{
+ assert(remove_index<m_programids.size());
+
+ programid_ptr save=m_current;
+ m_current = m_programids[remove_index];
+ unsigned int write_head_contacted = (unsigned int)GetHead(nHardware::HEAD_WRITE).GetMemSpace();
+
+ // First update the contacting head count for any cProgramids the heads
+ // of the programid to be removed might have been on
+ m_current->Detach();
+// m_programids[GetHead(nHardware::HEAD_READ).GetMemSpace()]->RemoveContactingHead(GetHead(nHardware::HEAD_READ));
+// m_programids[GetHead(nHardware::HEAD_WRITE).GetMemSpace()]->RemoveContactingHead(GetHead(nHardware::HEAD_WRITE));
+
+ // Update the programid list
+ delete *(m_programids.begin()+remove_index);
+ m_programids.erase(m_programids.begin()+remove_index);
+ // Add adjust all the programid ids from the removed programid to the end.
+ for(programid_list::iterator i=m_programids.begin()+remove_index; i!=m_programids.end(); ++i) {
+ --(*i)->m_id;
+ }
+
+ // We also need to make sure heads are on the correct memory
+ // spaces, since that indexing changes with the programid list
+ for(unsigned int i=0; i< m_programids.size(); i++) {
+ programid_ptr p = m_programids[i];
+ for(int j=0; j<NUM_HEADS; j++) {
+ // We removed the thing they were writing from or reading to
+ // For now, just put the write head back on themselves (inactivating further copies)
+ // Might want to also reset the read head..
+ if (p->m_heads[j].GetMemSpace() == (int)remove_index) {
+ p->m_heads[j].Set(0, p->m_id);
+ } else if (p->m_heads[j].GetMemSpace() > (int)remove_index) {
+ p->m_heads[j].Set(p->m_heads[j].GetPosition(), p->m_heads[j].GetMemSpace() - 1);
+ }
+ }
+ }
+
+ // Finally, also delete whatever programid our write head contacted (if not ourself!)
+ if(write_head_contacted != remove_index) {
+ RemoveProgramid( (write_head_contacted > remove_index) ? write_head_contacted - 1 : write_head_contacted);
+ }
+
+ m_current = save;
}
/*! Construct this cProgramid, and initialize hardware resources.
*/
-cHardwareGX::cProgramid::cProgramid(const cGenome& genome, cHardwareBase* cpu)
-: m_offspring(0)
-, m_memory(genome) {
+cHardwareGX::cProgramid::cProgramid(const cGenome& genome, cHardwareGX* hardware)
+: m_memory(genome)
+, m_executable(false)
+, m_bindable(false)
+, m_readable(false)
+, m_copying_site(false)
+, m_cpu_cycles_used(0)
+, m_gx_hardware(hardware)
+, m_unique_id(hardware->m_last_unique_id_assigned++)
+{
+ assert(m_gx_hardware!=0);
for(int i=0; i<NUM_HEADS; ++i) {
- m_heads[i].Reset(cpu);
+ m_heads[i].Reset(hardware);
}
+
+ // Check what flags should be set on this programid.
+ for(int i=0; i<m_memory.GetSize();) {
+ if(m_memory[i]==GetInst("PROGRAMID")) {
+ m_memory.Remove(i);
+ continue;
+ }
+ if(m_memory[i]==GetInst("EXECUTABLE")) {
+ m_memory.Remove(i);
+ m_executable=true;
+ continue;
+ }
+ if(m_memory[i]==GetInst("BINDABLE")) {
+ m_memory.Remove(i);
+ m_bindable=true;
+ continue;
+ }
+ if(m_memory[i]==GetInst("READABLE")) {
+ m_memory.Remove(i);
+ m_readable=true;
+ continue;
+ }
+ ++i;
+ }
}
+/*! Append this programid's genome to the passed in genome. Include the tags
+that specify what this programid is capable of.
+*/
+void cHardwareGX::cProgramid::AppendLinearGenome(cCPUMemory& genome) {
+ genome.Append(GetInst("PROGRAMID"));
+ if(GetExecutable()) { genome.Append(GetInst("EXECUTABLE")); }
+ if(GetBindable()) { genome.Append(GetInst("BINDABLE")); }
+ if(GetReadable()) { genome.Append(GetInst("READABLE")); }
+ genome.Append(m_memory);
+}
+
+
+void cHardwareGX::cProgramid::PrintGenome(std::ostream& out) {
+ out << "Programid ID: " << m_id << " UID:" << m_unique_id << endl;
+ if(GetExecutable()) out << " EXECUTABLE";
+ if(GetBindable()) out << " BINDABLE";
+ if(GetReadable()) out << " READABLE";
+ out << endl;
+ out << " Mem (" << GetMemory().GetSize() << "):" << " " << GetMemory().AsString() << endl;
+ out.flush();
+}
+
+
/*! This method attempts to match this cProgramid with the passed-in label. If the
match is succesful, it returns true and a cMatchSite object that may be used to bind
to the programid. If the match is unsuccessful, it return false and the cMatchSite
@@ -2889,8 +3452,79 @@
to the the passed-in label. A number of configuration options (will eventually)
control how precisely the NOPs must be related (e.g., exact, all-but-one, etc.).
*/
-std::pair<bool, cHardwareGX::cMatchSite> cHardwareGX::cProgramid::Matches(const cCodeLabel& label) {
- return std::make_pair(false, cMatchSite());
+std::vector<cHardwareGX::cMatchSite> cHardwareGX::cProgramid::Sites(const cCodeLabel& label)
+{
+ std::vector<cHardwareGX::cMatchSite> matches;
+ if(!m_bindable) return matches;
+
+ cInstruction site_inst = m_gx_hardware->GetInstSet().GetInst("site");
+
+ // Create a new search head at the beginning of our memory space
+ // \to do doesn't properly find wrap-around matches overlapping the origin of the memory
+
+ //Find the first non-NOP and start there (this allows ups to wrap around correctly)
+ cHeadCPU search_head(m_gx_hardware, 0, m_id);
+ int first_non_nop = -1;
+ do {
+ if ( !m_gx_hardware->m_inst_set->IsNop(search_head.GetInst()) )
+ {
+ first_non_nop = search_head.GetPosition();
+ break;
+ }
+ search_head++;
+ } while (search_head.GetPosition() != 0);
+
+ // This genome is all NOPs...
+ if (first_non_nop == -1) return matches;
+
+ //keep track of the first time we find a non-NOP instruction (finish when we reach it a second time)
+ int site_pos = -1;
+ cCodeLabel site_label;
+
+ // Start at this instruction
+ search_head.Set(first_non_nop, m_id);
+ do {
+
+ if (search_head.GetInst() == site_inst)
+ {
+ site_pos = search_head.GetPosition();
+ site_label.Clear();
+ }
+ else if ( m_gx_hardware->m_inst_set->IsNop(search_head.GetInst()) && (site_pos != -1) )
+ {
+ // Add NOPs to the current label
+ site_label.AddNop( m_gx_hardware->m_inst_set->GetNopMod( search_head.GetInst() ) );
+ }
+ else // Any other non-NOP instruction means to stop looking for terminator matches
+ {
+ site_pos = -1;
+ }
+
+ // Is the next inst a NOP?
+ // If not, then check our current label for termination
+ if (site_pos != -1)
+ {
+ int old_pos = search_head.GetPosition();
+ search_head++;
+ if ( !m_gx_hardware->m_inst_set->IsNop( search_head.GetInst()) )
+ {
+ if ( site_label == label )
+ {
+ cMatchSite match;
+ match.m_programid = this;
+ match.m_site = site_pos; // We return is exactly on the site
+ match.m_label = site_label;
+ matches.push_back(match);
+ }
+ }
+
+ // Grrr. Heads don't wrap backwards properly!~! Can't just search_head--; No idea why.
+ search_head.Set(old_pos, m_id);
+ }
+
+ search_head++;
+ } while ( search_head.GetPosition() != first_non_nop ); // back at the beginning
+
}
@@ -2899,14 +3533,31 @@
location in the genome of the other cProgramid, but this will be extended later.
*/
void cHardwareGX::cProgramid::Bind(nHardware::tHeads head, cMatchSite& site) {
+ // We set the terminator site label to the complement of the one that was bound.
+ m_terminator_label = site.m_label;
+ m_terminator_label.Rotate(1, NUM_NOPS);
+
+ // Set the head.
+ if(GetHead(head).GetMemSpace() != GetID()) {
+ // Head is somewhere else; remove it
+ m_gx_hardware->m_programids[GetHead(head).GetMemSpace()]->RemoveContactingHead(GetHead(head));
+ }
+
+ // Now attach it to the passed-in match site
+ m_gx_hardware->m_programids[site.m_programid->GetID()]->AddContactingHead(GetHead(head));
+ GetHead(head).Set(site.m_site, site.m_programid->GetID());
}
-/*! Disassociate is called when this cProgramids's read head traverses over the
-complement of the label that was used to Bind this cProgramid to another. When
-called, Disassociate removes this cProgramid's read head from the bound cProgramid,
-searches for an Inst_OnDisassociate in its own genome, and, if found, updates this
-cProgramid's IP to point to it.
+/*! This method detaches the caller's heads from programids that it is connected
+to. It also updates the head contact counts.
*/
-void cHardwareGX::cProgramid::Disassociate() {
+void cHardwareGX::cProgramid::Detach() {
+ int head = GetHead(nHardware::HEAD_WRITE).GetMemSpace();
+ m_gx_hardware->m_programids[head]->RemoveContactingHead(GetHead(nHardware::HEAD_WRITE));
+ GetHead(nHardware::HEAD_WRITE).Set(0, GetID());
+
+ head = GetHead(nHardware::HEAD_READ).GetMemSpace();
+ m_gx_hardware->m_programids[head]->RemoveContactingHead(GetHead(nHardware::HEAD_READ));
+ GetHead(nHardware::HEAD_READ).Set(0, GetID());
}
Modified: branches/collect/source/cpu/cHardwareGX.h
===================================================================
--- branches/collect/source/cpu/cHardwareGX.h 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/cpu/cHardwareGX.h 2007-05-22 16:50:55 UTC (rev 1589)
@@ -19,8 +19,12 @@
* new CPU, so that's what we're doing. Eventually we'll need to revisit this.
*
* \todo There should be better ways for promoter regions to work. Right now,
- * we stop at the first one encountered.
+ * look for exact matches only and they have equal probabilities @JEB
*
+ * \todo We need to abstract cOrganism and derive a new class
+ * that can accommodate multiple genome fragments.
+ *
+ *
* Copyright 1999-2007 Michigan State University. All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -43,6 +47,7 @@
#include <iomanip>
#include <vector>
+#include <list>
#include <utility>
#include "cCodeLabel.h"
#include "cHeadCPU.h"
@@ -66,7 +71,8 @@
/*! Each organism may have a cHardwareGX structure that keeps track of the
* current status of simulated hardware. This particular CPU architecture is
-* designed to explore the evolution of gene expression.
+* designed to explore the evolution of gene expression and also the effect
+* of having persistent "protein-like" pieces of code that continually execute in parallel.
*/
class cHardwareGX : public cHardwareBase
{
@@ -78,6 +84,16 @@
static const int NUM_HEADS = nHardware::NUM_HEADS >= NUM_REGISTERS ? nHardware::NUM_HEADS : NUM_REGISTERS;
static const int NUM_NOPS = 3; //!< Number of NOPS that cHardwareGX supports.
+ //!< \todo JEB Make these config options
+ static const unsigned int MAX_PROGRAMIDS = 32; //!< Number of cProgramids that an organism can allocate.
+ static const int PROGRAMID_REPLACEMENT_METHOD = 0;
+ //!< Controls what happens when we try to allocate a new cProgramid, but are up against the limit
+ // 0 = Fail if no programids available
+ // 1 = Replace the programid that has completed the most instructions
+ static const int MAX_PROGRAMID_AGE = 2000; // Number of inst a cProgramid executes before ceasing to exist
+
+ unsigned int m_last_unique_id_assigned; // Counter so programids can be assigned unique IDs for tracking
+
//! Enums for the different supported registers.
enum tRegisters { REG_AX=0, REG_BX, REG_CX };
@@ -89,9 +105,24 @@
struct cMatchSite {
cMatchSite() : m_programid(0), m_site(0) { }
cProgramid* m_programid; //!< The programid matched against; 0 if not matched.
- cInstruction* m_site; //!< Location in the cProgramid where a match occurred; 0 if not matched.
+ int m_site; //!< Location in the cProgramid where a match occurred; 0 if not matched.
cCodeLabel m_label; //!< The label that was matched against.
};
+
+ /*! cHeadProgramid is just cHeadCPU with a link back to the programid
+ so that we can tell when a head is on the programid that owns it.
+ */
+ class cHeadProgramid : public cHeadCPU
+ {
+ private:
+ cProgramid* m_programid;
+ public:
+ cHeadProgramid() : cHeadCPU(), m_programid(NULL) { }
+ ~cHeadProgramid() { ; }
+
+ void SetProgramid(cProgramid* _programid) { m_programid = _programid; }
+ cProgramid* GetProgramid() { return m_programid; }
+ };
/*! cProgramid is the "heart" of the gene expression hardware. It encapsulates
the genome fragment that is used by both active and passive elements within
@@ -104,35 +135,97 @@
\todo Need to rework cHeadCPU to not need a pointer to cHardwareBase.
*/
- struct cProgramid {
+ class cProgramid {
+ public:
//! Constructs a cProgramid from a genome and CPU.
- cProgramid(const cGenome& genome, cHardwareBase* cpu);
+ cProgramid(const cGenome& genome, cHardwareGX* hardware);
//! Returns whether and where this cProgramid matches the passed-in label.
- std::pair<bool, cMatchSite> Matches(const cCodeLabel& label);
+ std::vector<cHardwareGX::cMatchSite> Sites(const cCodeLabel& label);
//! Binds one of this cProgramid's heads to the passed-in match site.
void Bind(nHardware::tHeads head, cMatchSite& site);
- //! Called when this cProgramid "falls off" the cProgramid it is bound to.
- void Disassociate();
+ //! Detaches this cProgramid's heads from bound cProgramids.
+ void Detach();
- programid_ptr m_offspring; //!< An offspring of this cProgramid; may be null.
- cCodeLabel m_terminator; //!< The label that this cProgramid must traverse to disassociate.
+ // Programids keep a count of the total number
+ // of READ + WRITE heads of other programids that
+ // have been placed on them. They only execute
+ // if free of other heads and also initialized as executable.
+ void RemoveContactingHead(cHeadProgramid& head) {
+ if(head.GetProgramid()->GetID() == m_id) return;
+ assert(m_contacting_heads > 0);
+ m_contacting_heads--;
+ }
+
+ void AddContactingHead(cHeadProgramid& head) {
+ if(head.GetProgramid()->GetID() == m_id) return;
+ m_contacting_heads++;
+ }
+
+ void ResetHeads() {
+ for(int i=0; i<NUM_HEADS; ++i) {
+ m_heads[i].SetProgramid(this);
+ m_heads[i].Reset(m_gx_hardware, m_id);
+ }
+ }
+
+ // Accessors
+ bool GetExecute() { return m_executable && (m_contacting_heads == 0); }
+ bool GetExecutable() { return m_executable; }
+ bool GetBindable() { return m_bindable; }
+ bool GetReadable() { return m_readable; }
+ int GetID() { return m_id; }
+ int GetCPUCyclesUsed() { return m_cpu_cycles_used; }
+ void ResetCPUCyclesUsed() { m_cpu_cycles_used = 0; }
+ cInstruction GetInst(cString inst) { assert(m_gx_hardware); return m_gx_hardware->GetInstSet().GetInst(inst); }
+
+ const cCPUMemory& GetMemory() const { return m_memory; }
+
+ //! Append this programid's genome to the passed-in genome in linear format (includes tags).
+ void AppendLinearGenome(cCPUMemory& genome);
+
+ //! Print this programid's genome, in linear format.
+ void PrintGenome(std::ostream& out);
+
+ cHeadProgramid& GetHead(int head_id) { return m_heads[head_id]; }
+
+ // Assignment
+ void SetExecutable(bool _executable) { m_executable = _executable; }
+ void SetBindable(bool _bindable) { m_bindable = _bindable; }
+ void SetReadable(bool _readable) { m_readable = _readable; }
+
+ void IncCPUCyclesUsed() { m_cpu_cycles_used++; }
+
+ cHardwareGX* m_gx_hardware; //!< Back reference
+ int m_id; //!< Each programid is cross-referenced to a memory space.
+ // The index in cHardwareGX::m_programids and cHeadCPU::GetMemSpace() must match up.
+ // A programid also needs to be kept aware of its current index.
+ int m_unique_id; // ID unique to this programid (per hardware)
+
+ int m_contacting_heads; //!< The number of read/write heads on this programid from other programids.
+ bool m_executable; //!< Is this programid ever executable? Currently, a programid with head from another cProgramid on it is also stopped.
+ bool m_bindable; //!< Is this programid bindable, i.e. can other programids put their read heads on it?
+ bool m_readable; //!< Is this programid readable?
+ int m_cpu_cycles_used; //!< Number of cpu cycles this programid has used.
+
+ bool m_copying_site; //! Are we in the middle of copying a "site" (which could cause termination)
+ cCodeLabel m_copying_label; //! The current site label that we are copying
+ cCodeLabel m_terminator_label; //!< The label that this cProgramid must traverse to disassociate.
+
+ // Core variables maintained from previous incarnation as a thread
cCodeLabel m_readLabel; //!< ?
cCodeLabel m_nextLabel; //!< ?
cCPUMemory m_memory; //!< This cProgramid's genome fragment.
cCPUStack m_stack; //!< This cProgramid's stack (no global stack).
- cHeadCPU m_heads[NUM_HEADS]; //!< This cProgramid's heads.
+ cHeadProgramid m_heads[NUM_HEADS]; //!< This cProgramid's heads.
int m_regs[NUM_REGISTERS]; //!< This cProgramid's registers.
};
-
-
protected:
static tInstLib<tMethod>* initInstLib(void); //!< Initialize the instruction library.
static tInstLib<tMethod>* s_inst_slib; //!< Instruction library (method pointers for all instructions).
programid_list m_programids; //!< The list of cProgramids.
programid_ptr m_current; //!< The currently-executing cProgramid.
-
// -------- Member Variables --------
const tMethod* m_functions;
@@ -141,6 +234,7 @@
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?
+ bool m_just_divided; // Did we just divide (in which case end execution of programids until next cycle).
// Instruction costs...
#if INSTRUCTION_COSTS
@@ -153,25 +247,25 @@
bool SingleProcess_ExecuteInst(cAvidaContext& ctx, const cInstruction& cur_inst);
// -------- Stack Manipulation... --------
- inline void StackPush(int value) { m_current->m_stack.Push(value); }
- inline int StackPop() { return m_current->m_stack.Pop(); }
- inline void StackFlip() { m_current->m_stack.Flip(); }
- inline void StackClear() { m_current->m_stack.Clear(); }
+ inline void StackPush(int value) { assert(m_current); m_current->m_stack.Push(value); }
+ inline int StackPop() { assert(m_current); return m_current->m_stack.Pop(); }
+ inline void StackFlip() { assert(m_current); m_current->m_stack.Flip(); }
+ inline void StackClear() { assert(m_current); m_current->m_stack.Clear(); }
inline void SwitchStack() { }
// -------- Head Manipulation (including IP) --------
void AdjustHeads();
// -------- Label Manipulation -------
- const cCodeLabel& GetLabel() const { return m_current->m_nextLabel; }
- cCodeLabel& GetLabel() { return m_current->m_nextLabel; }
+ const cCodeLabel& GetLabel() const { assert(m_current); return m_current->m_nextLabel; }
+ cCodeLabel& GetLabel() { assert(m_current); return m_current->m_nextLabel; }
void ReadLabel(int max_size=nHardware::MAX_LABEL_SIZE);
cHeadCPU FindLabel(int direction);
int FindLabel_Forward(const cCodeLabel & search_label, const cGenome& search_genome, int pos);
int FindLabel_Backward(const cCodeLabel & search_label, const cGenome& search_genome, int pos);
cHeadCPU FindLabel(const cCodeLabel & in_label, int direction);
- const cCodeLabel& GetReadLabel() const { return m_current->m_readLabel; }
- cCodeLabel& GetReadLabel() { return m_current->m_readLabel; }
+ const cCodeLabel& GetReadLabel() const { assert(m_current); return m_current->m_readLabel; }
+ cCodeLabel& GetReadLabel() { assert(m_current); return m_current->m_readLabel; }
// ---------- Instruction Helpers -----------
int FindModifiedRegister(int default_register);
@@ -211,33 +305,36 @@
// -------- Stack Manipulation... --------
- inline int GetStack(int depth=0, int stack_id=-1, int in_thread=-1) const { return m_current->m_stack.Get(depth); }
+ inline int GetStack(int depth=0, int stack_id=-1, int in_thread=-1) const { assert(m_current); return m_current->m_stack.Get(depth); }
inline int GetNumStacks() const { return 2; }
// -------- Head Manipulation (including IP) --------
- const cHeadCPU& GetHead(int head_id) const { return m_current->m_heads[head_id]; }
- cHeadCPU& GetHead(int head_id) { return m_current->m_heads[head_id];}
- const cHeadCPU& GetHead(int head_id, int thread) const { return m_current->m_heads[head_id]; }
- cHeadCPU& GetHead(int head_id, int thread) { return m_current->m_heads[head_id];}
+ const cHeadProgramid& GetHead(int head_id) const { assert(m_current); return m_current->m_heads[head_id]; }
+ cHeadProgramid& GetHead(int head_id) { assert(m_current); return m_current->m_heads[head_id];}
+ const cHeadProgramid& GetHead(int head_id, int thread) const { assert(m_current); return m_current->m_heads[head_id]; }
+ cHeadProgramid& GetHead(int head_id, int thread) { assert(m_current); return m_current->m_heads[head_id];}
int GetNumHeads() const { return NUM_HEADS; }
- const cHeadCPU& IP() const { return m_current->m_heads[nHardware::HEAD_IP]; }
- cHeadCPU& IP() { return m_current->m_heads[nHardware::HEAD_IP]; }
- const cHeadCPU& IP(int thread) const { return m_current->m_heads[nHardware::HEAD_IP]; }
- cHeadCPU& IP(int thread) { return m_current->m_heads[nHardware::HEAD_IP]; }
+ const cHeadCPU& IP() const { assert(m_current); return m_current->m_heads[nHardware::HEAD_IP]; }
+ cHeadCPU& IP() { assert(m_current); return m_current->m_heads[nHardware::HEAD_IP]; }
+ const cHeadCPU& IP(int thread) const { assert(m_current); return m_current->m_heads[nHardware::HEAD_IP]; }
+ cHeadCPU& IP(int thread) { assert(m_current); return m_current->m_heads[nHardware::HEAD_IP]; }
// -------- Memory Manipulation --------
- const cCPUMemory& GetMemory() const { return m_current->m_memory; }
- cCPUMemory& GetMemory() { return m_current->m_memory; }
- const cCPUMemory& GetMemory(int value) const { return m_current->m_memory; }
- cCPUMemory& GetMemory(int value) { return m_current->m_memory; }
- int GetNumMemSpaces() const { return 1; }
+ //<! Each programid counts as a memory space.
+ // Heads from one programid can end up on another,
+ // so be careful to fix these when changing the programid list.
+ const cCPUMemory& GetMemory() const { assert(m_current); return m_current->m_memory; }
+ cCPUMemory& GetMemory() { assert(m_current); return m_current->m_memory; }
+ const cCPUMemory& GetMemory(int value) const { return m_programids[value]->m_memory; }
+ cCPUMemory& GetMemory(int value) { return m_programids[value]->m_memory; }
+ int GetNumMemSpaces() const { return m_programids.size(); }
// -------- Register Manipulation --------
- const int GetRegister(int reg_id) const { return m_current->m_regs[reg_id]; }
- int& GetRegister(int reg_id) { return m_current->m_regs[reg_id]; }
+ const int GetRegister(int reg_id) const { assert(m_current); return m_current->m_regs[reg_id]; }
+ int& GetRegister(int reg_id) { assert(m_current); return m_current->m_regs[reg_id]; }
int GetNumRegisters() const { return NUM_REGISTERS; }
// -------- Thread Manipuluation --------
@@ -440,8 +537,22 @@
bool Inst_Skip(cAvidaContext& ctx);
// -= Gene expression instructions =-
- bool Inst_Match(cAvidaContext& ctx); //!< Attempt to match the currently executing cProgramid against other cProgramids.
- bool Inst_OnDisassociate(cAvidaContext& ctx); //!< Called automatically when a cProgramid disassociates.
+ bool Inst_NewProgramid(cAvidaContext& ctx, bool executable, bool bindable, bool readable); //!< Allocate a new programid and place the write head there.
+ bool Inst_NewExecutableProgramid(cAvidaContext& ctx) { return Inst_NewProgramid(ctx, true, false, false); } //!< Allocate a "protein". Cannot be bound or read.
+ bool Inst_NewGenomeProgramid(cAvidaContext& ctx) { return Inst_NewProgramid(ctx, false, true, true); } //!< Allocate a "genomic" fragment. Cannot execute.
+
+ bool Inst_Site(cAvidaContext& ctx); //!< A binding site (execution simply advances past label)
+ bool Inst_Bind(cAvidaContext& ctx); //!< Attempt to match the currently executing cProgramid against other cProgramids.
+ bool Inst_Bind2(cAvidaContext& ctx); //!< Attempt to locate two programids with the same site.
+ bool Inst_IfBind(cAvidaContext& ctx); //!< Attempt to match the currently executing cProgramid against other cProgramids. Execute next inst if successful.
+ bool Inst_IfBind2(cAvidaContext& ctx); //!< Attempt to match and bind two programids.
+ bool Inst_NumSites(cAvidaContext& ctx); //!< Count the number of corresponding binding sites
+ bool Inst_ProgramidCopy(cAvidaContext& ctx); //!< Like h-copy, but fails if read/write heads not on other programids and will not write over
+ bool Inst_ProgramidDivide(cAvidaContext& ctx); //!< Like h-divide,
+
+ //!< Add/Remove a new programid to/from the list and give it the proper index within the list so we keep track of memory spaces...
+ void AddProgramid(programid_ptr programid);
+ void RemoveProgramid(unsigned int remove_index);
};
Modified: branches/collect/source/main/cAvidaConfig.h
===================================================================
--- branches/collect/source/main/cAvidaConfig.h 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/main/cAvidaConfig.h 2007-05-22 16:50:55 UTC (rev 1589)
@@ -352,6 +352,10 @@
CONFIG_ADD_VAR(ANALYZE_OPTION_1, cString, "", "String variable accessible from analysis scripts");
CONFIG_ADD_VAR(ANALYZE_OPTION_2, cString, "", "String variable accessible from analysis scripts");
+ CONFIG_ADD_GROUP(SECOND_PASS_GROUP, "Tracking metrics known after the running experiment previously");
+ CONFIG_ADD_VAR(TRACK_CCLADES, int, 0, "Enable tracking of coalescence clades");
+ CONFIG_ADD_VAR(TRACK_CCLADES_IDS, cString, "coalescence.ids", "File storing coalescence IDs");
+
#endif
void Load(const cString& filename, const bool& crash_if_not_found);
Modified: branches/collect/source/main/cEnvironment.cc
===================================================================
--- branches/collect/source/main/cEnvironment.cc 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/main/cEnvironment.cc 2007-05-22 16:50:55 UTC (rev 1589)
@@ -827,12 +827,13 @@
}
const double task_quality = m_tasklib.TestOutput(taskctx);
+
// If this task wasn't performed, move on to the next one.
if (task_quality == 0.0) continue;
// Mark this task as performed...
- result.MarkTask(task_id, task_quality);
+ result.MarkTask(task_id, task_quality, taskctx.GetTaskValue());
// And let's process it!
DoProcesses(ctx, cur_reaction->GetProcesses(), resource_count, rbins_count, task_quality, task_cnt, i, result);
Modified: branches/collect/source/main/cMutationRates.h
===================================================================
--- branches/collect/source/main/cMutationRates.h 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/main/cMutationRates.h 2007-05-22 16:50:55 UTC (rev 1589)
@@ -92,6 +92,8 @@
bool TestPointMut(cAvidaContext& ctx) const { return ctx.GetRandom().P(exec.point_mut_prob); }
bool TestCopyMut(cAvidaContext& ctx) const { return ctx.GetRandom().P(copy.mut_prob); }
+ bool TestCopyIns(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.ins_prob); }
+ bool TestCopyDel(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.del_prob); }
bool TestDivideMut(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.divide_mut_prob); }
bool TestDivideIns(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.divide_ins_prob); }
bool TestDivideDel(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.divide_del_prob); }
Modified: branches/collect/source/main/cOrganism.h
===================================================================
--- branches/collect/source/main/cOrganism.h 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/main/cOrganism.h 2007-05-22 16:50:55 UTC (rev 1589)
@@ -95,9 +95,11 @@
int m_id; // unique id for each org, is just the number it was born
int m_lineage_label; // a lineages tag; inherited unchanged in offspring
cLineage* m_lineage; // A lineage descriptor... (different from label)
- tArray<double> m_rbins; // Holds amount of resources internal to org
+ int cclade_id; // @MRR Coalescence clade information (set in cPopulation)
+ tArray<double> m_rbins; // Holds amount of resources internal to org
+
+ // Other stats
- // Other stats
cCPUMemory m_child_genome; // Child genome, while under construction.
sCPUStats m_cpu_stats; // Info for statistics
@@ -161,13 +163,16 @@
void SetLineage(cLineage* in_lineage) { m_lineage = in_lineage; }
cLineage* GetLineage() const { return m_lineage; }
- const tArray<double>& GetRBins() const { return m_rbins; }
+ void SetCCladeLabel( int in_label ) { cclade_id = in_label; }; //@MRR
+ int GetCCladeLabel() const { return cclade_id; }
+
+ const tArray<double>& GetRBins() const { return m_rbins; }
tArray<double>& GetRBins() { return m_rbins; }
double GetRBin(int index) { return m_rbins[index]; }
void SetRBins(const tArray<double>& rbins_in);
void SetRBin(const int index, const double value);
void AddToRBin(const int index, const double value);
-
+
int GetMaxExecuted() const { return m_max_executed; }
cCPUMemory& ChildGenome() { return m_child_genome; }
@@ -243,6 +248,8 @@
// -------- Mutation Rate Convenience Methods --------
bool TestCopyMut(cAvidaContext& ctx) const { return m_mut_rates.TestCopyMut(ctx); }
+ bool TestCopyIns(cAvidaContext& ctx) const { return m_mut_rates.TestCopyIns(ctx); }
+ bool TestCopyDel(cAvidaContext& ctx) const { return m_mut_rates.TestCopyDel(ctx); }
bool TestDivideMut(cAvidaContext& ctx) const { return m_mut_rates.TestDivideMut(ctx); }
bool TestDivideIns(cAvidaContext& ctx) const { return m_mut_rates.TestDivideIns(ctx); }
bool TestDivideDel(cAvidaContext& ctx) const { return m_mut_rates.TestDivideDel(ctx); }
Modified: branches/collect/source/main/cPhenotype.cc
===================================================================
--- branches/collect/source/main/cPhenotype.cc 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/main/cPhenotype.cc 2007-05-22 16:50:55 UTC (rev 1589)
@@ -45,6 +45,7 @@
, cur_internal_task_count(m_world->GetEnvironment().GetNumTasks())
, eff_task_count(m_world->GetEnvironment().GetNumTasks())
, cur_task_quality(m_world->GetEnvironment().GetNumTasks())
+ , cur_task_value(m_world->GetEnvironment().GetNumTasks())
, cur_internal_task_quality(m_world->GetEnvironment().GetNumTasks())
, cur_rbins_total(m_world->GetNumResources())
, cur_rbins_avail(m_world->GetNumResources())
@@ -57,6 +58,7 @@
, last_internal_task_count(m_world->GetEnvironment().GetNumTasks())
, last_reaction_add_reward(m_world->GetEnvironment().GetReactionLib().GetSize())
, last_task_quality(m_world->GetEnvironment().GetNumTasks())
+ , last_task_value(m_world->GetEnvironment().GetNumTasks())
, last_internal_task_quality(m_world->GetEnvironment().GetNumTasks())
, last_rbins_total(m_world->GetNumResources())
, last_rbins_avail(m_world->GetNumResources())
@@ -141,6 +143,7 @@
cur_internal_task_count.SetAll(0);
eff_task_count.SetAll(0);
cur_task_quality.SetAll(0);
+ cur_task_value.SetAll(0);
cur_internal_task_quality.SetAll(0);
cur_rbins_total.SetAll(0);
cur_rbins_avail.SetAll(0);
@@ -160,6 +163,7 @@
last_task_count = parent_phenotype.last_task_count;
last_internal_task_count = parent_phenotype.last_internal_task_count;
last_task_quality = parent_phenotype.last_task_quality;
+ last_task_value = parent_phenotype.last_task_value;
last_internal_task_quality= parent_phenotype.last_internal_task_quality;
last_rbins_total = parent_phenotype.last_rbins_total;
last_rbins_avail = parent_phenotype.last_rbins_avail;
@@ -239,6 +243,7 @@
cur_internal_task_count.SetAll(0);
eff_task_count.SetAll(0);
cur_task_quality.SetAll(0);
+ cur_task_value.SetAll(0);
cur_internal_task_quality.SetAll(0);
cur_rbins_total.SetAll(0);
cur_rbins_avail.SetAll(0);
@@ -257,6 +262,7 @@
last_task_count.SetAll(0);
last_internal_task_count.SetAll(0);
last_task_quality.SetAll(0);
+ last_task_value.SetAll(0);
last_internal_task_quality.SetAll(0);
last_rbins_total.SetAll(0);
last_rbins_avail.SetAll(0);
@@ -341,6 +347,7 @@
last_task_count = cur_task_count;
last_internal_task_count = cur_internal_task_count;
last_task_quality = cur_task_quality;
+ last_task_value = cur_task_value;
last_internal_task_quality= cur_internal_task_quality;
last_rbins_total = cur_rbins_total;
last_rbins_avail = cur_rbins_avail;
@@ -357,6 +364,7 @@
cur_internal_task_count.SetAll(0);
eff_task_count.SetAll(0);
cur_task_quality.SetAll(0);
+ cur_task_value.SetAll(0);
cur_internal_task_quality.SetAll(0);
cur_rbins_total.SetAll(0);
cur_rbins_avail.SetAll(0);
@@ -449,9 +457,10 @@
last_task_count = cur_task_count;
last_internal_task_count = cur_internal_task_count;
last_task_quality = cur_task_quality;
+ last_task_value = cur_task_value;
last_internal_task_quality= cur_internal_task_quality;
- last_rbins_total = cur_rbins_total;
- last_rbins_avail = cur_rbins_avail;
+ last_rbins_total = cur_rbins_total;
+ last_rbins_avail = cur_rbins_avail;
last_reaction_count = cur_reaction_count;
last_reaction_add_reward = cur_reaction_add_reward;
last_inst_count = cur_inst_count;
@@ -465,6 +474,7 @@
cur_internal_task_count.SetAll(0);
eff_task_count.SetAll(0);
cur_task_quality.SetAll(0);
+ cur_task_value.SetAll(0);
cur_internal_task_quality.SetAll(0);
cur_rbins_total.SetAll(0);
cur_rbins_avail.SetAll(0);
@@ -657,6 +667,7 @@
cur_task_quality[i]+= result.TaskQuality(i);
if(result.UsedEnvResource() == false) { cur_internal_task_quality[i] += result.TaskQuality(i); }
}
+ cur_task_value[i] = result.TaskValue(i);
}
for (int i = 0; i < num_reactions; i++) {
if (result.ReactionTriggered(i) == true) cur_reaction_count[i]++;
Modified: branches/collect/source/main/cPhenotype.h
===================================================================
--- branches/collect/source/main/cPhenotype.h 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/main/cPhenotype.h 2007-05-22 16:50:55 UTC (rev 1589)
@@ -108,6 +108,7 @@
tArray<int> cur_internal_task_count; // Total times each task was performed using internal resources
tArray<int> eff_task_count; // Total times each task was performed (resetable during the life of the organism)
tArray<double> cur_task_quality; // Average (total?) quality with which each task was performed
+ tArray<double> cur_task_value; // Value with which this phenotype performs task
tArray<double> cur_internal_task_quality; // Average (total?) quaility with which each task using internal resources was performed
tArray<double> cur_rbins_total; // Total amount of resources collected
tArray<double> cur_rbins_avail; // Total amount of internal resources available
@@ -134,6 +135,7 @@
tArray<int> last_task_count;
tArray<int> last_internal_task_count;
tArray<double> last_task_quality;
+ tArray<double> last_task_value;
tArray<double> last_internal_task_quality;
tArray<double> last_rbins_total;
tArray<double> last_rbins_avail;
@@ -255,6 +257,7 @@
const tArray<int>& GetCurInternalTaskCount() const { assert(initialized == true); return cur_internal_task_count; }
void ClearEffTaskCount() { assert(initialized == true); eff_task_count.SetAll(0); }
const tArray<double> & GetCurTaskQuality() const { assert(initialized == true); return cur_task_quality; }
+ const tArray<double> & GetCurTaskValue() const { assert(initialized == true); return cur_task_value; }
const tArray<double> & GetCurInternalTaskQuality() const { assert(initialized == true); return cur_internal_task_quality; }
const tArray<double>& GetCurRBinsTotal() const { assert(initialized == true); return cur_rbins_total; }
const tArray<double>& GetCurRBinsAvail() const { assert(initialized == true); return cur_rbins_avail; }
@@ -274,6 +277,7 @@
const tArray<int>& GetLastTaskCount() const { assert(initialized == true); return last_task_count; }
const tArray<int>& GetLastInternalTaskCount() const { assert(initialized == true); return last_internal_task_count; }
const tArray<double>& GetLastTaskQuality() const { assert(initialized == true); return last_task_quality; }
+ const tArray<double>& GetLastTaskValue() const { assert(intialized == true); return last_task_value; }
const tArray<double>& GetLastInternalTaskQuality() const { assert(initialized == true); return last_internal_task_quality; }
const tArray<double>& GetLastRBinsTotal() const { assert(initialized == true); return last_rbins_total; }
const tArray<double>& GetLastRBinsAvail() const { assert(initialized == true); return last_rbins_avail; }
Modified: branches/collect/source/main/cPopulation.cc
===================================================================
--- branches/collect/source/main/cPopulation.cc 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/main/cPopulation.cc 2007-05-22 16:50:55 UTC (rev 1589)
@@ -280,7 +280,9 @@
// Do lineage tracking for the new organisms.
LineageSetupOrganism(child_array[i], parent_organism.GetLineage(),
parent_organism.GetLineageLabel(), parent_genotype);
-
+
+ //By default, store the parent cclade, this may get modified in ActivateOrgansim (@MRR)
+ child_array[i]->SetCCladeLabel(parent_organism.GetCCladeLabel());
}
@@ -393,6 +395,8 @@
environment.SetupInputs(ctx, target_cell.input_array);
// Update the archive...
+
+
in_genotype->AddOrganism();
if (old_genotype != NULL) {
@@ -418,7 +422,10 @@
// Statistics...
m_world->GetStats().RecordBirth(target_cell.GetID(), in_genotype->GetID(),
in_organism->GetPhenotype().ParentTrue());
-
+
+ // @MRR Do coalescence clade set up for new organisms.
+ CCladeSetupOrganism(in_organism );
+
//count how many times MERIT_BONUS_INST (rewarded instruction) is in the genome
//only relevant if merit is proportional to # times MERIT_BONUS_INST is in the genome
int rewarded_instruction = m_world->GetConfig().MERIT_BONUS_INST.Get();
@@ -1294,6 +1301,31 @@
/**
+This function will set up coalescence clade information. If this feature is activated in the configuration,
+ a list of coalescence genotype ids must be read in initially. These are furnished by doing an initial run
+ with the same seed and setup and retrieving information from the final dominant lineage and coalescence points.
+
+ The value is either (by default) inherited from the parent or the organism's genotypeID if it is known
+ to be a coalescence id.
+
+ Defaulting is established in Inject or ActivateOffspring methods of this class.
+
+ @MRR May 2007
+ **/
+void cPopulation::CCladeSetupOrganism(cOrganism* organism)
+{
+ int gen_id = organism->GetGenotype()->GetID();
+ if (m_world->GetConfig().TRACK_CCLADES.Get() > 0)
+ {
+ if (m_world->GetClassificationManager().IsCCladeFounder(gen_id))
+ {
+ organism->SetCCladeLabel(gen_id);
+ }
+ }
+}
+
+
+/**
* This function directs which position function should be used. It
* could have also been done with a function pointer, but the dividing
* of an organism takes enough time that this will be a negligible addition,
@@ -2265,6 +2297,9 @@
cAvidaContext& ctx = m_world->GetDefaultContext();
cOrganism* new_organism = new cOrganism(m_world, ctx, new_genotype->GetGenome());
+
+ //Coalescense Clade Setup
+ new_organism->SetCCladeLabel(-1);
// Set the genotype...
new_organism->SetGenotype(new_genotype);
Modified: branches/collect/source/main/cPopulation.h
===================================================================
--- branches/collect/source/main/cPopulation.h 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/main/cPopulation.h 2007-05-22 16:50:55 UTC (rev 1589)
@@ -131,7 +131,8 @@
void InjectClone(int cell_id, cOrganism& orig_org);
void LineageSetupOrganism(cOrganism* organism, cLineage* lineage, int lin_label, cGenotype* parent_genotype = NULL);
-
+ void CCladeSetupOrganism(cOrganism* organism);
+
// Must be called to activate *any* organism in the population.
void ActivateOrganism(cAvidaContext& ctx, cOrganism* in_organism, cPopulationCell& target_cell);
Modified: branches/collect/source/main/cReactionResult.cc
===================================================================
--- branches/collect/source/main/cReactionResult.cc 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/main/cReactionResult.cc 2007-05-22 16:50:55 UTC (rev 1589)
@@ -34,6 +34,7 @@
, resources_detected(num_resources)
, tasks_done(num_tasks)
, tasks_quality(num_tasks)
+ , tasks_value(num_tasks)
, reactions_triggered(num_reactions)
, reaction_add_bonus(num_reactions)
, bonus_add(0.0)
@@ -56,6 +57,7 @@
resources_detected.SetAll(-1.0);
tasks_done.SetAll(false);
tasks_quality.SetAll(0.0);
+ tasks_value.SetAll(0.0);
reactions_triggered.SetAll(false);
reaction_add_bonus.SetAll(0.0);
@@ -91,11 +93,12 @@
lethal = flag;
}
-void cReactionResult::MarkTask(int id, const double quality)
+void cReactionResult::MarkTask(int id, const double quality, const double value)
{
ActivateReaction();
tasks_done[id] = true;
tasks_quality[id] = quality;
+ tasks_value[id] = value;
}
@@ -168,3 +171,9 @@
return tasks_quality[id];
}
+double cReactionResult::TaskValue(int id)
+{
+ if (GetActive() == false) return 0;
+ return tasks_value[id];
+}
+
Modified: branches/collect/source/main/cReactionResult.h
===================================================================
--- branches/collect/source/main/cReactionResult.h 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/main/cReactionResult.h 2007-05-22 16:50:55 UTC (rev 1589)
@@ -37,6 +37,7 @@
tArray<double> resources_detected; //Initialize to -1.0
tArray<bool> tasks_done;
tArray<double> tasks_quality;
+ tArray<double> tasks_value;
tArray<bool> reactions_triggered;
tArray<double> reaction_add_bonus;
double bonus_add;
@@ -62,7 +63,7 @@
void Produce(int id, double num);
void Detect(int id, double num);
void Lethal(bool flag);
- void MarkTask(int id, const double quality=1);
+ void MarkTask(int id, const double quality=1, const double value=0);
void MarkReaction(int id);
void AddBonus(double value, int id);
@@ -77,6 +78,7 @@
bool ReactionTriggered(int id);
bool TaskDone(int id);
double TaskQuality(int id);
+ double TaskValue(int id);
double GetAddBonus() { return bonus_add; }
double GetReactionAddBonus(const int i) { return reaction_add_bonus[i]; }
double GetMultBonus() { return bonus_mult; }
Modified: branches/collect/source/main/cTaskContext.h
===================================================================
--- branches/collect/source/main/cTaskContext.h 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/main/cTaskContext.h 2007-05-22 16:50:55 UTC (rev 1589)
@@ -55,7 +55,11 @@
tBuffer<int>* m_received_messages;
int m_logic_id;
bool m_on_divide;
-
+
+ // for optimize tasks actual value of function org is outputting, for all others nothing
+ // implemented for now...
+ double m_task_value;
+
cTaskEntry* m_task_entry;
tHashTable<void*, cTaskState*>* m_task_states;
@@ -77,6 +81,7 @@
, m_task_entry(NULL)
, m_task_states(NULL)
{
+ m_task_value = 0;
}
inline int GetInputAt(int index) { return m_interface->GetInputAt(index); }
@@ -90,6 +95,8 @@
inline int GetLogicId() const { return m_logic_id; }
inline void SetLogicId(int v) { m_logic_id = v; }
inline bool GetOnDivide() const { return m_on_divide; }
+ inline void SetTaskValue(double v) { m_task_value = v; }
+ inline double GetTaskValue() { return m_task_value; }
inline void SetTaskEntry(cTaskEntry* in_entry) { m_task_entry = in_entry; }
inline cTaskEntry* GetTaskEntry() { return m_task_entry; }
Modified: branches/collect/source/main/cTaskLib.cc
===================================================================
--- branches/collect/source/main/cTaskLib.cc 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/main/cTaskLib.cc 2007-05-22 16:50:55 UTC (rev 1589)
@@ -35,6 +35,7 @@
#include <cstdlib>
#include <cmath>
#include <climits>
+#include <iomanip>
// Various workarounds for Visual Studio shortcomings
#if AVIDA_PLATFORM(WINDOWS)
@@ -347,7 +348,7 @@
// Optimization Tasks
if (name == "optimize")
- Load_Optimize(name, info, envreqs, errors);
+ Load_Optimize(name, info, envreqs, errors);
if (name == "mult")
Load_Mult(name, info, envreqs, errors);
@@ -371,13 +372,13 @@
if (name == "comm_echo")
NewTask(name, "Echo of Neighbor's Input", &cTaskLib::Task_CommEcho, REQ_NEIGHBOR_INPUT);
else if (name == "comm_not")
- NewTask(name, "Not of Neighbor's Input", &cTaskLib::Task_CommNot, REQ_NEIGHBOR_INPUT);
+ NewTask(name, "Not of Neighbor's Input", &cTaskLib::Task_CommNot, REQ_NEIGHBOR_INPUT);
// Network Tasks
if (name == "net_send")
- NewTask(name, "Successfully Sent Network Message", &cTaskLib::Task_NetSend);
+ NewTask(name, "Successfully Sent Network Message", &cTaskLib::Task_NetSend);
else if (name == "net_receive")
- NewTask(name, "Successfully Received Network Message", &cTaskLib::Task_NetReceive);
+ NewTask(name, "Successfully Received Network Message", &cTaskLib::Task_NetReceive);
@@ -1844,62 +1845,62 @@
double cTaskLib::Task_MatchStr(cTaskContext& ctx) const
{
- tBuffer<int> temp_buf(ctx.GetOutputBuffer());
- // if (temp_buf[0] != 357913941) return 0;
+ tBuffer<int> temp_buf(ctx.GetOutputBuffer());
+ // if (temp_buf[0] != 357913941) return 0;
- // temp_buf.Pop(); // pop the signal value off of the buffer
+ // temp_buf.Pop(); // pop the signal value off of the buffer
- const cString& string_to_match = ctx.GetTaskEntry()->GetArguments().GetString(0);
- int string_index;
- int num_matched = 0;
- int test_output;
+ const cString& string_to_match = ctx.GetTaskEntry()->GetArguments().GetString(0);
+ int string_index;
+ int num_matched = 0;
+ int test_output;
int max_num_matched = 0;
- if (temp_buf.GetNumStored() > 0) {
- test_output = temp_buf[0];
-
- for (int j = 0; j < string_to_match.GetSize(); j++) {
- string_index = string_to_match.GetSize() - j - 1; // start with last char in string
- int k = 1 << j;
- if ((string_to_match[string_index] == '0' && !(test_output & k)) ||
+ if (temp_buf.GetNumStored() > 0) {
+ test_output = temp_buf[0];
+
+ for (int j = 0; j < string_to_match.GetSize(); j++) {
+ string_index = string_to_match.GetSize() - j - 1; // start with last char in string
+ int k = 1 << j;
+ if ((string_to_match[string_index] == '0' && !(test_output & k)) ||
(string_to_match[string_index] == '1' && (test_output & k))) num_matched++;
- }
- max_num_matched = num_matched;
- }
+ }
+ max_num_matched = num_matched;
+ }
- bool used_received = false;
- if (ctx.GetReceivedMessages()) {
- tBuffer<int> received(*(ctx.GetReceivedMessages()));
- for (int i = 0; i < received.GetNumStored(); i++) {
- test_output = received[i];
- num_matched = 0;
-
+ bool used_received = false;
+ if (ctx.GetReceivedMessages()) {
+ tBuffer<int> received(*(ctx.GetReceivedMessages()));
+ for (int i = 0; i < received.GetNumStored(); i++) {
+ test_output = received[i];
+ num_matched = 0;
+
for (int j = 0; j < string_to_match.GetSize(); j++) {
- string_index = string_to_match.GetSize() - j - 1; // start with last char in string
- int k = 1 << j;
- if ((string_to_match[string_index]=='0' && !(test_output & k)) ||
+ string_index = string_to_match.GetSize() - j - 1; // start with last char in string
+ int k = 1 << j;
+ if ((string_to_match[string_index]=='0' && !(test_output & k)) ||
(string_to_match[string_index]=='1' && (test_output & k))) num_matched++;
- }
-
+ }
+
if (num_matched > max_num_matched) {
- max_num_matched = num_matched;
- used_received = true;
- }
- }
- }
+ max_num_matched = num_matched;
+ used_received = true;
+ }
+ }
+ }
- double bonus = 0.0;
- // return value between 0 & 1 representing the percentage of string that was matched
- double base_bonus = static_cast<double>(max_num_matched) * 2.0 / static_cast<double>(string_to_match.GetSize()) - 1;
-
- if (base_bonus > 0.0) {
- bonus = pow(base_bonus, 2);
- if (used_received)
+ double bonus = 0.0;
+ // return value between 0 & 1 representing the percentage of string that was matched
+ double base_bonus = static_cast<double>(max_num_matched) * 2.0 / static_cast<double>(string_to_match.GetSize()) - 1;
+
+ if (base_bonus > 0.0) {
+ bonus = pow(base_bonus, 2);
+ if (used_received)
m_world->GetStats().AddMarketItemUsed();
- else
- m_world->GetStats().AddMarketOwnItemUsed();
- }
- return bonus;
+ else
+ m_world->GetStats().AddMarketOwnItemUsed();
+ }
+ return bonus;
}
@@ -2116,115 +2117,132 @@
void cTaskLib::Load_Optimize(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors)
{
- cArgSchema schema;
+ cArgSchema schema;
- // Integer Arguments
- schema.AddEntry("function", 0, cArgSchema::SCHEMA_INT);
- schema.AddEntry("binary", 1, 0);
- schema.AddEntry("varlength", 2, 8);
- // Double Arguments
- schema.AddEntry("basepow", 0, 2.0);
- schema.AddEntry("max_Fx", 1, 1.0);
- schema.AddEntry("min_Fx", 2, 0.0);
+ // Integer Arguments
+ schema.AddEntry("function", 0, cArgSchema::SCHEMA_INT);
+ schema.AddEntry("binary", 1, 0);
+ schema.AddEntry("varlength", 2, 8);
+ // Double Arguments
+ schema.AddEntry("basepow", 0, 2.0);
+ schema.AddEntry("maxFx", 1, 1.0);
+ schema.AddEntry("minFx", 2, 0.0);
- cArgContainer* args = cArgContainer::Load(argstr, schema, errors);
- if (args)
- {
- if (args->GetInt(1))
- {
- envreqs.SetMinOutputs(args->GetInt(2)*2);
- }
- else
- {
- // once have ability to change args should in each of these cases change the max/min
- // to the appropriate defaults for this function
- switch (args->GetInt(0))
- {
- case 1:
- envreqs.SetMinOutputs(1);
- case 2:
- envreqs.SetMinOutputs(2);
- case 3:
- envreqs.SetMinOutputs(2);
- };
- }
+ cArgContainer* args = cArgContainer::Load(argstr, schema, errors);
+ if (args)
+ {
+ if (args->GetInt(1))
+ {
+ envreqs.SetMinOutputs(args->GetInt(2)*2);
+ }
+ else
+ {
+ // once have ability to change args should in each of these cases change the max/min
+ // to the appropriate defaults for this function
+ switch (args->GetInt(0))
+ {
+ case 1:
+ envreqs.SetMinOutputs(1);
+ case 2:
+ envreqs.SetMinOutputs(2);
+ case 3:
+ envreqs.SetMinOutputs(2);
+ };
+ }
- NewTask(name, "Optimize", &cTaskLib::Task_Optimize, 0, args);
- }
+ NewTask(name, "Optimize", &cTaskLib::Task_Optimize, 0, args);
+ }
}
double cTaskLib::Task_Optimize(cTaskContext& ctx) const
{
- // if the org hasn't output yet enough numbers, just return without completing any tasks
- if (ctx.GetOutputBuffer().GetNumStored() < ctx.GetOutputBuffer().GetCapacity())
- return 0;
+ // if the org hasn't output yet enough numbers, just return without completing any tasks
+ if (ctx.GetOutputBuffer().GetNumStored() < ctx.GetOutputBuffer().GetCapacity()) return 0;
- double quality = 0.0;
+ double quality = 0.0;
- // which function are we currently checking?
- const int function = ctx.GetTaskEntry()->GetArguments().GetInt(0);
+ // which function are we currently checking?
+ const int function = ctx.GetTaskEntry()->GetArguments().GetInt(0);
- // always get x&y, at least for now, turn it into a double between 0 and 1
- double y, x;
+ // always get x&y, at least for now, turn it into a double between 0 and 1
+ double y, x, Fx;
- const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
- if (args.GetInt(1))
- {
- int len = args.GetInt(2);
- double base_pow = args.GetDouble(0);
- double tempX = 0, tempY=0, tot=0;
- for (int i=len-1; i>=0; i--)
- {
- tempX += ctx.GetOutputBuffer()[i+len]*pow(base_pow,(len-1)-i);
- tempY += ctx.GetOutputBuffer()[i]*pow(base_pow,(len-1)-i);
- tot += pow(base_pow,i);
- }
- x = (double)tempX/tot;
- y = (double)tempY/tot;
- }
- else
- {
- x = (double)ctx.GetOutputBuffer()[0] / 0xffffffff;
- y = (double)ctx.GetOutputBuffer()[1] / 0xffffffff;
- }
+ const cArgContainer& args = ctx.GetTaskEntry()->GetArguments();
+ if (args.GetInt(1)) {
+ int len = args.GetInt(2);
+ double base_pow = args.GetDouble(0);
+ double tempX = 0, tempY = 0, tot = 0;
+ for (int i = len - 1; i >= 0; i--) {
+ tempX += ctx.GetOutputBuffer()[i + len] * pow(base_pow, (len - 1) - i);
+ tempY += ctx.GetOutputBuffer()[i] * pow(base_pow, (len - 1) - i);
+ tot += pow(base_pow, double(i));
+ }
+ x = tempX / tot;
+ y = tempY / tot;
+ } else {
+ x = abs(double(ctx.GetOutputBuffer()[0]) / 0xffffffff);
+ y = abs(double(ctx.GetOutputBuffer()[1]) / 0xffffffff);
+ }
- switch(function)
- {
- case 1:
- quality = 1 - x;
- break;
+ switch(function) {
+ case 1:
+ Fx = x; // F1
+ break;
- case 2:
- quality = 1 - ((1+y)*(1-sqrt(x/(1+y))))/2.0; // F2
- break;
+ case 2:
+ Fx = (1.0 + y) * (1.0 - sqrt(x / (1.0 + y))); // F2
+ break;
- case 3:
- quality = 1 - ((1+y)*(1-pow(x/(1+y),2)))/2.0; // F3
- break;
+ case 3:
+ Fx = (1.0 + y) * (1.0 - pow(x / (1.0 + y), 2.0)); // F3
+ break;
- case 4:
- quality = 1 - (( (1+y)*(1 - sqrt(x/(1+y)) - (x/(1+y))*sin(3.14159*x*10) ) +.76) / 2.76);
- break;
+ case 4:
+ Fx = (1.0 + y) * (1.0 - sqrt(x / (1.0 + y)) - (x / (1.0 + y)) * sin(3.14159 * x * 10.0));
+ break;
- default:
- quality = .001;
- }
+ case 5:
+ x = x * -2.0;
+ Fx = x*x + y*y;
+ break;
- // because want org to only have 1 shot to use outputs for all functions at once, even if they
- // output numbers that give a quality of 0 on a function, still want to mark it as completed
- // so give it a very low quality instead of 0 (if using limited resources they still will get
- // no reward because set the minimum consumed to max*.001, meaning even if they get the max
- // possible fraction they'll be below minimum allowed consumed and will consume nothing
+ case 6:
+ x = x * -2.0;
+ Fx = (x + 2.0)*(x + 2.0) + y*y;
+ break;
- if (quality > 1)
- cout << "\n\nquality > 1, wtf?!\n\n";
- if (quality < .001)
- return .001;
- else
- return quality;
+ case 7:
+ x = x * 4.0;
+ Fx = sqrt(x) + y;
+ break;
- return 0;
+ case 8:
+ x = x * 4.0;
+ Fx = sqrt(4.0 - x) + y;
+ break;
+
+ default:
+ quality = .001;
+ }
+ ctx.SetTaskValue(Fx);
+ quality = (args.GetDouble(1) - Fx + .001) / (args.GetDouble(1) - args.GetDouble(2) + .001);
+
+ // because want org to only have 1 shot to use outputs for all functions at once, even if they
+ // output numbers that give a quality of 0 on a function, still want to mark it as completed
+ // so give it a very low quality instead of 0 (if using limited resources they still will get
+ // no reward because set the minimum consumed to max*.001, meaning even if they get the max
+ // possible fraction they'll be below minimum allowed consumed and will consume nothing
+
+ if (quality > 1)
+ cout << "\n\nquality > 1!\n\n";
+
+ if (quality < .001)
+ return .001;
+ else
+ return quality;
+
+ return 0;
}
void cTaskLib::Load_Mult(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors)
Modified: branches/collect/source/main/cWorld.cc
===================================================================
--- branches/collect/source/main/cWorld.cc 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/main/cWorld.cc 2007-05-22 16:50:55 UTC (rev 1589)
@@ -102,8 +102,11 @@
for (int i = 0; i < inst_set.GetSize(); i++)
m_stats->SetInstName(i, inst_set.GetName(i));
+ // @MRR CClade Tracking
+ if (m_conf->TRACK_CCLADES.Get() > 0)
+ m_class_mgr->LoadCCladeFounders(m_conf->TRACK_CCLADES_IDS.Get());
- m_pop = new cPopulation(this);
+ m_pop = new cPopulation(this);
// Setup Event List
m_event_list = new cEventList(this);
@@ -112,6 +115,7 @@
ExitAvida(-1);
}
+
const bool revert_fatal = m_conf->REVERT_FATAL.Get() > 0.0;
const bool revert_neg = m_conf->REVERT_DETRIMENTAL.Get() > 0.0;
Modified: branches/collect/source/targets/avida/primitive.cc
===================================================================
--- branches/collect/source/targets/avida/primitive.cc 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/targets/avida/primitive.cc 2007-05-22 16:50:55 UTC (rev 1589)
@@ -30,10 +30,14 @@
#include "cDriverManager.h"
#include "cWorld.h"
+#include "FloatingPoint.h"
+
using namespace std;
int main(int argc, char * argv[])
{
+ SetupFloatingPointEnvironment();
+
// Catch Interrupt making sure to close appropriately
signal(SIGINT, ExitAvida);
Modified: branches/collect/source/targets/avida-viewer/viewer.cc
===================================================================
--- branches/collect/source/targets/avida-viewer/viewer.cc 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/source/targets/avida-viewer/viewer.cc 2007-05-22 16:50:55 UTC (rev 1589)
@@ -30,10 +30,16 @@
#include "cTextViewerDriver.h"
#include "cWorld.h"
+#include "FloatingPoint.h"
+
using namespace std;
+
int main(int argc, char * argv[])
{
+ SetupFloatingPointEnvironment();
+
+
// Catch Interrupt making sure to close appropriately
signal(SIGINT, ExitAvida);
Copied: branches/collect/source/targets/unit-tests (from rev 1587, development/source/targets/unit-tests)
Modified: branches/collect/support/config/avida.cfg
===================================================================
--- branches/collect/support/config/avida.cfg 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/support/config/avida.cfg 2007-05-22 16:50:55 UTC (rev 1589)
@@ -255,3 +255,8 @@
MT_CONCURRENCY 1 # Number of concurrent analyze threads
ANALYZE_OPTION_1 # String variable accessible from analysis scripts
ANALYZE_OPTION_2 # String variable accessible from analysis scripts
+
+### SECOND_PASS_GROUP ###
+# Tracking metrics known after the running experiment previously
+TRACK_CCLADES 0 # Enable tracking of coalescence clades
+TRACK_CCLADES_IDS coalescence.ids # File storing coalescence IDs
Modified: branches/collect/support/config/default-gx.org
===================================================================
--- branches/collect/support/config/default-gx.org 2007-05-22 16:41:10 UTC (rev 1588)
+++ branches/collect/support/config/default-gx.org 2007-05-22 16:50:55 UTC (rev 1589)
@@ -1,20 +1,88 @@
-nop-A # Origin of replication.
-nop-B # Beginning of RNAP.
-match # Attempt to match against a nop-B.
- nop-B
-h-copy # Copy from read-head to write-head (requires a match).
-on-da # When the complement of nop-B is reached...
- sever # Sever the link between RNAP and it's transcription target.
-nop-C # End of RNAP.
-nop-C # ...
-nop-B # Beginning of DNAP.
-match # Attempt to match against a nop-A/nop-B.
+PROGRAMID
+READABLE
+BINDABLE
+site # Origin of replication
+nop-A
+nop-B
+site # Label and empty space
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+site # Start RNAP
+nop-B
+if-bind # Move read head to site with matching label
+ nop-B
+ p-alloc # If there was a match, then allocate another *executable* programid
+p-copy # Copy the next instruction
+site
+nop-C # End of RNAP
+site # Label and empty space
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+site # Start DNAP
+nop-B
+if-bind # Move read head to matching site
nop-A
nop-B
-h-copy # Copy from read-head to write-head (requires a match).
-on-da # When the complement of nop-A/nop-B is reached...
- h-divide # Divide!
-nop-C # End of DNAP.
-nop-C # ...
-nop-B # Replication terminator.
+ g-alloc # If there was a match, then allocate another *genome* programid
+p-copy # Copy the next instruction
+site
+nop-C # End of DNAP
+site # Site and empty space
nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+site
+nop-B # Cell-cycle programid. This programid is responsible for
+if-bind2 # locating two genomes and then triggering the divide process.
+ nop-B
+ nop-C
+ p-divide
+site
+nop-C # End of cell-cycle programid..
+site # Site and empty space.
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+nop-C
+site
+nop-B
+nop-C
+PROGRAMID # This is the initial RNAP molecule
+EXECUTABLE
+site
+nop-B
+if-bind # Move read head to site with matching label
+ nop-B
+ p-alloc # If there was a match, then allocate another *executable* programid
+p-copy # Copy the next instruction
+site
+nop-C
Copied: branches/collect/tests/_avida_GA_lim_res (from rev 1587, development/tests/_avida_GA_lim_res)
Copied: branches/collect/tests/_task_optimize_lim_res (from rev 1587, development/tests/_task_optimize_lim_res)
Copied: branches/collect/tests/string_match_embed3 (from rev 1587, development/tests/string_match_embed3)
More information about the Avida-cvs
mailing list