lalib/tests/fields/test_axioms.py

97 lines
2.7 KiB
Python
Raw Normal View History

"""Ensure all `Field`s fulfill the axioms from math.
Source: https://en.wikipedia.org/wiki/Field_(mathematics)#Classic_definition
"""
import contextlib
import operator
import pytest
from tests.fields import utils
# None of the test cases below contributes towards higher coverage
pytestmark = pytest.mark.integration_test
@pytest.mark.repeat(utils.N_RANDOM_DRAWS)
@pytest.mark.parametrize("field", utils.ALL_FIELDS)
class TestAllFieldsManyTimes:
"""Run the tests many times for all `field`s."""
@pytest.mark.parametrize("opr", [operator.add, operator.mul])
def test_associativity(self, field, opr):
"""`a + (b + c) == (a + b) + c` ...
... and `a * (b * c) == (a * b) * c`.
"""
a, b, c = field.random(), field.random(), field.random()
left = opr(a, opr(b, c))
right = opr(opr(a, b), c)
assert left == pytest.approx(right, abs=utils.DEFAULT_THRESHOLD)
@pytest.mark.parametrize("opr", [operator.add, operator.mul])
def test_commutativity(self, field, opr):
"""`a + b == b + a` ...
... and `a * b == b * a`.
"""
a, b = field.random(), field.random()
left = opr(a, b)
right = opr(b, a)
assert left == pytest.approx(right, abs=utils.DEFAULT_THRESHOLD)
def test_additive_identity(self, field):
"""`a + 0 == a`."""
a = field.random()
left = a + field.zero
right = a
assert left == pytest.approx(right, abs=utils.DEFAULT_THRESHOLD)
def test_multiplicative_identity(self, field):
"""`a * 1 == a`."""
a = field.random()
left = a * field.one
right = a
assert left == pytest.approx(right, abs=utils.DEFAULT_THRESHOLD)
def test_additive_inverse(self, field):
"""`a + (-a) == 0`."""
a = field.random()
left = a + (-a)
right = field.zero
assert left == pytest.approx(right, abs=utils.DEFAULT_THRESHOLD)
def test_multiplicative_inverse(self, field):
"""`a * (1 / a) == 1`."""
a = field.random()
# Realistically, `ZeroDivisionError` only occurs for `GF2`
# => With a high enough `utils.N_RANDOM_DRAWS`
# this test case is also `assert`ed for `GF2`
with contextlib.suppress(ZeroDivisionError):
left = a * (field.one / a)
right = field.one
assert left == pytest.approx(right, abs=utils.DEFAULT_THRESHOLD)
def test_distributivity(self, field):
"""`a * (b + c) == (a * b) + (a * c)`."""
a, b, c = field.random(), field.random(), field.random()
left = a * (b + c)
right = (a * b) + (a * c)
assert left == pytest.approx(right, abs=utils.DEFAULT_THRESHOLD)