(self, op: Operator, n: int)
Unroll all possible operators from the grammar `g` starting from    non-terminal `op` after `n` derivations.

        Parameters
        ----------
        op : Operator
            starting rule (e.g., `g.start`)
        n : int
            number of derivations

        Returns
        -------
        Optional[Operator]
Unroll all possible operators from the grammar `g` starting from    non-terminal `op` after `n` derivations.
Unroll all possible operators from the grammar g starting from non - terminal op after n derivations .
def _unfold(self, op: Operator, n: int) -> Optional[Operator]:
        """Unroll all possible operators from the grammar `g` starting from    non-terminal `op` after `n` derivations.

        Parameters
        ----------
        op : Operator
            starting rule (e.g., `g.start`)
        n : int
            number of derivations

        Returns
        -------
        Optional[Operator]
        """
        if isinstance(op, BasePipeline):
            steps = op.steps()
            new_maybe_steps: List[Optional[Operator]] = [
                self._unfold(sop, n) for sop in op.steps()
            ]
            if None not in new_maybe_steps:
                new_steps: List[Operator] = cast(List[Operator], new_maybe_steps)
                step_map = {steps[i]: new_steps[i] for i in range(len(steps))}
                new_edges = [(step_map[s], step_map[d]) for s, d in op.edges()]
                return make_pipeline_graph(new_steps, new_edges, True)
            else:
                return None
        if isinstance(op, OperatorChoice):
            steps = [s for s in (self._unfold(sop, n) for sop in op.steps()) if s]
            return make_choice(*steps) if steps else None
        if isinstance(op, NonTerminal):
            return self._unfold(self._variables[op.name()], n - 1) if n > 0 else None
        if isinstance(op, IndividualOp):
            return op
        assert False, f"Unknown operator {op}"
def _unfold ( self , op : Operator , n : int ) -> Optional [ Operator ] : if isinstance ( op , BasePipeline ) : steps = op . steps ( ) new_maybe_steps : List [ Optional [ Operator ] ] = [ self . _unfold ( sop , n ) for sop in op . steps ( ) ] if None not in new_maybe_steps : new_steps : List [ Operator ] = cast ( List [ Operator ] , new_maybe_steps ) step_map = { steps [ i ] : new_steps [ i ] for i in range ( len ( steps ) ) } new_edges = [ ( step_map [ s ] , step_map [ d ] ) for s , d in op . edges ( ) ] return make_pipeline_graph ( new_steps , new_edges , True ) else : return None if isinstance ( op , OperatorChoice ) : steps = [ s for s in ( self . _unfold ( sop , n ) for sop in op . steps ( ) ) if s ] return make_choice ( * steps ) if steps else None if isinstance ( op , NonTerminal ) : return self . _unfold ( self . _variables [ op . name ( ) ] , n - 1 ) if n > 0 else None if isinstance ( op , IndividualOp ) : return op assert False , f"Unknown operator {op}"