private State GetState(TSource node, Func <TSource, bool> isWildcard) { if (isWildcard(node)) { if (!_wildcards.TryGetValue(node, out int state)) { state = AddToForest(node); _wildcards[node] = state; } var res = new State(state); res.WildcardTraversals[node] = new WildcardTraversal <TSource>(node); return(res); } else { var childStates = new List <State>(); var wildcardTraversals = new WildcardTraversalMap <TSource>(); var childIndex = 0; foreach (var childNode in node.Children) { var childState = GetState((TSource)childNode, isWildcard); childStates.Add(childState); var childTraversals = childState.WildcardTraversals; childTraversals.PushPathSegment(childIndex); wildcardTraversals.Merge(childTraversals); childIndex++; } if (childStates.Count == 0) { return(GetStateForConstant(node)); } if (!_states.TryGetValue(node.Value, out NAryMap <int, int> map)) { map = new NAryMap <int, int>(childStates.Count); _states[node.Value] = map; } var childStateValues = childStates.Select(c => c.Value).ToList(); if (!map.TryGetValue(childStateValues, out int state)) { state = AddToForest(node); map[childStateValues] = state; } var res = new State(state, wildcardTraversals); return(res); } }
public State(int state, WildcardTraversalMap <TSource> wildcardTraversals) { Value = state; WildcardTraversals = wildcardTraversals; }