feat: replace ExpressionA with IsNull("a") (#2651)

Closes https://github.com/apache/iceberg-python/issues/2637

# Rationale for this change

## Are these changes tested?

Yes, tests and lint passing

## Are there any user-facing changes?
diff --git a/tests/expressions/test_expressions.py b/tests/expressions/test_expressions.py
index 0731fff..45addd8 100644
--- a/tests/expressions/test_expressions.py
+++ b/tests/expressions/test_expressions.py
@@ -77,29 +77,6 @@
     StringType,
     StructType,
 )
-from pyiceberg.utils.singleton import Singleton
-
-
-class ExpressionA(BooleanExpression, Singleton):
-    def __invert__(self) -> BooleanExpression:
-        return ExpressionB()
-
-    def __repr__(self) -> str:
-        return "ExpressionA()"
-
-    def __str__(self) -> str:
-        return "testexpra"
-
-
-class ExpressionB(BooleanExpression, Singleton):
-    def __invert__(self) -> BooleanExpression:
-        return ExpressionA()
-
-    def __repr__(self) -> str:
-        return "ExpressionB()"
-
-    def __str__(self) -> str:
-        return "testexprb"
 
 
 def test_isnull_inverse() -> None:
@@ -504,18 +481,18 @@
     "exp, testexpra, testexprb",
     [
         (
-            And(ExpressionA(), ExpressionB()),
-            And(ExpressionA(), ExpressionB()),
-            Or(ExpressionA(), ExpressionB()),
+            And(IsNull("a"), IsNull("b")),
+            And(IsNull("a"), IsNull("b")),
+            Or(IsNull("a"), IsNull("b")),
         ),
         (
-            Or(ExpressionA(), ExpressionB()),
-            Or(ExpressionA(), ExpressionB()),
-            And(ExpressionA(), ExpressionB()),
+            Or(IsNull("a"), IsNull("b")),
+            Or(IsNull("a"), IsNull("b")),
+            And(IsNull("a"), IsNull("b")),
         ),
-        (Not(ExpressionA()), Not(ExpressionA()), ExpressionB()),
-        (ExpressionA(), ExpressionA(), ExpressionB()),
-        (ExpressionB(), ExpressionB(), ExpressionA()),
+        (Not(IsNull("a")), Not(IsNull("a")), IsNull("b")),
+        (IsNull("a"), IsNull("a"), IsNull("b")),
+        (IsNull("b"), IsNull("b"), IsNull("a")),
         (
             In(Reference("foo"), ("hello", "world")),
             In(Reference("foo"), ("hello", "world")),
@@ -536,16 +513,16 @@
     "lhs, rhs",
     [
         (
-            And(ExpressionA(), ExpressionB()),
-            Or(ExpressionB(), ExpressionA()),
+            And(IsNull("a"), IsNull("b")),
+            Or(NotNull("a"), NotNull("b")),
         ),
         (
-            Or(ExpressionA(), ExpressionB()),
-            And(ExpressionB(), ExpressionA()),
+            Or(IsNull("a"), IsNull("b")),
+            And(NotNull("a"), NotNull("b")),
         ),
         (
-            Not(ExpressionA()),
-            ExpressionA(),
+            Not(IsNull("a")),
+            IsNull("a"),
         ),
         (
             In(Reference("foo"), ("hello", "world")),
@@ -559,8 +536,8 @@
         (LessThan(Reference("foo"), 5), GreaterThanOrEqual(Reference("foo"), 5)),
         (EqualTo(Reference("foo"), 5), NotEqualTo(Reference("foo"), 5)),
         (
-            ExpressionA(),
-            ExpressionB(),
+            IsNull("a"),
+            NotNull("a"),
         ),
     ],
 )
@@ -572,14 +549,14 @@
     "lhs, rhs",
     [
         (
-            And(ExpressionA(), ExpressionB(), ExpressionA()),
-            And(ExpressionA(), And(ExpressionB(), ExpressionA())),
+            And(IsNull("a"), IsNull("b"), IsNull("a")),
+            And(IsNull("a"), And(IsNull("b"), IsNull("a"))),
         ),
         (
-            Or(ExpressionA(), ExpressionB(), ExpressionA()),
-            Or(ExpressionA(), Or(ExpressionB(), ExpressionA())),
+            Or(IsNull("a"), IsNull("b"), IsNull("a")),
+            Or(IsNull("a"), Or(IsNull("b"), IsNull("a"))),
         ),
-        (Not(Not(ExpressionA())), ExpressionA()),
+        (Not(Not(IsNull("a"))), IsNull("a")),
     ],
 )
 def test_reduce(lhs: BooleanExpression, rhs: BooleanExpression) -> None:
@@ -589,13 +566,13 @@
 @pytest.mark.parametrize(
     "lhs, rhs",
     [
-        (And(AlwaysTrue(), ExpressionB()), ExpressionB()),
-        (And(AlwaysFalse(), ExpressionB()), AlwaysFalse()),
-        (And(ExpressionB(), AlwaysTrue()), ExpressionB()),
-        (Or(AlwaysTrue(), ExpressionB()), AlwaysTrue()),
-        (Or(AlwaysFalse(), ExpressionB()), ExpressionB()),
-        (Or(ExpressionA(), AlwaysFalse()), ExpressionA()),
-        (Not(Not(ExpressionA())), ExpressionA()),
+        (And(AlwaysTrue(), IsNull("b")), IsNull("b")),
+        (And(AlwaysFalse(), IsNull("b")), AlwaysFalse()),
+        (And(IsNull("b"), AlwaysTrue()), IsNull("b")),
+        (Or(AlwaysTrue(), IsNull("b")), AlwaysTrue()),
+        (Or(AlwaysFalse(), IsNull("b")), IsNull("b")),
+        (Or(IsNull("a"), AlwaysFalse()), IsNull("a")),
+        (Not(Not(IsNull("a"))), IsNull("a")),
         (Not(AlwaysTrue()), AlwaysFalse()),
         (Not(AlwaysFalse()), AlwaysTrue()),
     ],