[Avida-cvs] [avida-svn] r966 - in development: Avida.xcodeproj source/main source/tools

brysonda at myxo.css.msu.edu brysonda at myxo.css.msu.edu
Sat Sep 16 19:47:45 PDT 2006


Author: brysonda
Date: 2006-09-16 22:47:45 -0400 (Sat, 16 Sep 2006)
New Revision: 966

Added:
   development/source/tools/cArgContainer.cc
   development/source/tools/cArgContainer.h
   development/source/tools/cArgSchema.cc
   development/source/tools/cArgSchema.h
Modified:
   development/Avida.xcodeproj/project.pbxproj
   development/source/main/cTaskEntry.h
   development/source/main/cTaskLib.cc
   development/source/main/cTaskLib.h
   development/source/tools/CMakeLists.txt
   development/source/tools/SConscript
   development/source/tools/tDictionary.h
Log:
Add cArgContainer and accompanying cArgSchema.  cArgContainer serves as a fast access container for arguments that have been parsed from an input file.  The parsing routine loads in named arguments with various types, the details of which are encoded in a cArgSchema object.   Schema entries specify the name of the argument, the target index, and a type specifier or default value.  When a default value is specified, the argument is regarded as optional, otherwise the entry is treated as a require value.

cArgContainer objects can only be constructed through the class static cArgContainer::Load method, which ensures that the supplied argument string is compliant with the supplied schema prior to returning.   Optionally, a tList<cString*> can be passed in to the Load method.  When a list is supplied, strings describing any errors that occur in attempting to load the arguments will be appended to it (this will simplify displaying errors in the future, where multiple worlds may be running and/or within a GUI).


Adjusted cTaskEntry (and references within cTaskLib) to hold a cArgContainer in place of the former info string.  New tasks can now use cArgContainers to parse the info string into fast access arguments (to speed up evaluation at each IO).

Changed matchstr task to use cArgContainer, as it was using the info string.   

Modified: development/Avida.xcodeproj/project.pbxproj
===================================================================
--- development/Avida.xcodeproj/project.pbxproj	2006-09-14 20:07:01 UTC (rev 965)
+++ development/Avida.xcodeproj/project.pbxproj	2006-09-17 02:47:45 UTC (rev 966)
@@ -37,6 +37,10 @@
 		7039884E09F00D030052ACE7 /* avida.cfg in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2D509EE8501001AEA89 /* avida.cfg */; };
 		7039884F09F00D060052ACE7 /* environment.cfg in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2D709EE8501001AEA89 /* environment.cfg */; };
 		7039885009F00D080052ACE7 /* events.cfg in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2D809EE8501001AEA89 /* events.cfg */; };
+		703D4D6E0ABA374A0032C8A0 /* cArgSchema.cc in Sources */ = {isa = PBXBuildFile; fileRef = 703D4D6D0ABA374A0032C8A0 /* cArgSchema.cc */; };
+		703D4D6F0ABA374A0032C8A0 /* cArgSchema.cc in Sources */ = {isa = PBXBuildFile; fileRef = 703D4D6D0ABA374A0032C8A0 /* cArgSchema.cc */; };
+		703D4D700ABA374A0032C8A0 /* cArgSchema.cc in Sources */ = {isa = PBXBuildFile; fileRef = 703D4D6D0ABA374A0032C8A0 /* cArgSchema.cc */; };
+		703D4E2E0ABCAC4A0032C8A0 /* cArgContainer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70BCB21C0AB7ADA6003FF331 /* cArgContainer.cc */; };
 		7040D3A6090964D100AA820F /* cMxCodeArray.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70B0865808F4974300FC65FE /* cMxCodeArray.cc */; };
 		70422A28091B141000A5E67F /* cAnalyze.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70422A1C091B141000A5E67F /* cAnalyze.cc */; };
 		70422A30091B141000A5E67F /* cAnalyzeGenotype.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70422A24091B141000A5E67F /* cAnalyzeGenotype.cc */; };
@@ -198,6 +202,8 @@
 		70B08B9308FB2E6B00FC65FE /* cWeightedIndex.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70B08B9108FB2E6B00FC65FE /* cWeightedIndex.cc */; };
 		70B08B9408FB2E6B00FC65FE /* cTools.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70B08B9008FB2E6B00FC65FE /* cTools.cc */; };
 		70B08B9508FB2E6B00FC65FE /* cWeightedIndex.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70B08B9108FB2E6B00FC65FE /* cWeightedIndex.cc */; };
+		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 */; };
 		70C054F80A4F704D002703C1 /* PopulationActions.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70C054C90A4F6E19002703C1 /* PopulationActions.cc */; };
 		70C054F90A4F704E002703C1 /* SaveLoadActions.cc in Sources */ = {isa = PBXBuildFile; fileRef = 708051A80A1F65FE00CBB8B6 /* SaveLoadActions.cc */; };
@@ -477,6 +483,7 @@
 		703CA3760A5073CD00AB4DB4 /* SConscript */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SConscript; sourceTree = "<group>"; };
 		703CA3770A50740300AB4DB4 /* SConscript */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SConscript; sourceTree = "<group>"; };
 		703CA3780A50749F00AB4DB4 /* SConstruct */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SConstruct; sourceTree = "<group>"; };
