Exemple #1
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);
        }
Exemple #2
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);
        }
Exemple #3
0
        // limited substitution of pattern direction
        IList <AtomicRule> ExpandDirectionSingle(RuleIterator riter, Direction olddir)
        {
            var newrules = new List <AtomicRule>();

            foreach (var newdir in _expanddirlookup[olddir])
            {
                var newrule = riter.Rule.Clone();
                newrule.Patterns[riter.SubRuleIndex].Cells[riter.CellIndex] = ReplaceDirection(riter.PatternAtoms, olddir, newdir);
                if (riter.HasAction)
                {
                    newrule.Actions[riter.SubRuleIndex].Cells[riter.CellIndex] = ReplaceDirection(riter.ActionAtoms, olddir, newdir);
                }
                newrules.AddRange(ExpandRule(newrule));
            }
            return(newrules);
        }
Exemple #4
0
 // expand ambiguous directions in rule pattern known to have no matching action
 // replacing by individuals (absolute or relative)
 // abs could be fixed by more powerful vm code
 IList <AtomicRule> ExpandDirectionSimple(AtomicRule oldrule)
 {
     for (var riter = new RuleIterator {
         Rule = oldrule
     }; !riter.Done; riter.Step())
     {
         // look for any ambiguous unmatched pattern directions, just one each time
         var patom = riter.PatternAtoms.FirstOrDefault(a => _expanddirlookup.ContainsKey(a.Direction));
         if (patom != null)
         {
             return(ExpandDirectionSingle(riter, patom.Direction));
         }
     }
     return(new List <AtomicRule> {
         oldrule
     });
 }
Exemple #5
0
        // expand a rule where an occurrence on an action does not match its pattern
        // replacing combination directions and symbols by individuals (absolute or relative)
        // could be fixed by more powerful vm code
        IList <AtomicRule> ExpandRule(AtomicRule oldrule)
        {
            if (!oldrule.HasAction)
            {
                return(ExpandDirectionSimple(oldrule));
            }

            // check each cell of each subrule
            for (var riter = new RuleIterator {
                Rule = oldrule
            }; !riter.Done; riter.Step())
            {
                // Do no expansion on random actions
                if (riter.ActionAtoms.Any(a => a.IsRandom))
                {
                    oldrule.Prefixes.Add(RulePrefix.Final);
                }
                else
                {
                    // check for action atom with ambiguous direction and no matching pattern atom
                    var datom = riter.ActionAtoms.FirstOrDefault(a => _expanddirlookup.ContainsKey(a.Direction) &&
                                                                 !riter.PatternAtoms.Any(p => p.Matches(a) && p.Direction == a.Direction));
                    if (datom != null)
                    {
                        return(ExpandDirectionMulti(oldrule, datom.Direction));
                    }

                    // check for action atom with property symbol and no matching pattern atom
                    var satom = riter.ActionAtoms.FirstOrDefault(a => a.Symbol.Kind == SymbolKind.Property &&
                                                                 !a.IsNegated && !a.IsRandom && !riter.PatternAtoms.Any(p => p.Matches(a)));
                    if (satom != null)
                    {
                        var newrules = ExpandSymbolMulti(oldrule, satom.Symbol) ?? ExpandPropertyMatcher(riter);
                        if (newrules == null)
                        {
                            _parser.CompileError("'{0}' in action cannot be matched", satom.Symbol.Name);
                        }
                        else
                        {
                            return(newrules);
                        }
                    }
                }
            }
            return(ExpandDirectionSimple(oldrule));
        }
Exemple #6
0
        // look for matching property objects in pattern and action, expand matching pairwise
        IList <AtomicRule> ExpandPropertyMatcher(RuleIterator riter)
        {
            var patom = riter.PatternAtoms.FirstOrDefault(a => a.Symbol.Kind == SymbolKind.Property &&
                                                          !a.IsNegated && !a.IsRandom);
            var aatom = riter.ActionAtoms.FirstOrDefault(a => a.Symbol.Kind == SymbolKind.Property &&
                                                         !a.IsNegated && !a.IsRandom);

            if (patom != null && aatom != null && patom.Symbol.ObjectIds.Count == aatom.Symbol.ObjectIds.Count)
            {
                var newrules = new List <AtomicRule>();
                for (int i = 0; i < patom.Symbol.ObjectIds.Count; i++)
                {
                    var newrule = riter.Rule.Clone();
                    newrule.Prefixes.Add(RulePrefix.Final);
                    newrule.Patterns[riter.SubRuleIndex].Cells[riter.CellIndex]
                        = ReplaceObject(riter.PatternAtoms, patom.Symbol, patom.Symbol.ObjectIds[i]);
                    newrule.Actions[riter.SubRuleIndex].Cells[riter.CellIndex]
                        = ReplaceObject(riter.ActionAtoms, aatom.Symbol, aatom.Symbol.ObjectIds[i]);
                    newrules.Add(newrule);
                }
                return(newrules);
            }
            return(null);
        }