public LGPInstruction Clone()
        {
            LGPInstruction clone = new LGPInstruction(mProgram);

            clone.mProgram             = mProgram;
            clone.mIsStructuralIntron  = mIsStructuralIntron;
            clone.mOperator            = mOperator;
            clone.mOperand1            = mOperand1;
            clone.mOperand2            = mOperand2;
            clone.mDestinationRegister = mDestinationRegister;
            return(clone);
        }
        public virtual double[] Execute(double [] register_values)
        {
            for (int i = 0; i < mRegisterSet.RegisterCount; ++i)
            {
                mRegisterSet.FindRegisterByIndex(i).Value = register_values[i % register_values.Length];
            }

            LGPOperator.OperatorExecutionStatus command  = LGPOperator.OperatorExecutionStatus.LGP_EXECUTE_NEXT_INSTRUCTION;
            LGPInstruction current_effective_instruction = null;
            LGPInstruction prev_effective_instruction    = null;

            foreach (LGPInstruction instruction in mInstructions)
            {
                if (instruction.IsStructuralIntron)
                {
                    continue;
                }
                prev_effective_instruction    = current_effective_instruction;
                current_effective_instruction = instruction;
                if (command == LGPOperator.OperatorExecutionStatus.LGP_EXECUTE_NEXT_INSTRUCTION)
                {
                    command = current_effective_instruction.Execute();
                }
                else
                {
                    // Xianshun says:
                    // as suggested in Linear Genetic Programming
                    // the condictional construct is restricted to single condictional construct
                    // an example of single conditional construct would be
                    // line 1: if(register[a])
                    // line 2: <action1>
                    // line 3: <action2>
                    // if register[a]==true, then <action1> and <action2> are executed
                    // if register[a]==false, then <action1> is skipped and <action2> is executed
                    // <action1> and <action2> are restricted to effective instruction
                    if (prev_effective_instruction.IsConditionalConstruct)
                    {
                        command = LGPOperator.OperatorExecutionStatus.LGP_EXECUTE_NEXT_INSTRUCTION;
                    }
                }
            }

            double[] outputs = new double[mRegisterSet.RegisterCount];
            for (int i = 0; i < outputs.Length; ++i)
            {
                outputs[i] = mRegisterSet.FindRegisterByIndex(i).Value;
            }
            return(outputs);
        }
        public void MutateInstructionRegister()
        {
            LGPInstruction selected_instruction = mInstructions[Statistics.DistributionModel.NextInt(InstructionCount)];
            double         p_const = 0;

            foreach (LGPInstruction instruction in mInstructions)
            {
                if (instruction.IsOperand1ConstantRegister || instruction.IsOperand2ConstantRegister)
                {
                    p_const += 1.0;
                }
            }
            p_const /= InstructionCount;
            selected_instruction.MutateRegister(p_const);
        }
        public virtual void Create(int size)
        {
            if (!mSetup)
            {
                Setup();
            }

            // Xianshun says:
            // In this method, the instruction created is not garanteed to be structurally effective
            for (int i = 0; i < size; ++i)
            {
                LGPInstruction instruction = new LGPInstruction(this);
                instruction.Create();
                mInstructions.Add(instruction);
            }
        }
        protected void ExecuteOnFitnessCase(LGPFitnessCase fitness_case)
        {
            mPop.InitializeProgramRegisters(this, fitness_case);

            LGPOperator.OperatorExecutionStatus command  = LGPOperator.OperatorExecutionStatus.LGP_EXECUTE_NEXT_INSTRUCTION;
            LGPInstruction current_effective_instruction = null;
            LGPInstruction prev_effective_instruction    = null;

            foreach (LGPInstruction instruction in mInstructions)
            {
                if (instruction.IsStructuralIntron)
                {
                    continue;
                }
                prev_effective_instruction    = current_effective_instruction;
                current_effective_instruction = instruction;
                if (command == LGPOperator.OperatorExecutionStatus.LGP_EXECUTE_NEXT_INSTRUCTION)
                {
                    command = current_effective_instruction.Execute();
                    fitness_case.ReportProgress(instruction.Operator, instruction.Operand1, instruction.Operand2, instruction.DestinationRegister, RegisterSet);
                }
                else
                {
                    // Xianshun says:
                    // as suggested in Linear Genetic Programming
                    // the condictional construct is restricted to single condictional construct
                    // an example of single conditional construct would be
                    // line 1: if(register[a])
                    // line 2: <action1>
                    // line 3: <action2>
                    // if register[a]==true, then <action1> and <action2> are executed
                    // if register[a]==false, then <action1> is skipped and <action2> is executed
                    // <action1> and <action2> are restricted to effective instruction
                    if (prev_effective_instruction.IsConditionalConstruct)
                    {
                        command = LGPOperator.OperatorExecutionStatus.LGP_EXECUTE_NEXT_INSTRUCTION;
                    }
                }
            }

            double[] outputs = new double[mRegisterSet.RegisterCount];
            for (int i = 0; i < outputs.Length; ++i)
            {
                outputs[i] = mRegisterSet.FindRegisterByIndex(i).Value;
            }
            fitness_case.RunLGPProgramCompleted(outputs);
        }
        /// <summary>
        /// this is derived from the micro mutation implementation in section
        /// 6.2.2 of Linear Genetic Programming
        /// 1. randomly select an (effective) instruction with a constant c
        /// 2. change constant c through a standard deviation from the current value
        /// c:=c + normal(mean:=0, standard_deviation)
        /// </summary>
        public void MutateInstructionConstant(Statistics.Gaussian guass)
        {
            LGPInstruction selected_instruction = null;

            foreach (LGPInstruction instruction in mInstructions)
            {
                if (!instruction.IsStructuralIntron && (instruction.IsOperand1ConstantRegister || instruction.IsOperand2ConstantRegister))
                {
                    if (selected_instruction == null)
                    {
                        selected_instruction = instruction;
                    }
                    else if (Statistics.DistributionModel.GetUniform() < 0.5)
                    {
                        selected_instruction = instruction;
                    }
                }
            }
            if (selected_instruction != null)
            {
                selected_instruction.MutateConstant(guass, MicroMutateConstantStandardDeviation);
            }
        }
        public void MutateInstructionOperator()
        {
            LGPInstruction instruction = mInstructions[Statistics.DistributionModel.NextInt(InstructionCount)];

            instruction.MutateOperator();
        }
        public void MarkStructuralIntrons(int stop_point, HashSet <int> Reff)
        {
            /*
             * Source: Brameier, M 2004  On Linear Genetic Programming (thesis)
             *
             * Algorithm 3.1 (detection of structural introns)
             * 1. Let set R_eff always contain all registers that are effective at the current program
             * position. R_eff := { r | r is output register }.
             * Start at the last program instruction and move backwards.
             * 2. Mark the next preceding operation in program with:
             * destination register r_dest element-of R_eff.
             * If such an instruction is not found then go to 5.
             * 3. If the operation directly follows a branch or a sequence of branches then mark these
             * instructions too. Otherwise remove r_dest from R_eff .
             * 4. Insert each source (operand) register r_op of newly marked instructions in R_eff
             * if not already contained. Go to 2.
             * 5. Stop. All unmarked instructions are introns.
             */

            // Xianshun says:
            // this is a variant of Algorithm 3.1 that run Algorithm 3.1 until stop_point and return the Reff at that stage

            int instruction_count = mInstructions.Count;

            for (int i = instruction_count - 1; i > stop_point; i--)
            {
                mInstructions[i].IsStructuralIntron = true;
            }

            Reff.Clear();
            int register_count = mPop.RegisterCount;

            for (int i = 0; i < register_count; ++i)
            {
                Reff.Add(i);
            }

            LGPInstruction current_instruction = null;
            LGPInstruction prev_instruction    = null;

            for (int i = instruction_count - 1; i > stop_point; i--)
            {
                prev_instruction    = current_instruction;
                current_instruction = mInstructions[i];
                // prev_instruction is not an structural intron and the current_instruction
                // is a condictional construct then, the current_instruction is not structural intron either
                // this directly follows from Step 3 of Algorithm 3.1
                if (current_instruction.IsConditionalConstruct && prev_instruction != null)
                {
                    if (!prev_instruction.IsStructuralIntron)
                    {
                        current_instruction.IsStructuralIntron = false;
                    }
                }
                else
                {
                    if (Reff.Contains(current_instruction.DestinationRegisterIndex))
                    {
                        current_instruction.IsStructuralIntron = false;
                        Reff.Remove(current_instruction.DestinationRegisterIndex);

                        if (!current_instruction.IsOperand1ConstantRegister)
                        {
                            Reff.Add(current_instruction.Operand1RegisterIndex);
                        }
                        if (!current_instruction.IsOperand2ConstantRegister)
                        {
                            Reff.Add(current_instruction.Operand2RegisterIndex);
                        }
                    }
                }
            }
        }