Repository: sympy/sympy

Issue:
allow Min/Max to be written in terms of Abs
```diff
diff --git a/sympy/functions/elementary/miscellaneous.py b/sympy/functions/elementary/miscellaneous.py
index 1d161f9..b4bbf97 100644
--- a/sympy/functions/elementary/miscellaneous.py
+++ b/sympy/functions/elementary/miscellaneous.py
@@ -604,6 +604,12 @@ def _eval_derivative(self, s):
             l.append(df * da)
         return Add(*l)
 
+    def _eval_rewrite_as_Abs(self, *args):
+        from sympy.functions.elementary.complexes import Abs
+        s = (args[0] + self.func(*args[1:]))/2
+        d = abs(args[0] - self.func(*args[1:]))/2
+        return (s + d if isinstance(self, Max) else s - d).rewrite(Abs)
+
     def evalf(self, prec=None, **options):
         return self.func(*[a.evalf(prec, **options) for a in self.args])
     n = evalf
diff --git a/sympy/functions/elementary/tests/test_miscellaneous.py b/sympy/functions/elementary/tests/test_miscellaneous.py
index cc9bb74..d45d325 100644
--- a/sympy/functions/elementary/tests/test_miscellaneous.py
+++ b/sympy/functions/elementary/tests/test_miscellaneous.py
@@ -394,3 +394,19 @@ def test_instantiation_evaluation():
         A, B = B, A
     assert Min(w, Max(x, y), Max(v, x, z)) == Min(
         w, Max(x, Min(y, Max(v, z))))
+
+
+def test_rewrite_as_Abs():
+    from itertools import permutations
+    from sympy.functions.elementary.complexes import Abs
+    from sympy.abc import x, y, z
+    def test(e):
+        free = e.free_symbols
+        a = e.rewrite(Abs)
+        for i in permutations(range(len(free))):
+            reps = dict(zip(free, i))
+            assert a.xreplace(reps) == e.xreplace(reps)
+
+    test(Min(x, y))
+    test(Max(x, y))
+    test(Min(x, y, z))
```

Discussion:

Patch:
diff --git a/sympy/core/mod.py b/sympy/core/mod.py
index eae25630cc..ef4a69b7ed 100644
--- a/sympy/core/mod.py
+++ b/sympy/core/mod.py
@@ -107,38 +107,6 @@ def doit(p, q):
             elif (qinner*(q + qinner)).is_nonpositive:
                 # |qinner| < |q| and have different sign
                 return p
-        elif isinstance(p, Add):
-            # separating into modulus and non modulus
-            both_l = non_mod_l, mod_l = [], []
-            for arg in p.args:
-                both_l[isinstance(arg, cls)].append(arg)
-            # if q same for all
-            if mod_l and all(inner.args[1] == q for inner in mod_l):
-                net = Add(*non_mod_l) + Add(*[i.args[0] for i in mod_l])
-                return cls(net, q)
-
-        elif isinstance(p, Mul):
-            # separating into modulus and non modulus
-            both_l = non_mod_l, mod_l = [], []
-            for arg in p.args:
-                both_l[isinstance(arg, cls)].append(arg)
-
-            if mod_l and all(inner.args[1] == q for inner in mod_l):
-                # finding distributive term
-                non_mod_l = [cls(x, q) for x in non_mod_l]
-                mod = []
-                non_mod = []
-                for j in non_mod_l:
-                    if isinstance(j, cls):
-                        mod.append(j.args[0])
-                    else:
-                        non_mod.append(j)
-                prod_mod = Mul(*mod)
-                prod_non_mod = Mul(*non_mod)
-                prod_mod1 = Mul(*[i.args[0] for i in mod_l])
-                net = prod_mod1*prod_mod
-                return prod_non_mod*cls(net, q)
-
         # XXX other possibilities?
 
         # extract gcd; any further simplification should be done by the user
diff --git a/sympy/functions/elementary/miscellaneous.py b/sympy/functions/elementary/miscellaneous.py
index 1d161f9a78..b4bbf9720d 100644
--- a/sympy/functions/elementary/miscellaneous.py
+++ b/sympy/functions/elementary/miscellaneous.py
@@ -604,6 +604,12 @@ def _eval_derivative(self, s):
             l.append(df * da)
         return Add(*l)
 
+    def _eval_rewrite_as_Abs(self, *args):
+        from sympy.functions.elementary.complexes import Abs
+        s = (args[0] + self.func(*args[1:]))/2
+        d = abs(args[0] - self.func(*args[1:]))/2
+        return (s + d if isinstance(self, Max) else s - d).rewrite(Abs)
+
     def evalf(self, prec=None, **options):
         return self.func(*[a.evalf(prec, **options) for a in self.args])
     n = evalf


Test patch:
diff --git a/sympy/core/tests/test_arit.py b/sympy/core/tests/test_arit.py
index 0eef313604..91e185e8eb 100644
--- a/sympy/core/tests/test_arit.py
+++ b/sympy/core/tests/test_arit.py
@@ -1655,12 +1655,6 @@ def test_Mod():
     # issue 10963
     assert (x**6000%400).args[1] == 400
 
-    #issue 13543
-    assert Mod(Mod(x + 1, 2) + 1 , 2) == Mod(x,2)
-
-    assert Mod(Mod(x + 2, 4)*(x + 4), 4) == Mod(x*(x + 2), 4)
-    assert Mod(Mod(x + 2, 4)*4, 4) == 0
-
 
 def test_Mod_is_integer():
     p = Symbol('p', integer=True)
diff --git a/sympy/functions/elementary/tests/test_miscellaneous.py b/sympy/functions/elementary/tests/test_miscellaneous.py
index cc9bb740d9..3e691645bd 100644
--- a/sympy/functions/elementary/tests/test_miscellaneous.py
+++ b/sympy/functions/elementary/tests/test_miscellaneous.py
@@ -394,3 +394,19 @@ def test_instantiation_evaluation():
         A, B = B, A
     assert Min(w, Max(x, y), Max(v, x, z)) == Min(
         w, Max(x, Min(y, Max(v, z))))
+
+def test_rewrite_as_Abs():
+    from itertools import permutations
+    from sympy.functions.elementary.complexes import Abs
+    from sympy.abc import x, y, z, w
+    def test(e):
+        free = e.free_symbols
+        a = e.rewrite(Abs)
+        assert not a.has(Min, Max)
+        for i in permutations(range(len(free))):
+            reps = dict(zip(free, i))
+            assert a.xreplace(reps) == e.xreplace(reps)
+    test(Min(x, y))
+    test(Max(x, y))
+    test(Min(x, y, z))
+    test(Min(Max(w, x), Max(y, z)))