Example #1
0
        public void DeleteRule(Rule rule)
        {
            //delete from rules dictionary
            var lhs        = rule.Name.NonTerminal;
            var rulesOfLHS = Rules[lhs];

            rulesOfLHS.Remove(rule);
            var numberOfRemainingRules = rulesOfLHS.Count;

            if (numberOfRemainingRules == 0)
            {
                Rules.Remove(lhs);
            }

            //delete from inverse rules dictionary
            if (!rule.IsEpsilonRule())
            {
                var inverseKey = new InverseKeyType(rule.Production, rule.HeadPosition,
                                                    rule.Name.NonTerminal == StartSymbol);
                inverseRules.Remove(inverseKey);
            }

            RemoveNonTerminalCounts(rule);
            ruleNumberDictionary.Remove(rule.Number);
            numberOfRules--;
            ReturnUnusedRuleNumber(rule.Number);
        }
Example #2
0
        public void AddNonTerminalCounts(Rule rule)
        {
            var lhs = rule.Name.NonTerminal;

            if (!nonTerminalCounts.ContainsKey(lhs))
            {
                nonTerminalCounts[lhs] = new NonTerminalCounts();
            }

            nonTerminalCounts[lhs].lhsCounts++;

            if (!rule.IsEpsilonRule())
            {
                int i = 0;
                foreach (var item in rule.Production)
                {
                    var rhs = item.NonTerminal;
                    if (!nonTerminalCounts.ContainsKey(rhs))
                    {
                        nonTerminalCounts[rhs] = new NonTerminalCounts();
                    }
                    nonTerminalCounts[rhs].rhsCounts++;

                    if (!RHSDictionary.ContainsKey(rhs))
                    {
                        RHSDictionary[rhs] = new HashSet <Tuple <int, int> >();
                    }
                    RHSDictionary[rhs].Add(Tuple.Create(rule.Number, i));
                    i++;
                }
            }
        }
Example #3
0
        public string AddRule(Rule rule)
        {
            EnforceHeadRelations(rule);

            // if production already exists under some other rule name, do not re-add the rule
            //that is, if exists A->BC and we encounter D->BC, then A=D.
            var inverseKey    = new InverseKeyType(rule.Production, rule.HeadPosition, rule.Name.NonTerminal == StartSymbol);
            var isEpislonRule = rule.IsEpsilonRule();

            if (isEpislonRule || !inverseRules.ContainsKey(inverseKey))
            {
                // add the rule:
                //1) to inverse rules dictionary:
                numberOfRules++;
                rule.Number = GetNextAvailableRuleNumber(); //note: depends on value of self.numberOfRules

                if (!isEpislonRule)
                {
                    inverseRules[inverseKey] = rule.Name.NonTerminal;
                }
                //if the rule is epsilon rule, it does not have inverse key.
                else
                {
                    nullableProductions[rule.Name] = 1.0f; //TODO - temporary probabilioty of 1.0.
                }
                AddNonTerminalCounts(rule);

                //3) to rules dictionary
                if (!Rules.ContainsKey(rule.Name.NonTerminal))
                {
                    Rules[rule.Name.NonTerminal] = new List <Rule>();
                    rule.Occurrences             = 1;
                }
                else
                {
                    if (rule.Occurrences == 0) //if rule does not come with positive occurrences (= 0):
                    {
                        //make the occurrences average of the current occurrences.
                        var l     = Rules[rule.Name.NonTerminal];
                        var count = l.Count;
                        rule.Occurrences = l.Sum(x => x.Occurrences) / count;
                    }
                }

                Rules[rule.Name.NonTerminal].Add(rule);
                ruleNumberDictionary[rule.Number] = rule;
            }
            //for the sake of convenience, return the rule name that was added
            //it is useful when replacing no longer used symbols with the
            //new rule names.
            if (!isEpislonRule)
            {
                return(inverseRules[inverseKey]);
            }
            return(rule.Name.NonTerminal);
        }
