"""The payoff tables a monotonic QMIX mixer cannot represent
Deterministic, standard-library experiment. RESULTS contains the full data.
"""
from itertools import permutations, product

tables = {
    'additive': [[0, 2], [1, 3]],
    'monotonic nonlinear': [[0, 1], [1, 4]],
    'ranking reversal': [[0, 2], [2, 0]],
}

def monotonic_order_exists(table):
    for rows in permutations(range(2)):
        for cols in permutations(range(2)):
            ordered = [[table[r][c] for c in cols] for r in rows]
            row_ok = all(row[0] <= row[1] for row in ordered)
            col_ok = all(ordered[0][c] <= ordered[1][c] for c in range(2))
            if row_ok and col_ok:
                return True
    return False

for name, table in tables.items():
    difference = table[0][0] + table[1][1] - table[0][1] - table[1][0]
    print(f'{name}: mixed difference={difference}, monotonic={monotonic_order_exists(table)}')

def mixer(u, v):
    return u + v + 2 * u * v

for a, b in product(range(2), repeat=2):
    assert mixer(a, b) == tables['monotonic nonlinear'][a][b]
assert monotonic_order_exists(tables['additive'])
assert not monotonic_order_exists(tables['ranking reversal'])
print('constructed monotonic mixer greedy value:', mixer(1, 1))


records=[]
for name,table in tables.items():
    orderings=[]
    for rs in permutations(range(2)):
        for cs in permutations(range(2)):
            ordered=[[table[r][c] for c in cs] for r in rs]
            violations=sum(row[0]>row[1] for row in ordered)+sum(ordered[0][c]>ordered[1][c] for c in range(2))
            orderings.append(dict(rows=list(rs),columns=list(cs),violations=violations))
    records.append(dict(name=name,table=table,mixed_difference=table[0][0]+table[1][1]-table[0][1]-table[1][0],monotonic=monotonic_order_exists(table),orderings=orderings))
# Strictly increasing affine remapping preserves every ordering contradiction.
transformed=[[3*x+7 for x in row] for row in tables['ranking reversal']]
assert not monotonic_order_exists(transformed)
RESULTS=dict(tables=records,affine_reversal_still_impossible=True,mixer_corners=[dict(u=u,v=v,value=mixer(u,v)) for u,v in product(range(2),repeat=2)])
print('All 12 row/column orderings enumerated; affine-remapped reversal also rejected')
