1 /* 2 * cHardwareGX.h 3 * Avida 4 * 5 * Copyright 1999-2011 Michigan State University. All rights reserved. 6 * 7 * 8 * This file is part of Avida. 9 * 10 * Avida is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License 11 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 12 * 13 * Avida is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public License along with Avida. 17 * If not, see <http://www.gnu.org/licenses/>. 18 * 19 * 20 * cHardwareGX enables gene expression as follows: 21 * 1) Unlike cHardware{CPU,SMT,TransSMT}, the genome is not directly 22 * executed by this organism. Instead, cHardwareGX enables portions of the 23 * genome to be transcribed into "programids," which are able to execute 24 * independently. 25 * 2) The interaction between programids within cHardwareGX is based on 26 * pattern-matching different genome fragments. Each programid is able to 27 * specify a "match" that will be probabilistically compared against other 28 * programids. When (if) a match is found, those two programids "bind" 29 * together. Different actions may be taken on bind, depending on the 30 * type of match performed. 31 * 32 * \todo cHardwareGX is really not a new CPU architecture, but rather a way for 33 * CPUs to interact. It's much easier, however, to start off by implementing a 34 * new CPU, so that's what we're doing. Eventually we'll need to revisit this. 35 * 36 * \todo There should be better ways for promoter regions to work. Right now, 37 * look for exact matches only and they have equal probabilities @JEB 38 * 39 * \todo We need to abstract cOrganism and derive a new class 40 * that can accommodate multiple genome fragments. 41 * 42 */ 43 #ifndef cHardwareGX_h 44 #define cHardwareGX_h 45 46 #include "avida/Avida.h" 47 48 #include "cCodeLabel.h" 49 #include "cHeadCPU.h" 50 #include "cCPUMemory.h" 51 #include "cCPUStack.h" 52 #include "cHardwareBase.h" 53 #include "cString.h" 54 #include "cStats.h" 55 #include "tArray.h" 56 #include "tInstLib.h" 57 #include "nHardware.h" 58 #include "tBuffer.h" 59 60 #include <iomanip> 61 #include <vector> 62 #include <list> 63 #include <utility> 64 65 class cInstLib; 66 class cInstSet; 67 class cOrganism; 68 69 /*! Each organism may have a cHardwareGX structure that keeps track of the 70 * current status of simulated hardware. This particular CPU architecture is 71 * designed to explore the evolution of gene expression and also the effect 72 * of having persistent "protein-like" pieces of code that continually execute in parallel. 73 */ 74 class cHardwareGX : public cHardwareBase 75 { 76 public: 77 typedef bool (cHardwareGX::*tMethod)(cAvidaContext& ctx); //!< Instruction type. 78 79 static const int NUM_REGISTERS = 3; //!< Number of registers each cProgramid has. 80 //! Number of heads each cProgramid has. 81 static const int NUM_HEADS = nHardware::NUM_HEADS >= NUM_REGISTERS ? nHardware::NUM_HEADS : NUM_REGISTERS; 82 static const int NUM_NOPS = 3; //!< Number of NOPS that cHardwareGX supports. 83 84 // GX "options" that haven't graduated to the Config File 85 86 // "Normal" Model 87 88 static const int PROGRAMID_REPLACEMENT_METHOD = 0; 89 //!< Controls what happens when we try to allocate a new cProgramid, but are up against the limit 90 // 0 = Fail if no programids available 91 // 1 = Replace the programid that has used the most cpu cycles 92 static const double EXECUTABLE_COPY_PROCESSIVITY; // Set to 1.0 by default 93 static const double READABLE_COPY_PROCESSIVITY; // Set to 1.0 by default 94 95 unsigned int m_last_unique_id_assigned; // Counter: so programids can be assigned unique IDs for tracking 96 97 //! Enums for the different supported registers. 98 enum tRegisters { REG_AX=0, REG_BX, REG_CX }; 99 100 class cProgramid; // pre-declaration. 101 typedef cProgramid* programid_ptr; //!< It would be nice to change this to boost::shared_ptr. 102 typedef std::vector<programid_ptr> programid_list; //!< Type for the list of cProgramids. 103 104 //! cMatchSite holds a couple useful pointers for cProgramid::Match, Bind. 105 struct cMatchSite { cMatchSitecMatchSite106 cMatchSite() : m_programid(0), m_site(0) { } 107 cProgramid* m_programid; //!< The programid matched against; 0 if not matched. 108 int m_site; //!< Location in the cProgramid where a match occurred; 0 if not matched. 109 cCodeLabel m_label; //!< The label that was matched against. 110 }; 111 112 /*! cHeadProgramid is just cHeadCPU with a link back to the programid 113 so that we can tell when a head is on the programid that owns it. 114 */ 115 class cHeadProgramid : public cHeadCPU 116 { 117 private: 118 cProgramid* m_programid; 119 public: cHeadCPU(hw,pos,ms)120 cHeadProgramid(cHardwareBase* hw = NULL, int pos = 0, int ms = 0) : cHeadCPU(hw, pos, ms) , m_programid(NULL) { }; ~cHeadProgramid()121 ~cHeadProgramid() { ; } 122 SetProgramid(cProgramid * _programid)123 void SetProgramid(cProgramid* _programid) { m_programid = _programid; } GetProgramid()124 cProgramid* GetProgramid() { return m_programid; } 125 }; 126 127 /*! cProgramid is the "heart" of the gene expression hardware. It encapsulates 128 the genome fragment that is used by both active and passive elements within 129 this organism, and enables these fragments to match against, and bind to, each 130 other depending on their particular instruction sequence. 131 132 It is similar in spirit to a thread, but has certain operational characteristics 133 that make it unique (e.g., matching, disassociation, and a self-contained genome 134 fragment). 135 136 \todo Need to rework cHeadCPU to not need a pointer to cHardwareBase. 137 */ 138 class cProgramid { 139 public: 140 //! Constructs a cProgramid from a genome and CPU. 141 cProgramid(const Sequence& genome, cHardwareGX* hardware); ~cProgramid()142 ~cProgramid() {} 143 144 //! Returns whether and where this cProgramid matches the passed-in label. 145 std::vector<cHardwareGX::cMatchSite> Sites(const cCodeLabel& label); 146 //! Binds one of this cProgramid's heads to the passed-in match site. 147 void Bind(nHardware::tHeads head, cMatchSite& site); 148 //! Detaches this cProgramid's heads from bound cProgramids. 149 void Detach(); 150 151 //! Removes regulation in implicit GX mode 152 void RemoveRegulation(); 153 154 // Programids keep a count of the total number 155 // of READ + WRITE heads of other programids that 156 // have been placed on them. They only execute 157 // if free of other heads and also initialized as executable. RemoveContactingHead(cHeadProgramid & head)158 void RemoveContactingHead(cHeadProgramid& head) { 159 if(head.GetProgramid()->GetID() == m_id) return; 160 assert(m_contacting_heads > 0); 161 m_contacting_heads--; 162 } 163 AddContactingHead(cHeadProgramid & head)164 void AddContactingHead(cHeadProgramid& head) { 165 if(head.GetProgramid()->GetID() == m_id) return; 166 m_contacting_heads++; 167 } 168 169 void ResetHeads(); 170 void Reset(); 171 172 // Accessors GetExecute()173 bool GetExecute() { return m_executable && (m_contacting_heads == 0); } GetExecutable()174 bool GetExecutable() { return m_executable; } GetBindable()175 bool GetBindable() { return m_bindable; } GetReadable()176 bool GetReadable() { return m_readable; } GetID()177 int GetID() { return m_id; } GetInputBuf()178 tBuffer<int>& GetInputBuf() { return m_input_buf; } GetOutputBuf()179 tBuffer<int>& GetOutputBuf() { return m_output_buf; } GetCPUCyclesUsed()180 int GetCPUCyclesUsed() { return m_cpu_cycles_used; } ResetCPUCyclesUsed()181 void ResetCPUCyclesUsed() { m_cpu_cycles_used = 0; } GetInst(cString inst)182 cInstruction GetInst(cString inst) { assert(m_gx_hardware); return m_gx_hardware->GetInstSet().GetInst(inst); } 183 GetMemory()184 const cCPUMemory& GetMemory() const { return m_memory; } 185 186 //! Append this programid's genome to the passed-in genome in linear format (includes tags). 187 void AppendLinearGenome(Sequence& genome); 188 189 //! Print this programid's genome, in linear format. 190 void PrintGenome(std::ostream& out); 191 GetHead(int head_id)192 cHeadProgramid& GetHead(int head_id) { return m_heads[head_id]; } 193 194 // Assignment SetExecutable(bool _executable)195 void SetExecutable(bool _executable) { m_executable = _executable; } SetBindable(bool _bindable)196 void SetBindable(bool _bindable) { m_bindable = _bindable; } SetReadable(bool _readable)197 void SetReadable(bool _readable) { m_readable = _readable; } 198 IncCPUCyclesUsed()199 void IncCPUCyclesUsed() { m_cpu_cycles_used++; } 200 201 cHardwareGX* m_gx_hardware; //!< Back reference 202 int m_id; //!< Each programid is cross-referenced to a memory space. 203 // The index in cHardwareGX::m_programids and cHeadCPU::GetMemSpace() must match up. 204 // A programid also needs to be kept aware of its current index. 205 int m_unique_id; // ID unique to this programid (per hardware) 206 207 int m_contacting_heads; //!< The number of read/write heads on this programid from other programids. 208 bool m_executable; //!< Is this programid ever executable? Currently, a programid with head from another cProgramid on it is also stopped. 209 bool m_bindable; //!< Is this programid bindable, i.e. can other programids put their read heads on it? 210 bool m_readable; //!< Is this programid readable? 211 bool m_marked_for_death; //!< Is this programid marked for deletion? 212 int m_cpu_cycles_used; //!< Number of cpu cycles this programid has used. 213 214 bool m_copying_site; //! Are we in the middle of copying a "site" (which could cause termination) 215 cCodeLabel m_copying_label; //! The current site label that we are copying 216 cCodeLabel m_terminator_label; //!< The label that this cProgramid must traverse to disassociate. 217 218 // Core variables maintained from previous incarnation as a thread 219 cCodeLabel m_read_label; //!< ? 220 cCodeLabel m_next_label; //!< ? 221 cCPUMemory m_memory; //!< This cProgramid's genome fragment. 222 cCPUStack m_stack; //!< This cProgramid's stack (no global stack). 223 cHeadProgramid m_heads[NUM_HEADS]; //!< This cProgramid's heads. 224 int m_regs[NUM_REGISTERS]; //!< This cProgramid's registers. 225 226 int m_input_pointer; 227 tBuffer<int> m_input_buf; //!< This programid's input buffer. 228 tBuffer<int> m_output_buf; //!< This programid's output buffer. 229 230 }; 231 232 protected: 233 static tInstLib<tMethod>* initInstLib(void); //!< Initialize the instruction library. 234 static tInstLib<tMethod>* s_inst_slib; //!< Instruction library (method pointers for all instructions). 235 236 programid_list m_programids; //!< The list of cProgramids. 237 programid_ptr m_current; //!< The currently-executing cProgramid. 238 239 // Implicit RNAP Model only 240 cHeadProgramid m_promoter_update_head; //Promoter position that last executable programid was created from. 241 tArray<double> m_promoter_states; 242 tArray<double> m_promoter_rates; // CURRENT promoter rates. Regulation on top of default. 243 tArray<double> m_promoter_default_rates; // Rates sans regulation 244 tArray<int> m_promoter_occupied_sites; // Whether the site is blocked by a currently bound regulatory protein. 245 double m_recycle_state; 246 double m_promoter_sum; 247 248 // -------- Member Variables -------- 249 const tMethod* m_functions; 250 251 // Flags... 252 bool m_mal_active; // Has an allocate occured since last divide? 253 bool m_advance_ip; // Should the IP advance after this instruction? 254 bool m_executedmatchstrings; // Have we already executed the match strings instruction? 255 bool m_just_divided; // Did we just divide (in which case end execution of programids until next cycle). 256 bool m_reset_inputs; // Flag to make it easy for instructions to reset all inputs (force task modularity). 257 bool m_reset_heads; // Flas to make it easy for instructions to reset heads back (force task modularity). 258 259 bool SingleProcess_ExecuteInst(cAvidaContext& ctx, const cInstruction& cur_inst); 260 261 // -------- Stack Manipulation... -------- StackPush(int value)262 inline void StackPush(int value) { assert(m_current); m_current->m_stack.Push(value); } StackPop()263 inline int StackPop() { assert(m_current); return m_current->m_stack.Pop(); } StackFlip()264 inline void StackFlip() { assert(m_current); m_current->m_stack.Flip(); } StackClear()265 inline void StackClear() { assert(m_current); m_current->m_stack.Clear(); } SwitchStack()266 inline void SwitchStack() { } 267 268 // -------- Head Manipulation (including IP) -------- 269 void AdjustHeads(); 270 271 // -------- Label Manipulation ------- GetLabel()272 const cCodeLabel& GetLabel() const { assert(m_current); return m_current->m_next_label; } GetLabel()273 cCodeLabel& GetLabel() { assert(m_current); return m_current->m_next_label; } 274 void ReadLabel(int max_size=nHardware::MAX_LABEL_SIZE); 275 cHeadCPU FindLabel(int direction); 276 int FindLabel_Forward(const cCodeLabel & search_label, const Sequence& search_genome, int pos); 277 int FindLabel_Backward(const cCodeLabel & search_label, const Sequence& search_genome, int pos); 278 cHeadCPU FindLabel(const cCodeLabel & in_label, int direction); GetReadLabel()279 const cCodeLabel& GetReadLabel() const { assert(m_current); return m_current->m_read_label; } GetReadLabel()280 cCodeLabel& GetReadLabel() { assert(m_current); return m_current->m_read_label; } 281 282 // ---------- Instruction Helpers ----------- 283 int FindModifiedRegister(int default_register); 284 int FindModifiedNextRegister(int default_register); 285 int FindModifiedPreviousRegister(int default_register); 286 int FindModifiedHead(int default_head); 287 int FindNextRegister(int base_reg); 288 289 bool Allocate_Necro(const int new_size); 290 bool Allocate_Random(cAvidaContext& ctx, const int old_size, const int new_size); 291 bool Allocate_Default(const int new_size); 292 bool Allocate_Main(cAvidaContext& ctx, const int allocated_size); 293 294 295 void internalReset(); 296 void internalResetOnFailedDivide(); 297 298 299 int calcExecutedSize(const int parent_size); 300 int calcCopiedSize(const int parent_size, const int child_size); 301 bool Divide_Main(cAvidaContext& ctx); 302 bool HeadCopy_ErrorCorrect(cAvidaContext& ctx, double reduction); 303 void ReadInst(const int in_inst); 304 305 public: 306 //! Main constructor for cHardwareGX; called from cHardwareManager for every organism. 307 cHardwareGX(cAvidaContext& ctx, cWorld* world, cOrganism* in_organism, cInstSet* in_inst_set); 308 virtual ~cHardwareGX(); //!< Destructor; removes all cProgramids. 309 GetInstLib()310 static tInstLib<tMethod>* GetInstLib() { return s_inst_slib; } GetDefaultInstFilename()311 static cString GetDefaultInstFilename() { return "instset-gx.cfg"; } 312 313 bool SingleProcess(cAvidaContext& ctx, bool speculative = false); 314 void ProcessBonusInst(cAvidaContext& ctx, const cInstruction& inst); 315 316 317 // -------- Helper methods -------- GetType()318 int GetType() const { return HARDWARE_TYPE_CPU_GX; } SupportsSpeculative()319 bool SupportsSpeculative() const { return false; } 320 void PrintStatus(std::ostream& fp); SetupMiniTraceFileHeader(const cString & filename,const int gen_id,const cString & genotype)321 void SetupMiniTraceFileHeader(const cString& filename, const int gen_id, const cString& genotype) { } PrintMiniTraceStatus(cAvidaContext & ctx,std::ostream & fp,const cString & next_name)322 void PrintMiniTraceStatus(cAvidaContext& ctx, std::ostream& fp, const cString& next_name) { } PrintMiniTraceSuccess(std::ostream & fp,const int exec_success)323 void PrintMiniTraceSuccess(std::ostream& fp, const int exec_success) { } 324 325 // -------- Stack Manipulation... -------- 326 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); } GetNumStacks()327 inline int GetNumStacks() const { return 2; } 328 329 // -------- Head Manipulation (including IP) -------- GetHead(int head_id)330 const cHeadProgramid& GetHead(int head_id) const { assert(m_current); return m_current->m_heads[head_id]; } GetHead(int head_id)331 cHeadProgramid& GetHead(int head_id) { assert(m_current); return m_current->m_heads[head_id];} GetHead(int head_id,int thread)332 const cHeadProgramid& GetHead(int head_id, int thread) const { assert(m_current); return m_current->m_heads[head_id]; } GetHead(int head_id,int thread)333 cHeadProgramid& GetHead(int head_id, int thread) { assert(m_current); return m_current->m_heads[head_id];} GetNumHeads()334 int GetNumHeads() const { return NUM_HEADS; } 335 IP()336 const cHeadCPU& IP() const { assert(m_current); return m_current->m_heads[nHardware::HEAD_IP]; } IP()337 cHeadCPU& IP() { assert(m_current); return m_current->m_heads[nHardware::HEAD_IP]; } IP(int thread)338 const cHeadCPU& IP(int thread) const { assert(m_current); return m_current->m_heads[nHardware::HEAD_IP]; } IP(int thread)339 cHeadCPU& IP(int thread) { assert(m_current); return m_current->m_heads[nHardware::HEAD_IP]; } 340 341 342 // -------- Memory Manipulation -------- 343 //<! Each programid counts as a memory space. 344 // Heads from one programid can end up on another, 345 // so be careful to fix these when changing the programid list. GetMemory()346 const cCPUMemory& GetMemory() const { assert(m_current); return m_current->m_memory; } GetMemory()347 cCPUMemory& GetMemory() { assert(m_current); return m_current->m_memory; } GetMemSize()348 int GetMemSize() const { assert(m_current); return m_current->m_memory.GetSize(); } GetMemory(int value)349 const cCPUMemory& GetMemory(int value) const { return m_programids[value]->m_memory; } GetMemory(int value)350 cCPUMemory& GetMemory(int value) { return m_programids[value]->m_memory; } GetMemSize(int value)351 int GetMemSize(int value) const { return m_programids[value]->m_memory.GetSize(); } GetNumMemSpaces()352 int GetNumMemSpaces() const { return m_programids.size(); } 353 354 355 // -------- Register Manipulation -------- GetRegister(int reg_id)356 int GetRegister(int reg_id) const { assert(m_current); return m_current->m_regs[reg_id]; } GetRegister(int reg_id)357 int& GetRegister(int reg_id) { assert(m_current); return m_current->m_regs[reg_id]; } GetNumRegisters()358 int GetNumRegisters() const { return NUM_REGISTERS; } 359 360 // -------- Thread Manipuluation -------- 361 /* cHardwareGX does not support threads (at least, not as in other CPUs). */ ThreadSelect(const int thread_id)362 virtual bool ThreadSelect(const int thread_id) { return false; } ThreadSelect(const cCodeLabel & in_label)363 virtual bool ThreadSelect(const cCodeLabel& in_label) { return false; } ThreadPrev()364 virtual void ThreadPrev() { ; } ThreadNext()365 virtual void ThreadNext() { ; } ThreadGetOwner()366 virtual cBioUnit* ThreadGetOwner() { return m_organism; } 367 GetNumThreads()368 virtual int GetNumThreads() const { return 1; } GetCurThread()369 virtual int GetCurThread() const { return -1; } GetCurThreadID()370 virtual int GetCurThreadID() const { return -1; } 371 372 // interrupt current thread InterruptThread(int interruptType)373 bool InterruptThread(int interruptType) { return false; } GetThreadMessageTriggerType(int _index)374 int GetThreadMessageTriggerType(int _index) { return -1; } 375 376 // -------- Parasite Stuff -------- ParasiteInfectHost(cBioUnit * bu)377 bool ParasiteInfectHost(cBioUnit* bu) { return false; } 378 379 380 // -------- Input/Output Buffers -------- GetInputBuf()381 virtual tBuffer<int>& GetInputBuf() { return m_current->GetInputBuf(); } GetOutputBuf()382 virtual tBuffer<int>& GetOutputBuf() { return m_current->GetOutputBuf(); } 383 384 private: 385 cHardwareGX& operator=(const cHardwareGX&); //!< Not implemented. 386 cHardwareGX(const cHardwareGX&); //!< Not implemented. 387 388 // ---------- Instruction Library ----------- 389 390 // Flow Control 391 bool Inst_If0(cAvidaContext& ctx); 392 bool Inst_IfEqu(cAvidaContext& ctx); 393 bool Inst_IfNot0(cAvidaContext& ctx); 394 bool Inst_IfNEqu(cAvidaContext& ctx); 395 bool Inst_IfGr0(cAvidaContext& ctx); 396 bool Inst_IfGr(cAvidaContext& ctx); 397 bool Inst_IfGrEqu0(cAvidaContext& ctx); 398 bool Inst_IfGrEqu(cAvidaContext& ctx); 399 bool Inst_IfLess0(cAvidaContext& ctx); 400 bool Inst_IfLess(cAvidaContext& ctx); 401 bool Inst_IfLsEqu0(cAvidaContext& ctx); 402 bool Inst_IfLsEqu(cAvidaContext& ctx); 403 bool Inst_IfBit1(cAvidaContext& ctx); 404 bool Inst_IfANotEqB(cAvidaContext& ctx); 405 bool Inst_IfBNotEqC(cAvidaContext& ctx); 406 bool Inst_IfANotEqC(cAvidaContext& ctx); 407 408 // bool Inst_JumpF(cAvidaContext& ctx); 409 // bool Inst_JumpB(cAvidaContext& ctx); 410 bool Inst_Call(cAvidaContext& ctx); 411 bool Inst_Return(cAvidaContext& ctx); 412 413 bool Inst_Throw(cAvidaContext& ctx); 414 bool Inst_ThrowIf0(cAvidaContext& ctx); 415 bool Inst_ThrowIfNot0(cAvidaContext& ctx); Inst_Catch(cAvidaContext & ctx)416 bool Inst_Catch(cAvidaContext& ctx) { ReadLabel(); return true; }; 417 418 bool Inst_Goto(cAvidaContext& ctx); 419 bool Inst_GotoIf0(cAvidaContext& ctx); 420 bool Inst_GotoIfNot0(cAvidaContext& ctx); Inst_Label(cAvidaContext & ctx)421 bool Inst_Label(cAvidaContext& ctx) { ReadLabel(); return true; }; 422 423 // Stack and Register Operations 424 bool Inst_Pop(cAvidaContext& ctx); 425 bool Inst_Push(cAvidaContext& ctx); 426 bool Inst_HeadPop(cAvidaContext& ctx); 427 bool Inst_HeadPush(cAvidaContext& ctx); 428 429 bool Inst_PopA(cAvidaContext& ctx); 430 bool Inst_PopB(cAvidaContext& ctx); 431 bool Inst_PopC(cAvidaContext& ctx); 432 bool Inst_PushA(cAvidaContext& ctx); 433 bool Inst_PushB(cAvidaContext& ctx); 434 bool Inst_PushC(cAvidaContext& ctx); 435 436 bool Inst_SwitchStack(cAvidaContext& ctx); 437 bool Inst_FlipStack(cAvidaContext& ctx); 438 bool Inst_Swap(cAvidaContext& ctx); 439 bool Inst_SwapAB(cAvidaContext& ctx); 440 bool Inst_SwapBC(cAvidaContext& ctx); 441 bool Inst_SwapAC(cAvidaContext& ctx); 442 bool Inst_CopyReg(cAvidaContext& ctx); 443 bool Inst_CopyRegAB(cAvidaContext& ctx); 444 bool Inst_CopyRegAC(cAvidaContext& ctx); 445 bool Inst_CopyRegBA(cAvidaContext& ctx); 446 bool Inst_CopyRegBC(cAvidaContext& ctx); 447 bool Inst_CopyRegCA(cAvidaContext& ctx); 448 bool Inst_CopyRegCB(cAvidaContext& ctx); 449 bool Inst_Reset(cAvidaContext& ctx); 450 451 // Single-Argument Math 452 bool Inst_ShiftR(cAvidaContext& ctx); 453 bool Inst_ShiftL(cAvidaContext& ctx); 454 bool Inst_Bit1(cAvidaContext& ctx); 455 bool Inst_SetNum(cAvidaContext& ctx); 456 bool Inst_ValGrey(cAvidaContext& ctx); 457 bool Inst_ValDir(cAvidaContext& ctx); 458 bool Inst_ValAddP(cAvidaContext& ctx); 459 bool Inst_ValFib(cAvidaContext& ctx); 460 bool Inst_ValPolyC(cAvidaContext& ctx); 461 bool Inst_Inc(cAvidaContext& ctx); 462 bool Inst_Dec(cAvidaContext& ctx); 463 bool Inst_Zero(cAvidaContext& ctx); 464 bool Inst_Not(cAvidaContext& ctx); 465 bool Inst_Neg(cAvidaContext& ctx); 466 bool Inst_Square(cAvidaContext& ctx); 467 bool Inst_Sqrt(cAvidaContext& ctx); 468 bool Inst_Log(cAvidaContext& ctx); 469 bool Inst_Log10(cAvidaContext& ctx); 470 bool Inst_Minus17(cAvidaContext& ctx); 471 472 // Double Argument Math 473 bool Inst_Add(cAvidaContext& ctx); 474 bool Inst_Sub(cAvidaContext& ctx); 475 bool Inst_Mult(cAvidaContext& ctx); 476 bool Inst_Div(cAvidaContext& ctx); 477 bool Inst_Mod(cAvidaContext& ctx); 478 bool Inst_Nand(cAvidaContext& ctx); 479 bool Inst_Nor(cAvidaContext& ctx); 480 bool Inst_And(cAvidaContext& ctx); 481 bool Inst_Order(cAvidaContext& ctx); 482 bool Inst_Xor(cAvidaContext& ctx); 483 484 // Biological 485 bool Inst_Copy(cAvidaContext& ctx); 486 bool Inst_ReadInst(cAvidaContext& ctx); 487 bool Inst_WriteInst(cAvidaContext& ctx); 488 bool Inst_StackReadInst(cAvidaContext& ctx); 489 bool Inst_StackWriteInst(cAvidaContext& ctx); 490 bool Inst_Compare(cAvidaContext& ctx); 491 bool Inst_IfNCpy(cAvidaContext& ctx); 492 bool Inst_Allocate(cAvidaContext& ctx); 493 bool Inst_CAlloc(cAvidaContext& ctx); 494 bool Inst_MaxAlloc(cAvidaContext& ctx); 495 496 bool Inst_Repro(cAvidaContext& ctx); 497 498 bool Inst_SpawnDeme(cAvidaContext& ctx); 499 bool Inst_Kazi(cAvidaContext& ctx); 500 bool Inst_Kazi5(cAvidaContext& ctx); 501 bool Inst_Die(cAvidaContext& ctx); 502 503 // I/O and Sensory 504 bool Inst_TaskGet(cAvidaContext& ctx); 505 bool Inst_TaskGet2(cAvidaContext& ctx); 506 bool Inst_TaskStackGet(cAvidaContext& ctx); 507 bool Inst_TaskStackLoad(cAvidaContext& ctx); 508 bool Inst_TaskPut(cAvidaContext& ctx); 509 bool Inst_TaskPutResetInputs(cAvidaContext& ctx); 510 bool Inst_TaskIO(cAvidaContext& ctx); 511 bool Inst_TaskIO_DecayBonus(cAvidaContext& ctx); 512 bool Inst_TaskIO_Feedback(cAvidaContext& ctx); 513 bool Inst_MatchStrings(cAvidaContext& ctx); 514 bool Inst_Sell(cAvidaContext& ctx); 515 bool Inst_Buy(cAvidaContext& ctx); 516 bool Inst_Send(cAvidaContext& ctx); 517 bool Inst_Receive(cAvidaContext& ctx); 518 bool Inst_SenseLog2(cAvidaContext& ctx); 519 bool Inst_SenseUnit(cAvidaContext& ctx); 520 bool Inst_SenseMult100(cAvidaContext& ctx); 521 bool DoSense(cAvidaContext& ctx, int conversion_method, double base); 522 523 void DoDonate(cOrganism * to_org); 524 bool Inst_DonateRandom(cAvidaContext& ctx); 525 bool Inst_DonateEditDist(cAvidaContext& ctx); 526 bool Inst_DonateGreenBeardGene(cAvidaContext& ctx); 527 bool Inst_DonateTrueGreenBeard(cAvidaContext& ctx); 528 bool Inst_DonateThreshGreenBeard(cAvidaContext& ctx); 529 bool Inst_DonateQuantaThreshGreenBeard(cAvidaContext& ctx); 530 bool Inst_DonateNULL(cAvidaContext& ctx); 531 532 bool Inst_SearchF(cAvidaContext& ctx); 533 bool Inst_SearchB(cAvidaContext& ctx); 534 bool Inst_MemSize(cAvidaContext& ctx); 535 536 // Environment 537 bool Inst_RotateL(cAvidaContext& ctx); 538 bool Inst_RotateR(cAvidaContext& ctx); 539 bool Inst_SetCopyMut(cAvidaContext& ctx); 540 bool Inst_ModCopyMut(cAvidaContext& ctx); 541 542 // Energy use 543 bool Inst_ZeroEnergyUsed(cAvidaContext& ctx); 544 545 // Head-based instructions... 546 bool Inst_AdvanceHead(cAvidaContext& ctx); 547 bool Inst_MoveHead(cAvidaContext& ctx); 548 bool Inst_JumpHead(cAvidaContext& ctx); 549 bool Inst_GetHead(cAvidaContext& ctx); 550 bool Inst_IfLabel(cAvidaContext& ctx); 551 bool Inst_IfLabel2(cAvidaContext& ctx); 552 bool Inst_HeadDivide(cAvidaContext& ctx); 553 bool Inst_HeadRead(cAvidaContext& ctx); 554 bool Inst_HeadWrite(cAvidaContext& ctx); 555 bool Inst_HeadCopy(cAvidaContext& ctx); 556 bool Inst_HeadSearch(cAvidaContext& ctx); 557 bool Inst_SetFlow(cAvidaContext& ctx); 558 559 bool Inst_HeadCopy2(cAvidaContext& ctx); 560 bool Inst_HeadCopy3(cAvidaContext& ctx); 561 bool Inst_HeadCopy4(cAvidaContext& ctx); 562 bool Inst_HeadCopy5(cAvidaContext& ctx); 563 bool Inst_HeadCopy6(cAvidaContext& ctx); 564 bool Inst_HeadCopy7(cAvidaContext& ctx); 565 bool Inst_HeadCopy8(cAvidaContext& ctx); 566 bool Inst_HeadCopy9(cAvidaContext& ctx); 567 bool Inst_HeadCopy10(cAvidaContext& ctx); 568 569 //// Placebo //// 570 bool Inst_Skip(cAvidaContext& ctx); 571 572 // -= Gene expression instructions =- 573 bool Inst_NewProgramid(cAvidaContext& ctx, bool executable, bool bindable, bool readable); //!< Allocate a new programid and place the write head there. Inst_NewExecutableProgramid(cAvidaContext & ctx)574 bool Inst_NewExecutableProgramid(cAvidaContext& ctx) { return Inst_NewProgramid(ctx, true, false, false); } //!< Allocate a "protein". Cannot be bound or read. Inst_NewGenomeProgramid(cAvidaContext & ctx)575 bool Inst_NewGenomeProgramid(cAvidaContext& ctx) { return Inst_NewProgramid(ctx, false, true, true); } //!< Allocate a "genomic" fragment. Cannot execute. 576 577 bool Inst_Site(cAvidaContext& ctx); //!< A binding site (execution simply advances past label) 578 bool Inst_Bind(cAvidaContext& ctx); //!< Attempt to match the currently executing cProgramid against other cProgramids. 579 bool Inst_Bind2(cAvidaContext& ctx); //!< Attempt to locate two programids with the same site. 580 bool Inst_IfBind(cAvidaContext& ctx); //!< Attempt to match the currently executing cProgramid against other cProgramids. Execute next inst if successful. 581 bool Inst_IfBind2(cAvidaContext& ctx); //!< Attempt to match and bind two programids. 582 bool Inst_NumSites(cAvidaContext& ctx); //!< Count the number of corresponding binding sites 583 bool Inst_ProgramidCopy(cAvidaContext& ctx); //!< Like h-copy, but fails if read/write heads not on other programids and will not write over 584 bool Inst_ProgramidDivide(cAvidaContext& ctx); //!< Like h-divide, 585 bool Inst_ProgramidImplicitAllocate(cAvidaContext& ctx); 586 bool Inst_ProgramidImplicitDivide(cAvidaContext& ctx); 587 bool Inst_EndProgramidExecution(cAvidaContext& ctx); 588 589 bool Inst_Promoter(cAvidaContext& ctx); 590 bool Inst_Terminator(cAvidaContext& ctx); 591 bool Inst_HeadActivate(cAvidaContext& ctx); 592 bool Inst_HeadRepress(cAvidaContext& ctx); 593 594 //!< 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... 595 void AddProgramid(programid_ptr programid); 596 void RemoveProgramid(unsigned int remove_index); 597 598 // Create executable programids in the implicit GX model 599 void ProcessImplicitGeneExpression(int in_limit = -1); 600 void AdjustPromoterRates(); //Call after a change to occupied array to correctly update rates. 601 int FindRegulatoryMatch(const cCodeLabel& label); 602 }; 603 604 #endif 605