예제 #1
0
 private IEnumerable <IAdTree> GetGrammarCharacterTransferences(IAdTree adTree)
 {
     using (Trace.Entering())
     {
         IEnumerable <Pattern> patterns = myConstructiveDictionary.FindMonoTransferencePatterns(adTree.Morpheme);
         foreach (Pattern pattern in patterns)
         {
             // Note: in case of a grammar character transference it is expected the morpheme rule always represents
             //       a concrete value.
             if (pattern.UpRule.AttributesRule is IReferenceValueRule <BigInteger> isRule)
             {
                 IAdTree adTreeCopy         = adTree.MakeShallowCopy();
                 IAdTree transferenceAdTree = new AdTree(new Morpheme(myConstructiveDictionary.AttributesModel, "", isRule.ReferenceValue), pattern);
                 transferenceAdTree.Right = adTreeCopy;
                 yield return(transferenceAdTree);
             }
         }
     }
 }
예제 #2
0
        // 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;
                    }
                }
            }
        }
예제 #3
0
        private void TryToAppend(IAdTree current, IAdTree appendee, string expectedSignature, List <IAdTree> results)
        {
            using (Trace.Entering())
            {
                IAdTree placeToAppend = GetPlaceToAppend(current);

                // If an adposition needs to be filled.
                if (!placeToAppend.Pattern.UpRule.Equals(MorphemeRule.Nothing) &&
                    !placeToAppend.Pattern.UpRule.Evaluate(placeToAppend.Morpheme))
                {
                    if (placeToAppend.Pattern.Equals(appendee.Pattern))
                    {
                        IAdTree newElementCopy = appendee.MakeShallowCopy();
                        IAdTree adTreeCopy     = placeToAppend.MakeShallowCopy();
                        adTreeCopy.Replace(newElementCopy);
                        results.Add(newElementCopy);
                    }

                    return;
                }

                bool isMorphematicAdPosition = appendee.Pattern.IsMorphematicAdPosition();
                bool canAppendIndirectly     = CanAppendIndirectly(current) && !isMorphematicAdPosition;


                // If the new element can be attached to left.
                if (placeToAppend.Left == null && !placeToAppend.Pattern.LeftRule.Equals(MorphemeRule.Nothing))
                {
                    // Try to attach the new element directly.
                    if (placeToAppend.CanAttachToLeft(appendee, myConstructiveDictionary.AttributesModel))
                    {
                        IAdTree newAdTreeElementCopy = appendee.MakeShallowCopy();
                        IAdTree adTreeCopy           = placeToAppend.MakeShallowCopy();
                        adTreeCopy.Left = newAdTreeElementCopy;
                        results.Add(newAdTreeElementCopy);
                    }
                    if (canAppendIndirectly)
                    {
                        // Try to attach the new element indirectly.
                        TryToAppendIndirectly(AttachingPosition.ParrentForLeft, placeToAppend, appendee, expectedSignature, results);
                    }
                }

                // If the new element can be attached to right.
                if (placeToAppend.Right == null && !placeToAppend.Pattern.RightRule.Equals(MorphemeRule.Nothing))
                {
                    // Try to attach the new element directly.
                    if (placeToAppend.CanAttachToRight(appendee, myConstructiveDictionary.AttributesModel))
                    {
                        IAdTree newAdTreeElementCopy = appendee.MakeShallowCopy();
                        IAdTree adTreeCopy           = placeToAppend.MakeShallowCopy();
                        adTreeCopy.Right = newAdTreeElementCopy;
                        results.Add(newAdTreeElementCopy);
                    }
                    if (canAppendIndirectly)
                    {
                        // Try to attach the new element indirectly.
                        TryToAppendIndirectly(AttachingPosition.ParrentForRight, placeToAppend, appendee, expectedSignature, results);
                    }
                }

                // If the new element can attach the placeToAppend to its left or right.
                // If the adtree has free adposition - i.e. it can be attached to left or right.
                if (placeToAppend.AdPosition == null)
                {
                    // The new element tries to attach the adtree to its left.
                    if (appendee.Left == null && !appendee.Pattern.LeftRule.Equals(MorphemeRule.Nothing))
                    {
                        if (appendee.CanAttachToLeft(placeToAppend, myConstructiveDictionary.AttributesModel))
                        {
                            IAdTree newAdTreeElementCopy = appendee.MakeShallowCopy();
                            IAdTree adTreeCopy           = placeToAppend.MakeShallowCopy();
                            newAdTreeElementCopy.Left = adTreeCopy;
                            results.Add(adTreeCopy);
                        }
                        // Try to attach the adtree indirectly via new element's left.
                        else if (canAppendIndirectly)
                        {
                            TryToAppendIndirectly(AttachingPosition.ParrentForLeft, appendee, placeToAppend, expectedSignature, results);
                        }
                    }

                    // The new element tries to attach the adtree to its right.
                    if (appendee.Right == null && !appendee.Pattern.RightRule.Equals(MorphemeRule.Nothing))
                    {
                        if (appendee.CanAttachToRight(placeToAppend, myConstructiveDictionary.AttributesModel))
                        {
                            IAdTree newAdTreeElementCopy = appendee.MakeShallowCopy();
                            IAdTree adTreeCopy           = placeToAppend.MakeShallowCopy();
                            newAdTreeElementCopy.Right = adTreeCopy;
                            results.Add(adTreeCopy);
                        }
                        // Try to attach the adtree indirectly via new element's right.
                        else if (canAppendIndirectly)
                        {
                            TryToAppendIndirectly(AttachingPosition.ParrentForRight, appendee, placeToAppend, expectedSignature, results);
                        }
                    }

                    if (canAppendIndirectly)
                    {
                        // Also try to connect the adtree and the new element indirectly via adtree adposition.
                        TryToAppendIndirectly(AttachingPosition.ChildOnLeft, placeToAppend, appendee, expectedSignature, results);
                        TryToAppendIndirectly(AttachingPosition.ChildOnRight, placeToAppend, appendee, expectedSignature, results);
                    }
                }
            }
        }