void submitTask(AdvancedAdaptiveLevinSearchProblem problem)
        {
            Observable levinSearchObservable = new Observable();

            levinSearchObservable.register(new AdvancedAdaptiveLevinSearchLogObserver(log));
            levinSearchObservable.register(this); // register ourself to know when the task failed or succeeded

            LevinSearchTask levinSearchTask = new LevinSearchTask(levinSearchObservable, database, problem);


            if (problem.humanReadableIndirectlyCallableProgramNames.Count > 0)
            {
                // query the problem for the hint
                Debug.Assert(problem.humanReadableIndirectlyCallableProgramNames.Count == 1, "Implemented for just one subproblem");
                var q = database.getQuery().whereHumanReadableProgramName(problem.humanReadableIndirectlyCallableProgramNames[0]);

                foreach (var iq in q.enumerable)
                {
                    Debug.Assert(iq.program != null, "Problem must have been already solved to be added as an indrectly callable program!");

                    levinSearchTask.problem.indirectCallablePrograms.Add(iq);
                }
            }


            scheduler.addTaskSync(levinSearchTask);

            levinSearchTask.levinSearchContext = new LevinSearchContext(problem);
            levinSearchTask.levinSearchContext.localInterpreterState.maxNumberOfRetiredInstructions = problem.maxNumberOfRetiredInstructions;
            fillUsedInstructionSet(levinSearchTask.levinSearchContext);
            levinSearchTask.levinSearchContext.initiateSearch(sparseArrayProgramDistribution, problem.enumerationMaxProgramLength);
        }
        // ignores if the # of ready problems is zero
        void tryToDequeueTaskAndSubmit()
        {
            if (problems.Count == 0)
            {
                return;
            }

            AdvancedAdaptiveLevinSearchProblem currentProblem = problems[0];

            problems.RemoveAt(0);
            submitTask(currentProblem);
        }
        public AdvancedAdaptiveLevinSearchProblem shallowCopy()
        {
            AdvancedAdaptiveLevinSearchProblem copied = new AdvancedAdaptiveLevinSearchProblem();

            copied.globalInitialArrayState = globalInitialArrayState;
            //copied.localInitialInterpreterState = localInitialInterpreterState;
            copied.trainingSamples                = trainingSamples;
            copied.enumerationMaxProgramLength    = enumerationMaxProgramLength;
            copied.instructionsetCount            = instructionsetCount;
            copied.maxNumberOfRetiredInstructions = maxNumberOfRetiredInstructions;
            copied.parentProgram      = parentProgram;
            copied.humanReadableHints = humanReadableHints;
            copied.humanReadableIndirectlyCallableProgramNames = humanReadableIndirectlyCallableProgramNames;
            copied.humanReadableTaskname = humanReadableTaskname;
            return(copied);
        }