diff --git a/pymc/logprob/mixture.py b/pymc/logprob/mixture.py index ce6a11d20..62f2a8f40 100644 --- a/pymc/logprob/mixture.py +++ b/pymc/logprob/mixture.py @@ -62,7 +62,7 @@ is_basic_idx, ) from pytensor.tensor.type import TensorType -from pytensor.tensor.type_other import NoneConst, NoneTypeT, SliceConstant, SliceType +from pytensor.tensor.type_other import NoneConst, NoneTypeT, SliceType from pytensor.tensor.variable import TensorVariable from pymc.logprob.abstract import ( @@ -289,9 +289,10 @@ def find_measurable_index_mixture(fgraph, node): # We don't support (non-scalar) integer array indexing as it can pick repeated values, # but the Mixture logprob assumes all mixture values are independent if any( - indices.dtype.startswith("int") and sum(1 - b for b in indices.type.broadcastable) > 0 + isinstance(indices, TensorVariable) + and indices.dtype.startswith("int") + and not all(indices.type.broadcastable) for indices in mixing_indices - if not isinstance(indices, SliceConstant) ): return None diff --git a/tests/logprob/test_mixture.py b/tests/logprob/test_mixture.py index ffb2bf07c..eb9fc8148 100644 --- a/tests/logprob/test_mixture.py +++ b/tests/logprob/test_mixture.py @@ -1156,3 +1156,30 @@ def test_nested_ifelse(): np.testing.assert_almost_equal(mix_logp_fn(0, test_value), sp.norm.logpdf(test_value, -5, 1)) np.testing.assert_almost_equal(mix_logp_fn(1, test_value), sp.norm.logpdf(test_value, 0, 1)) np.testing.assert_almost_equal(mix_logp_fn(2, test_value), sp.norm.logpdf(test_value, 5, 1)) + + +def test_advanced_subtensor_none_and_integer(): + """ + Test for correct error handling when the logp graph is over-specified. + + Providing values for both a random variable ('a') and its deterministic + child ('b') creates a logical conflict. The system should detect this + and raise a controlled RuntimeError. + + This test fails if the rewriter instead crashes with the old internal + AttributeError bug, which would indicate a regression. Please see: #7762 + """ + a = pt.random.normal(0, 1, size=(10,), name="a") + inds = np.array([0, 1, 2, 3], dtype="int32") + b = a[None, inds] + + b_val = b.type() + b_val.name = "b_val" + a_val = a.type() + a_val.name = "a_val" + + with pytest.raises( + RuntimeError, + match="logprob terms of the following value variables could not be derived: {b_val}", + ): + conditional_logp({b: b_val, a: a_val})