y0-causal-inference/y0

Intervene does not deduplicate interventions

djinnome opened this issue · 2 comments

>>> from y0.dsl import D, X, Z
>>> Z.intervene([D, D @ (-D, -X)]

$$Z_{D, D}$$

Solution was to swap the composition of _upgrade_ordering and _to_interventions

def intervene(self, variables: VariableHint) -> CounterfactualVariable:
        """Intervene on this variable with the given variable(s).

        :param variables: The variable(s) used to extend this variable as it is changed to a
            counterfactual variable
        :returns: A new counterfactual variable over this variable with the given intervention(s).

        .. note:: This function can be accessed with the matmult @ operator.
        """
        return CounterfactualVariable(
            name=self.name,
            star=self.star,
            interventions=_to_interventions(_upgrade_ordering(variables))

becomes

def intervene(self, variables: VariableHint) -> CounterfactualVariable:
        """Intervene on this variable with the given variable(s).

        :param variables: The variable(s) used to extend this variable as it is changed to a
            counterfactual variable
        :returns: A new counterfactual variable over this variable with the given intervention(s).

        .. note:: This function can be accessed with the matmult @ operator.
        """
        return CounterfactualVariable(
            name=self.name,
            star=self.star,
            interventions=_upgrade_ordering(_to_interventions(variables))

The solution turned out to be a bit more subtle:

    def intervene(self, variables: VariableHint) -> CounterfactualVariable:
        """Intervene on this variable with the given variable(s).

        :param variables: The variable(s) used to extend this variable as it is changed to a
            counterfactual variable
        :returns: A new counterfactual variable over this variable with the given intervention(s).

        .. note:: This function can be accessed with the matmult @ operator.
        """
        return CounterfactualVariable(
            name=self.name,
            star=self.star,
            interventions=_upgrade_ordering(_to_interventions(_upgrade_variables(variables))),
        )