src/main/java/com/basistech/tclre/Nfa.java
boolean pull(Arc con) throws RegexException {
        State from = con.from;
        State to = con.to;
        Arc a;
        Arc nexta;
        State s;

        if (from == to) {   /* circular constraint is pointless */
            freearc(con);
            return true;
        }
        if (0 != from.flag) {   /* can't pull back beyond start */
            return false;
        }
        if (from.nins == 0) {   /* unreachable */
            freearc(con);
            return true;
        }

    /* first, clone from state if necessary to avoid other outarcs */
        if (from.nouts > 1) {
            s = newstate();

            assert to != from;        /* con is not an inarc */
            copyins(from, s);       /* duplicate inarcs */
            cparc(con, s, to);      /* move constraint arc */
            freearc(con);
            from = s;
            con = from.outs;
        }
        assert from.nouts == 1;

    /* propagate the constraint into the from state's inarcs */
        for (a = from.ins; a != null; a = nexta) {
            nexta = a.inchain;
            switch (combine(con, a)) {
            case INCOMPATIBLE:  /* destroy the arc */
                freearc(a);
                break;
            case SATISFIED:     /* no action needed */
                break;
            case COMPATIBLE:    /* swap the two arcs, more or less */
                s = newstate();
                cparc(a, s, to);        /* anticipate move */
                cparc(con, a.from, s);
                freearc(a);
                break;
            default:
                throw new RegexException("REG_ASSERT");
            }
        }

    /* remaining inarcs, if any, incorporate the constraint */
        moveins(from, to);
        dropstate(from);        /* will free the constraint */
        return true;
    }
boolean pull(Arc con) throws RegexException {
        State from = con.from;
        State to = con.to;
        Arc a;
        Arc nexta;
        State s;

        if (from == to) {   /* circular constraint is pointless */
            freearc(con);
            return true;
        }
        if (0 != from.flag) {   /* can't pull back beyond start */
            return false;
        }
        if (from.nins == 0) {   /* unreachable */
            freearc(con);
            return true;
        }

    /* first, clone from state if necessary to avoid other outarcs */
        if (from.nouts > 1) {
            s = newstate();

            assert to != from;        /* con is not an inarc */
            copyins(from, s);       /* duplicate inarcs */
            cparc(con, s, to);      /* move constraint arc */
            freearc(con);
            from = s;
            con = from.outs;
        }
        assert from.nouts == 1;

    /* propagate the constraint into the from state's inarcs */
        for (a = from.ins; a != null; a = nexta) {
            nexta = a.inchain;
            switch (combine(con, a)) {
            case INCOMPATIBLE:  /* destroy the arc */
                freearc(a);
                break;
            case SATISFIED:     /* no action needed */
                break;
            case COMPATIBLE:    /* swap the two arcs, more or less */
                s = newstate();
                cparc(a, s, to);        /* anticipate move */
                cparc(con, a.from, s);
                freearc(a);
                break;
            default:
                throw new RegexException("REG_ASSERT");
            }
        }

    /* remaining inarcs, if any, incorporate the constraint */
        moveins(from, to);
        dropstate(from);        /* will free the constraint */
        return true;
    }
boolean pull ( Arc con ) throws RegexException { State from = con . from ; State to = con . to ; Arc a ; Arc nexta ; State s ; if ( from == to ) { /* circular constraint is pointless */ freearc ( con ) ; return true ; } if ( 0 != from . flag ) { /* can't pull back beyond start */ return false ; } if ( from . nins == 0 ) { /* unreachable */ freearc ( con ) ; return true ; } /* first, clone from state if necessary to avoid other outarcs */ if ( from . nouts > 1 ) { s = newstate ( ) ; assert to != from ; /* con is not an inarc */ copyins ( from , s ) ; /* duplicate inarcs */ cparc ( con , s , to ) ; /* move constraint arc */ freearc ( con ) ; from = s ; con = from . outs ; } assert from . nouts == 1 ; /* propagate the constraint into the from state's inarcs */ for ( a = from . ins ; a != null ; a = nexta ) { nexta = a . inchain ; switch ( combine ( con , a ) ) { case INCOMPATIBLE : /* destroy the arc */ freearc ( a ) ; break ; case SATISFIED : /* no action needed */ break ; case COMPATIBLE : /* swap the two arcs, more or less */ s = newstate ( ) ; cparc ( a , s , to ) ; /* anticipate move */ cparc ( con , a . from , s ) ; freearc ( a ) ; break ; default : throw new RegexException ( "REG_ASSERT" ) ; } } /* remaining inarcs, if any, incorporate the constraint */ moveins ( from , to ) ; dropstate ( from ) ; /* will free the constraint */ return true ; }
- pull - pull a back constraint backward past its source state
A significant property of this function is that it deletes at most
one state -- the constraint's from state -- and only if the constraint
was that state's last outarc.

@return success
- pull - pull a back constraint backward past its source state A significant property of this function is that it deletes at most one state -- the constraint s from state -- and only if the constraint was that state s last outarc .