private KnowledgeRule createRuleTree(IEnumerable <NodeReference> toCover, MultiTraceLog log)
        {
            var rule = createBestRule(toCover, log);

            if (rule == null)
            {
                return(null);
            }

            if (
                rule.InitialYesNodes.Count() == 0 ||
                rule.InitialNoNodes.Count() == 0
                )
            {
                //current rule doesn't provide any improvement
                return(rule);
            }


            if (!isClassConsistent(rule.InitialNoNodes))
            {
                rule.AddNoBranch(createRuleTree(rule.InitialNoNodes, log));
            }

            if (!isClassConsistent(rule.InitialYesNodes))
            {
                rule.AddYesBranch(createRuleTree(rule.InitialYesNodes, log));
            }

            return(rule);
        }
        internal void Retrain()
        {
            var log = new MultiTraceLog(_knownClassifications.Keys, Knowledge);

            Root = createRuleTree(new HashSet <NodeReference>(_knownClassifications.Keys), log);
        }
        private KnowledgeRule createBestRule(IEnumerable <NodeReference> classifiedNodes, MultiTraceLog log)
        {
            var       bestScore     = Double.NegativeInfinity;
            TraceNode bestTraceNode = null;
            Trace     bestTrace     = null;
            IEnumerable <NodeReference> bestCoverage = null;

            //find best classification rule
            foreach (var traceNode in log.TraceNodes)
            {
                var debug = traceNode.ToString();
                foreach (var trace in traceNode.Traces)
                {
                    var coverage     = trace.InitialNodes;
                    var currentScore = getClassificationScore(classifiedNodes, coverage, trace);
                    if (currentScore > bestScore)
                    {
                        bestCoverage  = coverage;
                        bestScore     = currentScore;
                        bestTraceNode = traceNode;
                        bestTrace     = trace;
                    }
                }
            }

            if (bestCoverage == null)
            {
                return(null);
            }

            var yesNodes = bestCoverage.Intersect(classifiedNodes);
            var noNodes  = classifiedNodes.Except(yesNodes);

            return(new KnowledgeRule(bestTraceNode.Path, bestTrace.CurrentNode, yesNodes, noNodes));
        }