def get_function_possibly_converted(cf, P, context): """ Returns a resource possibly converted to the space P """ check_isinstance(cf, CFunction) F = context.get_ftype(cf) tu = get_types_universe() if tu.equal(F, P): return cf else: try: tu.check_leq(P, F) except NotLeq as e: msg = 'Cannot convert %s to %s.' % (P, F) raise_wrapped(DPSemanticError, e, msg,P=P, F=F) conversion = get_conversion(P, F) if conversion is None: return cf else: cf2 = create_operation_lf(context, dp=conversion, functions=[cf], name_prefix='_conv_gfpc', op_prefix='_op', res_prefix='_res') return cf2
def get_resource_possibly_converted(r, P, context): """ Returns a resource possibly converted to the space P """ assert isinstance(r, CResource) R = context.get_rtype(r) tu = get_types_universe() if tu.equal(R, P): return r else: try: tu.get_super_conversion(R, P) except NotLeq as e: msg = 'Cannot convert %s to %s.' % (R, P) raise_wrapped(DPSemanticError, e, msg, R=R, P=P, exc=sys.exc_info()) conversion = get_conversion(R, P) if conversion is None: return r else: r2 = create_operation(context, conversion, [r], name_prefix='_conv_grpc', op_prefix='_op', res_prefix='_res') return r2
def create_operation_lf(context, dp, functions, name_prefix, op_prefix='_op', res_prefix='_res', allow_conversion=True): name = context.new_name(name_prefix) name_result = context.new_res_name(res_prefix) rnames = [] for i, f in enumerate(functions): ni = context.new_fun_name('%s%s' % (op_prefix, i)) rnames.append(ni) _rnames = rnames[0] if len(rnames) == 1 else rnames ndp = dpwrap(dp, name_result, _rnames) connections = [] tu = get_types_universe() for i, f in enumerate(functions): # source resource Fi = context.get_ftype(f) # function Fhave = ndp.get_rtype(rnames[i]) # print('------- argu %d' % i) # # print('I need to connect function %s of type %s to resource %s of new NDP with type %s'% # (f, Fi, rnames[i], Fhave)) # # print('Fi: %s' % Fi) # print('Fhave: %s' % Fhave) if not tu.equal(Fi, Fhave): if not allow_conversion: msg = ('The types are %s and %s are not equal, and ' 'allow_conversion is False' % (Fi, Fhave)) raise DPInternalError(msg) # print('creating conversion') conversion = get_conversion(Fhave, Fi) if conversion is None: msg = 'I need a conversion from %s to %s' % (Fi, Fhave) raise DPInternalError(msg) else: # print('Conversion: %s' % conversion.repr_long()) # print('Creating recursive...') f = create_operation_lf(context, conversion, [f], name_prefix='_conversion_for_%s' % name_result, allow_conversion=False) c = Connection(dp2=f.dp, s2=f.s, dp1=name, s1=rnames[i]) connections.append(c) context.add_ndp(name, ndp) for c in connections: context.add_connection(c) res = context.make_function(name, name_result) return res
def get_resource_possibly_converted(r, P, context): """ Returns a resource possibly converted to the space P """ assert isinstance(r, CResource) R = context.get_rtype(r) tu = get_types_universe() if tu.equal(R, P): return r else: try: tu.check_leq(R, P) except NotLeq as e: msg = 'Cannot convert %s to %s.' % (R, P) raise_wrapped(DPSemanticError, e, msg, R=R, P=P) conversion = get_conversion(R, P) if conversion is None: return r else: r2 = create_operation(context, conversion, [r], name_prefix='_conv_grpc', op_prefix='_op', res_prefix='_res') return r2
def create_operation_lf(context, dp, functions, name_prefix=None, op_prefix='_op', res_prefix='_res', allow_conversion=True): if name_prefix is None: name_prefix = '_%s' % type(dp).__name__ name = context.new_name(name_prefix) name_result = context.new_res_name(res_prefix) rnames = [] for i, f in enumerate(functions): ni = context.new_fun_name('%s%s' % (op_prefix, i)) rnames.append(ni) _rnames = rnames[0] if len(rnames) == 1 else rnames ndp = dpwrap(dp, name_result, _rnames) connections = [] tu = get_types_universe() for i, f in enumerate(functions): # source resource Fi = context.get_ftype(f) # function Fhave = ndp.get_rtype(rnames[i]) # print('------- argu %d' % i) # # print('I need to connect function %s of type %s to resource %s of new NDP with type %s'% # (f, Fi, rnames[i], Fhave)) # # print('Fi: %s' % Fi) # print('Fhave: %s' % Fhave) if not tu.equal(Fi, Fhave): if not allow_conversion: msg = ('The types are %s and %s are not equal, and ' 'allow_conversion is False' % (Fi, Fhave)) raise DPInternalError(msg) # print('creating conversion') conversion = get_conversion(Fhave, Fi) if conversion is None: msg = 'I need a conversion from %s to %s' % (Fi, Fhave) raise DPInternalError(msg) else: # print('Conversion: %s' % conversion.repr_long()) # print('Creating recursive...') f = create_operation_lf(context, conversion, [f], name_prefix='_conversion_for_%s' % name_result, allow_conversion=False) c = Connection(dp2=f.dp, s2=f.s, dp1=name, s1=rnames[i]) connections.append(c) context.add_ndp(name, ndp) for c in connections: context.add_connection(c) res = context.make_function(name, name_result) return res
def create_operation(context, dp, resources, name_prefix=None, op_prefix=None, res_prefix=None): """ This is useful to create operations that take possibly many inputs and produce one output. Example use: R = mult_table_seq(resources_types) dp = ProductN(tuple(resources_types), R) from mcdp_lang.helpers import create_operation r = create_operation(context, dp, resources, name_prefix='_prod', op_prefix='_factor', res_prefix='_result') """ if name_prefix is None: name_prefix = '_%s' % type(dp).__name__ # new name for the ndp name = context.new_name(name_prefix) if op_prefix is None: op_prefix = '_op' if res_prefix is None: res_prefix = '_res' name_result = context.new_res_name(res_prefix) connections = [] fnames = [] for i, r in enumerate(resources): ni = context.new_fun_name('%s%s' % (op_prefix, i)) fnames.append(ni) fnames_ = fnames[0] if len(fnames) == 1 else fnames ndp = dpwrap(dp, fnames_, name_result) context.add_ndp(name, ndp) tu = get_types_universe() for i, r in enumerate(resources): # this is where we check for types # source resource R = context.get_rtype(r) # function F = ndp.get_ftype(fnames[i]) if not tu.equal(F, R): conversion = get_conversion(R, F) if conversion is None: msg = 'I need a conversion from %s to %s' % (R, F) raise DPInternalError(msg) else: r = create_operation(context, conversion, [r], name_prefix='_conversion_for_%s' % name_result) R = context.get_rtype(r) assert tu.equal(F, R) c = Connection(dp1=r.dp, s1=r.s, dp2=name, s2=fnames[i]) connections.append(c) for c in connections: context.add_connection(c) res = context.make_resource(name, name_result) return res
def eval_ndp_dpwrap(r, context): tu = get_types_universe() statements = unwrap_list(r.statements) fun = [x for x in statements if isinstance(x, CDP.FunStatement)] res = [x for x in statements if isinstance(x, CDP.ResStatement)] assert len(fun) + len(res) == len(statements), statements impl = r.impl from .eval_primitivedp_imp import eval_primitivedp dp = eval_primitivedp(impl, context) fnames = [f.fname.value for f in fun] rnames = [r.rname.value for r in res] if len(fnames) == 1: use_fnames = fnames[0] else: use_fnames = fnames if len(rnames) == 1: use_rnames = rnames[0] else: use_rnames = rnames dp_F = dp.get_fun_space() dp_R = dp.get_res_space() # Check that the functions are the same want_Fs = tuple([eval_space(f.unit, context) for f in fun]) if len(want_Fs) == 1: want_F = want_Fs[0] else: want_F = PosetProduct(want_Fs) want_Rs = tuple([eval_space(r.unit, context) for r in res]) if len(want_Rs) == 1: want_R = want_Rs[0] else: want_R = PosetProduct(want_Rs) mcdp_dev_warning('Not sure about this') dp_prefix = get_conversion(want_F, dp_F) dp_postfix = get_conversion(dp_R, want_R) if dp_prefix is not None: dp = make_series(dp_prefix, dp) if dp_postfix is not None: dp = make_series(dp, dp_postfix) try: w = SimpleWrap(dp=dp, fnames=use_fnames, rnames=use_rnames) except ValueError as e: raise DPSemanticError(str(e), r.where) ftypes = w.get_ftypes(fnames) rtypes = w.get_rtypes(rnames) ftypes_expected = PosetProduct(tuple([eval_space(f.unit, context) for f in fun])) rtypes_expected = PosetProduct(tuple([eval_space(r.unit, context) for r in res])) try: tu.check_equal(ftypes, ftypes_expected) tu.check_equal(rtypes, rtypes_expected) except NotEqual as e: msg = 'The types in the description do not match.' raise_wrapped(DPSemanticError, e, msg, dp=dp, ftypes=ftypes, ftypes_expected=ftypes_expected, rtypes=rtypes, rtypes_expected=rtypes_expected, compact=True) return w
def eval_ndp_dpwrap(r, context): tu = get_types_universe() statements = unwrap_list(r.statements) fun = [x for x in statements if isinstance(x, CDP.FunStatement)] res = [x for x in statements if isinstance(x, CDP.ResStatement)] assert len(fun) + len(res) == len(statements), statements impl = r.impl from .eval_primitivedp_imp import eval_primitivedp dp = eval_primitivedp(impl, context) fnames = [f.fname.value for f in fun] rnames = [r.rname.value for r in res] if len(fnames) == 1: use_fnames = fnames[0] else: use_fnames = fnames if len(rnames) == 1: use_rnames = rnames[0] else: use_rnames = rnames dp_F = dp.get_fun_space() dp_R = dp.get_res_space() # Check that the functions are the same want_Fs = tuple([eval_space(f.unit, context) for f in fun]) if len(want_Fs) == 1: want_F = want_Fs[0] else: want_F = PosetProduct(want_Fs) want_Rs = tuple([eval_space(r.unit, context) for r in res]) if len(want_Rs) == 1: want_R = want_Rs[0] else: want_R = PosetProduct(want_Rs) mcdp_dev_warning('Not sure about this') dp_prefix = get_conversion(want_F, dp_F) dp_postfix = get_conversion(dp_R, want_R) if dp_prefix is not None: dp = make_series(dp_prefix, dp) if dp_postfix is not None: dp = make_series(dp, dp_postfix) try: w = SimpleWrap(dp=dp, fnames=use_fnames, rnames=use_rnames) except ValueError as e: raise DPSemanticError(str(e), r.where) ftypes = w.get_ftypes(fnames) rtypes = w.get_rtypes(rnames) ftypes_expected = PosetProduct( tuple([eval_space(f.unit, context) for f in fun])) rtypes_expected = PosetProduct( tuple([eval_space(r.unit, context) for r in res])) try: tu.check_equal(ftypes, ftypes_expected) tu.check_equal(rtypes, rtypes_expected) except NotEqual as e: msg = 'The types in the description do not match.' raise_wrapped(DPSemanticError, e, msg, dp=dp, ftypes=ftypes, ftypes_expected=ftypes_expected, rtypes=rtypes, rtypes_expected=rtypes_expected, compact=True) return w
def create_operation(context, dp, resources, name_prefix, op_prefix=None, res_prefix=None): """ This is useful to create operations that take possibly many inputs and produce one output. Example use: R = mult_table_seq(resources_types) dp = ProductN(tuple(resources_types), R) from mcdp_lang.helpers import create_operation r = create_operation(context, dp, resources, name_prefix='_prod', op_prefix='_factor', res_prefix='_result') """ # new name for the ndp name = context.new_name(name_prefix) if op_prefix is None: op_prefix = '_op' if res_prefix is None: res_prefix = '_res' name_result = context.new_res_name(res_prefix) connections = [] fnames = [] for i, r in enumerate(resources): ni = context.new_fun_name('%s%s' % (op_prefix, i)) fnames.append(ni) fnames_ = fnames[0] if len(fnames) == 1 else fnames ndp = dpwrap(dp, fnames_, name_result) context.add_ndp(name, ndp) tu = get_types_universe() for i, r in enumerate(resources): # this is where we check for types # source resource R = context.get_rtype(r) # function F = ndp.get_ftype(fnames[i]) if not tu.equal(F, R): conversion = get_conversion(R, F) if conversion is None: msg = 'I need a conversion from %s to %s' % (R, F) raise DPInternalError(msg) else: r = create_operation(context, conversion, [r], name_prefix='_conversion_for_%s' % name_result) R = context.get_rtype(r) assert tu.equal(F, R) c = Connection(dp1=r.dp, s1=r.s, dp2=name, s2=fnames[i]) connections.append(c) for c in connections: context.add_connection(c) res = context.make_resource(name, name_result) return res