+		703D4D6D0ABA374A0032C8A0 /* cArgSchema.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cArgSchema.cc; sourceTree = "<group>"; };
 		70422A1C091B141000A5E67F /* cAnalyze.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cAnalyze.cc; sourceTree = "<group>"; };
 		70422A1D091B141000A5E67F /* cAnalyze.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cAnalyze.h; sourceTree = "<group>"; };
 		70422A1E091B141000A5E67F /* cAnalyzeCommand.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cAnalyzeCommand.h; sourceTree = "<group>"; };
@@ -757,6 +764,9 @@
 		70B08B9008FB2E6B00FC65FE /* cTools.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cTools.cc; sourceTree = "<group>"; };
 		70B08B9108FB2E6B00FC65FE /* cWeightedIndex.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = cWeightedIndex.cc; sourceTree = "<group>"; };
 		70B3984E0947B29D0018F09D /* tManagedPointerArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tManagedPointerArray.h; sourceTree = "<group>"; };
+		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>"; };
 		70C054C80A4F6E19002703C1 /* PopulationActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PopulationActions.h; sourceTree = "<group>"; };
 		70C054C90A4F6E19002703C1 /* PopulationActions.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PopulationActions.cc; sourceTree = "<group>"; };
 		70C054F10A4F6FF1002703C1 /* SConscript */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SConscript; sourceTree = "<group>"; };
@@ -1653,6 +1663,10 @@
 				7054A11E09A7BEFC00038658 /* cThread.h */,
 				7054A11F09A7BEFC00038658 /* cThread.cc */,
 				7093DB4009D6F50300DE7FEB /* tSmartArray.h */,
+				70BCB21B0AB7ADA6003FF331 /* cArgContainer.h */,
+				70BCB21C0AB7ADA6003FF331 /* cArgContainer.cc */,
+				70BCB2470AB7B634003FF331 /* cArgSchema.h */,
+				703D4D6D0ABA374A0032C8A0 /* cArgSchema.cc */,
 			);
 			path = tools;
 			sourceTree = "<group>";
@@ -1979,6 +1993,8 @@
 				704ADBC80A6EEFC300666970 /* DriverActions.cc in Sources */,
 				705ABB3E0A8A6B4400A6A80E /* EnvironmentActions.cc in Sources */,
 				708BF3000AB65DC700A923BF /* cEventList.cc in Sources */,
+				70BCB2350AB7B26B003FF331 /* cArgContainer.cc in Sources */,
+				703D4D700ABA374A0032C8A0 /* cArgSchema.cc in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2108,6 +2124,8 @@
 				704ADBC60A6EEFC300666970 /* DriverActions.cc in Sources */,
 				705ABB3D0A8A6B4100A6A80E /* EnvironmentActions.cc in Sources */,
 				708BF2FF0AB65DC700A923BF /* cEventList.cc in Sources */,
+				703D4D6F0ABA374A0032C8A0 /* cArgSchema.cc in Sources */,
+				703D4E2E0ABCAC4A0032C8A0 /* cArgContainer.cc in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2218,6 +2236,8 @@
 				704ADBF90A6EF3A300666970 /* DriverActions.cc in Sources */,
 				705ABB3C0A8A6B3D00A6A80E /* EnvironmentActions.cc in Sources */,
 				708BF2FE0AB65DC700A923BF /* cEventList.cc in Sources */,
