public DerivationSequence AddDerivation(DerivationRule derivationRule, string derivedWord) { bool derivationIsSilent = derivationRule.Attributes.Contains(DerivationAttribute.Silent); return(With( allDerivationsTaken: AllDerivationsTaken.Add(derivationRule), nonSilentDerivationsTaken: !derivationIsSilent ? NonSilentDerivationsTaken.Add(derivationRule) : null, nonSilentWordFormProgression: !derivationIsSilent ? NonSilentWordFormProgression.Add(derivedWord) : null)); }
public bool IsInvalidDerivation() { /* * Check if any derivation in the sequence follows a sequence of derivations * that it's not allowed to follow. */ for (int i = 0; i < AllDerivationsTaken.Count; i++) { var derivation = AllDerivationsTaken[i]; foreach (var forbiddenPredecessorSequence in derivation.CannotFollow) { int nextDerivationOffset = 1; /* * The forbidden predecessor sequences are expressed in forward-order in derivations.js, * because they are easier to think about that way. But the conjugation code works in * reverse order, so we have to consider the forbidden predecessor sequences in reverse * order also. So start at the back of the sequence. */ for (int g = forbiddenPredecessorSequence.Count - 1; g >= 0; --g, ++nextDerivationOffset) { var nextDerivation = AllDerivationsTaken.ElementAtOrDefault(i + nextDerivationOffset); if (nextDerivation == null || nextDerivation.ConjugatedWordType != forbiddenPredecessorSequence[g]) { break; // A forbidden predecessor sequence was matched. Return true. } if (g == 0) { return(true); } } } } return(false); // No forbidden predecessor sequence was matched. }