Example #4
0
        private RuleConsistentWithDerivation IsPredictedRuleConsistentWithCurrentDerivation(
            NonTerminalObject currObject, Rule rule)
        {
            //TODO: change later to skip -all- rules whose derivation leads to the empty string.
            //I.e,  A-> B.C , C -> D E. D -> epsilon, E -> epsilon. C itself is not an epsilon rule.

            //1. states that are the result of a spontenous dot shift (due to nullable production)
            //have already been added to the agendas in Column.Add()
            if (rule.IsEpsilonRule() && Grammar.nullableProductions.ContainsKey(currObject))
            {
                return(RuleConsistentWithDerivation.SkipGeneration);
            }

            //2. if current stack is empty but predicted stack is not, mismatch - do not predict this rule.
            if (currObject.IsStackEmpty() && !rule.IsInitialOrDotStack())
            {
                return(RuleConsistentWithDerivation.RuleInconsistent);
            }

            if (rule.IsInitialRule())
            {
                var complementPositionObject = rule.Production[rule.ComplementPosition];

                //3. if current stack is not empty, but the complement position does not allow for stacks (POS),
                //mismatch - do not predict this rule.
                if (!currObject.IsStackEmpty() && Grammar.IsPOS(complementPositionObject.NonTerminal))
                {
                    return(RuleConsistentWithDerivation.RuleInconsistent);
                }
            }
            else
            {
                //4. if tops of the stacks do not match, continue. e.g created rule PP[PP] -> epsilon, current object: PP[NP].
                if (rule.Name.Stack.Peek() != "." &&
                    !currObject.Stack.GetListOfTopSymbols().Contains(rule.Name.Stack.Peek()))
                {
                    return(RuleConsistentWithDerivation.RuleInconsistent);
                }
            }
            return(RuleConsistentWithDerivation.RuleConsistent);
        }
Example #5
0
        public void RemoveNonTerminalCounts(Rule rule)
        {
            var lhs = rule.Name.NonTerminal;

            if (!nonTerminalCounts.ContainsKey(lhs))
            {
                throw new Exception(
                          string.Format("nonterminal {0} in rule {1} is missing from NonTerminalCounts dictionary", lhs, rule));
            }

            nonTerminalCounts[lhs].lhsCounts--;

            var productionNonterminals = new List <string>();

            if (!rule.IsEpsilonRule())
            {
                int i = 0;

                foreach (var item in rule.Production)
                {
                    var rhs = item.NonTerminal;
                    productionNonterminals.Add(rhs);
                    if (!nonTerminalCounts.ContainsKey(rhs))
                    {
                        throw new Exception(
                                  string.Format("nonterminal {0} in rule {1} is missing from NonTerminalCounts dictionary",
                                                lhs, rule));
                    }
                    nonTerminalCounts[rhs].rhsCounts--;

                    if (!RHSDictionary.ContainsKey(rhs))
                    {
                        throw new Exception(string.Format("nonterminal {0} in rule {1} is missing from RHSDictionary dictionary",
                                                          rhs, rule));
                    }

                    //remove from RHSDictionary.
                    RHSDictionary[rhs].Remove(new Tuple <int, int>(rule.Number, i));
                    i++;
                }
            }

            var lhsCountsOfLHS = nonTerminalCounts[lhs]; //the counts of the Left-hand sided of the rule.

            //if the removed rule has a LHS that no longer has any other LHS appearances, we can replace all its RHS appearances with another nonterminal,
            //because we cannot invoke that non-terminal anymore.

            if (lhsCountsOfLHS.lhsCounts == 0 && lhsCountsOfLHS.rhsCounts > 0 && !POSTypes.Contains(lhs) &&
                lhs != StartSymbol)
            {
                //alternatively - do nothing. The resulting grammar will not use these rules.
            }

            var lhStoDelete = new List <string>();

            if (!rule.IsEpsilonRule())
            {
                foreach (var item in productionNonterminals)
                {
                    var rhsCountsofRhs = nonTerminalCounts[item]; //the counts of the right-hand sided of the rule terms

                    //if the removed rule has a specific RHS, X, that no longer has any other RHS appearances, we can delete the rules that has X as their LHS
                    //because they will not be triggered (orphaned rules)
                    if (rhsCountsofRhs.rhsCounts == 0 && rhsCountsofRhs.lhsCounts > 0 && !POSTypes.Contains(item) &&
                        item != StartSymbol)
                    {
                        var possiblePOS = item.Substring(0, item.Length - 1);
                        if (!POSTypes.Contains(possiblePOS))
                        {
                            lhStoDelete.Add(item);
                        }
                    }
                }
            }

            foreach (var item in lhStoDelete)
            {
                var rules = Rules[item];
                var removedRulesNumbers = rules.Select(x => x.Number);

                foreach (var removedRuleNumber in removedRulesNumbers.ToArray())
                {
                    DeleteRule(ruleNumberDictionary[removedRuleNumber]);
                }
            }

            //after updating all counts of nonterminals in the rule, check if the type is still used.
            //if not, remove it.
            if (lhsCountsOfLHS.lhsCounts == 0 && lhsCountsOfLHS.rhsCounts == 0 && !POSTypes.Contains(lhs) &&
                lhs != StartSymbol)
            {
                var possiblePOS = lhs.Substring(0, lhs.Length - 1);
                if (!POSTypes.Contains(possiblePOS))
                {
                    Console.WriteLine("removed type {0}", lhs);
                    NonTerminalsTypeDictionary.Remove(lhs);
                    nonTerminalCounts.Remove(lhs);
                }
            }
        }