+				70BCB22E0AB7B23D003FF331 /* cArgContainer.cc in Sources */,
+				703D4D6E0ABA374A0032C8A0 /* cArgSchema.cc in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2351,14 +2371,6 @@
 				INSTALL_PATH = /usr/local/lib;
 				PREBINDING = NO;
 				PRODUCT_NAME = tcmalloc;
-				WARNING_CFLAGS = (
-					"-Wextra",
-					"-Wno-four-char-constants",
-					"-Wno-unknown-pragmas",
-					"-Wconversion",
-					"-Winline",
-					"-Wno-sign-compare",
-				);
 				ZERO_LINK = YES;
 			};
 			name = Development;

Modified: development/source/main/cTaskEntry.h
===================================================================
--- development/source/main/cTaskEntry.h	2006-09-14 20:07:01 UTC (rev 965)
+++ development/source/main/cTaskEntry.h	2006-09-17 02:47:45 UTC (rev 966)
@@ -11,6 +11,9 @@
 #ifndef cTaskEntry_h
 #define cTaskEntry_h
 
+#ifndef cArgContainer_h
+#include "cArgContainer.h"
+#endif
 #ifndef cString_h
 #include "cString.h"
 #endif
@@ -30,20 +33,22 @@
   cString m_desc;  // For more human-understandable output...
   int m_id;
   tTaskTest m_test_fun;
-  cString m_info;  // extra info (like the string or whatever to match)
+  cArgContainer* m_args;
 
 public:
-  cTaskEntry(const cString& name, const cString& desc, int in_id, tTaskTest test_fun, const cString& info)
-    : m_name(name), m_desc(desc), m_id(in_id), m_test_fun(test_fun), m_info(info)
+  cTaskEntry(const cString& name, const cString& desc, int in_id, tTaskTest fun, cArgContainer* args)
+    : m_name(name), m_desc(desc), m_id(in_id), m_test_fun(fun), m_args(args)
   {
   }
-  ~cTaskEntry() { ; }
+  ~cTaskEntry() { delete m_args; }
 
   const cString& GetName() const { return m_name; }
   const cString& GetDesc() const { return m_desc; }
   const int GetID() const { return m_id; }
   const tTaskTest GetTestFun() const { return m_test_fun; }
-  const cString& GetInfo() const { return m_info; }
+  
+  bool HasArguments() const { return (m_args != NULL); }
+  const cArgContainer& GetArguments() const { return *m_args; }
 };
 
 

Modified: development/source/main/cTaskLib.cc
===================================================================
--- development/source/main/cTaskLib.cc	2006-09-14 20:07:01 UTC (rev 965)
+++ development/source/main/cTaskLib.cc	2006-09-17 02:47:45 UTC (rev 966)
@@ -10,6 +10,9 @@
 
 #include "cTaskLib.h"
 
+#include "cArgSchema.h"
+
+#include <stdlib.h>
 extern "C" {
 #include <math.h>
 #include <limits.h>
@@ -37,7 +40,7 @@
   // Determine if this task is already in the active library.
   for (int i = 0; i < task_array.GetSize(); i++) {
     assert(task_array[i] != NULL);
-    if (task_array[i]->GetName() == name && task_array[i]->GetInfo() == info) return task_array[i];
+    if (task_array[i]->GetName() == name && !task_array[i]->HasArguments()) return task_array[i];
   }
   
   // Match up this name to its corresponding task
@@ -50,7 +53,7 @@
   else if (name == "add")  NewTask(name, "Add",  &cTaskLib::Task_Add);
   else if (name == "sub")  NewTask(name, "Sub",  &cTaskLib::Task_Sub);
   
-  // All one and two input logic functions
+  // All 1- and 2-Input Logic Functions
   if (name == "not") NewTask(name, "Not", &cTaskLib::Task_Not);
   else if (name == "nand") NewTask(name, "Nand", &cTaskLib::Task_Nand);
   else if (name == "and") NewTask(name, "And", &cTaskLib::Task_And);
@@ -61,7 +64,7 @@
   else if (name == "xor") NewTask(name, "Xor", &cTaskLib::Task_Xor);
   else if (name == "equ") NewTask(name, "Equals", &cTaskLib::Task_Equ);
   
-  // All three input logic functions
+  // All 3-Input Logic Functions
   if (name == "logic_3AA")
     NewTask(name, "Logic 3AA (A+B+C == 0)", &cTaskLib::Task_Logic3in_AA);
   else if (name == "logic_3AB")
@@ -199,7 +202,7 @@
   else if (name == "logic_3CP")
     NewTask(name, "Logic 3CP", &cTaskLib::Task_Logic3in_CP);
   
-  // Arbitrary one input math tasks
+  // Arbitrary 1-Input Math Tasks
   else if (name == "math_1AA")
     NewTask(name, "Math 1AA (2X)", &cTaskLib::Task_Math1in_AA);
   else if (name == "math_1AB")
@@ -233,7 +236,7 @@
   else if (name == "math_1AP")
     NewTask(name, "Math 1AP (X-7)", &cTaskLib::Task_Math1in_AP);
   
-  // Arbitrary two input math tasks
+  // Arbitrary 2-Input Math Tasks
   if (name == "math_2AA")
     NewTask(name, "Math 2AA (sqrt(X+Y))", &cTaskLib::Task_Math2in_AA);  
   else if (name == "math_2AB")
@@ -279,7 +282,7 @@
   else if (name == "math_2AV")
     NewTask(name, "Math 2AV (XY^2)", &cTaskLib::Task_Math2in_AV);
   
-  // Arbitrary three input logic tasks
+  // Arbitrary 3-Input Math Tasks
   if (name == "math_3AA")
     NewTask(name, "Math 3AA (X^2+Y^2+Z^2)", &cTaskLib::Task_Math3in_AA);  
   else if (name == "math_3AB")
@@ -307,16 +310,32 @@
   else if (name == "math_3AM")
     NewTask(name, "Math 3AM ((X+Y)^2+(Y+Z)^2)", &cTaskLib::Task_Math3in_AM);  
   
-  // match string task
-  if (name == "matchstr")  NewTask(name, "MatchStr", &cTaskLib::Task_MatchStr, 0, info);
+  // Matching Tasks
+  if (name == "matchstr") {
+    cArgSchema schema(',',':');
+    schema.AddEntry("string", 0, cArgSchema::SCHEMA_STRING);
+    cArgContainer* args = cArgContainer::Load(info, schema);
+    if (args) NewTask(name, "MatchStr", &cTaskLib::Task_MatchStr, 0, args);
+  } else if (name == "match_number") {
+    cArgSchema schema(',',':');
+    
+    // Integer Arguments
+    schema.AddEntry("target", 0, cArgSchema::SCHEMA_INT);
+    schema.AddEntry("threshold", 1, -1);
+    // Double Arguments
+    schema.AddEntry("halflife", 0, cArgSchema::SCHEMA_DOUBLE);
+    
+    cArgContainer* args = cArgContainer::Load(info, schema);
+    if (args) NewTask(name, "Match Number", &cTaskLib::Task_MatchNumber, 0, args);
+  }
 
-	// communication tasks
+	// Communication Tasks
   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);
 
-  // Network tasks
+  // Network Tasks
   if (name == "net_send")
 	  NewTask(name, "Successfully Sent Network Message", &cTaskLib::Task_NetSend);
   else if (name == "net_receive")
@@ -334,7 +353,21 @@
   return task_array[start_size];
 }
 
+void cTaskLib::NewTask(const cString& name, const cString& desc, tTaskTest task_fun, int reqs,
+                       cArgContainer* args)
+{
+  if (reqs & REQ_NEIGHBOR_INPUT == true) use_neighbor_input = true;
+  if (reqs & REQ_NEIGHBOR_OUTPUT == true) use_neighbor_output = true;
+  
+  const int id = task_array.GetSize();
+  task_array.Resize(id + 1);
+  task_array[id] = new cTaskEntry(name, desc, id, task_fun, args);
+}
 
+
+
+
+
 void cTaskLib::SetupTests(cTaskContext& ctx) const
 {
   // Collect the inputs in a useful form.
@@ -414,22 +447,7 @@
 }
 
 
-////////////////////////
-//  cTaskLib (private)
-////////////////////////
 
-void cTaskLib::NewTask(const cString & name, const cString & desc,
-					   tTaskTest task_fun, int reqs, const cString & info)
-{
-  if (reqs & REQ_NEIGHBOR_INPUT == true) use_neighbor_input = true;
-  if (reqs & REQ_NEIGHBOR_OUTPUT == true) use_neighbor_output = true;
-  
-  const int id = task_array.GetSize();
-  task_array.Resize(id+1);
-  task_array[id] = new cTaskEntry(name, desc, id, task_fun, info);
-}
-
-
 double cTaskLib::Task_Echo(cTaskContext* ctx) const
 {
   const int test_output = ctx->output_buffer[0];
@@ -1726,63 +1744,76 @@
 
 	temp_buf.Pop(); // pop the signal value off of the buffer
 
-	const cString& string_to_match = ctx->task_entry->GetInfo();
+	const cString& string_to_match = ctx->task_entry->GetArguments().GetString(0);
 	int string_index;
 	int num_matched = 0;
-	int test_output, max_num_matched = 0;
+	int test_output;
+  int max_num_matched = 0;
 
-	if (temp_buf.GetNumStored() > 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
+		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++;
+			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;
 	}
 
 	bool used_received = false;
-	if (ctx->received_messages)
-	{
+	if (ctx->received_messages) {
 		tBuffer<int> received(*(ctx->received_messages));
-		for (int i=0; i<received.GetNumStored(); i++)
-		{
+		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
+			
+      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++;
+				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)
-			{
+			
+      if (num_matched > max_num_matched) {
 				max_num_matched = num_matched;
 				used_received = true;
 			}
 		}
 	}
 
-	double bonus = 0;
+	double bonus = 0.0;
 	// return value between 0 & 1 representing the percentage of string that was matched
-	double base_bonus = double(max_num_matched)*2/(double)string_to_match.GetSize() - 1;
+	double base_bonus = static_cast<double>(max_num_matched) * 2.0 / static_cast<double>(string_to_match.GetSize()) - 1;
 	
-	if (base_bonus > 0)
-	{
-		bonus = pow(base_bonus,2);
+	if (base_bonus > 0.0) {
+		bonus = pow(base_bonus, 2);
 		if (used_received)
-			m_world->GetStats().AddMarketItemUsed();
+      m_world->GetStats().AddMarketItemUsed();
 		else
 			m_world->GetStats().AddMarketOwnItemUsed();
-	}	
+	}
 	return bonus;
 }
 
+double cTaskLib::Task_MatchNumber(cTaskContext* ctx) const
+{
+  double quality = 0.0;
+  const cArgContainer& args = ctx->task_entry->GetArguments();
+
+  int diff = abs(args.GetInt(0) - ctx->output_buffer[0]);
+  int threshold = args.GetInt(1);
+    
+  if (threshold < 0 || diff <= abs(threshold)) { // Negative threshold == infinite
+    // If within threshold range, quality decays based on absolute difference
+    double halflife = -1.0 * fabs(args.GetDouble(0));
+    quality = pow(2.0, static_cast<double>(diff) / halflife);
+  }
+
+  return quality;
+}
+
 double cTaskLib::Task_CommEcho(cTaskContext* ctx) const
 {
 	const int test_output = ctx->output_buffer[0];

Modified: development/source/main/cTaskLib.h
===================================================================
--- development/source/main/cTaskLib.h	2006-09-14 20:07:01 UTC (rev 965)
+++ development/source/main/cTaskLib.h	2006-09-17 02:47:45 UTC (rev 966)
@@ -71,7 +71,8 @@
   bool UseNeighborOutput() const { return use_neighbor_output; }
   
 private:  // Direct task related methods
-  void NewTask(const cString& name, const cString& desc, tTaskTest task_fun, int reqs = 0, const cString& info = "");
+  void NewTask(const cString& name, const cString& desc, tTaskTest task_fun, int reqs = 0,
+               cArgContainer* args = NULL);
 
   inline double FractionalReward(unsigned int supplied, unsigned int correct);  
 
@@ -79,7 +80,7 @@
   double Task_Add(cTaskContext* ctx) const;
   double Task_Sub(cTaskContext* ctx) const;
 
-  // 1- and 2-Input Logic Tasks
+  // All 1- and 2-Input Logic Functions
   double Task_Not(cTaskContext* ctx) const;
   double Task_Nand(cTaskContext* ctx) const;
   double Task_And(cTaskContext* ctx) const;
@@ -90,7 +91,7 @@
   double Task_Xor(cTaskContext* ctx) const;
   double Task_Equ(cTaskContext* ctx) const;
 
-  // 3-Input Logic Tasks
+  // All 3-Input Logic Functions
   double Task_Logic3in_AA(cTaskContext* ctx) const;
   double Task_Logic3in_AB(cTaskContext* ctx) const;
   double Task_Logic3in_AC(cTaskContext* ctx) const;
@@ -160,7 +161,7 @@
   double Task_Logic3in_CO(cTaskContext* ctx) const;
   double Task_Logic3in_CP(cTaskContext* ctx) const;
 
-  // 1-Input math tasks...
+  // Arbitrary 1-Input Math Tasks
   double Task_Math1in_AA(cTaskContext* ctx) const;
   double Task_Math1in_AB(cTaskContext* ctx) const;
   double Task_Math1in_AC(cTaskContext* ctx) const;
@@ -178,7 +179,7 @@
   double Task_Math1in_AO(cTaskContext* ctx) const;
   double Task_Math1in_AP(cTaskContext* ctx) const;
 
-  // 2-Input math tasks...
+  // Arbitrary 2-Input Math Tasks
   double Task_Math2in_AA(cTaskContext* ctx) const;
   double Task_Math2in_AB(cTaskContext* ctx) const;
   double Task_Math2in_AC(cTaskContext* ctx) const;
@@ -202,6 +203,7 @@
   double Task_Math2in_AU(cTaskContext* ctx) const;
   double Task_Math2in_AV(cTaskContext* ctx) const;
 
+  // Arbitrary 3-Input Math Tasks
   double Task_Math3in_AA(cTaskContext* ctx) const;
   double Task_Math3in_AB(cTaskContext* ctx) const;
   double Task_Math3in_AC(cTaskContext* ctx) const;
@@ -216,12 +218,15 @@
   double Task_Math3in_AL(cTaskContext* ctx) const;
   double Task_Math3in_AM(cTaskContext* ctx) const;
   
-  // match string tasks
+  // Matching Tasks
   double Task_MatchStr(cTaskContext* ctx) const;
-  // Communication Tasks...
+  double Task_MatchNumber(cTaskContext* ctx) const;
+
+  // Communication Tasks
   double Task_CommEcho(cTaskContext* ctx) const;
   double Task_CommNot(cTaskContext* ctx) const;
   
+  // Network Tasks
   double Task_NetSend(cTaskContext* ctx) const;
   double Task_NetReceive(cTaskContext* ctx) const;
 };

Modified: development/source/tools/CMakeLists.txt
===================================================================
--- development/source/tools/CMakeLists.txt	2006-09-14 20:07:01 UTC (rev 965)
+++ development/source/tools/CMakeLists.txt	2006-09-17 02:47:45 UTC (rev 966)
@@ -1,4 +1,6 @@
 SET(libtools_a_SOURCES
+  cArgContainer.cc
+  cArgSchema.cc
   cChangeList.cc
   cConstSchedule.cc
   cDataEntry.cc

Modified: development/source/tools/SConscript
===================================================================
--- development/source/tools/SConscript	2006-09-14 20:07:01 UTC (rev 965)
+++ development/source/tools/SConscript	2006-09-17 02:47:45 UTC (rev 966)
@@ -12,6 +12,8 @@
   'tVerifierSuite.hh',
   'tVerifierSuiteRecurser.hh',
   'win32_mkdir_hack.hh',
+  'cArgContainer.h',
+  'cArgSchema.h',
   'cBlockStruct.h',
   'cChangeList.h',
   'cConstSchedule.h',
@@ -82,6 +84,8 @@
 
 srcs = [
   #'cBlockStruct.cc',
+  'cArgContainer.cc',
+  'cArgSchema.cc',
   'cChangeList.cc',
   'cConstSchedule.cc',
   'cDataEntry.cc',

Added: development/source/tools/cArgContainer.cc
===================================================================
--- development/source/tools/cArgContainer.cc	2006-09-14 20:07:01 UTC (rev 965)
+++ development/source/tools/cArgContainer.cc	2006-09-17 02:47:45 UTC (rev 966)
@@ -0,0 +1,130 @@
+/*
+ *  cArgContainer.cc
+ *  Avida
+ *
+ *  Created by David Bryson on 9/12/06.
+ *  Copyright 2006 Michigan State University. All rights reserved.
+ *
+ */
+
+#include "cArgContainer.h"
+
+#include "cArgSchema.h"
+#include "tList.h"
+
+
+cArgContainer* cArgContainer::Load(cString args, const cArgSchema& schema, tList<cString>* errors)
+{
+  tArray<bool> set_ints;
+  tArray<bool> set_doubles;
+  tArray<bool> set_strings;
+  
+  cArgContainer* ret = new cArgContainer();
+
+  set_ints.Resize(schema.GetNumIntArgs(), false);
+  ret->m_ints.Resize(schema.GetNumIntArgs());
+  set_doubles.Resize(schema.GetNumDoubleArgs(), false);
+  ret->m_doubles.Resize(schema.GetNumDoubleArgs());
+  set_strings.Resize(schema.GetNumStringArgs(), false);
+  ret->m_strings.Resize(schema.GetNumStringArgs());
+
+  cString arg_ent;
+  cString arg_name;
+  bool success = true;
+
+  arg_ent = args.Pop(schema.GetEntrySeparator());
+  while (arg_ent.GetSize() > 0) {
+    arg_name = arg_ent.Pop(schema.GetValueSeparator());
+    schema.AdjustArgName(arg_name);
+    
+    cArgSchema::tType type;
+    int index;
+    if (schema.FindEntry(arg_name, type, index)) {
+      switch (type) {
+        case cArgSchema::SCHEMA_INT:
+          set_ints[index] = true;
+          ret->m_ints[index] = arg_ent.AsInt();
+          break;
+        case cArgSchema::SCHEMA_DOUBLE:
+          set_doubles[index] = true;
+          ret->m_doubles[index] = arg_ent.AsDouble();
+          break;
+        case cArgSchema::SCHEMA_STRING:
+          set_strings[index] = true;
+          arg_ent.Trim();
+          ret->m_strings[index] = arg_ent;
+          break;
+        default:
+          success = false;
+          if (errors) errors->PushRear(new cString("Invalid schema argument type!"));
+      }
+    } else {
+      success = false;
+      if (errors) {
+        cString* err_str = new cString();
+        err_str->Set("Unrecognized argument: '%s'", static_cast<const char*>(arg_name));
+        errors->PushRear(err_str);
+      }
+    }
+    arg_ent = args.Pop(schema.GetEntrySeparator());
+  }
+  
+  for (int i = 0; i < set_ints.GetSize(); i++) {
+    if (set_ints[i]) continue;
+    if (schema.IsOptionalInt(i)) schema.SetDefaultInt(i, ret->m_ints[i]);
+    else {
+      success = false; // doc err here
+      if (errors) {
+        cString* err_str = new cString();
+        cString name;
+        if (schema.GetIntName(i, name)) {
+          err_str->Set("Required argument '%s' was not found.", static_cast<const char*>(name));
+        } else {
+          err_str->Set("Invalid int schema entry at index %d.", i);
+        }
+        errors->PushRear(err_str);
+      }      
+    }
+  }
+  for (int i = 0; i < set_doubles.GetSize(); i++) {
+    if (set_doubles[i]) continue;
+    if (schema.IsOptionalDouble(i)) schema.SetDefaultDouble(i, ret->m_doubles[i]);
+    else {
+      success = false; // doc err here
+      if (errors) {
+        cString* err_str = new cString();
+        cString name;
+        if (schema.GetDoubleName(i, name)) {
+          err_str->Set("Required argument '%s' was not found.", static_cast<const char*>(name));
+        } else {
+          err_str->Set("Invalid double schema entry at index %d.", i);
+        }
+        errors->PushRear(err_str);
+      }      
+    }
+  }
+  for (int i = 0; i < set_strings.GetSize(); i++) {
+    if (set_strings[i]) continue;
+    if (schema.IsOptionalString(i)) schema.SetDefaultString(i, ret->m_strings[i]);
+    else {
+      success = false; // doc err here
+      if (errors) {
+        cString* err_str = new cString();
+        cString name;
+        if (schema.GetStringName(i, name)) {
+          err_str->Set("Required argument '%s' was not found.", static_cast<const char*>(name));
+        } else {
+          err_str->Set("Invalid string schema entry at index %d.", i);
+        }
+        errors->PushRear(err_str);
+      }      
+    }
+  }
+  
+  if (!success) {
+    delete ret;
+    ret = NULL;
+  }
+  
+  return ret;
+}

