/// <summary></summary> protected virtual bool InferTemplates(ref bool exit, IList <ISource> unresolvedSourceList, IErrorList errorList) { bool Success = true; List <ISource> FailedSourceList = new List <ISource>(); for (int i = 0; i < RuleTemplateList.Count; i++) { IRuleTemplate Rule = RuleTemplateList[i]; /*if (Rule is IQueryOverloadTypeConformanceRuleTemplate AsRuleTemplate) * { * * }*/ foreach (ISource Source in unresolvedSourceList) { if (!Rule.NodeType.IsAssignableFrom(Source.GetType())) { continue; } bool IsNoDestinationSet = Rule.IsNoDestinationSet(Source); if (IsNoDestinationSet) { bool AreAllSourcesReady = Rule.AreAllSourcesReady(Source, out IDictionary <ISourceTemplate, object> DataList); bool NoError = Rule.ErrorList.IsEmpty; if (!AreAllSourcesReady && !FailedSourceList.Contains(Source)) { FailedSourceList.Add(Source); } if (AreAllSourcesReady && NoError) { if (Rule.CheckConsistency(Source, DataList, out object data)) { Debug.Assert(Rule.ErrorList.IsEmpty); Rule.Apply(Source, data); Debug.Assert(Rule.AreAllDestinationsSet(Source)); exit = false; } else { Debug.Assert(!Rule.ErrorList.IsEmpty); errorList.AddErrors(Rule.ErrorList); Success = false; } } } } } return(Success); }
private static void ShuffleRules(IList <IRuleTemplate> ruleTemplateList, int retries) { Random Rng = new Random(retries); int ShuffleCount = ruleTemplateList.Count * 4; int Count = ruleTemplateList.Count; for (int i = 0; i < ShuffleCount; i++) { int Index = Rng.Next(Count); IRuleTemplate RuleTemplate = ruleTemplateList[Index]; ruleTemplateList.RemoveAt(Index); Index = Rng.Next(Count); ruleTemplateList.Insert(Index, RuleTemplate); } }
private bool FindRuleWithDestination(ICollection <IRuleTemplate> ruleTemplateList, IList <ISource> unresolvedSourceList, string path, Type type, ITemplatePathStart startingPoint, out IRuleTemplate matchingRule) { matchingRule = null; foreach (IRuleTemplate Rule in ruleTemplateList) { foreach (ISource Source in unresolvedSourceList) { if (!Rule.NodeType.IsAssignableFrom(Source.GetType())) { continue; } IList <IDestinationTemplate> DestinationTemplateList = Rule.GetAllDestinationTemplatesNotSet(Source); foreach (IDestinationTemplate DestinationTemplate in DestinationTemplateList) { if (DestinationTemplate.Path == path && DestinationTemplate.StartingPoint == startingPoint) { if (DestinationTemplate.DestinationType == type) { matchingRule = Rule; return(true); } } } } } return(false); }
private void ListDependencies(IList <ISource> unresolvedSourceList) { Debug.WriteLine("Performing cyclic dependencies analysis..."); Dictionary <IRuleTemplate, IList <ISource> > Analysis = new Dictionary <IRuleTemplate, IList <ISource> >(); foreach (IRuleTemplate Rule in RuleTemplateList) { /*if (Rule is IConstraintRuleTemplate AsRuleTemplate) * { * * }*/ foreach (ISource Source in unresolvedSourceList) { if (!Rule.NodeType.IsAssignableFrom(Source.GetType())) { continue; } bool IsNoDestinationSet = Rule.IsNoDestinationSet(Source); if (IsNoDestinationSet) { bool AreAllSourcesReady = Rule.AreAllSourcesReady(Source, out IDictionary <ISourceTemplate, object> DataList); if (!AreAllSourcesReady) { IList <ISourceTemplate> SourceTemplateList = Rule.GetAllSourceTemplatesNotReady(Source); Debug.Assert(SourceTemplateList.Count > 0); if (!Analysis.ContainsKey(Rule)) { Analysis.Add(Rule, new List <ISource>()); } Analysis[Rule].Add(Source); } } } } bool Exit; do { ICollection <IRuleTemplate> Rules = Analysis.Keys; IList <IRuleTemplate> ToRemove = new List <IRuleTemplate>(); foreach (KeyValuePair <IRuleTemplate, IList <ISource> > Entry in Analysis) { IRuleTemplate Rule = Entry.Key; IList <ISource> SourceList = Entry.Value; Debug.Assert(SourceList.Count > 0); foreach (ISource Source in SourceList) { IList <ISourceTemplate> SourceTemplateList = Rule.GetAllSourceTemplatesNotReady(Source); Debug.Assert(SourceTemplateList.Count > 0); foreach (ISourceTemplate SourceTemplate in SourceTemplateList) { string Path = SourceTemplate.Path; Type SourceType = SourceTemplate.SourceType; ITemplatePathStart StartingPoint = SourceTemplate.StartingPoint; if (FindRuleWithDestination(Rules, unresolvedSourceList, Path, SourceType, StartingPoint, out IRuleTemplate MatchingRule)) { if (!ToRemove.Contains(Rule)) { ToRemove.Add(Rule); } } } } } foreach (IRuleTemplate Rule in ToRemove) { Analysis.Remove(Rule); } Exit = ToRemove.Count == 0; }while (!Exit); Debug.WriteLine($"{Analysis.Count} rule(s) are waiting on a source template:"); foreach (KeyValuePair <IRuleTemplate, IList <ISource> > Entry in Analysis) { Debug.WriteLine($"{Entry.Key} on {Entry.Value.Count} node(s)"); } }