Example #6
0
        public string AddRule(Rule rule)
        {
            EnforceHeadRelations(rule);

            // if production already exists under some other rule name, do not re-add the rule
            //that is, if exists A->BC and we encounter D->BC, then A=D.
            var inverseKey = new InverseKeyType(rule.Production, rule.HeadPosition, rule.Name.NonTerminal == StartSymbol);
            var isEpislonRule = rule.IsEpsilonRule();

            if (isEpislonRule || !inverseRules.ContainsKey(inverseKey))
            {
                // add the rule:
                //1) to inverse rules dictionary:
                numberOfRules++;
                rule.Number = GetNextAvailableRuleNumber(); //note: depends on value of self.numberOfRules

                if (!isEpislonRule)
                    inverseRules[inverseKey] = rule.Name.NonTerminal;
                //if the rule is epsilon rule, it does not have inverse key.
                else
                    nullableProductions[rule.Name] = 1.0f; //TODO - temporary probabilioty of 1.0.

                AddNonTerminalCounts(rule);

                //3) to rules dictionary
                if (!Rules.ContainsKey(rule.Name.NonTerminal))
                {
                    Rules[rule.Name.NonTerminal] = new List<Rule>();
                    rule.Occurrences = 1;
                }
                else
                {
                    if (rule.Occurrences == 0) //if rule does not come with positive occurrences (= 0):
                    {
                        //make the occurrences average of the current occurrences.
                        var l = Rules[rule.Name.NonTerminal];
                        var count = l.Count;
                        rule.Occurrences = l.Sum(x => x.Occurrences)/count;
                    }
                }

                Rules[rule.Name.NonTerminal].Add(rule);
                ruleNumberDictionary[rule.Number] = rule;
            }
            //for the sake of convenience, return the rule name that was added
            //it is useful when replacing no longer used symbols with the
            //new rule names.
            if (!isEpislonRule)
                return inverseRules[inverseKey];
            return rule.Name.NonTerminal;
        }
Example #7
0
        public void AddNonTerminalCounts(Rule rule)
        {
            var lhs = rule.Name.NonTerminal;

            if (!nonTerminalCounts.ContainsKey(lhs))
                nonTerminalCounts[lhs] = new NonTerminalCounts();

            nonTerminalCounts[lhs].lhsCounts++;

            if (!rule.IsEpsilonRule())
            {
                foreach (var item in rule.Production)
                {
                    var rhs = item.NonTerminal;
                    if (!nonTerminalCounts.ContainsKey(rhs))
                        nonTerminalCounts[rhs] = new NonTerminalCounts();
                    nonTerminalCounts[rhs].rhsCounts++;
                }
            }
        }