Added: development/source/tools/cArgContainer.h
===================================================================
--- development/source/tools/cArgContainer.h	2006-09-14 20:07:01 UTC (rev 965)
+++ development/source/tools/cArgContainer.h	2006-09-17 02:47:45 UTC (rev 966)
@@ -0,0 +1,69 @@
+/*
+ *  cArgContainer.h
+ *  Avida
+ *
+ *  Created by David Bryson on 9/12/06.
+ *  Copyright 2006 Michigan State University. All rights reserved.
+ *
+ */
+
+#ifndef cArgContainer_h
+#define cArgContainer_h
+
+#ifndef cString_h
+#include "cString.h"
+#endif
+#ifndef tArray_h
+#include "tArray.h"
+#endif
+
+class cArgSchema;
+template <class T> class tList;
+
+// A generic argument container that will load in named arguments from a string
+// into a specific index in an array for the type specified in the argument schema.
+class cArgContainer
+{
+private:
+  tArray<int> m_ints;
+  tArray<double> m_doubles;
+  tArray<cString> m_strings;
+  
+
+  inline void SetInt(int i, int v);
+  inline void SetDouble(int i, double v);
+  inline void SetString(int i, const cString& v);
+
+  
+  cArgContainer() { ; }
+  cArgContainer(const cArgContainer&); // @not_implemented
+  cArgContainer& operator=(const cArgContainer&); // @not_implemented
+  
+public:
+  static cArgContainer* Load(cString args, const cArgSchema& schema, tList<cString>* errors = NULL);
+  
+  inline int GetInt(int i) const { return m_ints[i]; }
+  inline double GetDouble(int i) const { return m_doubles[i]; }
+  inline const cString& GetString(int i) const { return m_strings[i]; }
+};
+
+
+inline void cArgContainer::SetInt(int i, int v)
+{
+  if (m_ints.GetSize() <= i) m_ints.Resize(i + 1);
+  m_ints[i] = v;
+}
+
+inline void cArgContainer::SetDouble(int i, double v)
+{
+  if (m_doubles.GetSize() <= i) m_doubles.Resize(i + 1);
+  m_doubles[i] = v;
+}
+
+inline void cArgContainer::SetString(int i, const cString& v)
+{
+  if (m_strings.GetSize() <= i) m_strings.Resize(i + 1);
+  m_strings[i] = v;
+}
+
+#endif

