Ejemplo n.º 1
0
def templatize_rule(block, rule, index_set):
    import pyomo.core.base.set
    context = _template_iter_context()
    internal_error = None
    _old_iters = (
        pyomo.core.base.set._FiniteSetMixin.__iter__,
        GetItemExpression.__iter__,
        GetAttrExpression.__iter__,
    )
    _old_sum = builtins.sum
    try:
        # Override Set iteration to return IndexTemplates
        pyomo.core.base.set._FiniteSetMixin.__iter__ \
            = GetItemExpression.__iter__ \
            = GetAttrExpression.__iter__ \
            = lambda x: context.get_iter(x).__iter__()
        # Override sum with our sum
        builtins.sum = context.sum_template
        # Get the index templates needed for calling the rule
        if index_set is not None:
            if not index_set.isfinite():
                raise TemplateExpressionError(
                    None,
                    "Cannot templatize rule with non-finite indexing set")
            indices = next(iter(index_set))
            try:
                context.cache.pop()
            except IndexError:
                assert indices is None
                indices = ()
        else:
            indices = ()
        if type(indices) is not tuple:
            indices = (indices, )
        # Call the rule, returning the template expression and the
        # top-level IndexTemplate(s) generated when calling the rule.
        #
        # TBD: Should this just return a "FORALL()" expression node that
        # behaves similarly to the GetItemExpression node?
        return rule(block, *indices), indices
    except:
        internal_error = sys.exc_info()
        raise
    finally:
        pyomo.core.base.set._FiniteSetMixin.__iter__, \
            GetItemExpression.__iter__, \
            GetAttrExpression.__iter__ = _old_iters
        builtins.sum = _old_sum
        if len(context.cache):
            if internal_error is not None:
                logger.error("The following exception was raised when "
                             "templatizing the rule '%s':\n\t%s" %
                             (rule.__name__, internal_error[1]))
            raise TemplateExpressionError(
                None,
                "Explicit iteration (for loops) over Sets is not supported "
                "by template expressions.  Encountered loop over %s" %
                (context.cache[-1][0]._set, ))
    return None, indices
Ejemplo n.º 2
0
 def __call__(self, exception=True):
     """
     Return the value of this object.
     """
     if self._value is None:
         if exception:
             raise TemplateExpressionError(self)
         return None
     else:
         return self._value
Ejemplo n.º 3
0
 def __call__(self, exception=True):
     """
     Return the value of this object.
     """
     if self._value is _NotSpecified:
         if exception:
             raise TemplateExpressionError(
                 self,
                 "Evaluating uninitialized IndexTemplate (%s)" % (self, ))
         return None
     else:
         return self._value