Пример #1
0
        public CNFGrammar(IEnumerable <Production> productions, Nonterminal start)
        {
            this.Start = start;

            foreach (var production in productions)
            {
                if (production.Lhs == start && production.Rhs.Count == 0)
                {
                    if (production.Weight == 0.0)
                    {
                        continue;
                    }
                    if (_emptyProductions.Count == 0)
                    {
                        _emptyProductions.Add(production);
                    }
                    else
                    {
                        _emptyProductions.First().Weight += production.Weight;
                    }
                }
                else if (production.IsCnfNonterminal)
                {
                    _nonterminalProductions.Add(production);
                }
                else
                {
                    _terminalProductions.Add(production);
                }
            }

            SimplifyWithoutInvalidate();
            BuildLookups();
            BuildHelpers();
        }
Пример #2
0
        // TODO: need to check that this is unbiased
        internal Sentence ProduceNonterminal(Nonterminal nt)
        {
            Sentence result = null;

            var productions = ProductionsFrom(nt);

            if (productions.Count() == 0)
            {
                throw new Exception(string.Format("Can't produce nonterminal {0}; no productions with it on LHS", nt));
            }

            var totalWeight = productions.Sum(w => w.Weight);
            var targetValue = totalWeight * _rand.NextDouble();

            var currentWeight = 0.0;

            foreach (var production in productions)
            {
                currentWeight += production.Weight;
                if (currentWeight < targetValue)
                {
                    continue;
                }
                result = new Sentence(production.Rhs);
                break;
            }

            Debug.Assert(result != null);
            return(result);
        }
Пример #3
0
		public static Nonterminal Of(string v) {
			Nonterminal nonterminal;
			if (!_history.TryGetValue(v, out nonterminal)) {
				nonterminal = new Nonterminal(v);
				_history[v] = nonterminal;
			}
			return nonterminal;
		}
Пример #4
0
		/// <summary>
		/// Eliminate the start symbol from right-hand sides
		/// </summary>
		/// <param name="productions"></param>
		private void StepStart(ISet<Production> productions) {
			var fresh = GetFresh();
			productions.Add(
				// new Production(fresh, new Sentence { Nonterminal.Of("S") })
				new Production(fresh, new Sentence { _grammar.Start })
			);
			_startSymbol = fresh;
		}
Пример #5
0
        public static Nonterminal Of(string v)
        {
            Nonterminal nonterminal;

            if (!_history.TryGetValue(v, out nonterminal))
            {
                nonterminal = new Nonterminal(v);
                _history[v] = nonterminal;
            }
            return(nonterminal);
        }
Пример #6
0
		/// <summary>
		/// Returns a new production.
		/// </summary>
		public Production(Nonterminal lhs, Sentence rhs, double weight = 1.0) {
			if (lhs == null) {
				throw new ArgumentNullException("Lhs must be non-null");
			}
			if (rhs == null) {
				throw new ArgumentNullException("Rhs must be non-null");
			}
			this.Lhs = lhs;
			_rhs = rhs;
			this.Weight = weight;
		}
Пример #7
0
        // todo: horrible
        private Nonterminal GetFresh()
        {
            var         originalNonterminals = _grammar.GetNonterminals();
            Nonterminal result;

            do
            {
                result = Nonterminal.Of("X_" + _freshx);
                _freshx++;
            } while (originalNonterminals.Contains(result));
            return(result);
        }
Пример #8
0
        /// <summary>
        /// Eliminate the start symbol from right-hand sides
        /// </summary>
        /// <param name="productions"></param>
        private void StepStart(ISet <Production> productions)
        {
            var fresh = GetFresh();

            productions.Add(
                // new Production(fresh, new Sentence { Nonterminal.Of("S") })
                new Production(fresh, new Sentence {
                _grammar.Start
            })
                );
            _startSymbol = fresh;
        }
Пример #9
0
        public Production NextCNFNonterminalProduction(int numNonTerminals, Nonterminal lhs = null)
        {
            if (lhs == null)
            {
                lhs = RandomNonterminal(numNonTerminals);
            }
            var rhs1 = RandomNonterminal(numNonTerminals, false);
            var rhs2 = RandomNonterminal(numNonTerminals, false);

            return(new Production(lhs, new Sentence {
                rhs1, rhs2
            }));
        }