Added: development/source/tools/cArgSchema.cc
===================================================================
--- development/source/tools/cArgSchema.cc	2006-09-14 20:07:01 UTC (rev 965)
+++ development/source/tools/cArgSchema.cc	2006-09-17 02:47:45 UTC (rev 966)
@@ -0,0 +1,104 @@
+/*
+ *  cArgSchema.cc
+ *  Avida
+ *
+ *  Created by David Bryson on 9/14/06.
+ *  Copyright 2006 Michigan State University. All rights reserved.
+ *
+ */
+
+#include "cArgSchema.h"
+
+
+cArgSchema::~cArgSchema()
+{
+  for (int i = 0; i < m_ints.GetSize(); i++) delete m_ints[i];
+  for (int i = 0; i < m_doubles.GetSize(); i++) delete m_doubles[i];
+  for (int i = 0; i < m_strings.GetSize(); i++) delete m_strings[i];
+}
+
+bool cArgSchema::AddEntry(cString in_name, int in_idx, tType in_type)
+{
+  AdjustArgName(in_name);
+  if (m_entries.HasEntry(in_name)) return false;
+  
+  sArgSchemaEntry* entry = new sArgSchemaEntry(in_name, in_idx, in_type);
+  
+  switch (in_type) {
+    case SCHEMA_INT:
+      if (m_ints.GetSize() <= in_idx) m_ints.Resize(in_idx + 1, NULL);
+      m_ints[in_idx] = entry;
+      break;
+    case SCHEMA_DOUBLE:
+      if (m_doubles.GetSize() <= in_idx) m_doubles.Resize(in_idx + 1, NULL);
+      m_doubles[in_idx] = entry;
+      break;
+    case SCHEMA_STRING:
+      if (m_strings.GetSize() <= in_idx) m_strings.Resize(in_idx + 1, NULL);
+      m_strings[in_idx] = entry;
+      break;
+    default:
+      delete entry;
+      return false;
+  }
+  
+  m_entries.Add(in_name, entry);
+  
+  return true;
+}
+
+bool cArgSchema::AddEntry(cString in_name, int in_idx, int def)
+{
+  AdjustArgName(in_name);
+  if (m_entries.HasEntry(in_name)) return false;
+  
+  sArgSchemaEntry* entry = new sArgSchemaEntry(in_name, in_idx, def); 
+  m_entries.Add(in_name, entry);
+
+  if (m_ints.GetSize() <= in_idx) m_ints.Resize(in_idx + 1, NULL);
+  m_ints[in_idx] = entry;
+  
+  return true;
+}
+
+bool cArgSchema::AddEntry(cString in_name, int in_idx, double def)
+{
+  AdjustArgName(in_name);
+  if (m_entries.HasEntry(in_name)) return false;
+  
+  sArgSchemaEntry* entry = new sArgSchemaEntry(in_name, in_idx, def); 
+  m_entries.Add(in_name, entry);
+  
+  if (m_doubles.GetSize() <= in_idx) m_doubles.Resize(in_idx + 1, NULL);
+  m_doubles[in_idx] = entry;
+  
+  return true;
+}
+
+bool cArgSchema::AddEntry(cString in_name, int in_idx, const cString& def)
+{
+  AdjustArgName(in_name);
+  if (m_entries.HasEntry(in_name)) return false;
+  
+  cString* str = new cString(def);
+  sArgSchemaEntry* entry = new sArgSchemaEntry(in_name, in_idx, str); 
+  m_entries.Add(in_name, entry);
+  
+  if (m_strings.GetSize() <= in_idx) m_strings.Resize(in_idx + 1, NULL);
+  m_strings[in_idx] = entry;
+  
+  return true;
+}
+
+
+bool cArgSchema::FindEntry(const cString& in_name, tType& ret_type, int& ret_idx) const
+{
+  sArgSchemaEntry* entry;
+  if (m_entries.Find(in_name, entry)) {
+    ret_type = entry->type;
+    ret_idx = entry->index;
+    return true;
+  }
+  
+  return false;
+}

