Repository: sympy/sympy

Issue:
Nested floor and ceiling expressions could be reduced
Related to #11207: floor(ceiling(x)) doesn't simplify

```python
>>> x, y = symbols('x y')
>>> floor(-floor(ceiling(x**3)/y))

⎢ ⎢⎡ 3⎤⎥⎥
⎢ ⎢⎢x ⎥⎥⎥
⎢-⎢────⎥⎥
⎣ ⎣ y  ⎦⎦

>>> -ceiling(-ceiling(floor(x)/y))

 ⎡ ⎡⌊x⌋⎤⎤
-⎢-⎢───⎥⎥
 ⎢ ⎢ y ⎥⎥
```

Discussion:

Patch:
diff --git a/sympy/functions/elementary/integers.py b/sympy/functions/elementary/integers.py
index f2ba99e50b..fff00401a9 100644
--- a/sympy/functions/elementary/integers.py
+++ b/sympy/functions/elementary/integers.py
@@ -122,9 +122,8 @@ class floor(RoundFunction):
     def _eval_number(cls, arg):
         if arg.is_Number:
             return arg.floor()
-        elif isinstance(arg, ceiling):
-            return arg
-        elif isinstance(arg, floor):
+        elif any(isinstance(i, j)
+                for i in (arg, -arg) for j in (floor, ceiling)):
             return arg
         if arg.is_NumberSymbol:
             return arg.approximation_interval(Integer)[0]
@@ -195,9 +194,8 @@ class ceiling(RoundFunction):
     def _eval_number(cls, arg):
         if arg.is_Number:
             return arg.ceiling()
-        elif isinstance(arg, ceiling):
-            return arg
-        elif isinstance(arg, floor):
+        elif any(isinstance(i, j)
+                for i in (arg, -arg) for j in (floor, ceiling)):
             return arg
         if arg.is_NumberSymbol:
             return arg.approximation_interval(Integer)[1]


Test patch:
diff --git a/sympy/functions/elementary/tests/test_integers.py b/sympy/functions/elementary/tests/test_integers.py
index 3e1d28eed0..125ca9f8fd 100644
--- a/sympy/functions/elementary/tests/test_integers.py
+++ b/sympy/functions/elementary/tests/test_integers.py
@@ -258,8 +258,16 @@ def test_issue_4149():
     assert floor(3*I + pi*I + y*I) == floor(3 + pi + y)*I
     assert floor(3 + E + pi*I + y*I) == 5 + floor(pi + y)*I
 
+
 def test_issue_11207():
     assert floor(floor(x)) == floor(x)
     assert floor(ceiling(x)) == ceiling(x)
     assert ceiling(floor(x)) == floor(x)
     assert ceiling(ceiling(x)) == ceiling(x)
+
+
+def test_nested_floor_ceiling():
+    assert floor(-floor(ceiling(x**3)/y)) == -floor(ceiling(x**3)/y)
+    assert ceiling(-floor(ceiling(x**3)/y)) == -floor(ceiling(x**3)/y)
+    assert floor(ceiling(-floor(x**Rational(7, 2)/y))) == -floor(x**Rational(7, 2)/y)
+    assert -ceiling(-ceiling(floor(x)/y)) == ceiling(floor(x)/y)