def is_factorial()

in ax/core/batch_trial.py [0:0]


    def is_factorial(self) -> bool:
        """Return true if the trial's arms are a factorial design with
        no linked factors.
        """
        # To match the model behavior, this should probably actually be pulled
        # from exp.parameters. However, that seems rather ugly when this function
        # intuitively should just depend on the arms.
        sufficient_factors = all(len(arm.parameters or []) >= 2 for arm in self.arms)
        if not sufficient_factors:
            return False
        param_levels: DefaultDict[str, Dict[Union[str, float], int]] = defaultdict(dict)
        for arm in self.arms:
            for param_name, param_value in arm.parameters.items():
                # Expected `Union[float, str]` for 2nd anonymous parameter to call
                # `dict.__setitem__` but got `Optional[Union[bool, float, str]]`.
                # pyre-fixme[6]: Expected `Union[float, str]` for 1st param but got `...
                param_levels[param_name][param_value] = 1
        param_cardinality = 1
        for param_values in param_levels.values():
            param_cardinality *= len(param_values)
        return len(self.arms) == param_cardinality