Added: development/source/tools/cArgSchema.h
===================================================================
--- development/source/tools/cArgSchema.h	2006-09-14 20:07:01 UTC (rev 965)
+++ development/source/tools/cArgSchema.h	2006-09-17 02:47:45 UTC (rev 966)
@@ -0,0 +1,165 @@
+/*
+ *  cArgSchema.h
+ *  Avida
+ *
+ *  Created by David Bryson on 9/12/06.
+ *  Copyright 2006 Michigan State University. All rights reserved.
+ *
+ */
+
+#ifndef cArgSchema_h
+#define cArgSchema_h
+
+#ifndef tDictionary_h
+#include "tDictionary.h"
+#endif
+
+
+class cArgSchema
+{
+public:
+  enum tType { SCHEMA_INT, SCHEMA_DOUBLE, SCHEMA_STRING };
+
+private:
+  struct sArgSchemaEntry
+  {
+    cString name;
+    tType type;
+    int index;
+    bool optional;
+    union {
+      int def_int;
+      double def_double;
+      cString* def_string;
+    };
+    
+    sArgSchemaEntry() { ; }
+    sArgSchemaEntry(const cString& in_name, int in_idx, tType in_type)  // Required Argument (supplied type)
+      : name(in_name), type(in_type), index(in_idx), optional(false) { ; }
+    sArgSchemaEntry(const cString& in_name, int in_idx, int def)        // Optional Int Argument
+      : name(in_name), type(SCHEMA_INT), index(in_idx), optional(true), def_int(def) { ; }
+    sArgSchemaEntry(const cString& in_name, int in_idx, double def)     // Optional Double Argument
+      : name(in_name), type(SCHEMA_DOUBLE), index(in_idx), optional(true), def_double(def) { ; }
+    sArgSchemaEntry(const cString& in_name, int in_idx, cString* def)   // Optional String Argument
+      : name(in_name), type(SCHEMA_STRING), index(in_idx), optional(true), def_string(def) { ; }
+    ~sArgSchemaEntry() { if (type == SCHEMA_STRING) delete def_string; }  // Cleanup string object
+  };
+  
+  
+  tDictionary<sArgSchemaEntry*> m_entries;
+  tArray<sArgSchemaEntry*> m_ints;
+  tArray<sArgSchemaEntry*> m_doubles;
+  tArray<sArgSchemaEntry*> m_strings;
+  
+  char m_sep_entry;
+  char m_sep_value;
+  
+  bool m_case_sensitive;
+
+  
+public:
+  cArgSchema(char entry = ',', char value = '=', bool case_sensitive = false)
+    : m_sep_entry(entry), m_sep_value(value), m_case_sensitive(case_sensitive) { ; }
+  ~cArgSchema();
+  
+  inline void AdjustArgName(cString& in_name) const;
+
+  char GetEntrySeparator() const { return m_sep_entry; }
+  char GetValueSeparator() const { return m_sep_value; }
+  bool IsCaseSensitive() const { return m_case_sensitive; }
+  
+  bool AddEntry(cString in_name, int in_idx, tType in_type);       // Required Argument (supplied type)
+  bool AddEntry(cString in_name, int in_idx, int def);             // Optional Int Argument
+  bool AddEntry(cString in_name, int in_idx, double def);          // Optional Double Argument
+  bool AddEntry(cString in_name, int in_idx, const cString& def);  // Optional String Argument
+  
+  bool FindEntry(const cString& in_name, tType& ret_type, int& ret_idx) const;
+  
+  inline int GetNumIntArgs() const { return m_ints.GetSize(); }
+  inline int GetNumDoubleArgs() const { return m_doubles.GetSize(); }
+  inline int GetNumStringArgs() const { return m_strings.GetSize(); }
+  
+  inline bool IsOptionalInt(int i) const;
+  inline bool IsOptionalDouble(int i) const;
+  inline bool IsOptionalString(int i) const;
+  
+  inline void SetDefaultInt(int i, int& v) const;
+  inline void SetDefaultDouble(int i, double& v) const;
+  inline void SetDefaultString(int i, cString& v) const;
+  
+  inline bool GetIntName(int i, cString& name) const;
+  inline bool GetDoubleName(int i, cString& name) const;
+  inline bool GetStringName(int i, cString& name) const;  
+};
+
+
+inline void cArgSchema::AdjustArgName(cString& in_name) const
+{
+  in_name.Trim();
+  if (!m_case_sensitive) in_name.ToLower();
+}
+
+
+inline void cArgSchema::SetDefaultInt(int i, int& v) const
+{
+  if (IsOptionalInt(i)) v = m_ints[i]->def_int;
+}
+
+inline void cArgSchema::SetDefaultDouble(int i, double& v) const
+{
+  if (IsOptionalDouble(i)) v = m_doubles[i]->def_double;
+}
+
+inline void cArgSchema::SetDefaultString(int i, cString& v) const
+{
+  if (IsOptionalString(i)) v = *m_strings[i]->def_string;
+}
+
+
+inline bool cArgSchema::IsOptionalInt(int i) const
+{
+  if (i < m_ints.GetSize() && m_ints[i]) return m_ints[i]->optional;
+  return false;
+}
+
+inline bool cArgSchema::IsOptionalDouble(int i) const
+{
+  if (i < m_doubles.GetSize() && m_doubles[i]) return m_doubles[i]->optional;
+  return false;
+}
+
+inline bool cArgSchema::IsOptionalString(int i) const
+{
+  if (i < m_strings.GetSize() && m_strings[i]) return m_strings[i]->optional;
+  return false;
+}
+
+
+inline bool cArgSchema::GetIntName(int i, cString& name) const
+{
+  if (i < m_ints.GetSize() && m_ints[i]) {
+    name = m_ints[i]->name;
+    return true;
+  }
+  return false;
+}
+
+inline bool cArgSchema::GetDoubleName(int i, cString& name) const
+{
+  if (i < m_doubles.GetSize() && m_doubles[i]) {
+    name = m_doubles[i]->name;
+    return true;
+  }
+  return false;
+}
+
+inline bool cArgSchema::GetStringName(int i, cString& name) const
+{
+  if (i < m_strings.GetSize() && m_strings[i]) {
+    name = m_strings[i]->name;
+    return true;
+  }
+  return false;
+}
+
+#endif

