/// <summary> /// Compute the abstract successors caused by updating the queue of <paramref name="currIndex"/> machine. /// /// </summary> /// <param name="currIndex">The index for the machine about to explore</param> /// <param name="abstract_succs"></param> /// <param name="abstract_succs_SW"></param> void CollectAbstractSuccessorsFromList(int currIndex, HashSet <int> abstract_succs, StreamWriter abstract_succs_SW) { List <PrtEventNode> preDequeEvents = ImplMachines[currIndex].eventQueue.events; // pre-dequeue events list var choiceVector = new List <bool>(); bool more; do { StateImpl succ = (StateImpl)Clone(); PrtImplMachine machineOfSucc = succ.ImplMachines[currIndex]; // the machine of successor indexing in currIndex PrtEventBuffer queueOfMachine = machineOfSucc.eventQueue; // the message queue of successor machine List <PrtEventNode> queueEvents = queueOfMachine.events; // the events list of successor machine more = machineOfSucc.PrtRunStateMachineNextChoice(choiceVector); Debug.Assert(preDequeEvents.Count - queueOfMachine.Size() <= 1); // we have dequeued at most one event /// If dequeing was unsuccessful, then there is nothing left to do. /// No more nondeterministic choices to try if (preDequeEvents.Count == queueOfMachine.Size() || succ.CheckFailure(0)) // { return; // } int idxOfEventDequeuedFromSuffix = Math.Max(PrtEventBuffer.idxOfLastDequeuedEvent, PrtEventBuffer.p); PrtEventNode eventDequeuedFromSuffix = preDequeEvents[idxOfEventDequeuedFromSuffix]; /// <remarks>Choice 1: </remarks> The eventDequeuedFromSuffix, aka the last dequeued event, existed /// exactly once in the concrete suffix. /// Then it is gone after the dequeue, in both abstract and concrete. The new state abstract is valid. succ.AddToAbstractSuccessorsIfInvSat(currIndex, this, abstract_succs, abstract_succs_SW); /// <remarks>Choice 1: </remarks> The eventDequeuedFromSuffix, aka the last dequeued event, existed /// >= twice in concrete suffix. /// We need to find all positions where to re-introduce it in the abstract queue, and try them all /// non-deterministically. for (int pos = idxOfEventDequeuedFromSuffix; pos < queueOfMachine.Size(); ++pos) { // insert eventDequeuedFromSuffix at position pos (push the rest to the right) queueEvents.Insert(pos, eventDequeuedFromSuffix); succ.AddToAbstractSuccessorsIfInvSat(currIndex, this, abstract_succs, abstract_succs_SW); queueEvents.RemoveAt(pos); // restore previous state } queueEvents.Add(eventDequeuedFromSuffix); // finally, insert eventDequeuedFromSuffix at end succ.AddToAbstractSuccessorsIfInvSat(currIndex, this, abstract_succs, abstract_succs_SW); } while (more); }
public void EnqueueEvent(PrtValue e, PrtValue arg, string senderMachineName, string senderMachineStateName) { Debug.Assert(e is PrtEventValue, "Illegal enqueue of null event"); var en = new PrtEventNode(e, arg, senderMachineName, senderMachineStateName); if (IsConcrete()) // concrete: honor k-bounded queue semantics, instance counters, etc { if (k > 0 && Size() == k) { // Console.WriteLine("PrtEventBuffer.EnqueueEvent: queue bound {0} reached in attempt to enqueue; rejecting send event", k); throw new PrtAssumeFailureException(); } PrtEventValue ev = e as PrtEventValue; if (ev.evt.maxInstances != PrtEvent.DefaultMaxInstances) // instance counter is used { if (CalculateInstances(e) == ev.evt.maxInstances) { if (ev.evt.doAssume) { throw new PrtAssumeFailureException(); } else { throw new PrtMaxEventInstancesExceededException(String.Format(@"< Exception > Attempting to enqueue event {0} more than {1} many times\n", ev.evt.name, ev.evt.maxInstances)); } } } } events.Add(en); // concrete or abstract if (IsAbstract() && Size() >= p + 2) // if the suffix was not empty before enqueuing this element { RemoveDuplicatesInSuffix(); } }