CFGLib.GrammarHelpers.GetNullable C# (CSharp) Method

GetNullable() static private method

Returns a dictionary containing the probability that any particular nonterminal yields ε
static private GetNullable ( ISet originalProductions ) : double>.Dictionary
originalProductions ISet
return double>.Dictionary
		internal static Dictionary<Nonterminal, double> GetNullable(ISet<Production> originalProductions) {
			var results = new Dictionary<Nonterminal, double>();

			var productionByNt = BuildLookupTable(originalProductions);
			var nonterminals = GetNonterminals(originalProductions);
			foreach (var nt in nonterminals) {
				ICollection<Production> productions;
				if (!productionByNt.TryGetValue(nt, out productions)) {
					productionByNt[nt] = new List<Production>();
				}
			}

			var indexToNonterminal = nonterminals.ToArray();
			var nonterminalToIndex = new Dictionary<Nonterminal, int>();
			for (int i = 0; i < nonterminals.Count; i++) {
				nonterminalToIndex[indexToNonterminal[i]] = i;
			}

			// seeding the estimates with a magic value
			// this keeps all iterations behaving the same
			var previousEstimates = Enumerable.Repeat(_magicStartProbability, indexToNonterminal.Length).ToArray();
			var currentEstimates = new double[indexToNonterminal.Length];

			// figure out which nonterminals are definitely not nullable, and go ahead and set them that way
			var nullableNonterminals = GetNullableNonterminals(originalProductions);
			foreach (var nt in nonterminals) {
				if (!nullableNonterminals.Contains(nt)) {
					previousEstimates[nonterminalToIndex[nt]] = 0.0;
				}
			}

			bool changed = true;
			while (changed == true) {
				changed = false;
				Array.Clear(currentEstimates, 0, currentEstimates.Length);

				// consider each nonterminal.  calculate a new nullable estimate based on the previous
				for (int i = 0; i < currentEstimates.Length; i++) {
					var nt = indexToNonterminal[i];

					var productions = productionByNt[nt];
					double weightSum = 0.0; // productions.Sum((p) => p.Weight);
					foreach (var production in productions) {
						var productionWeight = production.Weight;
						weightSum += productionWeight;
						var innerProb = GetProductionProbability(production, nonterminalToIndex, previousEstimates);
						currentEstimates[i] += productionWeight * innerProb;
					}
					if (weightSum == 0.0) {
						currentEstimates[i] = 0.0;
					} else {
						currentEstimates[i] /= weightSum;
					}
					
					if (currentEstimates[i] > previousEstimates[i]) {
						throw new Exception("Didn't expect estimates to increase");
					} else if (currentEstimates[i] < previousEstimates[i]) {
						changed = true;
					}
				}
				Helpers.Swap(ref previousEstimates, ref currentEstimates);
			}

			for (int i = 0; i < nonterminals.Count; i++) {
				var nt = indexToNonterminal[i];
				results[nt] = previousEstimates[i];
			}

			return results;
		}

Usage Example

Example #1
0
        /// <summary>
        /// Eliminate ε-rules
        /// </summary>
        /// <param name="productions"></param>
        // TODO: Does not preserve weights
        private void StepDel(ISet <Production> productions)
        {
            var nullableProbabilities = GrammarHelpers.GetNullable(productions);
            var newRules = new List <Production>();

            foreach (var production in productions)
            {
                var toAdd = Nullate(production, nullableProbabilities);
                RemoveExtraneousNulls(toAdd);
                newRules.AddRange(toAdd);
            }
            productions.Clear();
            productions.UnionWith(newRules);
        }
All Usage Examples Of CFGLib.GrammarHelpers::GetNullable