Ejemplo n.º 1
0
        private void onNewInstanceCreated(ActiveInstance activeInstance)
        {
            newInstanceSet.Add(activeInstance);
            ExecutionStrategy ex = activeInstance.IndexedMType.Type.ExecutionStrategy;

            while (ex != null && ex.Rules.Count == 0)
            {
                ex = ex.Next;
            }

            if (ex != null)
            {
                allOperationalInstances.Add(activeInstance);
            }

            if (RegisterNewInstance != null)
            {
                RegisterNewInstance(activeInstance.Instance);
            }

            if (step >= startStep)
            {
                if (recordInstanceCreation)
                {
                    if (NewInstanceCreated != null)
                    {
                        NewInstanceCreated(activeInstance.Instance, activeInstance.Type);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// These are unidirectional methods, should be used with caution otherwise they will cause chaos
        /// </summary>
        /// <param name="ai"></param>
        private void disconnectFrom(ActiveInstance ai)
        {
            List <ActiveInstance> ail = connections[ai.IndexedMType.Index];

            if (ail != null)
            {
                ail.Remove(ai);
            }
        }
Ejemplo n.º 3
0
        public bool IsConnectedTo(ActiveInstance ai)
        {
            List <ActiveInstance> ail = connections[ai.IndexedMType.Index];

            if (ail == null)
            {
                return(false);
            }

            return(ail.Contains(ai));
        }
Ejemplo n.º 4
0
        private void connectTo(ActiveInstance ai)
        {
            List <ActiveInstance> ail = connections[ai.IndexedMType.Index];

            if (ail == null)
            {
                ail = new List <ActiveInstance>();
                connections[ai.IndexedMType.Index] = ail;
            }
            ail.Add(ai);
        }
Ejemplo n.º 5
0
        public void CommitNewInstances(NewActiveInstanceCreated activeInstanceCreated)
        {
            foreach (ActiveInstanceBlueprint aib in newInstances)
            {
                MInstance newInstance = new MInstance();

                //add existing multiset. At this point everything in the Buffer should be commited according to
                //the kP system semantics
                newInstance.Multiset.Add(Instance.Multiset);
                newInstance.Multiset.Add(aib.InstanceBlueprint.Multiset);
                newInstance.IsCreated = true;

                //add the new instance to the KPsystem
                aib.IndexedMType.Type.Instances.Add(newInstance);
                //create the Active instance wrapper and register it to its appropriate type
                ActiveInstance ai = new ActiveInstance(aib.IndexedMType, newInstance, kp);
                ai.connections = new List <ActiveInstance> [kp.Types.Count];
                aib.IndexedMType.Instances.Add(ai);

                //remove connection from this instance and add them to the new active instance and inner MInstance
                for (int i = 0; i < connections.Length; i++)
                {
                    List <ActiveInstance> ail = connections[i];
                    if (ail != null)
                    {
                        foreach (ActiveInstance connection in ail)
                        {
                            connection.disconnectFrom(this);
                            Instance.DisconnectBidirectionalFrom(connection.Instance);
                            newInstance.ConnectBidirectionalTo(connection.Instance);
                            ai.connectTo(connection);
                            connection.connectTo(ai);
                        }
                    }
                }
                if (activeInstanceCreated != null)
                {
                    activeInstanceCreated(ai);
                }
            }
            //clear all connections from this instance
            for (int i = 0; i < connections.Length; i++)
            {
                List <ActiveInstance> ail = connections[i];
                if (ail != null)
                {
                    ail.Clear();
                }
            }
            newInstances.Clear();
            //will need to add each newly created Active instance to the allOperationalInstances and allInstances Lists outside this
            //method
        }
Ejemplo n.º 6
0
        public void AddConnectionTo(ActiveInstance ai)
        {
            List <ActiveInstance> ail = connections[ai.IndexedMType.Index];

            if (ail == null)
            {
                ail = new List <ActiveInstance>();
                connections[ai.IndexedMType.Index] = ail;
            }
            ail.Add(ai);
            Instance.ConnectBidirectionalTo(ai.Instance);
            ail = ai.connections[IndexedMType.Index];
            if (ail == null)
            {
                ail = new List <ActiveInstance>();
                ai.connections[IndexedMType.Index] = ail;
            }
            ail.Add(this);
        }
Ejemplo n.º 7
0
        public void Reset(KPsystem newModel)
        {
            Reset();
            kp = newModel;

            allInstances.Clear();
            allOperationalInstances.Clear();
            indexedTypes.Clear();

            int i = 0;

            foreach (MType mtype in kp.Types)
            {
                IndexedMType imt = new IndexedMType(mtype, i++);
                indexedTypes.Add(imt);
                indexedTypesByName.Add(mtype.Name, imt);

                ExecutionStrategy ex = mtype.ExecutionStrategy;
                while (ex != null && ex.Rules.Count == 0)
                {
                    ex = ex.Next;
                }
                foreach (MInstance instance in mtype.Instances)
                {
                    ActiveInstance activeInstance = new ActiveInstance(imt, instance, kp);
                    allInstances.Add(activeInstance);
                    aiMapping.Add(instance, activeInstance);
                    if (ex != null)
                    {
                        allOperationalInstances.Add(activeInstance);
                        activeInstance.CurrentStrategySegment = ex;
                    }
                }
            }

            foreach (ActiveInstance ai in allInstances)
            {
                ai.GenerateConnections(aiMapping);
                //set execution strategy to begining
                ai.ResetCurrentStrategySegment();
            }
        }
Ejemplo n.º 8
0
        public void GenerateConnections(Dictionary <MInstance, ActiveInstance> instanceMapping)
        {
            //init connections array
            connections = new List <ActiveInstance> [kp.Types.Count];

            foreach (MInstance instance in Instance.Connections)
            {
                ActiveInstance ai = null;
                instanceMapping.TryGetValue(instance, out ai);
                if (ai != null)
                {
                    List <ActiveInstance> ail = connections[ai.TypeIndex];
                    if (ail == null)
                    {
                        ail = new List <ActiveInstance>();
                        connections[ai.TypeIndex] = ail;
                    }
                    ail.Add(ai);
                }
            }
        }
Ejemplo n.º 9
0
 /// <summary>
 /// Do no use these methods when iterating on connections lists of other active membranes
 /// </summary>
 /// <param name="ai"></param>
 public void RemoveConnectionTo(ActiveInstance ai)
 {
     connections[ai.IndexedMType.Index].Remove(ai);
     Instance.DisconnectBidirectionalFrom(ai.Instance);
     ai.connections[IndexedMType.Index].Remove(this);
 }
Ejemplo n.º 10
0
        public KPsystem Run()
        {
            KpSimulationStep simStep = new KpSimulationStep()
            {
                KPsystem = kp, Step = step
            };

            if (SimulationStarted != null)
            {
                SimulationStarted(kp);
            }

            List <ActiveInstance>    activeInstances  = new List <ActiveInstance>();
            List <ActiveInstance>    targetSelections = new List <ActiveInstance>();
            HashSet <ActiveInstance> deadCells        = new HashSet <ActiveInstance>();

            while (!isHalted && step <= endStep)
            {
                rulesApplied = 0;
                bool advanceStrategyBlock = false;
                bool endStepForInstance   = false;

                bool dissolutionRuleApplied = false;
                bool divisionRuleApplied    = false;
                bool linkRuleApplied        = false;

                activeInstances.AddRange(allOperationalInstances);
                int aiCount = activeInstances.Count;

                while (aiCount > 0)
                {
                    //reset instance flags
                    advanceStrategyBlock = false;
                    endStepForInstance   = false;

                    //select an instance
                    ActiveInstance selectedInstance = activeInstances[rand.Next(aiCount)];

                    ExecutionStrategy ex = selectedInstance.CurrentStrategySegment;

                    //this can only happen if the rule set was set to empty
                    if (selectedInstance.ApplicableRules.Count > 0)
                    {
                        Rule selectedRule     = null;
                        bool isRuleApplicable = true;
                        if (ex.Operator == StrategyOperator.SEQUENCE)
                        {
                            selectedRule = selectedInstance.ApplicableRules.First();
                            if (selectedRule.IsGuarded)
                            {
                                if (!selectedRule.Guard.IsSatisfiedBy(selectedInstance.Instance.Multiset))
                                {
                                    isRuleApplicable = false;
                                }
                                else if (selectedInstance.FlagStructureRuleApplied)
                                {
                                    if (selectedRule.IsStructureChangingRule())
                                    {
                                        isRuleApplicable = false;
                                    }
                                }
                            }
                        }
                        else
                        {
                            int selectedIndex = 0;
                            int arCount       = selectedInstance.ApplicableRules.Count;

                            if (ex.Operator == StrategyOperator.ARBITRARY)
                            {
                                selectedIndex = rand.Next(arCount + 1);
                            }
                            else
                            {
                                selectedIndex = rand.Next(arCount);
                            }

                            if (selectedIndex == arCount)
                            {
                                //this essentially means "skip this block" - always in an arbitrary block, never elsewhere
                                selectedRule     = null;
                                isRuleApplicable = false;
                            }
                            else
                            {
                                selectedRule = selectedInstance.ApplicableRules[selectedIndex];
                                if (selectedInstance.FlagStructureRuleApplied)
                                {
                                    if (selectedRule.IsStructureChangingRule())
                                    {
                                        isRuleApplicable = false;
                                    }
                                }
                            }
                        }

                        if (isRuleApplicable)
                        {
                            if (selectedRule is ConsumerRule)
                            {
                                if ((selectedRule as ConsumerRule).Lhs > selectedInstance.Instance.Multiset)
                                {
                                    isRuleApplicable = false;
                                }
                            }
                        }

                        //At this point, the isRuleApplicable basically confirms that no structure rule has been applied thus far
                        //if the selected rule requires this, if guarded, the guard of the selected rule holds and
                        //the left hand multiset is contained in the instance multiset
                        if (isRuleApplicable)
                        {
                            switch (selectedRule.Type)
                            {
                            case RuleType.REWRITE_COMMUNICATION: {
                                RewriteCommunicationRule rcr = selectedRule as RewriteCommunicationRule;
                                foreach (KeyValuePair <IInstanceIdentifier, TargetedMultiset> kv in rcr.TargetRhs)
                                {
                                    if (kv.Key is InstanceIdentifier)
                                    {
                                        InstanceIdentifier iid = kv.Key as InstanceIdentifier;
                                        if (iid.Indicator == InstanceIndicator.TYPE)
                                        {
                                            IndexedMType targetType = indexedTypesByName[iid.Value];
                                            int          cCount     = selectedInstance.ConnectionCount(targetType);
                                            if (cCount > 0)
                                            {
                                                ActiveInstance selectedTarget = selectedInstance.GetTargetAtIndex(rand.Next(cCount), targetType);
                                                selectedTarget.CommunicatedMultiset = kv.Value.Multiset;
                                                targetSelections.Add(selectedTarget);
                                            }
                                            else
                                            {
                                                isRuleApplicable = false;
                                                break;
                                            }
                                        }
                                    }
                                }
                                if (isRuleApplicable)
                                {
                                    selectedInstance.Instance.Multiset.Subtract(rcr.Lhs);
                                    selectedInstance.Buffer.Add(rcr.Rhs);
                                    ruleApplied(selectedRule, selectedInstance.Instance);
                                    foreach (ActiveInstance ai in targetSelections)
                                    {
                                        if (step >= startStep)
                                        {
                                            if (recordTargetSelection)
                                            {
                                                if (TargetSelected != null)
                                                {
                                                    TargetSelected(ai.Instance, ai.Type, selectedRule);
                                                }
                                            }
                                        }
                                        ai.CommitCommunication();
                                    }
                                }
                                else
                                {
                                    foreach (ActiveInstance ai in targetSelections)
                                    {
                                        ai.ResetCommunication();
                                    }
                                }
                                targetSelections.Clear();
                            } break;

                            case RuleType.MULTISET_REWRITING: {
                                ruleApplied(selectedRule, selectedInstance.Instance);
                                selectedInstance.Instance.Multiset.Subtract((selectedRule as ConsumerRule).Lhs);
                                selectedInstance.Buffer.Add((selectedRule as RewritingRule).Rhs);
                            } break;

                            case RuleType.MEMBRANE_DISSOLUTION: {
                                ruleApplied(selectedRule, selectedInstance.Instance);
                                dissolutionRuleApplied         = true;
                                selectedInstance.FlagDissolved = true;
                                selectedInstance.Instance.Multiset.Subtract((selectedRule as ConsumerRule).Lhs);
                            } break;

                            case RuleType.LINK_CREATION: {
                                LinkRule lr = selectedRule as LinkRule;
                                if (lr.Target is InstanceIdentifier)
                                {
                                    string         typeName       = (lr.Target as InstanceIdentifier).Value;
                                    IndexedMType   targetType     = indexedTypesByName[typeName];
                                    ActiveInstance selectedTarget = null;
                                    //check if there is a link-free instance we can connect to
                                    int freeLinkCount = targetType.Instances.Count - selectedInstance.ConnectionCount(targetType);
                                    if (freeLinkCount > 0)
                                    {
                                        int selection = rand.Next(freeLinkCount);
                                        int i         = 0;
                                        foreach (ActiveInstance ai in targetType.Instances)
                                        {
                                            if (!selectedInstance.IsConnectedTo(ai))
                                            {
                                                if (i++ == selection)
                                                {
                                                    selectedTarget = ai;
                                                }
                                            }
                                        }

                                        selectedInstance.Instance.Multiset.Subtract(lr.Lhs);
                                        ruleApplied(selectedRule, selectedInstance.Instance);
                                        linkRuleApplied = true;
                                        //selected target can't be null here
                                        selectedInstance.ConnectionToCreate  = selectedTarget;
                                        selectedInstance.FlagLinkRuleApplied = true;
                                        if (step >= startStep)
                                        {
                                            if (recordTargetSelection)
                                            {
                                                if (TargetSelected != null)
                                                {
                                                    TargetSelected(selectedTarget.Instance, selectedTarget.Type, selectedRule);
                                                }
                                            }
                                        }

                                        //a structure rule can only be applied once per step so remove it
                                        selectedInstance.ApplicableRules.Remove(selectedRule);
                                    }
                                    else
                                    {
                                        isRuleApplicable = false;
                                    }
                                }
                            } break;

                            case RuleType.LINK_DESTRUCTION: {
                                LinkRule lr = selectedRule as LinkRule;
                                if (lr.Target is InstanceIdentifier)
                                {
                                    string       typeName   = (lr.Target as InstanceIdentifier).Value;
                                    IndexedMType targetType = indexedTypesByName[typeName];
                                    int          cCount     = selectedInstance.ConnectionCount(targetType);
                                    if (cCount > 0)
                                    {
                                        ActiveInstance selectedTarget = selectedInstance.GetTargetAtIndex(rand.Next(cCount), targetType);

                                        selectedInstance.Instance.Multiset.Subtract(lr.Lhs);
                                        ruleApplied(selectedRule, selectedInstance.Instance);
                                        linkRuleApplied = true;
                                        //selected target can't be null here
                                        selectedInstance.ConnectionToDestroy = selectedTarget;
                                        selectedInstance.FlagLinkRuleApplied = true;
                                        if (step >= startStep)
                                        {
                                            if (recordTargetSelection)
                                            {
                                                if (TargetSelected != null)
                                                {
                                                    TargetSelected(selectedTarget.Instance, selectedTarget.Type, selectedRule);
                                                }
                                            }
                                        }

                                        //a structure rule can only be applied once per step so remove it
                                        selectedInstance.ApplicableRules.Remove(selectedRule);
                                    }
                                    else
                                    {
                                        isRuleApplicable = false;
                                    }
                                }
                            } break;

                            case RuleType.MEMBRANE_DIVISION: {
                                DivisionRule dr = selectedRule as DivisionRule;
                                selectedInstance.Instance.Multiset.Subtract(dr.Lhs);
                                foreach (InstanceBlueprint ib in dr.Rhs)
                                {
                                    selectedInstance.AddInstanceBlueprint(ib, indexedTypesByName[ib.Type.Name]);
                                }
                                selectedInstance.FlagDivided = true;
                                ruleApplied(selectedRule, selectedInstance.Instance);
                                divisionRuleApplied = true;
                            } break;
                            }
                        }


                        if (selectedInstance.FlagDissolved || selectedInstance.FlagDivided)
                        {
                            allOperationalInstances.Remove(selectedInstance);
                            endStepForInstance = true;
                        }
                        else
                        {
                            switch (ex.Operator)
                            {
                            case StrategyOperator.SEQUENCE: {
                                if (isRuleApplicable)
                                {
                                    selectedInstance.ApplicableRules.Remove(selectedRule);
                                }
                                else
                                {
                                    endStepForInstance = true;
                                }
                            } break;

                            case StrategyOperator.MAX: {
                                if (!isRuleApplicable)
                                {
                                    selectedInstance.ApplicableRules.Remove(selectedRule);
                                }
                            } break;

                            case StrategyOperator.CHOICE: {
                                if (isRuleApplicable)
                                {
                                    advanceStrategyBlock = true;
                                }
                                else
                                {
                                    selectedInstance.ApplicableRules.Remove(selectedRule);
                                }
                            } break;

                            case StrategyOperator.ARBITRARY: {
                                if (!isRuleApplicable)
                                {
                                    if (selectedRule == null)
                                    {
                                        advanceStrategyBlock = true;
                                    }
                                    else
                                    {
                                        selectedInstance.ApplicableRules.Remove(selectedRule);
                                    }
                                }
                            } break;
                            }
                        }
                    }

                    if (endStepForInstance)
                    {
                        activeInstances.Remove(selectedInstance);
                    }
                    else
                    {
                        if (selectedInstance.ApplicableRules.Count == 0)
                        {
                            advanceStrategyBlock = true;
                        }

                        if (advanceStrategyBlock)
                        {
                            ex = ex.Next;

                            //if the next execution block is null, then remove this compartment from the active instance array
                            if (ex == null)
                            {
                                activeInstances.Remove(selectedInstance);
                            }
                            else
                            {
                                selectedInstance.CurrentStrategySegment = ex;
                            }
                        }
                    }

                    aiCount = activeInstances.Count;
                }

                if (rulesApplied == 0)
                {
                    isHalted = true;
                }
                else
                {
                    //Clear buffer for all instances;

                    foreach (ActiveInstance instance in allInstances)
                    {
                        instance.CommitBuffer();

                        if (linkRuleApplied)
                        {
                            if (instance.FlagLinkRuleApplied)
                            {
                                instance.CommitConnectionUpdates();
                            }
                        }
                    }

                    if (dissolutionRuleApplied || divisionRuleApplied)
                    {
                        foreach (ActiveInstance instance in allInstances)
                        {
                            if (instance.FlagDissolved)
                            {
                                instance.Instance.IsDissolved = true;
                                deadCells.Add(instance);
                                instance.CommitDissolution();
                            }
                            else if (instance.FlagDivided)
                            {
                                instance.Instance.IsDivided = true;
                                deadCells.Add(instance);
                                instance.CommitNewInstances(onNewInstanceCreated);
                            }
                        }

                        if (divisionRuleApplied)
                        {
                            foreach (ActiveInstance ai in newInstanceSet)
                            {
                                allInstances.Add(ai);
                            }
                            newInstanceSet.Clear();
                        }
                    }

                    foreach (ActiveInstance instance in deadCells)
                    {
                        //remove from allInstances collection such that a dead instance will never be
                        //considered for updates or any sort of operations
                        allInstances.Remove(instance);
                        //remove this instance from the set of instances associated to its type so
                        //it will never be considered for link creation or destruction
                        instance.IndexedMType.Instances.Remove(instance);
                    }

                    if (deadCells.Count > 0)
                    {
                        deadCells.Clear();
                    }

                    //reset execution strategy to begining
                    //it's important this is done after everthing has been commited, because the guards must be evaluated on the updated multiset
                    //in the instance
                    foreach (ActiveInstance ai in allOperationalInstances)
                    {
                        ai.ResetCurrentStrategySegment();
                    }

                    if (step >= startStep)
                    {
                        if (SimulationParams.RecordConfigurations)
                        {
                            if (StepComplete != null)
                            {
                                simStep.Step = step;
                                StepComplete(simStep);
                            }
                        }
                    }
                    ++step;
                }
            }

            --step;
            if (IsHalted() && SystemHalted != null)
            {
                SystemHalted(step);
            }
            if (SimulationComplete != null)
            {
                SimulationComplete(step);
            }

            return(kp);
        }