Modified: development/source/tools/tDictionary.h
===================================================================
--- development/source/tools/tDictionary.h	2006-09-14 20:07:01 UTC (rev 965)
+++ development/source/tools/tDictionary.h	2006-09-17 02:47:45 UTC (rev 966)
@@ -45,19 +45,19 @@
   // disabled copy constructor.
   tDictionary(const tDictionary &);
 public:
-  tDictionary() {}
-  tDictionary(int in_hash_size) : m_hash(in_hash_size) {}
+  tDictionary() { ; }
+  tDictionary(int in_hash_size) : m_hash(in_hash_size) { ; }
 
   // The following methods just call the encapsulated tHashTable
   bool OK() { return m_hash.OK(); }
   int GetSize() { return m_hash.GetSize(); }
-  void Add(const cString & name, T data) { m_hash.Add(name, data); }
-  void SetValue(const cString & name, T data) { m_hash.SetValue(name, data); }
-  bool HasEntry(const cString & name) const { return m_hash.HasEntry(name); }
-  bool Find(const cString & name, T & out_data) const { return m_hash.Find(name, out_data); }
-  T Remove(const cString & name) { return m_hash.Remove(name); }
+  void Add(const cString& name, T data) { m_hash.Add(name, data); }
+  void SetValue(const cString& name, T data) { m_hash.SetValue(name, data); }
+  bool HasEntry(const cString& name) const { return m_hash.HasEntry(name); }
+  bool Find(const cString& name, T& out_data) const { return m_hash.Find(name, out_data); }
+  T Remove(const cString& name) { return m_hash.Remove(name); }
   void SetHash(int _hash) { m_hash.SetTableSize(_hash); }
-  void AsLists(tList<cString> & name_list, tList<T> & value_list) const
+  void AsLists(tList<cString>& name_list, tList<T>& value_list) const
   {
     m_hash.AsLists(name_list, value_list);
   }
@@ -83,7 +83,7 @@
   }
 
   template<class Archive>
-  void serialize(Archive & a, const unsigned int version){
+  void serialize(Archive& a, const unsigned int version){
     a.ArkvObj("m_hash", m_hash);
   }
 };




More information about the Avida-cvs mailing list