From 2a62224e1789049569769abcbc8006180e8efcc8 Mon Sep 17 00:00:00 2001 From: drdkad Date: Mon, 20 Jul 2026 14:13:46 +0100 Subject: [PATCH 1/2] Add xfail tests for non-injective RSF labels --- tests/test_strategic.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/test_strategic.py b/tests/test_strategic.py index fedef6097..266272d28 100644 --- a/tests/test_strategic.py +++ b/tests/test_strategic.py @@ -1,3 +1,5 @@ +import io + import pytest import pygambit as gbt @@ -73,3 +75,33 @@ def test_game_get_min_payoff(): def test_game_get_max_payoff(): game = games.read_from_file("mixed_strategy.nfg") assert game.max_payoff == 3 + + +@pytest.mark.xfail( + reason="Generated reduced-strategy labels are not injective", + raises=AssertionError, strict=True, +) +def test_generated_strategy_labels_are_unique(): + """#981 established that a strategy label must be nonempty, valid, and + unique among a player's strategies. Labels generated for reduced + strategies bypass the check: two 11-action information sets yield + strategies (1, 11) and (11, 1), both rendering as "111".""" + g = games.read_from_file("label-collision.efg") + labels = [s.label for s in g.players["Player 1"].strategies] + dups = sorted({lab for lab in labels if labels.count(lab) > 1}) + assert len(set(labels)) == len(labels), f"duplicate generated labels: {dups}" + + +@pytest.mark.xfail( + reason="Generated reduced-strategy labels are not injective; " + "duplicate labels break NFG re-read", + raises=ValueError, strict=True, +) +def test_game_with_duplicate_generated_labels_roundtrips_through_nfg(): + """WriteNfgFile serialises the duplicate generated labels; + ReadNfgFile then rejects its own output. FAILS on 16.7.0. + + The game has two 11-action information sets for one player (imperfect + recall); reduced strategies (1, 11) and (11, 1) both render as "111".""" + g = games.read_from_file("label-collision.efg") + gbt.read_nfg(io.StringIO(g.to_nfg())) From e6fadfb7725d757b45e93dc4b789c639f719399a Mon Sep 17 00:00:00 2001 From: drdkad Date: Mon, 20 Jul 2026 14:14:19 +0100 Subject: [PATCH 2/2] Add label-collision.efg: a game with duplicate RSF labels --- tests/test_games/label-collision.efg | 37 ++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 tests/test_games/label-collision.efg diff --git a/tests/test_games/label-collision.efg b/tests/test_games/label-collision.efg new file mode 100644 index 000000000..1334c81cb --- /dev/null +++ b/tests/test_games/label-collision.efg @@ -0,0 +1,37 @@ +EFG 2 R "label collision counterexample" { "Player 1" } +"Two 11-action information sets for one player: reduced strategies (1,11) and (11,1) both render label 111" + +p "" 1 1 "" { "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" } 0 +p "" 1 2 "" { "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" } 0 +t "" 1 "" { 1 } +t "" 2 "" { 2 } +t "" 3 "" { 3 } +t "" 4 "" { 4 } +t "" 5 "" { 5 } +t "" 6 "" { 6 } +t "" 7 "" { 7 } +t "" 8 "" { 8 } +t "" 9 "" { 9 } +t "" 10 "" { 10 } +t "" 11 "" { 11 } +t "" 12 "" { 12 } +t "" 13 "" { 13 } +t "" 14 "" { 14 } +t "" 15 "" { 15 } +t "" 16 "" { 16 } +t "" 17 "" { 17 } +t "" 18 "" { 18 } +t "" 19 "" { 19 } +t "" 20 "" { 20 } +p "" 1 2 "" { "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" "11" } 0 +t "" 21 "" { 21 } +t "" 22 "" { 22 } +t "" 23 "" { 23 } +t "" 24 "" { 24 } +t "" 25 "" { 25 } +t "" 26 "" { 26 } +t "" 27 "" { 27 } +t "" 28 "" { 28 } +t "" 29 "" { 29 } +t "" 30 "" { 30 } +t "" 31 "" { 31 }