/// <summary> /// The singleton instance. /// </summary> /// <returns> /// The <see cref="FaultTreeNodeFactory"/>. /// </returns> public static FaultTreeNodeFactory GetInstance() { return(instance ?? (instance = new FaultTreeNodeFactory())); }
public override FaultTree Read(FileStream stream) { var sr = new StreamReader(stream); //Preprocess lines to remove .dot structures and split information into single lines List <string> lines = sr.ReadToEnd().Split('\n').ToList(); lines = lines.Where(line => !string.IsNullOrWhiteSpace(line)).ToList().GetRange(1, lines.Count - 2).SelectMany(l => l.Split(';')).Where(l => !l.Trim().Equals("")).ToList(); //Create datastructures to store parsed tokens var symbols = from line in lines from pattern in PatternMatcher where pattern.IsMatch(line.Trim()) select new { Token = PatternMatcher.IndexOf(pattern), Information = pattern.Match(line.Trim()) }; //Group symbols be their token (allows for simplified FT construction) var symbolGroup = from symbol in symbols orderby symbol.Token group symbol by symbol.Token; Debug.Assert(symbolGroup.Count(g => g.Key == (int)DotParseToken.DOT_ROOT) == 1); //Extract different node types var rootNode = (from r in symbolGroup.FirstOrDefault(g => g.Key == (int)DotParseToken.DOT_ROOT) select FaultTreeNodeFactory.GetInstance().CreateGateNode(int.Parse(r.Information.Groups["id"].Value), FaultTreeNodeFactory.FaultTreeGateOperator.FAULT_TREE_OPERATOR_AND) as FaultTreeNode).ToList(); var terminals = (from symbol in symbolGroup.FirstOrDefault(g => g.Key == (int)DotParseToken.DOT_IDENTIFIER) select new FaultTreeTerminalNode(int.Parse(symbol.Information.Groups["id"].Value), int.Parse(symbol.Information.Groups["label"].Value))).ToList(); var gates = (from symbol in symbolGroup.FirstOrDefault(g => g.Key == (int)DotParseToken.DOT_GATE) select FaultTreeNodeFactory.GetInstance().CreateGateNode(int.Parse(symbol.Information.Groups["id"].Value), symbol.Information.Groups["operator"].Value) as FaultTreeNode).ToList(); //Union on all nodes var nodes = (from t in terminals select new { t.ID, Node = (FaultTreeNode)t }).Union(from g in gates select new { g.ID, Node = g }).Union(from r in rootNode select new { r.ID, Node = r }).OrderBy(n => n.ID).ToList(); (from trans in symbolGroup.FirstOrDefault(g => g.Key == (int)DotParseToken.DOT_TRANSITION) let f = nodes[int.Parse(trans.Information.Groups["from"].Value)] let t = nodes[int.Parse(trans.Information.Groups["to"].Value)] select new { From = f, To = t }).ToList().ForEach(trans => trans.From.Node.Childs.Add(trans.To.Node)); MarkovChain <FaultTreeTerminalNode> markovChain = new MarkovChain <FaultTreeTerminalNode>(terminals.Count); terminals.ForEach(terminal => markovChain.InitialDistribution[terminal] = 0.0d); if (symbolGroup.FirstOrDefault(g => g.Key == (int)DotParseToken.DOT_MARKOV_TRANSITION)?.Any() ?? false) { (from trans in symbolGroup.FirstOrDefault(g => g.Key == (int)DotParseToken.DOT_MARKOV_TRANSITION) let f = nodes[int.Parse(trans.Information.Groups["from"].Value)].Node as FaultTreeTerminalNode let t = nodes[int.Parse(trans.Information.Groups["to"].Value)].Node as FaultTreeTerminalNode let r = trans.Information.Groups["rate"].Value select new { From = f, To = t, Rate = r }).ToList().ForEach(trans => markovChain[trans.From, trans.To] = double.Parse(trans.Rate)); } if (symbolGroup.FirstOrDefault(g => g.Key == (int)DotParseToken.DOT_IMPLICIT_CHAIN)?.Any() ?? false) { int newLabel = terminals.Max(n => n.Label) + 1; int newID = nodes.Max(n => n.ID) + 1; var markovChainGroup = symbolGroup.FirstOrDefault(g => g.Key == (int)DotParseToken.DOT_IMPLICIT_CHAIN); if (markovChainGroup != null) { foreach (var implicitChain in markovChainGroup) { var newNode = new FaultTreeTerminalNode(newID, newLabel); var existingNode = terminals.First(t => t.ID == int.Parse(implicitChain.Information.Groups["id"].Value)); markovChain[newNode, existingNode] = double.Parse(implicitChain.Information.Groups["lambda"].Value); markovChain[existingNode, newNode] = double.Parse(implicitChain.Information.Groups["mu"].Value); markovChain.InitialDistribution[newNode] = 1.0d; } } } return(new FaultTree(rootNode.ElementAt(0).Childs.ElementAt(0), markovChain)); }