Example #8
0
        public void RemoveNonTerminalCounts(Rule rule)
        {
            var lhs = rule.Name.NonTerminal;

            if (!nonTerminalCounts.ContainsKey(lhs))
                throw new Exception(
                    string.Format("nonterminal {0} in rule {1} is missing from NonTerminalCounts dictionary", lhs, rule));

            nonTerminalCounts[lhs].lhsCounts--;

            var productionNonterminals = new List<string>();
            if (!rule.IsEpsilonRule())
            {
                foreach (var item in rule.Production)
                {
                    var rhs = item.NonTerminal;
                    productionNonterminals.Add(rhs);
                    if (!nonTerminalCounts.ContainsKey(rhs))
                        throw new Exception(
                            string.Format("nonterminal {0} in rule {1} is missing from NonTerminalCounts dictionary",
                                lhs, rule));
                    nonTerminalCounts[rhs].rhsCounts--;
                }
            }

            var lhsCountsOfLHS = nonTerminalCounts[lhs]; //the counts of the Left-hand sided of the rule.

            //if the removed rule has a LHS that no longer has any other LHS appearances, we can replace all its RHS appearances with another nonterminal,
            //because we cannot invoke that non-terminal anymore.

            if (lhsCountsOfLHS.lhsCounts == 0 && lhsCountsOfLHS.rhsCounts > 0 && !POSTypes.Contains(lhs) &&
                lhs != StartSymbol)
            {
                //alternatively - do nothing. The resulting grammar will not use these rules.
            }

            var lhStoDelete = new List<string>();
            if (!rule.IsEpsilonRule())
            {
                foreach (var item in productionNonterminals)
                {
                    var rhsCountsofRhs = nonTerminalCounts[item]; //the counts of the right-hand sided of the rule terms

                    //if the removed rule has a specific RHS, X, that no longer has any other RHS appearances, we can delete the rules that has X as their LHS
                    //because they will not be triggered (orphaned rules)
                    if (rhsCountsofRhs.rhsCounts == 0 && rhsCountsofRhs.lhsCounts > 0 && !POSTypes.Contains(item) &&
                        item != StartSymbol)
                    {
                        var possiblePOS = item.Substring(0, item.Length - 1);
                        if (!POSTypes.Contains(possiblePOS))
                        {
                            lhStoDelete.Add(item);
                        }
                    }
                }
            }

            foreach (var item in lhStoDelete)
            {
                var rules = Rules[item];
                var removedRulesNumbers = rules.Select(x => x.Number);

                foreach (var removedRuleNumber in removedRulesNumbers.ToArray())
                    DeleteRule(ruleNumberDictionary[removedRuleNumber]);
            }

            //after updating all counts of nonterminals in the rule, check if the type is still used.
            //if not, remove it.
            if (lhsCountsOfLHS.lhsCounts == 0 && lhsCountsOfLHS.rhsCounts == 0 && !POSTypes.Contains(lhs) &&
                lhs != StartSymbol)
            {
                var possiblePOS = lhs.Substring(0, lhs.Length - 1);
                if (!POSTypes.Contains(possiblePOS))
                {
                    Console.WriteLine("removed type {0}", lhs);
                    NonTerminalsTypeDictionary.Remove(lhs);
                    nonTerminalCounts.Remove(lhs);
                }
            }
        }
Example #9
0
        public void DeleteRule(Rule rule)
        {
            //delete from rules dictionary
            var lhs = rule.Name.NonTerminal;
            var rulesOfLHS = Rules[lhs];

            rulesOfLHS.Remove(rule);
            var numberOfRemainingRules = rulesOfLHS.Count;

            if (numberOfRemainingRules == 0)
                Rules.Remove(lhs);

            //delete from inverse rules dictionary
            if (!rule.IsEpsilonRule())
            {
                var inverseKey = new InverseKeyType(rule.Production, rule.HeadPosition,
                    rule.Name.NonTerminal == StartSymbol);
                inverseRules.Remove(inverseKey);
            }

            RemoveNonTerminalCounts(rule);
            ruleNumberDictionary.Remove(rule.Number);
            numberOfRules--;
            ReturnUnusedRuleNumber(rule.Number);
        }