static IEnumerable <string> PossibleInterpretationsHelper(string input, int depth) { yield return(input); if (depth == 0) { yield break; } var chars = Enumerable.Range('a', 'z' - 'a' + 1).Select(k => (char)k).ToList(); //var chars = new FiniteEnumeration<char>(tmp); Func <string, IEnumerable <string> > insert = str => { var positions = Enumerable.Range(0, str.Length).Where(k => Char.IsLetterOrDigit(str[k])); var strs = from pos in positions from c in chars from b in new[] { true, false } let edit = b ? Char.ToUpper(c) : c let copy = str.Insert(pos, edit.ToString()) where copy != input select copy; return(strs); }; Func <string, IEnumerable <string> > delete = str => { var strs = from pos in Enumerable.Range(0, str.Length) where Char.IsLetterOrDigit(str[pos]) let copy = str.Remove(pos, 1) where copy != input select copy; return(strs); }; Func <string, IEnumerable <string> > substitute = str => { var positions = Enumerable.Range(0, str.Length).Where(k => Char.IsLetterOrDigit(str[k])); var strs = from pos in positions from c in chars from b in new[] { true, false } let edit = b ? Char.ToUpper(c) : c let copy = str.Remove(pos, 1).Insert(pos, edit.ToString()) where copy != input select copy; return(strs); }; Func <string, int, bool> IsGreedy = (str, starpos) => { if (starpos + 1 == str.Length) { return(true); // last position is not a ? } if (str[starpos + 1] == '?') { return(false); // found a *? so this is a nongreedy match } return(true); // just a star in isolation }; Func <string, IEnumerable <string> > makenongreedy = str => { var starpos = str.Select((k, i) => Tuple.Create(k, i)).Where(i => i.Item1 == '*').Select(i => i.Item2).Where(k => IsGreedy(str, k)).ToList(); var strs = from pos in starpos //where IsGreedy(str, pos) == true let copy = str.Remove(pos, 1).Insert(pos, "*?") where copy != input select copy; return(strs); }; Func <string, IEnumerable <string> > makegreedy = str => { var starpos = str.Select((k, i) => Tuple.Create(k, i)).Where(i => i.Item1 == '*').Select(i => i.Item2).Where(k => !IsGreedy(str, k)).ToList(); var strs = from pos in starpos //where IsGreedy(str, pos) == false let copy = str.Remove(pos, 2).Insert(pos, "*") where copy != input select copy; return(strs); }; var edits = new[] { insert, delete, substitute, makenongreedy, makegreedy }; var output = from edit in edits from editedinput in edit(input) where Parser.IsExpression(editedinput) select editedinput; var recurse = from edit in output from next in PossibleInterpretationsHelper(edit, depth - 1) select next; foreach (var item in recurse) { yield return(item); } }
static Uncertain <string> PossibleInterpretations2(string input) { var tmp = Enumerable.Range('a', 'z' - 'a' + 1).Select(k => (char)k).ToList(); var chars = new Multinomial <char>(tmp); Func <string, Uncertain <string> > insert = str => { var positions = Enumerable.Range(0, str.Length).Where(k => Char.IsLetterOrDigit(str[k])); if (positions.Count() == 0) { return(String.Empty); } var strs = from pos in new Multinomial <int>(positions.ToList()) from c in chars from b in new Flip(0.5) let edit = b ? Char.ToUpper(c) : c let copy = str.Insert(pos, edit.ToString()) where copy != input select copy; return(strs); }; Func <string, Uncertain <string> > delete = str => { var positions = Enumerable.Range(0, str.Length).Where(k => Char.IsLetterOrDigit(str[k])); if (positions.Count() == 0) { return(String.Empty); } var strs = from pos in new Multinomial <int>(positions.ToList()) let copy = str.Remove(pos, 1) where copy != input select copy; return(strs); }; Func <string, Uncertain <string> > substitute = str => { var positions = Enumerable.Range(0, str.Length).Where(k => Char.IsLetterOrDigit(str[k])); if (positions.Count() == 0) { return(String.Empty); } var strs = from pos in new Multinomial <int>(positions.ToList()) from c in chars from b in new Flip(0.5) let edit = b ? Char.ToUpper(c) : c let copy = str.Remove(pos, 1).Insert(pos, edit.ToString()) where copy != input select copy; return(strs); }; Func <string, int, bool> IsGreedy = (str, starpos) => { if (starpos + 1 == str.Length) { return(true); // last position is not a ? } if (str[starpos + 1] == '?') { return(false); // found a *? so this is a nongreedy match } return(true); // just a star in isolation }; Func <string, Uncertain <string> > makenongreedy = str => { var starpos = str.Select((k, i) => Tuple.Create(k, i)).Where(i => i.Item1 == '*').Select(i => i.Item2).Where(k => IsGreedy(str, k)).ToList(); if (starpos.Count == 0) { return(String.Empty); } var strs = from pos in new Multinomial <int>(starpos) let copy = str.Remove(pos, 1).Insert(pos, "*?") where copy != input select copy; return(strs); }; Func <string, Uncertain <string> > makegreedy = str => { var starpos = str.Select((k, i) => Tuple.Create(k, i)).Where(i => i.Item1 == '*').Select(i => i.Item2).Where(k => !IsGreedy(str, k)).ToList(); if (starpos.Count == 0) { return(String.Empty); } var strs = from pos in new Multinomial <int>(starpos) let copy = str.Remove(pos, 2).Insert(pos, "*") where copy != input select copy; return(strs); }; var edits = new Multinomial <Func <string, Uncertain <string> > >(new[] { insert, delete, substitute, makenongreedy, makegreedy }); var output = from edit in edits from editedinput in edit(input) where editedinput != String.Empty && Parser.IsExpression(editedinput) select editedinput; var recurse = from edit in output from b in new Flip(0.1) let next = b ? PossibleInterpretations2(edit) : edit from recursivelyedited in next select recursivelyedited; return(recurse); }