/// <summary>
        /// Shifting is legal as long as the state is not finished and there
        /// are more items on the queue to be shifted.
        /// </summary>
        /// <remarks>
        /// Shifting is legal as long as the state is not finished and there
        /// are more items on the queue to be shifted.
        /// TODO: go through the papers and make sure they don't mention any
        /// other conditions where one shouldn't shift
        /// </remarks>
        public virtual bool IsLegal(State state, IList <ParserConstraint> constraints)
        {
            if (state.finished)
            {
                return(false);
            }
            if (state.tokenPosition >= state.sentence.Count)
            {
                return(false);
            }
            // We disallow shifting when the previous transition was a right
            // head transition to a partial (binarized) state
            // TODO: I don't have an explanation for this, it was just stated
            // in Zhang & Clark 2009
            if (state.stack.Size() > 0)
            {
                Tree top = state.stack.Peek();
                // Temporary node, eg part of a binarized sequence
                if (top.Label().Value().StartsWith("@") && top.Children().Length == 2 && ShiftReduceUtils.GetBinarySide(top) == BinaryTransition.Side.Right)
                {
                    return(false);
                }
            }
            if (constraints == null || state.stack.Size() == 0)
            {
                return(true);
            }
            Tree top_1 = state.stack.Peek();

            // If there are ParserConstraints, you can only shift if shifting
            // will not make a constraint unsolvable.  This happens if we
            // shift beyond the right end of a constraint which is not solved.
            foreach (ParserConstraint constraint in constraints)
            {
                // either went past or haven't gotten to this constraint yet
                if (ShiftReduceUtils.RightIndex(top_1) != constraint.end - 1)
                {
                    continue;
                }
                int left = ShiftReduceUtils.LeftIndex(top_1);
                if (left < constraint.start)
                {
                    continue;
                }
                if (left > constraint.start)
                {
                    return(false);
                }
                if (!ShiftReduceUtils.ConstraintMatchesTreeTop(top_1, constraint))
                {
                    return(false);
                }
            }
            return(true);
        }
Exemple #2
0
        public virtual bool IsLegal(State state, IList <ParserConstraint> constraints)
        {
            bool legal = !state.finished && state.tokenPosition >= state.sentence.Count && state.stack.Size() == 1 && rootStates.Contains(state.stack.Peek().Value());

            if (!legal || constraints == null)
            {
                return(legal);
            }
            foreach (ParserConstraint constraint in constraints)
            {
                if (constraint.start != 0 || constraint.end != state.sentence.Count)
                {
                    continue;
                }
                if (!ShiftReduceUtils.ConstraintMatchesTreeTop(state.stack.Peek(), constraint))
                {
                    return(false);
                }
            }
            return(true);
        }
        /// <summary>Legal as long as there are at least two items on the state's stack.</summary>
        public virtual bool IsLegal(State state, IList <ParserConstraint> constraints)
        {
            // some of these quotes come directly from Zhang Clark 09
            if (state.finished)
            {
                return(false);
            }
            if (state.stack.Size() <= 1)
            {
                return(false);
            }
            // at least one of the two nodes on top of stack must be non-temporary
            if (ShiftReduceUtils.IsTemporary(state.stack.Peek()) && ShiftReduceUtils.IsTemporary(state.stack.Pop().Peek()))
            {
                return(false);
            }
            if (ShiftReduceUtils.IsTemporary(state.stack.Peek()))
            {
                if (side == BinaryTransition.Side.Left)
                {
                    return(false);
                }
                if (!ShiftReduceUtils.IsEquivalentCategory(label, state.stack.Peek().Value()))
                {
                    return(false);
                }
            }
            if (ShiftReduceUtils.IsTemporary(state.stack.Pop().Peek()))
            {
                if (side == BinaryTransition.Side.Right)
                {
                    return(false);
                }
                if (!ShiftReduceUtils.IsEquivalentCategory(label, state.stack.Pop().Peek().Value()))
                {
                    return(false);
                }
            }
            // don't allow binarized labels if it makes the state have a stack
            // of size 1 and a queue of size 0
            if (state.stack.Size() == 2 && IsBinarized() && state.EndOfQueue())
            {
                return(false);
            }
            // when the stack contains only two nodes, temporary resulting
            // nodes from binary reduce must be left-headed
            if (state.stack.Size() == 2 && IsBinarized() && side == BinaryTransition.Side.Right)
            {
                return(false);
            }
            // when the queue is empty and the stack contains more than two
            // nodes, with the third node from the top being temporary, binary
            // reduce can be applied only if the resulting node is non-temporary
            if (state.EndOfQueue() && state.stack.Size() > 2 && ShiftReduceUtils.IsTemporary(state.stack.Pop().Pop().Peek()) && IsBinarized())
            {
                return(false);
            }
            // when the stack contains more than two nodes, with the third
            // node from the top being temporary, temporary resulting nodes
            // from binary reduce must be left-headed
            if (state.stack.Size() > 2 && ShiftReduceUtils.IsTemporary(state.stack.Pop().Pop().Peek()) && IsBinarized() && side == BinaryTransition.Side.Right)
            {
                return(false);
            }
            if (constraints == null)
            {
                return(true);
            }
            Tree top      = state.stack.Peek();
            int  leftTop  = ShiftReduceUtils.LeftIndex(top);
            int  rightTop = ShiftReduceUtils.RightIndex(top);
            Tree next     = state.stack.Pop().Peek();
            int  leftNext = ShiftReduceUtils.LeftIndex(next);

            // The binary transitions are affected by constraints in the
            // following two circumstances.  If a transition would cross the
            // left boundary of a constraint, that is illegal.  If the
            // transition is exactly the right size for the constraint and
            // would make a temporary node, that is also illegal.
            foreach (ParserConstraint constraint in constraints)
            {
                if (leftTop == constraint.start)
                {
                    // can't binary reduce away from a tree which doesn't match a constraint
                    if (rightTop == constraint.end - 1)
                    {
                        if (!ShiftReduceUtils.ConstraintMatchesTreeTop(top, constraint))
                        {
                            return(false);
                        }
                        else
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (rightTop >= constraint.end)
                        {
                            continue;
                        }
                        else
                        {
                            // can't binary reduce if it would make the tree cross the left boundary
                            return(false);
                        }
                    }
                }
                // top element is further left than the constraint, so
                // there's no harm to be done by binary reduce
                if (leftTop < constraint.start)
                {
                    continue;
                }
                // top element is past the end of the constraint, so it must already be satisfied
                if (leftTop >= constraint.end)
                {
                    continue;
                }
                // now leftTop > constraint.start and < constraint.end, eg inside the constraint
                // the next case is no good because it crosses the boundary
                if (leftNext < constraint.start)
                {
                    return(false);
                }
                if (leftNext > constraint.start)
                {
                    continue;
                }
                // can't transition to a binarized node when there's a constraint that matches.
                if (rightTop == constraint.end - 1 && IsBinarized())
                {
                    return(false);
                }
            }
            return(true);
        }
