示例#1
0
        private static bool IsAttachingOrderCorrect(IAdTree adTree, AttachingPosition position)
        {
            bool result = false;

            // If the attaching position is on the left.
            if (position == AttachingPosition.ChildOnLeft)
            {
                // If left is before the right
                if (adTree.Pattern.IsLeftFirst ||
                    // or right is already set
                    adTree.Right != null ||
                    // or right is not supposed to be set.
                    adTree.Pattern.RightRule.Equals(MorphemeRule.Nothing))
                {
                    result = true;
                }
            }
            else
            {
                if (!adTree.Pattern.IsLeftFirst ||
                    adTree.Left != null ||
                    adTree.Pattern.LeftRule.Equals(MorphemeRule.Nothing))
                {
                    result = true;
                }
            }

            return(result);
        }
示例#2
0
 /// <summary>
 /// Appends the adtree to the adtree.
 /// </summary>
 /// <param name="adTree">The adtree into which it shall be attached.</param>
 /// <param name="toAttach">The adtree which shall be appended.</param>
 /// <param name="appendPosition">The position how it shall be appended.</param>
 public static void Attach(this IAdTree adTree, IAdTree toAttach, AttachingPosition appendPosition)
 {
     if (appendPosition == AttachingPosition.ChildOnLeft)
     {
         adTree.Left = toAttach;
     }
     else if (appendPosition == AttachingPosition.ChildOnRight)
     {
         adTree.Right = toAttach;
     }
 }
示例#3
0
        /// <summary>
        /// Inserts the adtree into the adtree.
        /// </summary>
        /// <param name="adTree">The adtree into which it shall be inserted.</param>
        /// <param name="toInsert">The adtree which shall be inserted.</param>
        /// <param name="whereReattach">The adtree which shall reatach the adtree disconnected by the insertion.</param>
        /// <param name="reattachPosition">The position where the adtree shall be reattached after the insertion.</param>
        public static void Insert(this IAdTree adTree, IAdTree toInsert, IAdTree whereReattach, AttachingPosition reattachPosition)
        {
            // Insert the toInsert instead of the adTree.
            if (adTree.IsOnLeft)
            {
                adTree.AdPosition.Left = toInsert;
            }
            else if (adTree.IsOnRight)
            {
                adTree.AdPosition.Right = toInsert;
            }

            // Attach the adtree to the inserted adtree.
            whereReattach.Attach(adTree, reattachPosition);
        }
示例#4
0
        private static bool CanAttachViaRule(this IAdTree adTree, IAdTree adTreeToAttach, AttachingPosition attachPosition, IAttributesModel attributesModel)
        {
            // Get rule to evalute.
            MorphemeRule rule = attachPosition == AttachingPosition.ChildOnLeft ? adTree.Pattern.LeftRule : adTree.Pattern.RightRule;

            // If the rule allows to attach and the order of attaching is correct.
            if (!rule.Equals(MorphemeRule.Nothing) && IsAttachingOrderCorrect(adTree, attachPosition))
            {
                // If the adtree where to attach is morphematic then it is not possible to attach the second child until the morpheme is set.
                if (adTree.Pattern.IsMorphematicAdPosition() && (adTree.Right != null || adTree.Left != null) && string.IsNullOrEmpty(adTree.Morpheme.Morph))
                {
                    return(false);
                }

                // Note: from the tree to attach we need to get the adtree representing the morpheme which shall be evaluated.
                IAdTree morphemeAdTree = null;

                // If the adTreeToAttach is a morpheme or a transference.
                if (adTreeToAttach.Pattern.IsLikeMorpheme)
                {
                    morphemeAdTree = adTreeToAttach;
                }
                // It is an adposition.
                else if (adTreeToAttach.Pattern.IsEpsilonAdPosition() ||
                         adTreeToAttach.Pattern.IsMorphematicAdPosition())
                {
                    // If a substitution (because adTreeToAttach is adposition) can be attached.
                    if (rule.SubstitutionRule.Evaluate(adTreeToAttach.Morpheme.GrammarCharacter))
                    {
                        // If it shall be attached to the right and
                        // the valency position is specified then check correctness with regard to presence of previously filled valencies.
                        if (attachPosition == AttachingPosition.ChildOnRight)
                        {
                            IAdTree valencyElement = adTree.GetSequenceToRoot()
                                                     .TakeUntil(x => x.IsOnRight)
                                                     .FirstOrDefault(x => x.Pattern.ValencyPosition > 0);

                            if (valencyElement != null)
                            {
                                IAdTree previousValencyElement = adTreeToAttach.GetRightSequence()
                                                                 .FirstOrDefault(x => x.Pattern.ValencyPosition > 0);

                                if (previousValencyElement == null && valencyElement.Pattern.ValencyPosition > 1 ||
                                    previousValencyElement != null && valencyElement.Pattern.ValencyPosition != previousValencyElement.Pattern.ValencyPosition + 1)
                                {
                                    return(false);
                                }
                            }
                        }

                        // Try to get the driving morpheme.
                        morphemeAdTree = adTreeToAttach.RightChildren.FirstOrDefault(x => x.Pattern.IsLikeMorpheme);

                        // If the governor is not attached yet then check only rules.
                        if (morphemeAdTree == null)
                        {
                            IEnumerable <IAdTree> rightSequence = new IAdTree[] { adTreeToAttach }.Concat(adTreeToAttach.RightChildren);
                            if (rightSequence.Any(x => !x.Pattern.RightRule.IsSubruleOf(rule) && !rule.IsSubruleOf(x.Pattern.RightRule)))
                            {
                                return(false);
                            }

                            return(true);
                        }
                    }
                }

                if (morphemeAdTree != null)
                {
                    // If it shall be attached to the right the morpheme is a verb then check the valency.
                    if (attachPosition == AttachingPosition.ChildOnRight && attributesModel.IsVerb(morphemeAdTree.Morpheme.Attributes))
                    {
                        int valency = attributesModel.GetNumberOfValencies(morphemeAdTree.Morpheme.Attributes);

                        if (valency > -1)
                        {
                            // Get already filled valency positions.
                            int[] valencyPositions = morphemeAdTree.GetSequenceToRoot()
                                                     .TakeWhile(x => x != adTree) // This is to not make an assuption if it is already attached or not.
                                                     .TakeUntil(x => x.IsOnRight)
                                                     .Concat(adTree.GetSequenceToRoot().TakeUntil(x => x.IsOnRight))
                                                     .Where(x => x.Pattern.ValencyPosition > 0)
                                                     .Select(x => x.Pattern.ValencyPosition)
                                                     .ToArray();

                            // If such valency is already filled.
                            if (valencyPositions.Length > valency)
                            {
                                return(false);
                            }
                            for (int i = 0; i < valencyPositions.Length; ++i)
                            {
                                if (valencyPositions[i] != i + 1)
                                {
                                    return(false);
                                }
                            }
                        }
                    }

                    Morpheme morphemeToEvaluate = morphemeAdTree.TryGetTransferenceMorpheme();

                    if (string.IsNullOrEmpty(morphemeToEvaluate?.Morph) && morphemeAdTree.Pattern.IsPairTransference)
                    {
                        // The morpheme with the morph is not attached yet so check only attributes.
                        if (rule.AttributesRule.Evaluate(morphemeAdTree.Morpheme.Attributes))
                        {
                            return(true);
                        }
                        else
                        {
                            return(false);
                        }
                    }

                    // Check if the morpheme passes the rule.
                    bool result = rule.Evaluate(morphemeToEvaluate);
                    return(result);
                }
            }

            return(false);
        }
示例#5
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;
                    }
                }
            }
        }