/// <summary> /// Evaluates the application of the given operator for compliance with mutex groups. We assume the corresponding reference state /// has been already set (via LockState). Goes through the operator effects and locks all active mutexes. /// </summary> /// <param name="oper">Operator to be checked.</param> /// <returns>True, if the operator is applicable with compliance with the mutex groups, false otherwise.</returns> private bool LockForwardOperator(IOperator oper) { InitLocksByState(); for (int groupIndex = 0; groupIndex < MutexGroups.Count; ++groupIndex) { if (IsGroupLocked(groupIndex)) { foreach (var effect in oper.GetEffects()) { if (effect.IsApplicable(LockedState)) // effect can be conditional { // if any effect alters the currently locked item, then we need to unlock it if (TryUnlockAlteredMutexItem(groupIndex, effect.GetAssignment())) { break; } } } } var mutexGroup = MutexGroups[groupIndex]; foreach (var effect in oper.GetEffects()) { if (effect.IsApplicable(LockedState)) // effect can be conditional { int itemIndex; if (mutexGroup.TryFindAffectedMutexItem(effect.GetAssignment(), out itemIndex)) { if (!TryLockMutex(groupIndex, itemIndex)) { return(false); } } } } } return(true); }