Repository: pgmpy/pgmpy

Issue:
CausalInference.query() ValueError exception
evidence = {'W': 'True'}
counterfactual_intervention = {'S': 'False'}

counterfactual_query = causal_inference.query(
    variables=['R'],
    evidence=evidence,
    do=counterfactual_intervention
)

The above code throws the following exception:
ValueError: Can't have the same variables in both `variables` and `evidence`. Found in both: {'R'}



Discussion:
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/pgmpy/pgmpy/pull/2034?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pgmpy) Report
Attention: Patch coverage is `0%` with `5 lines` in your changes missing coverage. Please review.
> Project coverage is 34.38%. Comparing base [(`eb3a512`)](https://app.codecov.io/gh/pgmpy/pgmpy/commit/eb3a512e1fefc06d0aedfeba033376106bf727c2?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pgmpy) to head [(`83e3a6a`)](https://app.codecov.io/gh/pgmpy/pgmpy/commit/83e3a6aa5b075be9ecf473faaa44527b31fb8595?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pgmpy).
> Report is 24 commits behind head on dev.

| [Files with missing lines](https://app.codecov.io/gh/pgmpy/pgmpy/pull/2034?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pgmpy) | Patch % | Lines |
|---|---|---|
| [pgmpy/inference/CausalInference.py](https://app.codecov.io/gh/pgmpy/pgmpy/pull/2034?src=pr&el=tree&filepath=pgmpy%2Finference%2FCausalInference.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pgmpy#diff-cGdtcHkvaW5mZXJlbmNlL0NhdXNhbEluZmVyZW5jZS5weQ==) | 0.00% | [5 Missing :warning: ](https://app.codecov.io/gh/pgmpy/pgmpy/pull/2034?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pgmpy) |

> :exclamation:  There is a different number of reports uploaded between BASE (eb3a512) and HEAD (83e3a6a). Click for more details.
> 
> <details><summary>HEAD has 16 uploads less than BASE</summary>
>
>| Flag | BASE (eb3a512) | HEAD (83e3a6a) |
>|------|------|------|
>||18|2|
></details>

<details><summary>Additional details and impacted files</summary>


```diff
@@             Coverage Diff             @@
##              dev    #2034       +/-   ##
===========================================
- Coverage   94.59%   34.38%   -60.21%     
===========================================
  Files         147      149        +2     
  Lines       19660    20117      +457     
===========================================
- Hits        18597     6917    -11680     
- Misses       1063    13200    +12137     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/pgmpy/pgmpy/pull/2034?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pgmpy).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pgmpy).


Fix (patch):
diff --git a/pgmpy/inference/CausalInference.py b/pgmpy/inference/CausalInference.py
index 60320e73..1b692c17 100644
--- a/pgmpy/inference/CausalInference.py
+++ b/pgmpy/inference/CausalInference.py
@@ -986,6 +986,14 @@ class CausalInference(object):
                 "`evidence` must be a dict of the form: {variable_name: variable_state}"
             )
 
+        if do:
+            for var, do_var in product(variables, do):
+                if do_var in nx.descendants(self.dag, var):
+                    raise ValueError(
+                        f"Invalid causal query: There is a direct edge from the query variable '{var}' to the intervention variable '{do_var}'. "
+                        f"In causal inference, you can typically only query the effect on variables that are descendants of the intervention."
+                    )
+
         from pgmpy.inference import Inference
 
         if inference_algo == "ve":
diff --git a/pgmpy/utils/compat_fns.py b/pgmpy/utils/compat_fns.py
index b5848aae..2618e00e 100644
--- a/pgmpy/utils/compat_fns.py
+++ b/pgmpy/utils/compat_fns.py
@@ -139,7 +139,7 @@ def exp(arr):
 
 def sum(arr):
     if isinstance(arr, np.ndarray):
-        return np.sum(arr)
+        return arr.sum()
     else:
         return torch.sum(arr)
 
diff --git a/pyproject.toml b/pyproject.toml
index 081b1769..9827e8cb 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -87,4 +87,11 @@ build-backend = "setuptools.build_meta"
 exclude = ["tests"]
 
 [tool.setuptools.package-data]
-pgmpy = ["utils/example_models/*"]
+pgmpy = [
+  "utils/example_models/*.bif.gz",
+  "utils/example_models/*.json",
+  "utils/example_models/*.txt"
+]
+[tool.setuptools]
+include-package-data = true
+


Test changes:
diff --git a/pgmpy/tests/test_inference/test_CausalInference.py b/pgmpy/tests/test_inference/test_CausalInference.py
index 9ddfe0c0..a07fe4c9 100644
--- a/pgmpy/tests/test_inference/test_CausalInference.py
+++ b/pgmpy/tests/test_inference/test_CausalInference.py
@@ -1243,6 +1243,49 @@ class TestDoQuery(unittest.TestCase):
             inference_algo="random",
         )
 
+    def test_invalid_causal_query_direct_descendant_intervention(self):
+        # Model: R -> S -> W & R -> W. We intervene on S and query R.
+        model = DiscreteBayesianNetwork([("R", "W"), ("S", "W"), ("R", "S")])
+        cpd_rain = TabularCPD(
+            variable="R",
+            variable_card=2,
+            values=[[0.6], [0.4]],
+            state_names={"R": ["True", "False"]},
+        )
+        cpd_sprinkler = TabularCPD(
+            variable="S",
+            variable_card=2,
+            values=[[0.1, 0.5], [0.9, 0.5]],
+            evidence=["R"],
+            evidence_card=[2],
+            state_names={"S": ["True", "False"], "R": ["True", "False"]},
+        )
+        cpd_wet_grass = TabularCPD(
+            variable="W",
+            variable_card=2,
+            values=[[0.99, 0.9, 0.9, 0.01], [0.01, 0.1, 0.1, 0.99]],
+            evidence=["R", "S"],
+            evidence_card=[2, 2],
+            state_names={
+                "W": ["True", "False"],
+                "R": ["True", "False"],
+                "S": ["True", "False"],
+            },
+        )
+        model.add_cpds(cpd_rain, cpd_sprinkler, cpd_wet_grass)
+        causal_inference = CausalInference(model)
+
+        evidence = {"W": "True"}
+        counterfactual_intervention = {"S": "False"}
+        with self.assertRaises(ValueError) as cm:
+            causal_inference.query(
+                variables=["R"], evidence=evidence, do=counterfactual_intervention
+            )
+        self.assertIn(
+            "Invalid causal query: There is a direct edge from the query variable 'R' to the intervention variable 'S'.",
+            str(cm.exception),
+        )
+
 
 class TestEstimator(unittest.TestCase):
     def test_create_estimator(self):