private void AtomicityCheck() { var initialConstraints = new Dictionary <Absy, HashSet <int> >(); foreach (Block header in implGraph.Headers) { if (civlTypeChecker.IsYieldingLoopHeader(header, currLayerNum) || civlTypeChecker.IsCooperatingLoopHeader(header, currLayerNum)) { continue; } initialConstraints[header] = new HashSet <int> { RM }; } if (IsMoverProcedure) { foreach (var call in impl.Blocks.SelectMany(b => b.cmds).OfType <CallCmd>()) { if (!IsCooperatingCall(call)) { initialConstraints[call] = new HashSet <int> { RM }; } } } var simulationRelation = new SimulationRelation <Absy, int, string>(LabelsToLabeledEdges(atomicityLabels), AtomicitySpec, initialConstraints) .ComputeSimulationRelation(); if (IsMoverProcedure) { if (!CheckAtomicity(simulationRelation)) { civlTypeChecker.Error(impl, "The atomicity declared for mover procedure is not valid"); } } else if (simulationRelation[initialState].Count == 0) { civlTypeChecker.Error(impl, $"Implementation {impl.Name} fails atomicity check at layer {currLayerNum}. Transactions must be separated by yields."); } }