Repository: Pyomo/pyomo

Issue:
BigM does not support RangeSet on disjuncts
I am seeing this error with a randomly generated model, which seems to imply lack of support for RangeSet on disjuncts.

```
pyomo.gdp.disjunct.GDP_Error: No BigM transformation handler registered for modeling components of type <class 'pyomo.core.base.rangeset.RangeSet'>
```


Discussion:

Resolving patch:
diff --git a/pyomo/gdp/plugins/bigm.py b/pyomo/gdp/plugins/bigm.py
--- a/pyomo/gdp/plugins/bigm.py
+++ b/pyomo/gdp/plugins/bigm.py
@@ -15,8 +15,8 @@
 
 from pyomo.core import (
     Block, Connector, Constraint, Param, Set, Suffix, Var,
-    Expression, SortComponents, TraversalStrategy, Any, value
-)
+    Expression, SortComponents, TraversalStrategy, Any, value,
+    RangeSet)
 from pyomo.core.base import Transformation, TransformationFactory
 from pyomo.core.base.component import ComponentUID, ActiveComponent
 from pyomo.core.kernel.component_map import ComponentMap
@@ -129,6 +129,7 @@ def __init__(self):
             Suffix:      False,
             Param:       False,
             Set:         False,
+            RangeSet:    False,
             Disjunction: self._warn_for_active_disjunction,
             Disjunct:    self._warn_for_active_disjunct,
             Block:       self._transform_block_on_disjunct,
diff --git a/pyomo/gdp/plugins/chull.py b/pyomo/gdp/plugins/chull.py
--- a/pyomo/gdp/plugins/chull.py
+++ b/pyomo/gdp/plugins/chull.py
@@ -8,19 +8,12 @@
 #  This software is distributed under the 3-clause BSD License.
 #  ___________________________________________________________________________
 
-import weakref
 import logging
-import textwrap
 
 import pyomo.common.config as cfg
 from pyomo.common.modeling import unique_component_name
-from pyomo.core.expr.numvalue import native_numeric_types, ZeroConstant
-from pyomo.core.expr import current as EXPR
-from pyomo.core import *
-from pyomo.core.base.block import SortComponents
-from pyomo.core.base.component import ComponentUID, ActiveComponent
-from pyomo.core.base import _ExpressionData
-from pyomo.core.base.var import _VarData
+from pyomo.core.expr.numvalue import ZeroConstant
+from pyomo.core.base.component import ActiveComponent
 from pyomo.core.kernel.component_map import ComponentMap
 from pyomo.core.kernel.component_set import ComponentSet
 import pyomo.core.expr.current as EXPR
@@ -28,7 +21,7 @@
 from pyomo.core import (
     Block, Connector, Constraint, Param, Set, Suffix, Var,
     Expression, SortComponents, TraversalStrategy,
-    Any, Reals, value
+    Any, RangeSet, Reals, value
 )
 from pyomo.gdp import Disjunct, Disjunction, GDP_Error
 from pyomo.gdp.util import clone_without_expression_components, target_list
@@ -36,8 +29,6 @@
 
 from six import iteritems, iterkeys
 
-# DEBUG
-from nose.tools import set_trace
 
 logger = logging.getLogger('pyomo.gdp.chull')
 
@@ -170,6 +161,7 @@ def __init__(self):
             Expression : False,
             Param :      False,
             Set :        False,
+            RangeSet:    False,
             Suffix :     False,
             Disjunction: self._warn_for_active_disjunction,
             Disjunct:    self._warn_for_active_disjunct,


Test patch:
diff --git a/pyomo/gdp/tests/models.py b/pyomo/gdp/tests/models.py
--- a/pyomo/gdp/tests/models.py
+++ b/pyomo/gdp/tests/models.py
@@ -1,5 +1,5 @@
 from pyomo.core import (Block, ConcreteModel, Constraint, Objective, Param,
-                        Set, Var, inequality)
+                        Set, Var, inequality, RangeSet)
 from pyomo.gdp import Disjunct, Disjunction
 
 
@@ -426,3 +426,14 @@ def innerdisj_rule(d, flag):
     m.disjunction = Disjunction(expr=[m.outerdisjunct[0],
                                       m.outerdisjunct[1]])
     return m
+
+
+def makeDisjunctWithRangeSet():
+    m = ConcreteModel()
+    m.x = Var(bounds=(0, 1))
+    m.d1 = Disjunct()
+    m.d1.s = RangeSet(1)
+    m.d1.c = Constraint(rule=lambda _: m.x == 1)
+    m.d2 = Disjunct()
+    m.disj = Disjunction(expr=[m.d1, m.d2])
+    return m
diff --git a/pyomo/gdp/tests/test_bigm.py b/pyomo/gdp/tests/test_bigm.py
--- a/pyomo/gdp/tests/test_bigm.py
+++ b/pyomo/gdp/tests/test_bigm.py
@@ -2205,5 +2205,12 @@ def test_activeInnerDisjunction_err(self):
                      ComponentUID(m.disjunction)])
 
 
+class RangeSetOnDisjunct(unittest.TestCase):
+    def test_RangeSet(self):
+        m = models.makeDisjunctWithRangeSet()
+        TransformationFactory('gdp.bigm').apply_to(m)
+        self.assertIsInstance(m.d1.s, RangeSet)
+
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/pyomo/gdp/tests/test_chull.py b/pyomo/gdp/tests/test_chull.py
--- a/pyomo/gdp/tests/test_chull.py
+++ b/pyomo/gdp/tests/test_chull.py
@@ -765,6 +765,13 @@ def test_local_vars(self):
         self.assertEqual(rd.z_bounds['ub'].body(), 9)
 
 
+class RangeSetOnDisjunct(unittest.TestCase):
+    def test_RangeSet(self):
+        m = models.makeDisjunctWithRangeSet()
+        TransformationFactory('gdp.chull').apply_to(m)
+        self.assertIsInstance(m.d1.s, RangeSet)
+
+
 # TODO (based on coverage):
 
 # test targets of all flavors