def eval_PlusN_(constants, resources, context): from .misc_math import plus_constantsN try: # it's a constant value if len(resources) == 0: # try: return plus_constantsN(constants) # except ConstantsNotCompatibleForAddition as e: # raise_desc(DPSemanticError, str(e)) elif len(resources) == 1: if len(constants) > 0: c = plus_constantsN(constants) return get_plus_op(context, r=resources[0], c=c) else: return resources[0] else: # there are some resources r = eval_PlusN_ops(resources, context) if not constants: return r else: # try: c = plus_constantsN(constants) # except ConstantsNotCompatibleForAddition as e: # raise_wrapped(DPSemanticError, e, compact=True) return get_plus_op(context, r=r, c=c) except ConstantsNotCompatibleForAddition as e: msg = 'Incompatible units for addition' raise_wrapped(DPSemanticError, e, msg, compact=True)
def eval_PlusN_(constants, resources, context): from .misc_math import plus_constantsN # it's a constant value if len(resources) == 0: return plus_constantsN(constants) elif len(resources) == 1: if len(constants) > 0: c = plus_constantsN(constants) return get_plus_op(context, r=resources[0], c=c) else: return resources[0] else: # there are some resources r = eval_PlusN_ops(resources, context) if not constants: return r else: c = plus_constantsN(constants) return get_plus_op(context, r=r, c=c)
def eval_PlusN(x, context, wants_constant): """ Raises NotConstant if wants_constant is True. """ assert isinstance(x, CDP.PlusN) assert len(x.ops) > 1 # ops as a list ops_list = get_odd_ops(unwrap_list(x.ops)) # First, we flatten all operators ops = flatten_plusN(ops_list) # Then we divide in positive constants, negative constants, and resources. pos_constants, neg_constants, resources = \ eval_PlusN_sort_ops(ops, context, wants_constant) # first, sum the positive constants and the resources res = eval_PlusN_(pos_constants, resources, context) if len(neg_constants) == 0: # If there are no negative constants, we are done return res # elif len(neg_constants) > 1: # msg = 'Not implemented addition of more than one negative constant.' # raise_desc(DPInternalError, msg, neg_constants=neg_constants) else: # we have only one negative constant from mcdp_lang.misc_math import plus_constantsN constant = plus_constantsN(neg_constants) check_isinstance(constant.unit, RbicompUnits) constant.unit.check_leq(constant.value, 0.0) # now it's a positive value valuepos = RbicompUnits_reflect(constant.unit, constant.value) F = context.get_rtype(res) c_space = RcompUnits(pint_unit=constant.unit.units, string=constant.unit.string) # mainly to make sure we handle Top if is_top(constant.unit, valuepos): valuepos2 = c_space.get_top() else: valuepos2 = valuepos dp = MinusValueDP(F=F, c_value=valuepos2, c_space=c_space) r2 = create_operation(context, dp, resources=[res], name_prefix='_minus', op_prefix='_x', res_prefix='_y') return r2
def eval_PlusN(x, context, wants_constant): """ Raises NotConstant if wants_constant is True. """ assert isinstance(x, CDP.PlusN) assert len(x.ops) > 1 # ops as a list ops_list = get_odd_ops(unwrap_list(x.ops)) # First, we flatten all operators ops = flatten_plusN(ops_list) # Then we divide in positive constants, negative constants, and resources. pos_constants, neg_constants, resources = \ eval_PlusN_sort_ops(ops, context, wants_constant) # first, sum the positive constants and the resources res = eval_PlusN_(pos_constants, resources, context) if len(neg_constants) == 0: # If there are no negative constants, we are done return res # elif len(neg_constants) > 1: # msg = 'Not implemented addition of more than one negative constant.' # raise_desc(DPInternalError, msg, neg_constants=neg_constants) else: # we have only one negative constant from mcdp_lang.misc_math import plus_constantsN constant = plus_constantsN(neg_constants) check_isinstance(constant.unit, RbicompUnits) constant.unit.check_leq(constant.value, 0.0) # now it's a positive value valuepos = RbicompUnits_reflect(constant.unit, constant.value) F = context.get_rtype(res) c_space = RcompUnits(pint_unit=constant.unit.units, string=constant.unit.string) # mainly to make sure we handle Top if is_top(constant.unit, valuepos): valuepos2 = c_space.get_top() else: valuepos2 = valuepos dp = MinusValueDP(F=F, c_value=valuepos2, c_space=c_space) r2 = create_operation(context, dp, resources=[res]) return r2
def eval_rvalue_RValueMinusN(x, context, wants_constant=False): """ If wants_constant is True, returns a ValueWithUnit """ from .eval_constant_imp import eval_constant ops = get_odd_ops(unwrap_list(x.ops)) # ops after the first should be constant, otherwise # we lose monotonicity must_be_constants = ops[1:] constants = [] for mc in must_be_constants: try: c = eval_constant(mc, context) assert isinstance(c, ValueWithUnits) constants.append(c) except NotConstant: msg = 'The expression involving "-" is not monotone because one ' msg += 'of the values after "-" is not a constant:\n\n' s = format_where(mc.where, context_before=0, arrow=False, mark=None, use_unicode=True) msg += indent(s, ' '*4) raise DPSemanticError(msg) # Is the first value a constant? try: x = eval_constant(ops[0], context) assert isinstance(x, ValueWithUnits) # if so, this is just x - constants[0] - constants[1] - ... vu = x_minus_constants(x, constants) if wants_constant: return vu else: return get_valuewithunits_as_resource(vu, context) except NotConstant: # if we wanted this to be constant, it's a problem if wants_constant: raise # first value is not constant rvalue = eval_rvalue(ops[0], context) # we cannot do it with more than 1 # if len(constants) > 1: # msg = 'This code works only with 1 constant.' # raise_desc(DPNotImplementedError, msg) # from .misc_math import plus_constantsN constant = plus_constantsN(constants) R = context.get_rtype(rvalue) if isinstance(R, Nat) and isinstance(constant.unit, Nat): dp = MinusValueNatDP(constant.value) elif isinstance(R, Rcomp) and not isinstance(R, RcompUnits): dp = MinusValueRcompDP(constant.value) elif isinstance(R, RcompUnits): dp = MinusValueDP(F=R, c_value=constant.value, c_space=constant.unit) else: msg = 'Could not create this operation with %s ' % R raise_desc(DPSemanticError, msg, R=R) return create_operation(context, dp=dp, resources=[rvalue], name_prefix='_minusvalue', op_prefix='_op', res_prefix='_result')
def eval_rvalue_RValueMinusN(x, context, wants_constant=False): """ If wants_constant is True, returns a ValueWithUnit """ from .eval_constant_imp import eval_constant ops = get_odd_ops(unwrap_list(x.ops)) # ops after the first should be constant, otherwise # we lose monotonicity must_be_constants = ops[1:] constants = [] for mc in must_be_constants: try: c = eval_constant(mc, context) assert isinstance(c, ValueWithUnits) constants.append(c) except NotConstant: msg = 'The expression involving "-" is not monotone because one ' msg += 'of the values after "-" is not a constant:\n\n' s = format_where(mc.where, context_before=0, arrow=False, mark=None, use_unicode=True) msg += indent(s, ' ' * 4) raise DPSemanticError(msg) # Is the first value a constant? try: x = eval_constant(ops[0], context) assert isinstance(x, ValueWithUnits) # if so, this is just x - constants[0] - constants[1] - ... vu = x_minus_constants(x, constants) if wants_constant: return vu else: return get_valuewithunits_as_resource(vu, context) except NotConstant: # if we wanted this to be constant, it's a problem if wants_constant: raise # first value is not constant rvalue = eval_rvalue(ops[0], context) # we cannot do it with more than 1 # if len(constants) > 1: # msg = 'This code works only with 1 constant.' # raise_desc(DPNotImplementedError, msg) # from .misc_math import plus_constantsN constant = plus_constantsN(constants) R = context.get_rtype(rvalue) if isinstance(R, Nat) and isinstance(constant.unit, Nat): dp = MinusValueNatDP(constant.value) elif isinstance(R, Rcomp) and not isinstance(R, RcompUnits): dp = MinusValueRcompDP(constant.value) elif isinstance(R, RcompUnits): dp = MinusValueDP(F=R, c_value=constant.value, c_space=constant.unit) else: msg = 'Could not create this operation with %s ' % R raise_desc(DPSemanticError, msg, R=R) return create_operation(context, dp=dp, resources=[rvalue], name_prefix='_minusvalue', op_prefix='_op', res_prefix='_result')