Exemple #4
0
 /// <summary>
 /// Returns a transition which might not even be part of the model,
 /// but will hopefully allow progress in an otherwise stuck parse
 /// TODO: perhaps we want to create an EmergencyTransition class
 /// which indicates that something has gone wrong
 /// </summary>
 public virtual ITransition FindEmergencyTransition(State state, IList <ParserConstraint> constraints)
 {
     if (state.stack.Size() == 0)
     {
         return(null);
     }
     // See if there is a constraint whose boundaries match the end
     // points of the top node on the stack.  If so, we can apply a
     // UnaryTransition / CompoundUnaryTransition if that would solve
     // the constraint
     if (constraints != null)
     {
         Tree top = state.stack.Peek();
         foreach (ParserConstraint constraint in constraints)
         {
             if (ShiftReduceUtils.LeftIndex(top) != constraint.start || ShiftReduceUtils.RightIndex(top) != constraint.end - 1)
             {
                 continue;
             }
             if (ShiftReduceUtils.ConstraintMatchesTreeTop(top, constraint))
             {
                 continue;
             }
             // found an unmatched constraint that can be fixed with a unary transition
             // now we need to find a matching state for the transition
             foreach (string label in knownStates)
             {
                 if (constraint.state.Matcher(label).Matches())
                 {
                     return((op.compoundUnaries) ? new CompoundUnaryTransition(Java.Util.Collections.SingletonList(label), false) : new UnaryTransition(label, false));
                 }
             }
         }
     }
     if (ShiftReduceUtils.IsTemporary(state.stack.Peek()) && (state.stack.Size() == 1 || ShiftReduceUtils.IsTemporary(state.stack.Pop().Peek())))
     {
         return((op.compoundUnaries) ? new CompoundUnaryTransition(Java.Util.Collections.SingletonList(Sharpen.Runtime.Substring(state.stack.Peek().Value(), 1)), false) : new UnaryTransition(Sharpen.Runtime.Substring(state.stack.Peek().Value(), 1),
                                                                                                                                                                                               false));
     }
     if (state.stack.Size() == 1 && state.tokenPosition >= state.sentence.Count)
     {
         // either need to finalize or transition to a root state
         if (!rootStates.Contains(state.stack.Peek().Value()))
         {
             string root = rootStates.GetEnumerator().Current;
             return((op.compoundUnaries) ? new CompoundUnaryTransition(Java.Util.Collections.SingletonList(root), false) : new UnaryTransition(root, false));
         }
     }
     if (state.stack.Size() == 1)
     {
         return(null);
     }
     if (ShiftReduceUtils.IsTemporary(state.stack.Peek()))
     {
         return(new BinaryTransition(Sharpen.Runtime.Substring(state.stack.Peek().Value(), 1), BinaryTransition.Side.Right));
     }
     if (ShiftReduceUtils.IsTemporary(state.stack.Pop().Peek()))
     {
         return(new BinaryTransition(Sharpen.Runtime.Substring(state.stack.Pop().Peek().Value(), 1), BinaryTransition.Side.Left));
     }
     return(null);
 }