/// <summary> /// Returns structural attributes for the provided grammar character. /// </summary> /// <param name="grammarCharacter"></param> /// <returns></returns> public BigInteger GetAttributes(GrammarCharacter grammarCharacter) { if (grammarCharacter == GrammarCharacter.O) { return(EnglishAttributes.O); } if (grammarCharacter == GrammarCharacter.I) { return(EnglishAttributes.I); } if (grammarCharacter == GrammarCharacter.A) { return(EnglishAttributes.A); } if (grammarCharacter == GrammarCharacter.E) { return(EnglishAttributes.E); } if (grammarCharacter == GrammarCharacter.U) { return(EnglishAttributes.U); } return(EnglishAttributes.Epsilon); }
public override int GetHashCode() { int hash = 486187739; hash = (hash * 16777619) ^ MorphRule.GetHashCode(); hash = (hash * 16777619) ^ GrammarCharacter.GetHashCode(); hash = (hash * 16777619) ^ AttributesRule.GetHashCode(); hash = (hash * 16777619) ^ SubstitutionRule.GetHashCode(); return(hash); }
public MorphemeRule(GrammarCharacter grammarCharacter, IRule <string> morphRule, IRule <BigInteger> attributesRule) { GrammarCharacter = grammarCharacter; MorphRule = morphRule ?? throw new ArgumentNullException(nameof(morphRule)); AttributesRule = attributesRule ?? throw new ArgumentNullException(nameof(attributesRule)); }
// Note: indirect append means that adtress (with unfilled values) will be inserted inbetween start and end adtree. // Unfilled values are expected to be filled later otherwise the adtree will be not valid. private void TryToAppendIndirectly(AttachingPosition appendingPositionOfStartElement, IAdTree start, IAdTree end, string expectedSignature, List <IAdTree> results) { using (Trace.Entering()) { GrammarCharacter startGrammarCharacter = GrammarCharacter.e; GrammarCharacter endGrammarCharacter = GrammarCharacter.e; // If start adTree connects the bridge on its left. if (appendingPositionOfStartElement == AttachingPosition.ParrentForLeft) { startGrammarCharacter = start.Pattern.LeftRule.GrammarCharacter; endGrammarCharacter = end.RulingGrammarCharacter; } // If start adTree connects the bridge on its right. else if (appendingPositionOfStartElement == AttachingPosition.ParrentForRight) { startGrammarCharacter = start.Pattern.RightRule.GrammarCharacter; endGrammarCharacter = end.RulingGrammarCharacter; } // If the bridge connects the start adtree on its left. else if (appendingPositionOfStartElement == AttachingPosition.ChildOnLeft) { startGrammarCharacter = start.RulingGrammarCharacter; endGrammarCharacter = end.RulingGrammarCharacter; } // If the bridge connects the start adtree on its right. else if (appendingPositionOfStartElement == AttachingPosition.ChildOnRight) { startGrammarCharacter = start.RulingGrammarCharacter; endGrammarCharacter = end.RulingGrammarCharacter; } // Get all possibile ways how to get from start to end grammar character and path is not greater than 4. IEnumerable <IReadOnlyList <DirectedEdge <GrammarCharacter, Pattern> > > connectionPaths = myConstructiveDictionary.PatternGraph .FindAllEdges(startGrammarCharacter, endGrammarCharacter).ToList(); // Go via all possible ways. foreach (IReadOnlyList <DirectedEdge <GrammarCharacter, Pattern> > path in connectionPaths) { IAdTree startCopy = start.MakeShallowCopy(); IAdTree endCopy = end.MakeShallowCopy(); IAdTree previousBridge = null; // Go via the path. for (int i = 0; i < path.Count; ++i) { DirectedEdge <GrammarCharacter, Pattern> edge = path[i]; BigInteger attributes = edge.Value.UpRule.AttributesRule is IReferenceValueRule <BigInteger> referenceAttributes ? referenceAttributes.ReferenceValue : myConstructiveDictionary.AttributesModel.GetAttributes(edge.Value.UpRule.GrammarCharacter); IAdTree bridge = new AdTree(new Morpheme(myConstructiveDictionary.AttributesModel, "", attributes), edge.Value); // If it is the first item on the path. if (i == 0) { if (appendingPositionOfStartElement == AttachingPosition.ParrentForLeft) { if (startCopy.Left == null && startCopy.CanAttachToLeft(bridge, myConstructiveDictionary.AttributesModel)) { startCopy.Left = bridge; } else { break; } } else if (appendingPositionOfStartElement == AttachingPosition.ParrentForRight) { if (startCopy.Right == null && startCopy.CanAttachToRight(bridge, myConstructiveDictionary.AttributesModel)) { startCopy.Right = bridge; } else { break; } } else if (appendingPositionOfStartElement == AttachingPosition.ChildOnLeft) { if (bridge.Left == null && bridge.CanAttachToLeft(startCopy, myConstructiveDictionary.AttributesModel)) { bridge.Left = startCopy; } else { break; } } else if (appendingPositionOfStartElement == AttachingPosition.ChildOnRight) { if (bridge.Right == null && bridge.CanAttachToRight(startCopy, myConstructiveDictionary.AttributesModel)) { bridge.Right = startCopy; } else { break; } } } else { if (previousBridge.Left == null && previousBridge.CanAttachToLeft(bridge, myConstructiveDictionary.AttributesModel)) { previousBridge.Left = bridge; } else if (previousBridge.Right == null && previousBridge.CanAttachToRight(bridge, myConstructiveDictionary.AttributesModel)) { previousBridge.Right = bridge; } else { break; } } // If the signature does not match then break it. var currentSignature = bridge.Root.GetSignature(); if (!expectedSignature.StartsWith(currentSignature)) { break; } // If it is the last item in the path. if (i == path.Count - 1) { if (bridge.Left == null && bridge.CanAttachToLeft(endCopy, myConstructiveDictionary.AttributesModel)) { bridge.Left = endCopy; currentSignature = endCopy.Root.GetSignature(); if (expectedSignature.StartsWith(currentSignature)) { results.Add(endCopy); } } else if (bridge.Right == null && bridge.CanAttachToRight(endCopy, myConstructiveDictionary.AttributesModel)) { bridge.Right = endCopy; currentSignature = endCopy.Root.GetSignature(); if (expectedSignature.StartsWith(currentSignature)) { results.Add(endCopy); } } else { break; } } previousBridge = bridge; } } } }