Beispiel #1
0
    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_list()
            new_maybe_steps: List[Optional[Operator]] = [
                self._unfold(sop, n) for sop in op.steps_list()
            ]
            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_list())
                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}"
Beispiel #2
0
    def _sample(self, op: Operator, n: int) -> Optional[Operator]:
        """
        Sample the grammar `g` starting from `g.start`, that is, choose one element at random for each possible choices.

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

        Returns
        -------
        Optional[Operator]
        """
        if isinstance(op, BasePipeline):
            steps = op.steps_list()
            new_maybe_steps: List[Optional[Operator]] = [
                self._sample(sop, n) for sop in op.steps_list()
            ]
            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):
            return self._sample(random.choice(op.steps_list()), n)
        if isinstance(op, NonTerminal):
            return self._sample(getattr(self, op.name()), n -
                                1) if n > 0 else None
        if isinstance(op, IndividualOp):
            return op
        assert False, f"Unknown operator {op}"