Пример #10
0
        /// <summary>
        /// Tries to find a production lhs -> rhs in the grammar, and returns it if found.
        /// Returns null if no such production is found.
        /// </summary>
        // TODO: Inefficient
        public Production FindProduction(Nonterminal lhs, Sentence rhs)
        {
            var productions = ProductionsFrom(lhs);

            foreach (var production in productions)
            {
                if (production.Rhs.SequenceEqual(rhs))
                {
                    return(production);
                }
            }
            return(null);
        }
Пример #11
0
        /// <summary>
        /// Tries to estimate the probability of a nonterminal yielding null by generating a bunch randomly and counting.
        /// </summary>
        public double EstimateProbabilityNull(Nonterminal nt, long iterations)
        {
            long nulls = 0;

            for (int i = 0; i < iterations; i++)
            {
                if (this.ProduceNull(nt))
                {
                    nulls++;
                }
            }
            return((double)nulls / iterations);
        }
Пример #12
0
        private Nonterminal RandomNonterminal(int numNonterminals, bool allowStart = true)
        {
            int num;

            if (allowStart)
            {
                num = _rand.Next(0, numNonterminals);
            }
            else
            {
                num = _rand.Next(1, numNonterminals);
            }
            return(Nonterminal.Of("X_" + num));
        }
Пример #13
0
 /// <summary>
 /// Returns a new production.
 /// </summary>
 public Production(Nonterminal lhs, Sentence rhs, double weight = 1.0)
 {
     if (lhs == null)
     {
         throw new ArgumentNullException("Lhs must be non-null");
     }
     if (rhs == null)
     {
         throw new ArgumentNullException("Rhs must be non-null");
     }
     this.Lhs    = lhs;
     _rhs        = rhs;
     this.Weight = weight;
 }
Пример #14
0
        /// <summary>
        /// Turns a string like
        /// &lt;X> -> &lt;X> 'a' &lt;X>
        /// into a production.
        /// Nonterminals must be surrounded by angled brackets, terminals must be surrounded by single quotes, and everything must be separated by spaces.
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static Production Production(string s)
        {
            var match = ProductionRegex.Match(s);

            if (!match.Success)
            {
                throw new Exception("Didn't find valid string");
            }

            var lhsMatch    = match.Groups["lhs"];
            var ntMatch     = match.Groups["nt"];
            var tMatch      = match.Groups["t"];
            var weightMatch = match.Groups["weight"];

            if (!lhsMatch.Success)
            {
                throw new Exception("Didn't find LHS");
            }

            double weight;

            if (!double.TryParse(weightMatch.Value, out weight))
            {
                weight = 1.0;
            }

            var rhsList = new SortedList <int, Word>();

            foreach (Capture capture in ntMatch.Captures)
            {
                var word = Nonterminal.Of(capture.Value);
                rhsList.Add(capture.Index, word);
            }
            foreach (Capture capture in tMatch.Captures)
            {
                var word = Terminal.Of(capture.Value);
                rhsList.Add(capture.Index, word);
            }
            var rhs = new Sentence(rhsList.Values);
            var lhs = Nonterminal.Of(lhsMatch.Value);

            var retval = new Production(lhs, rhs, weight);

            return(retval);
        }
Пример #15
0
        public Grammar(IEnumerable <Production> productions, Nonterminal start) : base(start)
        {
            _productions = new List <Production>(productions);

            // if (simplify) {
            SimplifyWithoutInvalidate();
            //}

            _table = Cache.Create(() => Helpers.BuildLookup(
                                      () => _productions,
                                      (p) => p.Lhs,
                                      (p) => p,
                                      () => (ICollection <Production>) new List <Production>(),
                                      (x, y) => x.Add(y)
                                      ));
            this.Caches.Add(_table);

            BuildHelpers();
        }
Пример #16
0
		public Grammar(IEnumerable<Production> productions, Nonterminal start) {
			_productions = new List<Production>(productions);
			this.Start = start;
			
			// if (simplify) {
			SimplifyWithoutInvalidate();
			//}

			_table = Cache.Create(() => Helpers.BuildLookup(
				() => _productions,
				(p) => p.Lhs,
				(p) => p,
				() => (ICollection<Production>)new List<Production>(),
				(x, y) => x.Add(y)
			));
			this.Caches.Add(_table);

			BuildHelpers();
		}
