1 /*
2 * cHardwareCPU.h
3 * Avida
4 *
5 * Called "hardware_cpu.hh" prior to 11/17/05.
6 * Copyright 1999-2011 Michigan State University. All rights reserved.
7 * Copyright 1999-2003 California Institute of Technology.
8 *
9 *
10 * This file is part of Avida.
11 *
12 * Avida is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
14 *
15 * Avida is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License along with Avida.
19 * If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23 #ifndef cHardwareCPU_h
24 #define cHardwareCPU_h
25
26 #include "avida/Avida.h"
27
28 #include "cCodeLabel.h"
29 #include "cHeadCPU.h"
30 #include "cCPUMemory.h"
31 #include "cCPUStack.h"
32 #include "cHardwareBase.h"
33 #include "cString.h"
34 #include "cStats.h"
35 #include "tArray.h"
36 #include "tInstLib.h"
37
38 #include "nHardware.h"
39
40 #include <iomanip>
41 #include <vector>
42
43 /**
44 * Each organism may have a cHardwareCPU structure which keeps track of the
45 * current status of all the components of the simulated hardware.
46 *
47 * @see cHardwareCPU_Thread, cCPUStack, cCPUMemory, cInstSet
48 **/
49
50 class cInstLib;
51 class cInstSet;
52 class cOrganism;
53
54
55 class cHardwareCPU : public cHardwareBase
56 {
57 public:
58 typedef bool (cHardwareCPU::*tMethod)(cAvidaContext& ctx);
59
60 protected:
61 // -------- Structure Constants --------
62 static const int NUM_REGISTERS = 3;
63 static const int NUM_HEADS = nHardware::NUM_HEADS >= NUM_REGISTERS ? nHardware::NUM_HEADS : NUM_REGISTERS;
64 enum tRegisters { REG_AX = 0, REG_BX, REG_CX, REG_DX, REG_EX, REG_FX };
65 static const int NUM_NOPS = 3;
66
67 // -------- Data Structures --------
68 struct cLocalThread
69 {
70 private:
71 int m_id;
72 int m_promoter_inst_executed;
73 int m_messageTriggerType;
74 public:
75 int reg[NUM_REGISTERS];
76 cHeadCPU heads[NUM_HEADS];
77 cCPUStack stack;
78 unsigned char cur_stack; // 0 = local stack, 1 = global stack.
79 unsigned char cur_head;
80
81 cCodeLabel read_label;
82 cCodeLabel next_label;
83
84
85 cLocalThread(cHardwareBase* in_hardware = NULL, int in_id = -1) { Reset(in_hardware, in_id); }
~cLocalThreadcLocalThread86 ~cLocalThread() { ; }
87
88 void operator=(const cLocalThread& in_thread);
89
90 void Reset(cHardwareBase* in_hardware, int in_id);
GetIDcLocalThread91 int GetID() const { return m_id; }
SetIDcLocalThread92 void SetID(int in_id) { m_id = in_id; }
GetPromoterInstExecutedcLocalThread93 int GetPromoterInstExecuted() { return m_promoter_inst_executed; }
IncPromoterInstExecutedcLocalThread94 void IncPromoterInstExecuted() { m_promoter_inst_executed++; }
ResetPromoterInstExecutedcLocalThread95 void ResetPromoterInstExecuted() { m_promoter_inst_executed = 0; }
setMessageTriggerTypecLocalThread96 void setMessageTriggerType(int value) { m_messageTriggerType = value; }
getMessageTriggerTypecLocalThread97 int getMessageTriggerType() { return m_messageTriggerType; }
98 };
99
100
101 // -------- Static Variables --------
102 static tInstLib<tMethod>* s_inst_slib;
103 static tInstLib<tMethod>* initInstLib(void);
104
105
106 // -------- Member Variables --------
107 const tMethod* m_functions;
108
109 cCPUMemory m_memory; // Memory...
110 cCPUStack m_global_stack; // A stack that all threads share.
111
112 tArray<cLocalThread> m_threads;
113 int m_thread_id_chart;
114 int m_cur_thread;
115
116 // Flags...
117 struct {
118 bool m_mal_active:1; // Has an allocate occured since last divide?
119 bool m_advance_ip:1; // Should the IP advance after this instruction?
120 bool m_executedmatchstrings:1; // Have we already executed the match strings instruction?
121 bool m_spec_die:1;
122
123 bool m_thread_slicing_parallel:1;
124 bool m_no_cpu_cycle_time:1;
125
126 bool m_promoters_enabled:1;
127 bool m_constitutive_regulation:1;
128
129 bool m_slip_read_head:1;
130 };
131
132 // <-- Promoter model
133 int m_promoter_index; //site to begin looking for the next active promoter from
134 int m_promoter_offset; //bit offset when testing whether a promoter is on
135
136 struct cPromoter
137 {
138 public:
139 int m_pos; //position within genome
140 int m_bit_code; //bit code of promoter
141 int m_regulation; //bit code of promoter
142 public:
143 cPromoter(int _pos = 0, int _bit_code = 0, int _regulation = 0) { m_pos = _pos; m_bit_code = _bit_code; m_regulation = _regulation; }
GetRegulatedBitCodecPromoter144 int GetRegulatedBitCode() { return m_bit_code ^ m_regulation; }
~cPromotercPromoter145 ~cPromoter() { ; }
146 };
147 tArray<cPromoter> m_promoters;
148 // Promoter Model -->
149
150 // <-- Epigenetic State
151 bool m_epigenetic_state;
152 int m_epigenetic_saved_reg[NUM_REGISTERS];
153 cCPUStack m_epigenetic_saved_stack;
154 // Epigenetic State -->
155
156
157 bool SingleProcess_ExecuteInst(cAvidaContext& ctx, const cInstruction& cur_inst);
158
159 // -------- Stack Manipulation... --------
160 inline void StackPush(int value);
161 inline int StackPop();
162 inline void StackFlip();
163 inline void StackClear();
164 inline void SwitchStack();
165
166
167 // -------- Head Manipulation (including IP) --------
GetActiveHead()168 cHeadCPU& GetActiveHead() { return m_threads[m_cur_thread].heads[m_threads[m_cur_thread].cur_head]; }
169 void AdjustHeads();
170
171
172 // -------- Label Manipulation -------
GetLabel()173 const cCodeLabel& GetLabel() const { return m_threads[m_cur_thread].next_label; }
GetLabel()174 cCodeLabel& GetLabel() { return m_threads[m_cur_thread].next_label; }
175 void ReadLabel(int max_size=nHardware::MAX_LABEL_SIZE);
176 cHeadCPU FindLabel(int direction);
177 int FindLabel_Forward(const cCodeLabel & search_label, const Sequence& search_genome, int pos);
178 int FindLabel_Backward(const cCodeLabel & search_label, const Sequence& search_genome, int pos);
179 cHeadCPU FindLabel(const cCodeLabel & in_label, int direction);
GetReadLabel()180 const cCodeLabel& GetReadLabel() const { return m_threads[m_cur_thread].read_label; }
GetReadLabel()181 cCodeLabel& GetReadLabel() { return m_threads[m_cur_thread].read_label; }
182
183
184 // -------- Thread Manipulation -------
185 bool ForkThread(); // Adds a new thread based off of m_cur_thread.
186 bool InterruptThread(int interruptType); // Create a new thread that interrupts the current thread
187 bool KillThread(); // Kill the current thread!
188
189 // ---------- Instruction Helpers -----------
190 int FindModifiedRegister(int default_register);
191 int FindModifiedNextRegister(int default_register);
192 int FindModifiedPreviousRegister(int default_register);
193 int FindModifiedHead(int default_head);
194 int FindNextRegister(int base_reg);
195
getHead(int head_id)196 inline const cHeadCPU& getHead(int head_id) const { return m_threads[m_cur_thread].heads[head_id]; }
getHead(int head_id)197 inline cHeadCPU& getHead(int head_id) { return m_threads[m_cur_thread].heads[head_id];}
getHead(int head_id,int thread)198 inline const cHeadCPU& getHead(int head_id, int thread) const { return m_threads[thread].heads[head_id]; }
getHead(int head_id,int thread)199 inline cHeadCPU& getHead(int head_id, int thread) { return m_threads[thread].heads[head_id];}
200
getIP()201 inline const cHeadCPU& getIP() const { return m_threads[m_cur_thread].heads[nHardware::HEAD_IP]; }
getIP()202 inline cHeadCPU& getIP() { return m_threads[m_cur_thread].heads[nHardware::HEAD_IP]; }
getIP(int thread)203 inline const cHeadCPU& getIP(int thread) const { return m_threads[thread].heads[nHardware::HEAD_IP]; }
getIP(int thread)204 inline cHeadCPU& getIP(int thread) { return m_threads[thread].heads[nHardware::HEAD_IP]; }
205
206
207 bool Allocate_Necro(const int new_size);
208 bool Allocate_Random(cAvidaContext& ctx, const int old_size, const int new_size);
209 bool Allocate_Default(const int new_size);
210 bool Allocate_Main(cAvidaContext& ctx, const int allocated_size);
211
212
213 void internalReset();
214
215 void internalResetOnFailedDivide();
216
217
218 int calcCopiedSize(const int parent_size, const int child_size);
219
220 bool Divide_Main(cAvidaContext& ctx, const int divide_point, const int extra_lines=0, double mut_multiplier=1);
221 bool Divide_MainRS(cAvidaContext& ctx, const int divide_point, const int extra_lines=0, double mut_multiplier=1); //AWC 06/29/06
222 bool Divide_Main1RS(cAvidaContext& ctx, const int divide_point, const int extra_lines=0, double mut_multiplier=1); //AWC 07/28/06
223 bool Divide_Main2RS(cAvidaContext& ctx, const int divide_point, const int extra_lines=0, double mut_multiplier=1); //AWC 07/28/06
224
225 void Divide_DoTransposons(cAvidaContext& ctx);
226 void InheritState(cHardwareBase& in_hardware);
227
228 bool HeadCopy_ErrorCorrect(cAvidaContext& ctx, double reduction);
229 bool Inst_HeadDivideMut(cAvidaContext& ctx, double mut_multiplier = 1);
230
231 void ReadInst(const int in_inst);
232
233
234 cHardwareCPU& operator=(const cHardwareCPU&); // @not_implemented
235
236 public:
237 cHardwareCPU(cAvidaContext& ctx, cWorld* world, cOrganism* in_organism, cInstSet* in_inst_set);
~cHardwareCPU()238 ~cHardwareCPU() { ; }
239
GetInstLib()240 static tInstLib<tMethod>* GetInstLib() { return s_inst_slib; }
GetDefaultInstFilename()241 static cString GetDefaultInstFilename() { return "instset-heads.cfg"; }
242
243 bool SingleProcess(cAvidaContext& ctx, bool speculative = false);
244 void ProcessBonusInst(cAvidaContext& ctx, const cInstruction& inst);
245
246
247 // -------- Helper methods --------
GetType()248 int GetType() const { return HARDWARE_TYPE_CPU_ORIGINAL; }
SupportsSpeculative()249 bool SupportsSpeculative() const { return true; }
250 void PrintStatus(std::ostream& fp);
SetupMiniTraceFileHeader(const cString & filename,const int gen_id,const cString & genotype)251 void SetupMiniTraceFileHeader(const cString& filename, const int gen_id, const cString& genotype) { (void)filename, (void)gen_id, (void)genotype; }
PrintMiniTraceStatus(cAvidaContext & ctx,std::ostream & fp,const cString & next_name)252 void PrintMiniTraceStatus(cAvidaContext& ctx, std::ostream& fp, const cString& next_name) { (void)ctx, (void)fp, (void)next_name; }
PrintMiniTraceSuccess(std::ostream & fp,const int exec_success)253 void PrintMiniTraceSuccess(std::ostream& fp, const int exec_success) { (void)fp, (void)exec_success; }
254
255 // -------- Stack Manipulation... --------
256 inline int GetStack(int depth=0, int stack_id=-1, int in_thread=-1) const;
GetNumStacks()257 inline int GetNumStacks() const { return 2; }
258
259
260 // -------- Head Manipulation (including IP) --------
GetHead(int head_id)261 const cHeadCPU& GetHead(int head_id) const { return m_threads[m_cur_thread].heads[head_id]; }
GetHead(int head_id)262 cHeadCPU& GetHead(int head_id) { return m_threads[m_cur_thread].heads[head_id];}
GetHead(int head_id,int thread)263 const cHeadCPU& GetHead(int head_id, int thread) const { return m_threads[thread].heads[head_id]; }
GetHead(int head_id,int thread)264 cHeadCPU& GetHead(int head_id, int thread) { return m_threads[thread].heads[head_id];}
GetNumHeads()265 int GetNumHeads() const { return NUM_HEADS; }
266
IP()267 const cHeadCPU& IP() const { return m_threads[m_cur_thread].heads[nHardware::HEAD_IP]; }
IP()268 cHeadCPU& IP() { return m_threads[m_cur_thread].heads[nHardware::HEAD_IP]; }
IP(int thread)269 const cHeadCPU& IP(int thread) const { return m_threads[thread].heads[nHardware::HEAD_IP]; }
IP(int thread)270 cHeadCPU& IP(int thread) { return m_threads[thread].heads[nHardware::HEAD_IP]; }
271
272
273 // -------- Memory Manipulation --------
GetMemory()274 const cCPUMemory& GetMemory() const { return m_memory; }
GetMemory()275 cCPUMemory& GetMemory() { return m_memory; }
GetMemSize()276 int GetMemSize() const { return m_memory.GetSize(); }
GetMemory(int value)277 const cCPUMemory& GetMemory(int value) const { return m_memory; }
GetMemory(int value)278 cCPUMemory& GetMemory(int value) { return m_memory; }
GetMemSize(int value)279 int GetMemSize(int value) const { return m_memory.GetSize(); }
GetNumMemSpaces()280 int GetNumMemSpaces() const { return 1; }
281
282
283 // -------- Register Manipulation --------
GetRegister(int reg_id)284 int GetRegister(int reg_id) const { return m_threads[m_cur_thread].reg[reg_id]; }
GetRegister(int reg_id)285 int& GetRegister(int reg_id) { return m_threads[m_cur_thread].reg[reg_id]; }
GetNumRegisters()286 int GetNumRegisters() const { return NUM_REGISTERS; }
287
288
289 // -------- Thread Manipulation --------
290 bool ThreadSelect(const int thread_num);
ThreadSelect(const cCodeLabel & in_label)291 bool ThreadSelect(const cCodeLabel& in_label) { return false; } // Labeled threads not supported
292 inline void ThreadPrev(); // Shift the current thread in use.
293 inline void ThreadNext();
ThreadGetOwner()294 cBioUnit* ThreadGetOwner() { return m_organism; }
295
GetNumThreads()296 int GetNumThreads() const { return m_threads.GetSize(); }
GetCurThread()297 int GetCurThread() const { return m_cur_thread; }
GetCurThreadID()298 int GetCurThreadID() const { return m_threads[m_cur_thread].GetID(); }
GetThread(int _index)299 const cLocalThread& GetThread(int _index) const { return m_threads[_index]; }
GetThreadMessageTriggerType(int _index)300 int GetThreadMessageTriggerType(int _index) { return m_threads[_index].getMessageTriggerType(); }
301
302 // -------- Parasite Stuff --------
ParasiteInfectHost(cBioUnit * bu)303 bool ParasiteInfectHost(cBioUnit* bu) { return false; }
304
305 // -------- Kaboom Stuff ------------
306 bool checkNoMutList(cHeadCPU to);
307
308
309 // Non-Standard Methods
310
GetActiveStack()311 int GetActiveStack() const { return m_threads[m_cur_thread].cur_stack; }
GetMalActive()312 bool GetMalActive() const { return m_mal_active; }
313
314
315 private:
316 // ---------- Instruction Library -----------
317
318 // Flow Control
319 bool Inst_If0(cAvidaContext& ctx);
320 bool Inst_IfEqu(cAvidaContext& ctx);
321 bool Inst_IfNot0(cAvidaContext& ctx);
322 bool Inst_If0_defaultAX(cAvidaContext& ctx);
323 bool Inst_IfNot0_defaultAX(cAvidaContext& ctx);
324 bool Inst_IfNEqu(cAvidaContext& ctx);
325 bool Inst_IfGr0(cAvidaContext& ctx);
326 bool Inst_IfGr(cAvidaContext& ctx);
327 bool Inst_IfGrEqu0(cAvidaContext& ctx);
328 bool Inst_IfGrEqu(cAvidaContext& ctx);
329 bool Inst_IfLess0(cAvidaContext& ctx);
330 bool Inst_IfLess(cAvidaContext& ctx);
331 bool Inst_IfLsEqu0(cAvidaContext& ctx);
332 bool Inst_IfLsEqu(cAvidaContext& ctx);
333 bool Inst_IfBit1(cAvidaContext& ctx);
334 bool Inst_IfANotEqB(cAvidaContext& ctx);
335 bool Inst_IfBNotEqC(cAvidaContext& ctx);
336 bool Inst_IfANotEqC(cAvidaContext& ctx);
337 bool Inst_IfGrX(cAvidaContext& ctx);
338 bool Inst_IfEquX(cAvidaContext& ctx);
339
340 bool Inst_IfAboveResLevel(cAvidaContext& ctx);
341 bool Inst_IfAboveResLevelEnd(cAvidaContext& ctx);
342 bool Inst_IfNotAboveResLevel(cAvidaContext& ctx);
343 bool Inst_IfNotAboveResLevelEnd(cAvidaContext& ctx);
344
345 bool Inst_IfGerm(cAvidaContext& ctx);
346 bool Inst_IfSoma(cAvidaContext& ctx);
347
348 // Probabilistic ifs.
349 bool Inst_IfP0p125(cAvidaContext& ctx);
350 bool Inst_IfP0p25(cAvidaContext& ctx);
351 bool Inst_IfP0p50(cAvidaContext& ctx);
352 bool Inst_IfP0p75(cAvidaContext& ctx);
353
354 // If-less-else-if, else, endif
355 cHeadCPU Find(const char* instr);
356 void Else_TopHalf();
357 bool Inst_IfLessEnd(cAvidaContext& ctx);
358 bool Inst_IfNotEqualEnd(cAvidaContext& ctx);
359 bool Inst_IfGrtEquEnd(cAvidaContext& ctx);
360 bool Inst_Else(cAvidaContext& ctx);
361 bool Inst_EndIf(cAvidaContext& ctx);
362
363 bool Inst_JumpF(cAvidaContext& ctx);
364 bool Inst_JumpB(cAvidaContext& ctx);
365 bool Inst_Call(cAvidaContext& ctx);
366 bool Inst_Return(cAvidaContext& ctx);
367
368 bool Inst_Throw(cAvidaContext& ctx);
369 bool Inst_ThrowIf0(cAvidaContext& ctx);
370 bool Inst_ThrowIfNot0(cAvidaContext& ctx);
Inst_Catch(cAvidaContext & ctx)371 bool Inst_Catch(cAvidaContext& ctx) { ReadLabel(); return true; };
372
373 bool Inst_Goto(cAvidaContext& ctx);
374 bool Inst_GotoIf0(cAvidaContext& ctx);
375 bool Inst_GotoIfNot0(cAvidaContext& ctx);
Inst_Label(cAvidaContext & ctx)376 bool Inst_Label(cAvidaContext& ctx) { ReadLabel(); return true; };
377
378 // Stack and Register Operations
379 bool Inst_Pop(cAvidaContext& ctx);
380 bool Inst_Push(cAvidaContext& ctx);
381 bool Inst_HeadPop(cAvidaContext& ctx);
382 bool Inst_HeadPush(cAvidaContext& ctx);
383
384 bool Inst_PopA(cAvidaContext& ctx);
385 bool Inst_PopB(cAvidaContext& ctx);
386 bool Inst_PopC(cAvidaContext& ctx);
387 bool Inst_PushA(cAvidaContext& ctx);
388 bool Inst_PushB(cAvidaContext& ctx);
389 bool Inst_PushC(cAvidaContext& ctx);
390
391 bool Inst_SwitchStack(cAvidaContext& ctx);
392 bool Inst_FlipStack(cAvidaContext& ctx);
393 bool Inst_Swap(cAvidaContext& ctx);
394 bool Inst_SwapAB(cAvidaContext& ctx);
395 bool Inst_SwapBC(cAvidaContext& ctx);
396 bool Inst_SwapAC(cAvidaContext& ctx);
397 bool Inst_CopyReg(cAvidaContext& ctx);
398 bool Inst_CopyRegAB(cAvidaContext& ctx);
399 bool Inst_CopyRegAC(cAvidaContext& ctx);
400 bool Inst_CopyRegBA(cAvidaContext& ctx);
401 bool Inst_CopyRegBC(cAvidaContext& ctx);
402 bool Inst_CopyRegCA(cAvidaContext& ctx);
403 bool Inst_CopyRegCB(cAvidaContext& ctx);
404 bool Inst_Reset(cAvidaContext& ctx);
405
406 // Single-Argument Math
407 bool Inst_ShiftR(cAvidaContext& ctx);
408 bool Inst_ShiftL(cAvidaContext& ctx);
409 bool Inst_Bit1(cAvidaContext& ctx);
410 bool Inst_SetNum(cAvidaContext& ctx);
411 bool Inst_ValGrey(cAvidaContext& ctx);
412 bool Inst_ValDir(cAvidaContext& ctx);
413 bool Inst_ValAddP(cAvidaContext& ctx);
414 bool Inst_ValFib(cAvidaContext& ctx);
415 bool Inst_ValPolyC(cAvidaContext& ctx);
416 bool Inst_Inc(cAvidaContext& ctx);
417 bool Inst_Dec(cAvidaContext& ctx);
418 bool Inst_All1s(cAvidaContext& ctx);
419 bool Inst_Zero(cAvidaContext& ctx);
420 bool Inst_Not(cAvidaContext& ctx);
421 bool Inst_Neg(cAvidaContext& ctx);
422 bool Inst_Square(cAvidaContext& ctx);
423 bool Inst_Sqrt(cAvidaContext& ctx);
424 bool Inst_Log(cAvidaContext& ctx);
425 bool Inst_Log10(cAvidaContext& ctx);
426
427 // Double Argument Math
428 bool Inst_Add(cAvidaContext& ctx);
429 bool Inst_Sub(cAvidaContext& ctx);
430 bool Inst_Mult(cAvidaContext& ctx);
431 bool Inst_Div(cAvidaContext& ctx);
432 bool Inst_Mod(cAvidaContext& ctx);
433 bool Inst_Nand(cAvidaContext& ctx);
434 bool Inst_Or(cAvidaContext& ctx);
435 bool Inst_Nor(cAvidaContext& ctx);
436 bool Inst_And(cAvidaContext& ctx);
437 bool Inst_Order(cAvidaContext& ctx);
438 bool Inst_Xor(cAvidaContext& ctx);
439
440 // Bit-setting instructions
441 bool Inst_Setbit(cAvidaContext& ctx);
442 bool Inst_Clearbit(cAvidaContext& ctx);
443
444 // Double Argument Math that are treatable
445 bool Inst_NandTreatable(cAvidaContext& ctx);
446
447 // Biological
448 bool Inst_Copy(cAvidaContext& ctx);
449 bool Inst_ReadInst(cAvidaContext& ctx);
450 bool Inst_WriteInst(cAvidaContext& ctx);
451 bool Inst_StackReadInst(cAvidaContext& ctx);
452 bool Inst_StackWriteInst(cAvidaContext& ctx);
453 bool Inst_Compare(cAvidaContext& ctx);
454 bool Inst_IfNCpy(cAvidaContext& ctx);
455 bool Inst_Allocate(cAvidaContext& ctx);
456 bool Inst_Divide(cAvidaContext& ctx);
457 bool Inst_DivideRS(cAvidaContext& ctx); // AWC 06/29/06
458 bool Inst_CAlloc(cAvidaContext& ctx);
459 bool Inst_CDivide(cAvidaContext& ctx);
460 bool Inst_MaxAlloc(cAvidaContext& ctx);
461 bool Inst_MaxAllocMoveWriteHead(cAvidaContext& ctx);
462 bool Inst_Transposon(cAvidaContext& ctx);
463 bool Inst_ReproDeme(cAvidaContext& ctx);
464 bool Inst_Repro(cAvidaContext& ctx);
465 bool Inst_ReproSex(cAvidaContext& ctx);
466 bool Inst_ReproGermFlag(cAvidaContext& ctx);
467 bool Inst_TaskPutRepro(cAvidaContext& ctx);
468 bool Inst_TaskPutResetInputsRepro(cAvidaContext& ctx);
469 bool Inst_ConditionalRepro(cAvidaContext& ctx);
470 bool Inst_Sterilize(cAvidaContext& ctx);
471
472 bool Inst_SpawnDeme(cAvidaContext& ctx);
473 bool Inst_Kazi(cAvidaContext& ctx);
474 bool Inst_Kazi5(cAvidaContext& ctx);
475 bool Inst_Die(cAvidaContext& ctx);
476 bool Inst_Poison(cAvidaContext& ctx);
477 bool Inst_Suicide(cAvidaContext& ctx);
478 bool Inst_RelinquishEnergyToFutureDeme(cAvidaContext& ctx);
479 bool Inst_RelinquishEnergyToNeighborOrganisms(cAvidaContext& ctx);
480 bool Inst_RelinquishEnergyToOrganismsInDeme(cAvidaContext& ctx);
481
482 // I/O and Sensory
483 bool Inst_TaskGet(cAvidaContext& ctx);
484 bool Inst_TaskGet2(cAvidaContext& ctx);
485 bool Inst_TaskStackGet(cAvidaContext& ctx);
486 bool Inst_TaskStackLoad(cAvidaContext& ctx);
487 bool Inst_TaskPut(cAvidaContext& ctx);
488 bool Inst_TaskPutResetInputs(cAvidaContext& ctx);
489 bool Inst_TaskIO(cAvidaContext& ctx);
490 bool Inst_TaskIO_Feedback(cAvidaContext& ctx);
491 bool Inst_TaskIO_BonusCost(cAvidaContext& ctx, double bonus_cost);
Inst_TaskIO_BonusCost_0_001(cAvidaContext & ctx)492 bool Inst_TaskIO_BonusCost_0_001(cAvidaContext& ctx) { return Inst_TaskIO_BonusCost(ctx, 0.001); };
493 bool Inst_MatchStrings(cAvidaContext& ctx);
494 bool Inst_Sell(cAvidaContext& ctx);
495 bool Inst_Buy(cAvidaContext& ctx);
496 bool Inst_Send(cAvidaContext& ctx);
497 bool Inst_Receive(cAvidaContext& ctx);
498 bool Inst_SenseLog2(cAvidaContext& ctx);
499 bool Inst_SenseUnit(cAvidaContext& ctx);
500 bool Inst_SenseMult100(cAvidaContext& ctx);
501 bool DoSense(cAvidaContext& ctx, int conversion_method, double base);
502 bool DoSenseResourceX(int reg_to_set, int cell_id, int resid, cAvidaContext& ctx);
503 bool Inst_SenseResource0(cAvidaContext& ctx);
504 bool Inst_SenseResource1(cAvidaContext& ctx);
505 bool Inst_SenseResource2(cAvidaContext& ctx);
506 bool Inst_SenseFacedResource0(cAvidaContext& ctx);
507 bool Inst_SenseFacedResource1(cAvidaContext& ctx);
508 bool Inst_SenseFacedResource2(cAvidaContext& ctx);
509 bool Inst_SenseResourceID(cAvidaContext& ctx);
510 // Resources of next group +1 or -1, based on positive or negative value in the nop register,
511 // wrapping from the top group back to group 1 (skipping 0).
512 bool Inst_SenseNextResLevel(cAvidaContext& ctx);
513 bool Inst_SenseOpinionResourceQuantity(cAvidaContext& ctx);
514 bool Inst_SenseDiffFaced(cAvidaContext& ctx);
515 bool Inst_SenseFacedHabitat(cAvidaContext& ctx);
516
517 // Resources
518 int FindModifiedResource(cAvidaContext& ctx, int& spec_id);
519 bool DoCollect(cAvidaContext& ctx, bool env_remove, bool internal_add, bool probabilistic, bool unit);
520 bool DoActualCollect(cAvidaContext& ctx, int bin_used, bool env_remove, bool internal_add, bool probabilistic, bool unit);
521 bool Inst_Collect(cAvidaContext& ctx);
522 bool Inst_CollectNoEnvRemove(cAvidaContext& ctx);
523 bool Inst_Destroy(cAvidaContext& ctx);
524 bool Inst_NopCollect(cAvidaContext& ctx);
525 bool Inst_CollectUnitProbabilistic(cAvidaContext& ctx);
526 bool Inst_CollectSpecific(cAvidaContext& ctx);
527 bool Inst_DonateSpecific(cAvidaContext& ctx);
528 bool Inst_CheckFacedKin(cAvidaContext& ctx);
529 bool Inst_SetBeggar(cAvidaContext& ctx);
530 bool Inst_CheckFacedBeggar(cAvidaContext& ctx);
531 bool Inst_IfFacedKin(cAvidaContext& ctx);
532 bool Inst_IfFacedBeggar(cAvidaContext& ctx);
533 bool Inst_IfResources(cAvidaContext& ctx); //! Execute the following instruction if all resources are above their min level.
534 bool Inst_IfFacedBeggarAndNeedResource(cAvidaContext& ctx);
535 bool Inst_IfFacedBeggarAndKin(cAvidaContext& ctx);
536 bool Inst_IfFacedKinAndNeedResource(cAvidaContext& ctx);
537 bool Inst_IfFacedNeedResource(cAvidaContext& ctx);
538 bool Inst_IfFacedKinAndBeggarAndNeedResource(cAvidaContext& ctx);
539 bool Inst_IfFacedKinAndBeggarAndNeedResourceThenDonate(cAvidaContext& ctx);
540 bool Inst_IfFacedBeggarANdNeedsResourceThenDonate(cAvidaContext& ctx);
541 bool Inst_FailIfEmpty(cAvidaContext& ctx);
542 // Donation
543 void DoDonate(cOrganism * to_org);
544 void DoEnergyDonate(cOrganism* to_org);
545 void DoEnergyDonatePercent(cOrganism* to_org, const double frac_energy_given);
546 void DoEnergyDonateAmount(cOrganism* to_org, const double amount);
547 bool Inst_DonateRandom(cAvidaContext& ctx);
548 bool Inst_DonateKin(cAvidaContext& ctx);
549 bool Inst_DonateEditDist(cAvidaContext& ctx);
550 bool Inst_DonateGreenBeardGene(cAvidaContext& ctx);
551 bool Inst_DonateTrueGreenBeard(cAvidaContext& ctx);
552 bool Inst_DonateShadedGreenBeard(cAvidaContext& ctx);
553 bool Inst_DonateThreshGreenBeard(cAvidaContext& ctx);
554 bool Inst_DonateQuantaThreshGreenBeard(cAvidaContext& ctx);
555 bool Inst_DonateGreenBeardSameLocus(cAvidaContext& ctx);
556 bool Inst_DonateNULL(cAvidaContext& ctx);
557 bool Inst_DonateFacing(cAvidaContext& ctx);
558 bool Inst_ReceiveDonatedEnergy(cAvidaContext& ctx);
559 bool Inst_DonateEnergy(cAvidaContext& ctx);
560 bool Inst_UpdateMetabolicRate(cAvidaContext& ctx);
561 bool Inst_DonateEnergyFaced(cAvidaContext& ctx);
562 bool Inst_DonateEnergyFaced1(cAvidaContext& ctx);
563 bool Inst_DonateEnergyFaced2(cAvidaContext& ctx);
564 bool Inst_DonateEnergyFaced5(cAvidaContext& ctx);
565 bool Inst_DonateEnergyFaced10(cAvidaContext& ctx);
566 bool Inst_DonateEnergyFaced20(cAvidaContext& ctx);
567 bool Inst_DonateEnergyFaced50(cAvidaContext& ctx);
568 bool Inst_DonateEnergyFaced100(cAvidaContext& ctx);
569 bool Inst_RotateToMostNeedy(cAvidaContext& ctx);
570 bool Inst_RequestEnergy(cAvidaContext& ctx);
571 bool Inst_RequestEnergyFlagOn(cAvidaContext& ctx);
572 bool Inst_RequestEnergyFlagOff(cAvidaContext& ctx);
573 bool Inst_IncreaseEnergyDonation(cAvidaContext& ctx);
574 bool Inst_DecreaseEnergyDonation(cAvidaContext& ctx);
575
576 void DoResourceDonatePercent(cAvidaContext& ctx, const int to_cell, const int resource_id, const double frac_resource_given);
577 void DoResourceDonateAmount(cAvidaContext& ctx, const int to_cell, const int resource_id, const double amount);
578 bool DonateResourceX(cAvidaContext& ctx, const int res_id);
579 bool Inst_DonateResource0(cAvidaContext& ctx);
580 bool Inst_DonateResource1(cAvidaContext& ctx);
581 bool Inst_DonateResource2(cAvidaContext& ctx);
582
583 bool Inst_SearchF(cAvidaContext& ctx);
584 bool Inst_SearchB(cAvidaContext& ctx);
585 bool Inst_MemSize(cAvidaContext& ctx);
586
587 bool Inst_IOBufAdd1(cAvidaContext& ctx);
588 bool Inst_IOBufAdd0(cAvidaContext& ctx);
589
590 // Environment
591
592 bool Inst_RotateL(cAvidaContext& ctx);
593 bool Inst_RotateR(cAvidaContext& ctx);
594 bool Inst_RotateLeftOne(cAvidaContext& ctx);
595 bool Inst_RotateRightOne(cAvidaContext& ctx);
596 bool Inst_RotateLabel(cAvidaContext& ctx);
597 bool Inst_RotateOccupiedCell(cAvidaContext& ctx);
598 bool Inst_RotateNextOccupiedCell(cAvidaContext& ctx);
599 bool Inst_RotateUnoccupiedCell(cAvidaContext& ctx);
600 bool Inst_RotateNextUnoccupiedCell(cAvidaContext& ctx);
601 bool Inst_RotateEventCell(cAvidaContext& ctx);
602 bool Inst_RotateUphill(cAvidaContext& ctx);
603 bool Inst_RotateHome(cAvidaContext& ctx);
604 bool Inst_SetCopyMut(cAvidaContext& ctx);
605 bool Inst_ModCopyMut(cAvidaContext& ctx);
606 bool Inst_GetCellPosition(cAvidaContext& ctx);
607 bool Inst_GetCellPositionX(cAvidaContext& ctx);
608 bool Inst_GetCellPositionY(cAvidaContext& ctx);
609 bool Inst_GetDirectionOffNorth(cAvidaContext& ctx);
610 bool Inst_GetNortherly(cAvidaContext& ctx);
611 bool Inst_GetEasterly(cAvidaContext& ctx);
612 bool Inst_ZeroEasterly(cAvidaContext& ctx);
613 bool Inst_ZeroNortherly(cAvidaContext& ctx);
614
615 // State Grid Sensory/Movement
616 bool Inst_SGMove(cAvidaContext& ctx);
617 bool Inst_SGRotateL(cAvidaContext& ctx);
618 bool Inst_SGRotateR(cAvidaContext& ctx);
619 bool Inst_SGSense(cAvidaContext& ctx);
620
621 bool Inst_GetDistanceFromDiagonal(cAvidaContext& ctx);
622 bool Inst_Tumble(cAvidaContext& ctx);
623 bool Inst_Move(cAvidaContext& ctx);
624 bool Inst_MoveToEvent(cAvidaContext& ctx);
625 bool Inst_IfNeighborEventInUnoccupiedCell(cAvidaContext& ctx);
626 bool Inst_IfFacingEventCell(cAvidaContext& ctx);
627 bool Inst_IfEventInCell(cAvidaContext& ctx);
628
629 // Multi-threading...
630
631 bool Inst_ForkThread(cAvidaContext& ctx);
632 bool Inst_ForkThreadLabel(cAvidaContext& ctx);
633 bool Inst_ForkThreadLabelIf0(cAvidaContext& ctx);
634 bool Inst_ForkThreadLabelIfNot0(cAvidaContext& ctx);
635 bool Inst_KillThread(cAvidaContext& ctx);
636 bool Inst_ThreadID(cAvidaContext& ctx);
637
638 // Head-based instructions...
639
640 bool Inst_SetHead(cAvidaContext& ctx);
641 bool Inst_AdvanceHead(cAvidaContext& ctx);
642 bool Inst_MoveHead(cAvidaContext& ctx);
643 bool Inst_ResMoveHead(cAvidaContext& ctx);
644 bool Inst_JumpHead(cAvidaContext& ctx);
645 bool Inst_ResJumpHead(cAvidaContext& ctx);
646 bool Inst_GetHead(cAvidaContext& ctx);
647 bool Inst_IfLabel(cAvidaContext& ctx);
648 bool Inst_IfLabelDirect(cAvidaContext& ctx);
649 bool Inst_IfLabel2(cAvidaContext& ctx);
650 bool Inst_HeadDivide(cAvidaContext& ctx);
651 bool Inst_HeadDivideRS(cAvidaContext& ctx); //AWC 06/29/06
652 bool Inst_HeadDivide1RS(cAvidaContext& ctx); //AWC 07/28/06
653 bool Inst_HeadDivide2RS(cAvidaContext& ctx); //AWC 08/29/06
654 bool Inst_HeadRead(cAvidaContext& ctx);
655 bool Inst_HeadWrite(cAvidaContext& ctx);
656 bool Inst_HeadCopy(cAvidaContext& ctx);
657 bool Inst_HeadSearch(cAvidaContext& ctx);
658 bool Inst_HeadSearchDirect(cAvidaContext& ctx);
659 bool Inst_SetFlow(cAvidaContext& ctx);
660
661 bool Inst_HeadCopy2(cAvidaContext& ctx);
662 bool Inst_HeadCopy3(cAvidaContext& ctx);
663 bool Inst_HeadCopy4(cAvidaContext& ctx);
664 bool Inst_HeadCopy5(cAvidaContext& ctx);
665 bool Inst_HeadCopy6(cAvidaContext& ctx);
666 bool Inst_HeadCopy7(cAvidaContext& ctx);
667 bool Inst_HeadCopy8(cAvidaContext& ctx);
668 bool Inst_HeadCopy9(cAvidaContext& ctx);
669 bool Inst_HeadCopy10(cAvidaContext& ctx);
670
671 bool Inst_HeadDivideSex(cAvidaContext& ctx);
672 bool Inst_HeadDivideAsex(cAvidaContext& ctx);
673 bool Inst_HeadDivideAsexWait(cAvidaContext& ctx);
674 bool Inst_HeadDivideMateSelect(cAvidaContext& ctx);
675
676 bool Inst_HeadDivide1(cAvidaContext& ctx);
677 bool Inst_HeadDivide2(cAvidaContext& ctx);
678 bool Inst_HeadDivide3(cAvidaContext& ctx);
679 bool Inst_HeadDivide4(cAvidaContext& ctx);
680 bool Inst_HeadDivide5(cAvidaContext& ctx);
681 bool Inst_HeadDivide6(cAvidaContext& ctx);
682 bool Inst_HeadDivide7(cAvidaContext& ctx);
683 bool Inst_HeadDivide8(cAvidaContext& ctx);
684 bool Inst_HeadDivide9(cAvidaContext& ctx);
685 bool Inst_HeadDivide10(cAvidaContext& ctx);
686 bool Inst_HeadDivide16(cAvidaContext& ctx);
687 bool Inst_HeadDivide32(cAvidaContext& ctx);
688 bool Inst_HeadDivide50(cAvidaContext& ctx);
689 bool Inst_HeadDivide100(cAvidaContext& ctx);
690 bool Inst_HeadDivide500(cAvidaContext& ctx);
691 bool Inst_HeadDivide1000(cAvidaContext& ctx);
692 bool Inst_HeadDivide5000(cAvidaContext& ctx);
693 bool Inst_HeadDivide10000(cAvidaContext& ctx);
694 bool Inst_HeadDivide50000(cAvidaContext& ctx);
695 bool Inst_HeadDivide0_5(cAvidaContext& ctx);
696 bool Inst_HeadDivide0_1(cAvidaContext& ctx);
697 bool Inst_HeadDivide0_05(cAvidaContext& ctx);
698 bool Inst_HeadDivide0_01(cAvidaContext& ctx);
699 bool Inst_HeadDivide0_001(cAvidaContext& ctx);
700
701 bool Inst_IfEnergyLow(cAvidaContext& ctx);
702 bool Inst_IfEnergyNotLow(cAvidaContext& ctx);
703 bool Inst_IfFacedEnergyLow(cAvidaContext& ctx);
704 bool Inst_IfFacedEnergyNotLow(cAvidaContext& ctx);
705 bool Inst_IfEnergyHigh(cAvidaContext& ctx);
706 bool Inst_IfEnergyNotHigh(cAvidaContext& ctx);
707 bool Inst_IfFacedEnergyHigh(cAvidaContext& ctx);
708 bool Inst_IfFacedEnergyNotHigh(cAvidaContext& ctx);
709 bool Inst_IfEnergyMed(cAvidaContext& ctx);
710 bool Inst_IfFacedEnergyMed(cAvidaContext& ctx);
711 bool Inst_IfFacedEnergyMore(cAvidaContext& ctx);
712 bool Inst_IfFacedEnergyLess(cAvidaContext& ctx);
713 bool Inst_IfEnergyInBuffer(cAvidaContext& ctx);
714 bool Inst_IfEnergyNotInBuffer(cAvidaContext& ctx);
715 bool Inst_GetEnergyLevel(cAvidaContext& ctx);
716 bool Inst_GetFacedEnergyLevel(cAvidaContext& ctx);
717 bool Inst_IfFacedEnergyRequestOn(cAvidaContext& ctx);
718 bool Inst_IfFacedEnergyRequestOff(cAvidaContext& ctx);
719 bool Inst_GetEnergyRequestStatus(cAvidaContext& ctx);
720 bool Inst_GetFacedEnergyRequestStatus(cAvidaContext& ctx);
721
722
723
724 bool Inst_Sleep(cAvidaContext& ctx);
725 bool Inst_GetUpdate(cAvidaContext& ctx);
726
727 //// Promoter Model ////
728 bool Inst_Promoter(cAvidaContext& ctx);
729 bool Inst_Terminate(cAvidaContext& ctx);
730 bool Inst_Regulate(cAvidaContext& ctx);
731 bool Inst_RegulateSpecificPromoters(cAvidaContext& ctx);
732 bool Inst_SenseRegulate(cAvidaContext& ctx);
Inst_Numberate(cAvidaContext & ctx)733 bool Inst_Numberate(cAvidaContext& ctx) { return Do_Numberate(ctx); };
Inst_Numberate24(cAvidaContext & ctx)734 bool Inst_Numberate24(cAvidaContext& ctx) { return Do_Numberate(ctx, 24); };
735 bool Do_Numberate(cAvidaContext& ctx, int num_bits=0);
736
737 // Helper functions //
738 bool IsActivePromoter();
739 void NextPromoter();
740 int Numberate(int _pos, int _dir, int _num_bits = 0);
741
742 //// Bit consensus functions ////
743 inline unsigned int BitCount(unsigned int value) const;
744 bool Inst_BitConsensus(cAvidaContext& ctx);
745 bool Inst_BitConsensus24(cAvidaContext& ctx);
746 bool Inst_IfConsensus(cAvidaContext& ctx);
747 bool Inst_IfConsensus24(cAvidaContext& ctx);
748 bool Inst_IfLessConsensus(cAvidaContext& ctx);
749 bool Inst_IfLessConsensus24(cAvidaContext& ctx);
750
751 // Bit masking instructions
752 bool Inst_MaskSignBit(cAvidaContext& ctx);
753 bool Inst_MaskOffLower16Bits(cAvidaContext& ctx);
754 bool Inst_MaskOffLower16Bits_defaultAX(cAvidaContext& ctx);
755 bool Inst_MaskOffLower15Bits(cAvidaContext& ctx);
756 bool Inst_MaskOffLower15Bits_defaultAX(cAvidaContext& ctx);
757 bool Inst_MaskOffLower14Bits(cAvidaContext& ctx);
758 bool Inst_MaskOffLower14Bits_defaultAX(cAvidaContext& ctx);
759 bool Inst_MaskOffLower13Bits(cAvidaContext& ctx);
760 bool Inst_MaskOffLower13Bits_defaultAX(cAvidaContext& ctx);
761 bool Inst_MaskOffLower12Bits(cAvidaContext& ctx);
762 bool Inst_MaskOffLower12Bits_defaultAX(cAvidaContext& ctx);
763 bool Inst_MaskOffLower8Bits(cAvidaContext& ctx);
764 bool Inst_MaskOffLower8Bits_defaultAX(cAvidaContext& ctx);
765 bool Inst_MaskOffLower4Bits(cAvidaContext& ctx);
766 bool Inst_MaskOffLower4Bits_defaultAX(cAvidaContext& ctx);
767
768 //// Messaging ////
769 bool Inst_SendMessage(cAvidaContext& ctx);
770 bool SendMessage(cAvidaContext& ctx, int messageType = 0);
771 bool Inst_RetrieveMessage(cAvidaContext& ctx);
772 bool BroadcastX(cAvidaContext& ctx, int depth);
773 bool Inst_Broadcast1(cAvidaContext& ctx);
774 bool Inst_Broadcast2(cAvidaContext& ctx);
775 bool Inst_Broadcast4(cAvidaContext& ctx);
776 bool Inst_Broadcast8(cAvidaContext& ctx);
777
778 // Active messaging //
779 bool Inst_SendMessageInterruptType0(cAvidaContext& ctx);
780 bool Inst_SendMessageInterruptType1(cAvidaContext& ctx);
781 bool Inst_SendMessageInterruptType2(cAvidaContext& ctx);
782 bool Inst_SendMessageInterruptType3(cAvidaContext& ctx);
783 bool Inst_SendMessageInterruptType4(cAvidaContext& ctx);
784 bool Inst_SendMessageInterruptType5(cAvidaContext& ctx);
785 bool Inst_START_Handler(cAvidaContext& ctx);
786 bool Inst_End_Handler(cAvidaContext& ctx);
787
788 //// Alarm ////
789 bool Inst_Alarm_MSG_local(cAvidaContext& ctx);
790 bool Inst_Alarm_MSG_multihop(cAvidaContext& ctx);
791 bool Inst_Alarm_MSG_Bit_Cons24_local(cAvidaContext& ctx);
792 bool Inst_Alarm_MSG_Bit_Cons24_multihop(cAvidaContext& ctx);
793 bool Inst_Alarm_Label(cAvidaContext& ctx);
794 bool Jump_To_Alarm_Label(int jump_label);
795
796
797 // -------- Reputation support --------
798 /* These instructions interact with the "reputation" support in cOrganism.h. They
799 are based on the donate instructions. However, these instructions donate
800 "raw materials" rather than merit and will eventually be used to support
801 reputation based cooperation.
802 */
803 // Donate a raw material to the neighbor
804 bool Inst_DonateFacingRawMaterials(cAvidaContext& ctx);
805 // Donate a raw material to the neighbor if it is another species
806 bool Inst_DonateFacingRawMaterialsOtherSpecies(cAvidaContext& ctx);
807 // Donate a raw material to the neighbor if it was a prior donor
808 bool Inst_DonateIfDonor(cAvidaContext& ctx);
809 // Donate a string to the neighbor, if it's reputation is > 0
810 bool Inst_DonateStringIfDonorRep(cAvidaContext& ctx);
811 // Donate a string to a neighbor
812 bool Inst_DonateFacingString(cAvidaContext& ctx);
813
814 // Rotate to the organims with the greatest reputation
815 bool Inst_RotateToGreatestReputation(cAvidaContext& ctx);
816 // Rotate to the organims with the greatest reputation that has a different tag
817 bool Inst_RotateToGreatestReputationWithDifferentTag(cAvidaContext& ctx);
818 // Rotate to the organims with the greatest reputation that has a different tag
819 bool Inst_RotateToGreatestReputationWithDifferentLineage(cAvidaContext& ctx);
820 // Rotate to an organim with a different tag
821 bool Inst_RotateToDifferentTag(cAvidaContext& ctx);
822 // Rotate to the organims with the greatest reputation and donate
823 bool Inst_RotateToGreatestReputationAndDonate(cAvidaContext& ctx);
824 // Get a neighbor's reputation
825 bool Inst_GetNeighborsReputation(cAvidaContext& ctx);
826 // Get the organism's reputation
827 bool Inst_GetReputation(cAvidaContext& ctx);
828 // Execute the following instruction if the facing neighbor was a donor
829 bool Inst_IfDonor(cAvidaContext& ctx);
830 // Produce string
831 bool Inst_ProduceString(cAvidaContext& ctx);
832 // Get the organism's raw material level
833 bool Inst_GetAmountOfRawMaterials(cAvidaContext& ctx);
834 // Get the number of raw materials the organism
835 // has gotten from others
836 bool Inst_GetAmountOfOtherRawMaterials(cAvidaContext& ctx);
837 // Pretend to donate
838 bool Inst_Pose(cAvidaContext& ctx);
839
840 // Reputation
841 void ComputeReputation();
842
843
844 //// Placebo ////
845 bool Inst_Skip(cAvidaContext& ctx);
846
847 // @BDC Additions for pheromones
848 bool Inst_PheroOn(cAvidaContext& ctx);
849 bool Inst_PheroOff(cAvidaContext& ctx);
850 bool Inst_PheroToggle(cAvidaContext& ctx);
851 bool DoSenseFacing(cAvidaContext& ctx, int conversion_method, double base);
852 bool Inst_SenseLog2Facing(cAvidaContext& ctx);
853 bool Inst_SenseUnitFacing(cAvidaContext& ctx);
854 bool Inst_SenseMult100Facing(cAvidaContext& ctx);
855 bool Inst_SenseTarget(cAvidaContext& ctx);
856 bool Inst_SenseTargetFaced(cAvidaContext& ctx);
857 bool DoSensePheromone(cAvidaContext& ctx, int cellid);
858 bool DoSensePheromoneInDemeGlobal(cAvidaContext& ctx, tRegisters REG_DEFAULT);
859 bool DoSensePheromoneGlobal(cAvidaContext& ctx, tRegisters REG_DEFAULT);
860 bool Inst_SensePheromone(cAvidaContext& ctx);
861 bool Inst_SensePheromoneFaced(cAvidaContext& ctx);
862 bool Inst_SensePheromoneInDemeGlobal(cAvidaContext& ctx);
863 bool Inst_SensePheromoneGlobal(cAvidaContext& ctx);
864 bool Inst_SensePheromoneGlobal_defaultAX(cAvidaContext& ctx);
865 bool Inst_Exploit(cAvidaContext& ctx);
866 bool Inst_ExploitForward5(cAvidaContext& ctx);
867 bool Inst_ExploitForward3(cAvidaContext& ctx);
868 bool Inst_Explore(cAvidaContext& ctx);
869 bool Inst_MoveTarget(cAvidaContext& ctx);
870 bool Inst_MoveTargetForward5(cAvidaContext& ctx);
871 bool Inst_MoveTargetForward3(cAvidaContext& ctx);
872 bool Inst_SuperMove(cAvidaContext& ctx);
873 bool Inst_IfTarget(cAvidaContext& ctx);
874 bool Inst_IfNotTarget(cAvidaContext& ctx);
875 bool Inst_IfPheromone(cAvidaContext& ctx);
876 bool Inst_IfNotPheromone(cAvidaContext& ctx);
877 bool Inst_DropPheromone(cAvidaContext& ctx);
878
879 // -------- Opinion support --------
880 public:
881 /* These instructions interact with the "opinion" support in cOrganism.h. The
882 idea is that we're enabling organisms to express an opinion about *something*,
883 where that something is defined by the particular tasks and/or (deme) fitness function
884 in use. This may have to be extended in the future to support different kinds of
885 opinions that can be expressed during the same experiment, and possibly augmented
886 with a "strength" of that opinion (but not right now).
887 */
888 bool Inst_SetOpinion(cAvidaContext& ctx);
889 bool Inst_GetOpinion(cAvidaContext& ctx);
890 //! Only get opinion. If none then reg is set to zero
891 bool Inst_GetOpinionOnly_ZeroIfNone(cAvidaContext& ctx);
892 //! Clear this organism's current opinion.
893 bool Inst_ClearOpinion(cAvidaContext& ctx);
894 //! Execute next instruction is org has an opinion, otherwise skip
895 bool Inst_IfOpinionSet(cAvidaContext& ctx);
896 bool Inst_IfOpinionNotSet(cAvidaContext& ctx);
897 bool Inst_SetOpinionToZero(cAvidaContext& ctx);
898 bool Inst_SetOpinionToOne(cAvidaContext& ctx);
899 bool Inst_SetOpinionToTwo(cAvidaContext& ctx);
900
901
902 // -------- Cell Data Support --------
903 public:
904 //! Collect this cell's data, and place it in a register.
905 bool Inst_CollectCellData(cAvidaContext& ctx);
906 //! Detect if this cell's data has changed since the last collection.
907 bool Inst_IfCellDataChanged(cAvidaContext& ctx);
908 bool Inst_KillCellEvent(cAvidaContext& ctx);
909 bool Inst_KillFacedCellEvent(cAvidaContext& ctx);
910 bool Inst_CollectCellDataAndKillEvent(cAvidaContext& ctx);
911 bool Inst_ReadCellData(cAvidaContext& ctx);
912 bool Inst_ReadFacedCellData(cAvidaContext& ctx);
913 bool Inst_ReadFacedCellDataOrgID(cAvidaContext& ctx);
914 bool Inst_ReadFacedCellDataFreshness(cAvidaContext& ctx);
915 bool Inst_MarkCellWithID(cAvidaContext& ctx);
916 bool Inst_MarkCellWithVitality(cAvidaContext& ctx);
917 bool Inst_GetResStored(cAvidaContext& ctx);
918 bool Inst_GetID(cAvidaContext& ctx);
919 bool Inst_GetFacedVitalityDiff(cAvidaContext& ctx);
920 bool Inst_GetFacedOrgID(cAvidaContext& ctx);
921 bool Inst_AttackFacedOrg(cAvidaContext& ctx);
922 bool Inst_GetAttackOdds(cAvidaContext& ctx);
923
924 private:
925 std::pair<bool, int> m_last_cell_data; //<! If cell data has been previously collected, and it's value.
926
927 // -------- Synchronization primitives --------
928 public:
929 //! Called when the owning organism receives a flash from a neighbor.
930 virtual void ReceiveFlash();
931 //! Sends a "flash" to all neighboring organisms.
932 bool Inst_Flash(cAvidaContext& ctx);
933 //! Test if this organism has ever received a flash.
934 bool Inst_IfRecvdFlash(cAvidaContext& ctx);
935 //! Get if & when this organism last received a flash.
936 bool Inst_FlashInfo(cAvidaContext& ctx);
937 //! Get if (but not when) this organism last received a flash.
938 bool Inst_FlashInfoB(cAvidaContext& ctx);
939 //! Reset the information this organism has regarding receiving a flash.
940 bool Inst_ResetFlashInfo(cAvidaContext& ctx);
941 //! Reset the entire CPU.
942 bool Inst_HardReset(cAvidaContext& ctx);
943 //! Current "time": the number of cycles this CPU has been "alive."
944 bool Inst_GetCycles(cAvidaContext& ctx);
945
946 private:
947 /*! Used to track the last flash received; first=whether we've received a flash,
948 second= #cycles since we've received a flash, or 0 if we haven't. */
949 std::pair<unsigned int, unsigned int> m_flash_info;
950 //! Cycle timer; counts the number of cycles this virtual CPU has executed.
951 unsigned int m_cycle_counter;
952
953 // -------- Neighborhood-sensing support --------
954 public:
955 //! Loads the current neighborhood into the organism's memory.
956 bool Inst_GetNeighborhood(cAvidaContext& ctx);
957 //! Test if the current neighborhood has changed from that in the organism's memory.
958 bool Inst_IfNeighborhoodChanged(cAvidaContext& ctx);
959
960
961 // -------- Group Formation Support --------
962 public:
963 //! An organism joins a group by setting it opinion to the group id.
964 bool Inst_JoinGroup(cAvidaContext& ctx);
965 bool Inst_JoinMTGroup(cAvidaContext& ctx);
966 // Organism joins group +1 or -1 wrapping from the top group back to group 1 (skipping 0)
967 // based on whether the nop register is positive or negative.
968 bool Inst_JoinNextGroup(cAvidaContext& ctx);
969 bool Inst_JoinNextMTGroup(cAvidaContext& ctx);
970 //! Returns the number of organisms in the current organism's group
971 bool Inst_NumberOrgsInMyGroup(cAvidaContext& ctx);
972 bool Inst_NumberMTInMyGroup(cAvidaContext& ctx);
973 //! Returns the number of organisms in the current organism's group
974 bool Inst_NumberOrgsInGroup(cAvidaContext& ctx);
975 bool Inst_NumberMTInGroup(cAvidaContext& ctx);
976 // Places in BX register, the number of organisms in the group +1 or -1, wrapping from the top back to group 1
977 // skipping 0, based on whether the nop register is positive or negative.
978 bool Inst_NumberNextGroup(cAvidaContext& ctx);
979 bool Inst_NumberMTNextGroup(cAvidaContext& ctx);
980 bool Inst_KillGroupMember(cAvidaContext& ctx);
981
982 bool Inst_IncTolerance(cAvidaContext& ctx);
983 bool Inst_DecTolerance(cAvidaContext& ctx);
984 bool Inst_GetTolerance(cAvidaContext& ctx);
985 bool Inst_GetGroupTolerance(cAvidaContext& ctx);
986
987 // -------- Network creation support --------
988 public:
989 //! Create a link to the currently-faced cell.
990 bool Inst_CreateLinkByFacing(cAvidaContext& ctx);
991 //! Create a link to the cell specified by xy-coordinates.
992 bool Inst_CreateLinkByXY(cAvidaContext& ctx);
993 //! Create a link to the cell specified by index.
994 bool Inst_CreateLinkByIndex(cAvidaContext& ctx);
995 //! Broadcast a message in the communication network.
996 bool Inst_NetworkBroadcast1(cAvidaContext& ctx);
997 //! Unicast a message in the communication network.
998 bool Inst_NetworkUnicast(cAvidaContext& ctx);
999 //! Rotate the current active link by the contents of register ?BX?.
1000 bool Inst_NetworkRotate(cAvidaContext& ctx);
1001 //! Select the current active link from the contents of register ?BX?.
1002 bool Inst_NetworkSelect(cAvidaContext& ctx);
1003
1004
1005 // -------- Division of labor support --------
1006 bool Inst_GetTimeUsed(cAvidaContext& ctx);
1007 bool Inst_DonateResToDeme(cAvidaContext& ctx);
1008 // If there is a penalty for switching tasks, call this function and
1009 // the additional cycle cost will be added.
1010 void IncrementTaskSwitchingCost(int cost);
GetTaskSwitchingCost()1011 int GetTaskSwitchingCost() { return m_task_switching_cost; }
1012 // Apply point mutations to a genome.
1013 bool Inst_ApplyPointMutations(cAvidaContext& ctx);
1014 // Apply point mutations to a genome, where the mutation rate
1015 // depends on the task last performed
1016 bool Inst_ApplyVaryingPointMutations(cAvidaContext& ctx);
1017 // Apply point mutations to a genome in the deme with the same
1018 // germ/soma status
1019 bool Inst_ApplyPointMutationsGroupGS(cAvidaContext& ctx);
1020 // Apply point mutations to a genome in the deme at random
1021 bool Inst_ApplyPointMutationsGroupRandom(cAvidaContext& ctx);
1022
1023 bool Inst_JoinGermline(cAvidaContext& ctx);
1024 bool Inst_ExitGermline(cAvidaContext& ctx);
1025 bool Inst_RepairPointMutOn(cAvidaContext& ctx);
1026 bool Inst_RepairPointMutOff(cAvidaContext& ctx);
1027
1028
1029 // -------- Mating types support support --------
1030 public:
1031 bool Inst_SetMatingTypeMale(cAvidaContext& ctx);
1032 bool Inst_SetMatingTypeFemale(cAvidaContext& ctx);
1033 bool Inst_SetMatingTypeJuvenile(cAvidaContext& ctx);
1034 bool Inst_DivideSexMatingType(cAvidaContext& ctx);
1035 bool Inst_IfMatingTypeMale(cAvidaContext& ctx);
1036 bool Inst_IfMatingTypeFemale(cAvidaContext& ctx);
1037 bool Inst_IfMatingTypeJuvenile(cAvidaContext& ctx);
1038 bool Inst_IncrementMatingDisplayA(cAvidaContext& ctx);
1039 bool Inst_IncrementMatingDisplayB(cAvidaContext& ctx);
1040 bool Inst_SetMatingDisplayA(cAvidaContext& ctx);
1041 bool Inst_SetMatingDisplayB(cAvidaContext& ctx);
1042 bool Inst_SetMatePreference(cAvidaContext& ctx, int mate_pref);
1043 bool Inst_SetMatePreferenceHighestDisplayA(cAvidaContext& ctx);
1044 bool Inst_SetMatePreferenceHighestDisplayB(cAvidaContext& ctx);
1045 bool Inst_SetMatePreferenceRandom(cAvidaContext& ctx);
1046 bool Inst_SetMatePreferenceHighestMerit(cAvidaContext& ctx);
1047 };
1048
1049
ThreadSelect(const int thread_num)1050 inline bool cHardwareCPU::ThreadSelect(const int thread_num)
1051 {
1052 if (thread_num >= 0 && thread_num < m_threads.GetSize()) {
1053 m_cur_thread = thread_num;
1054 return true;
1055 }
1056
1057 return false;
1058 }
1059
ThreadNext()1060 inline void cHardwareCPU::ThreadNext()
1061 {
1062 m_cur_thread++;
1063 if (m_cur_thread >= m_threads.GetSize()) m_cur_thread = 0;
1064 }
1065
ThreadPrev()1066 inline void cHardwareCPU::ThreadPrev()
1067 {
1068 if (m_cur_thread == 0) m_cur_thread = m_threads.GetSize() - 1;
1069 else m_cur_thread--;
1070 }
1071
StackPush(int value)1072 inline void cHardwareCPU::StackPush(int value)
1073 {
1074 if (m_threads[m_cur_thread].cur_stack == 0) {
1075 m_threads[m_cur_thread].stack.Push(value);
1076 } else {
1077 m_global_stack.Push(value);
1078 }
1079 }
1080
StackPop()1081 inline int cHardwareCPU::StackPop()
1082 {
1083 int pop_value;
1084
1085 if (m_threads[m_cur_thread].cur_stack == 0) {
1086 pop_value = m_threads[m_cur_thread].stack.Pop();
1087 } else {
1088 pop_value = m_global_stack.Pop();
1089 }
1090
1091 return pop_value;
1092 }
1093
StackFlip()1094 inline void cHardwareCPU::StackFlip()
1095 {
1096 if (m_threads[m_cur_thread].cur_stack == 0) {
1097 m_threads[m_cur_thread].stack.Flip();
1098 } else {
1099 m_global_stack.Flip();
1100 }
1101 }
1102
GetStack(int depth,int stack_id,int in_thread)1103 inline int cHardwareCPU::GetStack(int depth, int stack_id, int in_thread) const
1104 {
1105 int value = 0;
1106
1107 if(in_thread >= m_threads.GetSize() || in_thread < 0) in_thread = m_cur_thread;
1108
1109 if (stack_id == -1) stack_id = m_threads[in_thread].cur_stack;
1110
1111 if (stack_id == 0) value = m_threads[in_thread].stack.Get(depth);
1112 else if (stack_id == 1) value = m_global_stack.Get(depth);
1113
1114 return value;
1115 }
1116
StackClear()1117 inline void cHardwareCPU::StackClear()
1118 {
1119 if (m_threads[m_cur_thread].cur_stack == 0) {
1120 m_threads[m_cur_thread].stack.Clear();
1121 } else {
1122 m_global_stack.Clear();
1123 }
1124 }
1125
SwitchStack()1126 inline void cHardwareCPU::SwitchStack()
1127 {
1128 m_threads[m_cur_thread].cur_stack++;
1129 if (m_threads[m_cur_thread].cur_stack > 1) m_threads[m_cur_thread].cur_stack = 0;
1130 }
1131
1132 #endif
1133
1134
1135