private HashSet <NodeReference> findRemainingNodes(ConstraintPoolRule rule) { var pool = new ContextPool(Graph); //TODO optimize filling the pool pool.Insert(_originalRemainingNodes.ToArray()); rule.Execute(pool); //take only those remaining nodes which have been selected var remainingNodes = new HashSet <NodeReference>(pool.ActiveNodes); return(remainingNodes); }
private ConstraintPoolRule[] combineRules(ConstraintPoolRule[] combinationRule, ConstraintPoolRule[] ruleToCombine) { var result = new ConstraintPoolRule[combinationRule.Length + ruleToCombine.Length]; for (var i = 0; i < combinationRule.Length; ++i) { result[i] = combinationRule[i]; } for (var i = 0; i < ruleToCombine.Length; ++i) { result[i + combinationRule.Length] = ruleToCombine[i]; } return(result); }
private bool tryFindNextConstraint() { var wasFirst = _isFirst; _isFirst = false; if (_originalRemainingNodes.Count == 0 || !_factory.HasNextPath) { //there is no need for other than empty rule if (!wasFirst) { IsEnd = true; } return(wasFirst); } var lastCompleteRuleCount = _completeRules.Count; if (_combinationIndex < 1) { //create new rule from next constraint path var pathSegment = _factory.GetNextSegment(); if (pathSegment == null) { return(false); } var constraint = createConstraint(pathSegment); var newRule = new ConstraintPoolRule[] { constraint }; var remainingNodes = findRemainingNodes(constraint); var isTrivialRule = remainingNodes.Count == _originalRemainingNodes.Count; if (isTrivialRule || Graph.ContainsLoop(new[] { _factory.StartingNode }, pathSegment.GetReversedEdges())) { //we don't need any trivial rule return(false); } _factory.Enqueue(pathSegment); addRule(newRule, remainingNodes); //set combination for next rules _combinationIndex = _incompleteRuleSequence.Count - 1; _combinationRule = newRule; _combinationNodes = remainingNodes; } else { --_combinationIndex; //combine with previous rule var ruleToCombine = _incompleteRuleSequence[_combinationIndex]; var nodesToCombine = _remainingNodes[_combinationIndex]; var combinedRule = combineRules(_combinationRule, ruleToCombine); var combinedNodes = combineNodes(_combinationNodes, nodesToCombine); var isTrivialExtension = combinedNodes.Count == _combinationNodes.Count || combinedNodes.Count == nodesToCombine.Count; if (!isTrivialExtension) { addRule(combinedRule, combinedNodes); } } //detect whether new complete rule has been found return(_completeRules.Count > lastCompleteRuleCount); }