예제 #1
0
        // expand an OR symbol throughout a rule
        // error if more than one in pattern
        IList <AtomicRule> ExpandSymbolMulti(AtomicRule oldrule, ObjectSymbol oldsym)
        {
            var pcells = oldrule.Patterns.SelectMany(p => p.Cells
                                                     .SelectMany(c => c.Where(a => a.Symbol == oldsym && !a.IsNegated)));

            if (pcells.Count() != 1)
            {
                return(null);
            }

            // expand one rule per object id
            var newrules = new List <AtomicRule>();

            foreach (var newobj in oldsym.ObjectIds)
            {
                var newrule = oldrule.Clone();
                for (var riter = new RuleIterator {
                    Rule = oldrule
                }; !riter.Done; riter.Step())
                {
                    newrule.Patterns[riter.SubRuleIndex].Cells[riter.CellIndex] = ReplaceObject(riter.PatternAtoms, oldsym, newobj);
                    newrule.Actions[riter.SubRuleIndex].Cells[riter.CellIndex]  = ReplaceObject(riter.ActionAtoms, oldsym, newobj);
                }
                newrules.AddRange(ExpandRule(newrule));
            }
            return(newrules);
        }
예제 #2
0
        // expand an ambiguous direction throughout a rule
        // error if more than one in pattern
        IList <AtomicRule> ExpandDirectionMulti(AtomicRule oldrule, Direction olddir)
        {
            var pcells = oldrule.Patterns.SelectMany(p => p.Cells
                                                     .SelectMany(c => c.Where(a => a.Direction == olddir)));

            if (pcells.Count() != 1)
            {
                _parser.CompileError("'{0}' in action cannot be matched", olddir);
            }

            // expand one rule per single direction
            var newrules = new List <AtomicRule>();

            foreach (var newdir in _expanddirlookup[olddir])
            {
                var newrule = oldrule.Clone();
                for (var riter = new RuleIterator {
                    Rule = oldrule
                }; !riter.Done; riter.Step())
                {
                    newrule.Patterns[riter.SubRuleIndex].Cells[riter.CellIndex] = ReplaceDirection(riter.PatternAtoms, olddir, newdir);
                    newrule.Actions[riter.SubRuleIndex].Cells[riter.CellIndex]  = ReplaceDirection(riter.ActionAtoms, olddir, newdir);
                }
                newrules.AddRange(ExpandRule(newrule));
            }
            return(newrules);
        }
예제 #3
0
        // Convert every relative direction into absolute
        AtomicRule MakeAbsolute(AtomicRule rule, Direction ruledir)
        {
            var newrule = rule.Clone();

            newrule.Directions = new HashSet <Direction>()
            {
                ruledir
            };
            MakeAbsolute(newrule.Patterns, ruledir);
            if (newrule.HasAction)
            {
                MakeAbsolute(newrule.Actions, ruledir);
            }
            return(newrule);
        }