Пример #17
0
 /// <summary>
 /// Returns a new production.
 /// </summary>
 public Production(Nonterminal lhs, Sentence rhs, double weight = 1.0, Annotations annotations = null)
 {
     if (lhs == null)
     {
         throw new ArgumentNullException("Lhs must be non-null");
     }
     if (rhs == null)
     {
         throw new ArgumentNullException("Rhs must be non-null");
     }
     this.Lhs    = lhs;
     Rhs         = rhs;
     this.Weight = weight;
     if (annotations == null)
     {
         annotations = Annotations.Empty;
     }
     Annotations = annotations;
 }
Пример #18
0
        /// <summary>
        /// Produces a random sentence and returns whether or not it was null
        /// </summary>
        /// <returns></returns>
        private bool ProduceNull(Nonterminal nt)
        {
            var sentence = new Sentence {
                nt
            };

            while (sentence.Count > 0)
            {
                for (int i = sentence.Count - 1; i >= 0; i--)
                {
                    var word     = sentence[i];
                    var newStuff = ProduceNonterminal((Nonterminal)word);
                    if (!newStuff.OnlyNonterminals())
                    {
                        return(false);
                    }
                    sentence.RemoveAt(i);
                    sentence.InsertRange(i, newStuff);
                }
            }
            return(true);
        }
Пример #19
0
 public ValueUnitProduction(Nonterminal lhs, Nonterminal rhs)
 {
     this.Lhs = lhs;
     this.Rhs = rhs;
 }
Пример #20
0
		internal override IEnumerable<Production> ProductionsFrom(Nonterminal lhs) {
			return _productionsFrom.Value.LookupEnumerable(lhs);
		}
Пример #21
0
		public CNFGrammar(IEnumerable<Production> productions, Nonterminal start) {
			this.Start = start;

			foreach (var production in productions) {
				if (production.Lhs == start && production.Rhs.Count == 0) {
					if (production.Weight == 0.0) {
						continue;
					}
					if (_emptyProductions.Count == 0) {
						_emptyProductions.Add(production);
					} else {
						_emptyProductions.First().Weight += production.Weight;
					}
				} else if (production.IsCnfNonterminal) {
					_nonterminalProductions.Add(production);
				} else {
					_terminalProductions.Add(production);
				}
			}

			SimplifyWithoutInvalidate();
			BuildLookups();
			BuildHelpers();
		}
Пример #22
0
 public Production(string lhsName, Word rhsOnlyWord, double weight = 1.0) : this(Nonterminal.Of(lhsName), new Sentence(rhsOnlyWord), weight)
 {
 }
Пример #23
0
 public Production(Nonterminal lhs, Word rhsOnlyWord, double weight = 1.0) : this(lhs, new Sentence(rhsOnlyWord), weight)
 {
 }
Пример #24
0
 public Production(string lhsName, Sentence rhs, double weight = 1.0) : this(Nonterminal.Of(lhsName), rhs, weight)
 {
 }
Пример #25
0
 internal abstract IEnumerable <Production> ProductionsFrom(Nonterminal lhs);
Пример #26
0
 internal override IEnumerable <Production> ProductionsFrom(Nonterminal lhs)
 {
     return(_table.Value.LookupEnumerable(lhs));
 }
Пример #27
0
		public Production NextCNFNonterminalProduction(int numNonTerminals, Nonterminal lhs = null) {
			if (lhs == null) {
				lhs = RandomNonterminal(numNonTerminals);
			}
			var rhs1 = RandomNonterminal(numNonTerminals, false);
			var rhs2 = RandomNonterminal(numNonTerminals, false);

			return new Production(lhs, new Sentence { rhs1, rhs2 });
		}
Пример #28
0
		public Production(Nonterminal lhs, Word rhsOnlyWord, double weight = 1.0) : this(lhs, new Sentence(rhsOnlyWord), weight) {
		}
Пример #29
0
 public BaseGrammar(Nonterminal start)
 {
     Start = start;
 }