Beispiel #1
0
def eval_lfunction_FValuePlusOrMinus(r, context):
    from mcdp_dp import UncertainGateSym, MinusValueDP, PlusValueDP

    from .eval_lfunction_imp import eval_lfunction
    from .eval_constant_imp import eval_constant
    from .helpers import create_operation_lf
    
    check_isinstance(r, CDP.FValuePlusOrMinus)
    median = eval_lfunction(r.median, context)
    extent = eval_constant(r.extent, context)
    
    F = context.get_ftype(median)

    # provides f = between 10 g and 20 g
    
    # MinusValueDP :   r + c ≥ f
    # PlusValueDP :   r ≥ f + c 
    
    # f <= f0 - c # pessimistic
    # f <= f0 + c # optimistic 
    dpl =  MinusValueDP(F, extent.value, extent.unit)
    dpu =  PlusValueDP(F, extent.value, extent.unit)
    
    fl = create_operation_lf(context, dpl, functions=[median])
    fu = create_operation_lf(context, dpu, functions=[median])
     
    dp = UncertainGateSym(F)
    return create_operation_lf(context, dp=dp, functions=[fl, fu])
Beispiel #2
0
def get_invplus_op(context, lf, c):
    """ (fvalue) + constant >= f """
    ftype = context.get_ftype(lf)

    T1 = ftype
    T2 = c.unit

    if isinstance(T1, Rcomp) and isinstance(T2, Rcomp):
        val = c.value
        dp = MinusValueRcompDP(val)
    elif isinstance(T1, Rcomp) and isinstance(T2, Nat):
        # cast Nat to Rcomp
        val = float(c.value)
        dp = MinusValueRcompDP(val)
    elif isinstance(T1, RcompUnits) and isinstance(T2, RcompUnits):
        dp = MinusValueDP(T1, c.value, T2)
    elif isinstance(T1, Nat) and isinstance(T2, Nat):
        dp = MinusValueNatDP(c.value)
    elif isinstance(T1, Nat) and isinstance(T2, Rcomp):
        # f2 <= required rb + Rcomp:2.3
        dp = MinusValueRcompDP(c.value)
    else:
        msg = (
            'Cannot create inverse addition operation between variable of type %s '
            'and constant of type %s.' % (T1, T2))
        raise_desc(DPInternalError, msg)

    r2 = create_operation_lf(context,
                             dp,
                             functions=[lf],
                             name_prefix='_invplusop')
    return r2
Beispiel #3
0
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
Beispiel #4
0
def eval_rvalue_RValuePlusOrMinus(r, context):
    from mcdp_dp import UncertainGate, MinusValueDP, PlusValueDP
    from .eval_resources_imp import eval_rvalue
    from .eval_constant_imp import eval_constant

    check_isinstance(r, CDP.RValuePlusOrMinus)
    median = eval_rvalue(r.median, context)
    extent = eval_constant(r.extent, context)
    
    Rl = context.get_rtype(median)

    dpl =  MinusValueDP(Rl, extent.value, extent.unit)
    rl = create_operation(context, dpl, resources=[median])
    dpu =  PlusValueDP(Rl, extent.value, extent.unit)
    ru = create_operation(context, dpu, resources=[median])
    
    dp = UncertainGate(Rl)

    return create_operation(context, dp=dp, resources=[rl, ru])
Beispiel #5
0
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')
Beispiel #6
0
def MinusValueDP2():
    F = parse_poset('J')
    U = parse_poset('mJ')
    v = U.get_top()
    return MinusValueDP(F=F, c_value=v, c_space=U)
Beispiel #7
0
def MinusValueDP1():
    F = parse_poset('J')
    U = parse_poset('mJ')
    v = 1000.0
    return MinusValueDP(F=F, c_value=v, c_space=U)