Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions src/argumentation/probabilistic/epistemic.py
Original file line number Diff line number Diff line change
Expand Up @@ -944,10 +944,9 @@ def update_assignment(
changed = True
if not belief_assignment_satisfies(graph, assignment):
raise ValueError("updated assignment cannot satisfy the graph constraints")
return {
argument: round(assignment[argument], 12)
for argument in sorted(graph.arguments)
}
# Return exactly the validated values: rounding here could move a value
# across an exact constraint bound after validation.
return {argument: assignment[argument] for argument in sorted(graph.arguments)}


def project_to_constellation_praf(graph: EpistemicGraph) -> ProbabilisticAF:
Expand Down
6 changes: 5 additions & 1 deletion tests/probabilistic/test_epistemic.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@ def test_update_assignment_clamps_evidence_and_propagates_fragment() -> None:
),
)

assert update_assignment(graph, {"a": 0.8}) == {"a": 0.8, "b": 0.8, "c": 0.2}
# Values are returned exactly as validated (issue #16), so c is the float
# 1 - 0.8 rather than a rounded 0.2.
assert update_assignment(graph, {"a": 0.8}) == pytest.approx(
{"a": 0.8, "b": 0.8, "c": 0.2}
)


def test_update_assignment_respects_explicit_belief_constraints() -> None:
Expand Down
39 changes: 39 additions & 0 deletions tests/probabilistic/test_epistemic_contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from argumentation.probabilistic.epistemic import (
AndTerm,
ArgumentTerm,
BeliefConstraint,
EpistemicGraph,
Influence,
InfluenceKind,
Expand All @@ -30,6 +31,7 @@
OrTerm,
ProbabilityTerm,
Term,
belief_assignment_satisfies,
least_squares_update_labelling,
parse_term,
update_assignment,
Expand Down Expand Up @@ -164,6 +166,43 @@ def tracer(frame: FrameType, event: str, arg: object) -> object:
sys.settrace(None)


@pytest.mark.parametrize(
"influences",
[(), (Influence("a", "b", InfluenceKind.NEGATIVE),)],
ids=["exact-bound", "negative-influence-from-exact-bound"],
)
def test_update_assignment_returns_values_that_satisfy_exact_bounds(
influences: tuple[Influence, ...],
) -> None:
"""Issue #16: the returned assignment must satisfy the graph constraints
(Hunter & Thimm 2017 epistemic constraints), including an exact bound
finer than 12 decimal places and a negative influence ``b <= 1 - a``
computed from it."""
value = 0.1234567890123
graph = EpistemicGraph(
frozenset({"a", "b"}),
influences=frozenset(influences),
constraints=(BeliefConstraint("a", value, value),),
)

result = update_assignment(graph, {})

assert result["a"] == value
assert belief_assignment_satisfies(graph, result)


def test_update_assignment_coarse_bound_control() -> None:
"""Control: a bound with few decimals is returned unchanged."""
graph = EpistemicGraph(
frozenset({"a"}), constraints=(BeliefConstraint("a", 0.25, 0.25),)
)

result = update_assignment(graph, {})

assert result == {"a": 0.25}
assert belief_assignment_satisfies(graph, result)


def test_update_assignment_rejects_contradictory_influences() -> None:
"""Issue #42: with P(a) = 0.8, a positive influence a -> b demands
P(b) >= 0.8 and a negative one demands P(b) <= 0.2 (Hunter & Thimm 2017
Expand Down
Loading