/// <summary> TODO low priority: move to class Connector when PSystem is available as singleton /// Checks whether two connector are mutually compatible (dimension, size, glues). /// Order of connectors matters due to possibly asymmetric glue relation! /// </summary> /// <param name="connector1"></param> /// <param name="connector2"></param> public bool AreCompatible(ConnectorOnTile connector1, ConnectorOnTile connector2) { return(GlueRelation.ContainsKey(Tuple.Create(connector1.Glue, connector2.Glue)) && (connector1.Positions.Count == 1 && connector2.Positions.Count == 1 && (connector1.OnTile.Vertices is Segment3D || connector2.OnTile.Vertices is Segment3D) || connector1.Positions.Count == 2 && connector2.Positions.Count == 2 && Math.Abs(connector1.Positions[0].DistanceTo(connector1.Positions[1]) - connector2.Positions[0].DistanceTo(connector2.Positions[1])) <= Tolerance)); }
/// <summary> /// P system constructor used during simulation. /// </summary> /// <param name="mSystemObjects">Deserialized M System objects.</param> /// <exception cref="ArgumentException"> /// If M System objects objecst list is null. /// </exception> public PSystem(DeserializedObjects mSystemObjects) { if (mSystemObjects == null) { throw new ArgumentException("M System objects can't be null."); } SeedTiles = mSystemObjects.SeedTiles; GlueRadius = mSystemObjects.GlueRadius; FloatingObjects = new ReadOnlyDictionary <string, FloatingObject>(mSystemObjects.FloatingObjects); if (FloatingObjects.Any()) { Mobility = FloatingObjects.Values.Max(obj => obj.Mobility); } v_Proteins = new ReadOnlyDictionary <string, Protein>(mSystemObjects.Proteins); Tiles = new ReadOnlyDictionary <string, Tile>(mSystemObjects.Tiles); GlueRelation = mSystemObjects.GluePRelation; v_EvolutionRules = mSystemObjects.EvolutionRules; //====================================================================== MetabolicRules = new Dictionary <string, IReadOnlyList <EvoMetabolicRule> >(); foreach (string proteinName in v_Proteins.Keys) { MetabolicRules[proteinName] = v_EvolutionRules.OfType <EvoMetabolicRule>().Where(rule => proteinName == rule.RProtein.Name).ToList(); } //====================================================================== CreationRules = new Dictionary <Glue, IReadOnlyList <EvoNonMetabolicRule> >(); foreach (Glue glue in mSystemObjects.Glues.Values) { var creationRules = v_EvolutionRules.OfType <EvoNonMetabolicRule>().Where(rule => rule.Type == EvolutionRule.RuleType.Create).ToList(); CreationRulesPriorities = new SortedSet <int>(creationRules.Select(rule => rule.Priority)); CreationRules[glue] = creationRules.Where(rule => rule.RightSideObjects.OfType <Tile>().Single() .Connectors.Any(connector => GlueRelation.ContainsKey(Tuple.Create(glue, connector.Glue)))) .ToList(); } //====================================================================== InsertionRules = new Dictionary <Glue, Dictionary <Glue, IReadOnlyList <EvoNonMetabolicRule> > >(); foreach (Glue glue1 in mSystemObjects.Glues.Values) { foreach (Glue glue2 in mSystemObjects.Glues.Values) { var insRules = v_EvolutionRules.OfType <EvoNonMetabolicRule>() .Where(rule => (rule.Type == EvolutionRule.RuleType.Insert) && IsInsertable(rule.RightSideObjects.OfType <Tile>().Single(), glue1, glue2)) .ToList(); if (insRules.Any()) { AddRulesToDictionary(InsertionRules, glue1, glue2, insRules); AddRulesToDictionary(InsertionRules, glue2, glue1, insRules); } } } //====================================================================== DestructionRules = new Dictionary <string, IReadOnlyList <EvoNonMetabolicRule> >(); foreach (string tileName in Tiles.Keys) { DestructionRules[tileName] = v_EvolutionRules.OfType <EvoNonMetabolicRule>().Where(rule => (rule.Type == EvolutionRule.RuleType.Destroy) && rule.LeftSideObjects.OfType <Tile>().Single().Name == tileName).ToList(); } //====================================================================== DivisionRules = new Dictionary <Glue, Dictionary <Glue, IReadOnlyList <EvoNonMetabolicRule> > >(); foreach (Glue glue1 in mSystemObjects.Glues.Values) { foreach (Glue glue2 in mSystemObjects.Glues.Values) { var divRules = v_EvolutionRules.OfType <EvoNonMetabolicRule>() .Where(rule => (rule.Type == EvolutionRule.RuleType.Divide) && glue1 == (Glue)rule.RightSideObjects[0] && glue2 == (Glue)rule.RightSideObjects[1]) .ToList(); if (divRules.Any()) { AddRulesToDictionary(DivisionRules, glue1, glue2, divRules); AddRulesToDictionary(DivisionRules, glue2, glue1, divRules); } } } }