CFGLib.CFGtoCNF.Nullate C# (CSharp) Method

Nullate() private static method

From a production, derive a set of productions for each combination of skipping nullable nonterminals. E.g., for production S -> AbB and nullable {A, B}, we get productions S -> AbB | Ab | bB | b
private static Nullate ( Production originalProduction, double>.Dictionary nullableProbabilities ) : List
originalProduction Production
nullableProbabilities double>.Dictionary
return List
		private static List<Production> Nullate(Production originalProduction, Dictionary<Nonterminal, double> nullableProbabilities) {
			var results = new List<Production>();
			results.Add(originalProduction);
			if (originalProduction.IsEmpty) {
				return results;
			}
			for (int i = originalProduction.Rhs.Count - 1; i >= 0; i--) {
				var newResults = new List<Production>();
				var toRemove = new List<Production>();
				foreach (var production in results) {
					var word = production.Rhs[i];
					var nt = word as Nonterminal;
					if (nt == null) { continue; }
					if (!nullableProbabilities.ContainsKey(nt)) {
						continue;
					}
					// var with = production.Clone();
					var without = production.DeepClone();
					without.Rhs.RemoveAt(i);
					
					var chanceNull = nullableProbabilities[nt];
					var newWithoutWeight = without.Weight * chanceNull;
					var newWithWeight = production.Weight * (1.0 - chanceNull);
					
					if (newWithoutWeight > 0.0) {
						without.Weight = newWithoutWeight;
						newResults.Add(without);
					}
					if (newWithWeight <= 0.0) {
						toRemove.Add(production);
					} else {
						production.Weight = newWithWeight;
					}
				}
				results.AddRange(newResults);
				// TODO: we should just make it so that if a weight is set to 0, the production gets removed from the grammar automatically, and that operation should be fast
				results.RemoveMany(toRemove);
			}
			// NullateAux(production, nullableSet, 0, result);

			if (results.Count == 0) {
				return results;
			}
			// Get rid of productions with zero weight
			//for (int i = results.Count - 1; i >= 0;  i--) {
			//	var result = results[i];
			//	if (result.Weight == 0.0) {
			//		results.RemoveAt(i);
			//	}
			//}
			return results;
		}