private static DisjunctiveExamplesSpec deduceSubstrBasedKey(FunctionalDisjunctiveOutputSpec spec, ComparatorCreator cmpCreator)
        {
            var strExamples = new Dictionary <State, IEnumerable <object> >();

            foreach (State input in spec.ProvidedInputs)
            {
                var validStrings = new List <string>();
                var relation     = spec.Relation[input];

                var superString = "";

                // To find a super-string, find a mapping that contains exactly
                // one value (i.e. a strict ordering)
                foreach (var mapping in relation)
                {
                    var key             = (Tuple <string, string>)mapping.Key;
                    var possibleResults = mapping.Value;
                    if (possibleResults.Count == 1)
                    {
                        var resultsEnumerator = possibleResults.GetEnumerator();
                        resultsEnumerator.MoveNext();
                        var onlyResult = (int)resultsEnumerator.Current;
                        if (onlyResult == 0)
                        {
                            throw new Exception("strict comparisons cannot be zero");
                        }

                        // If we have found a strict ordering, the super-string is
                        // the item corresponding to the larger value
                        superString = (string)((onlyResult > 0) ? key.Item1 : key.Item2);
                        break;
                    }
                }

                if (superString.Length == 0)
                {
                    throw new Exception("No strict ordering found");
                }

                // Generate all possible sub-strings from superString
                for (var i = 0; i < superString.Length - 1; i++)
                {
                    for (var len = 1; i + len <= superString.Length; len++)
                    {
                        // Extract sub-string
                        var subStr = superString.Substring(i, len);
                        // Create comparator from provided lambda
                        var cmp = cmpCreator(subStr);
                        // Check if this subStr is consistent for all mappings
                        if (validateComparator(relation, cmp))
                        {
                            validStrings.Add(subStr);
                        }
                    }
                }
                strExamples[input] = validStrings;
            }

            return(DisjunctiveExamplesSpec.From(strExamples));
        }
 public static DisjunctiveExamplesSpec WitnessLastStr(GrammarRule rule, FunctionalDisjunctiveOutputSpec spec)
 {
     return(deduceSubstrBasedKey(spec, s => Semantics.Semantics.Last(s)));
 }