Esempio n. 1
0
def fix_functions_with_multiple_connections(context):
    # tuples (ndp, res)
    from mocdp.comp.connection import find_functions_with_multiple_connections
    res = find_functions_with_multiple_connections(context.connections)
    for id_ndp, fname in res:
        matches = lambda c: c.dp2 == id_ndp and c.s2 == fname
        its = [c for c in context.connections if matches(c)]
        assert len(its) >= 2

        for c in its:
            context.connections.remove(c)

        P = context.get_ftype(CFunction(id_ndp, fname))
        new_name = context.new_name('_join_fname')
        dp = JoinNDP(n=len(its), P=P)

        new_connections = []
        fnames = []
        rname = '_a'
        for i, c in enumerate(its):
            fn = '_%s_%d' % (fname, i)
            fnames.append(fn)
            c2 = Connection(dp1=c.dp1, s1=c.s1, dp2=new_name, s2=fn)
            new_connections.append(c2)

        ndp = dpwrap(dp, fnames, rname)
        context.add_ndp(new_name, ndp)
        for c2 in new_connections:
            context.add_connection(c2)

        cc = Connection(dp1=new_name, s1=rname, dp2=id_ndp, s2=fname)
        context.add_connection(cc)
Esempio n. 2
0
File: helpers.py Progetto: rusi/mcdp
def get_valuewithunits_as_function(v, context):
    dp = Limit(v.unit, v.value)
    n = context.new_name('_lim')
    sn = context.new_fun_name('_l')
    ndp = dpwrap(dp, sn, [])
    context.add_ndp(n, ndp)
    return context.make_function(n, sn)
Esempio n. 3
0
def add_variable(vname, P, where, context):
    if vname in context.variables:
        msg = 'Variable name %r already used once.' % vname
        raise DPSemanticError(msg, where=where)

    if vname in context.rnames:
        msg = 'Conflict between variable and resource name %r.' % vname
        raise DPSemanticError(msg, where=where)

    if vname in context.fnames:
        msg = 'Conflict between variable and functionality name %r.' % vname
        raise DPSemanticError(msg, where=where)
    
    if vname in context.var2resource:
        msg = 'The name %r is already used as a resource.' % vname
        raise DPSemanticError(msg, where=where)

    if vname in context.var2function:
        msg = 'The name %r is already used as a functionality.' % vname
        raise DPSemanticError(msg, where=where)

    dp = VariableNode(P, vname)
    fname = '_' + vname
    rname = '_' + vname
    ndp = dpwrap(dp, fname, rname)
    context.add_ndp(vname, ndp)

    context.set_var2resource(vname, CResource(vname, rname))
    context.set_var2function(vname, CFunction(vname, fname))
    
    context.variables.add(vname)
Esempio n. 4
0
def fix_resources_with_multiple_connections(context):
    # tuples (ndp, res)
    from mocdp.comp.connection import find_resources_with_multiple_connections
    res = find_resources_with_multiple_connections(context.connections)
    for id_ndp, rname in res:
        matches = lambda c: c.dp1 == id_ndp and c.s1 == rname
        its = [c for c in context.connections if matches(c)]
        assert len(its) >= 2

        for c in its:
            context.connections.remove(c)

        P = context.get_rtype(CResource(id_ndp, rname))
        new_name = context.new_name('_join_fname')
        dp = MeetNDualDP(n=len(its), P=P)

        new_connections = []
        rnames = []
        for i, c in enumerate(its):
            rn = '_%s_%d' % (rname, i)
            rnames.append(rn)
            c2 = Connection(dp1=new_name, s1=rn, dp2=c.dp2, s2=c.s2)
            new_connections.append(c2)

        fname = '_a'
        ndp = dpwrap(dp, fname, rnames)
        context.add_ndp(new_name, ndp)
        for c2 in new_connections:
            context.add_connection(c2)

        # [ id_ndp : rname ] -> [ new_name ]
        cc = Connection(dp2=new_name, s2=fname, dp1=id_ndp, s1=rname)
        context.add_connection(cc)
Esempio n. 5
0
def get_valuewithunits_as_function(v, context):
    dp = Limit(v.unit, v.value)
    n = context.new_name('_lim')
    sn = context.new_fun_name('_l')
    ndp = dpwrap(dp, sn, [])
    context.add_ndp(n, ndp)
    return context.make_function(n, sn)
Esempio n. 6
0
def fix_functions_with_multiple_connections(context):
    # tuples (ndp, res)
    from mocdp.comp.connection import find_functions_with_multiple_connections
    res = find_functions_with_multiple_connections(context.connections)
    for id_ndp, fname in res:
        matches = lambda c: c.dp2 == id_ndp and c.s2 == fname
        its = [c for c in context.connections if matches(c)]
        assert len(its) >= 2

        for c in its:
            context.connections.remove(c)

        P = context.get_ftype(CFunction(id_ndp, fname))
        new_name = context.new_name('_join_fname')
        dp = JoinNDP(n=len(its), P=P)

        new_connections = []
        fnames = []
        rname = '_a'
        for i, c in enumerate(its):
            fn = '_%s_%d' % (fname, i)
            fnames.append(fn)
            c2 = Connection(dp1=c.dp1, s1=c.s1, dp2=new_name, s2=fn)
            new_connections.append(c2)

        ndp = dpwrap(dp, fnames, rname)
        context.add_ndp(new_name, ndp)
        for c2 in new_connections:
            context.add_connection(c2)

        cc = Connection(dp1=new_name, s1=rname, dp2=id_ndp, s2=fname)
        context.add_connection(cc)
Esempio n. 7
0
def fix_resources_with_multiple_connections(context):
    # tuples (ndp, res)
    from mocdp.comp.connection import find_resources_with_multiple_connections
    res = find_resources_with_multiple_connections(context.connections)
    for id_ndp, rname in res:
        matches = lambda c: c.dp1 == id_ndp and c.s1 == rname
        its = [c for c in context.connections if matches(c)]
        assert len(its) >= 2

        for c in its:
            context.connections.remove(c)

        P = context.get_rtype(CResource(id_ndp, rname))
        new_name = context.new_name('_join_fname')
        dp = MeetNDualDP(n=len(its), P=P)

        new_connections = []
        rnames = []
        for i, c in enumerate(its):
            rn = '_%s_%d' % (rname, i)
            rnames.append(rn)
            c2 = Connection(dp1=new_name, s1=rn, dp2=c.dp2, s2=c.s2)
            new_connections.append(c2)

        fname = '_a'
        ndp = dpwrap(dp, fname, rnames)
        context.add_ndp(new_name, ndp)
        for c2 in new_connections:
            context.add_connection(c2)

        # [ id_ndp : rname ] -> [ new_name ]
        cc = Connection(dp2=new_name, s2=fname, dp1=id_ndp, s1=rname)
        context.add_connection(cc)
Esempio n. 8
0
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
Esempio n. 9
0
File: helpers.py Progetto: rusi/mcdp
def get_constant_minimals_as_resources(R, values, context):
    for v in values:
        R.belongs(v)

    dp = ConstantMinimals(R=R, values=values)
    nres = context.new_res_name('_c')
    ndp = dpwrap(dp, [], nres)
    context.add_ndp(nres, ndp)
    return context.make_resource(nres, nres)
Esempio n. 10
0
def get_constant_maximals_as_function(F, values, context):
    for v in values:
        F.belongs(v)

    dp = LimitMaximals(F=F, values=values)
    nres = context.new_name('_c')
    ndp = dpwrap(dp, '_max', [])
    context.add_ndp(nres, ndp)
    return context.make_function(nres, '_max')
Esempio n. 11
0
def get_constant_minimals_as_resources(R, values, context):
    for v in values:
        R.belongs(v)

    dp = ConstantMinimals(R=R, values=values)
    nres = context.new_res_name('_c')
    ndp = dpwrap(dp, [], nres)
    context.add_ndp(nres, ndp)
    return context.make_resource(nres, nres)
Esempio n. 12
0
File: helpers.py Progetto: rusi/mcdp
def get_constant_maximals_as_function(F, values, context):
    for v in values:
        F.belongs(v)

    dp = LimitMaximals(F=F, values=values)
    nres = context.new_name('_c')
    ndp = dpwrap(dp, '_max', [])
    context.add_ndp(nres, ndp)
    return context.make_function(nres, '_max')
Esempio n. 13
0
def add_variable(vname, P, where, context):
    if vname in context.variables:
        msg = 'Variable name %r already used once.' % vname
        raise DPSemanticError(msg, where=where)

    if vname in context.rnames:
        msg = 'Conflict between variable and resource name %r.' % vname
        raise DPSemanticError(msg, where=where)

    if vname in context.fnames:
        msg = 'Conflict between variable and functionality name %r.' % vname
        raise DPSemanticError(msg, where=where)

    if vname in context.var2resource:
        msg = 'The name %r is already used as a resource.' % vname
        raise DPSemanticError(msg, where=where)

    if vname in context.var2function:
        msg = 'The name %r is already used as a functionality.' % vname
        raise DPSemanticError(msg, where=where)

    try:
        check_good_name_for_regular_node(vname)
    except ValueError as e:
        msg = 'Invalid name: %s' % e
        raise DPSemanticError(msg, where=where)

    dp = VariableNode(P, vname)
    fname = '_' + vname
    rname = '_' + vname
    ndp = dpwrap(dp, fname, rname)
    context.add_ndp(vname, ndp)

    context.set_var2resource(vname, CResource(vname, rname))
    context.set_var2function(vname, CFunction(vname, fname))

    context.variables.add(vname)
Esempio n. 14
0
def eval_ndp_catalogue3(r, context):
    check_isinstance(r, CDP.Catalogue3)

    statements = unwrap_list(r.funres)
    fun = [x for x in statements if isinstance(x, CDP.FunStatement)]
    res = [x for x in statements if isinstance(x, CDP.ResStatement)]
    Fs = [eval_space(_.unit, context) for _ in fun]
    Rs = [eval_space(_.unit, context) for _ in res]

    assert len(fun) + len(res) == len(statements), statements

    tu = get_types_universe()

    rows = unwrap_list(r.table)

    entries = []  # (name, f, r)

    for i, row in enumerate(rows):
        check_isinstance(row, CDP.CatalogueRow3)

        check_isinstance(row.functions, CDP.CatalogueFunc)
        row.leftright
        check_isinstance(row.resources, CDP.CatalogueRes)

        fs = get_odd_ops(unwrap_list(row.functions.ops))
        rs = get_odd_ops(unwrap_list(row.resources.ops))

        for _ in list(fs) + list(rs):
            if isinstance(_, CDP.CatalogueEntryConstantUncertain):
                msg = 'Uncertain catalogue not implemented'
                raise DPNotImplementedError(msg, where=_.where)

        fs_evaluated = [eval_constant(_.constant, context) for _ in fs]
        rs_evaluated = [eval_constant(_.constant, context) for _ in rs]

        if len(Fs) == 0:
            # expect <>
            if len(fs) != 1 and fs_evaluated.value != ():
                msg = 'Because there are no functionalities, I expected simply "<>".'
                raise DPSemanticError(msg, where=row.functions.where)
        else:
            if len(fs_evaluated) != len(Fs):
                msg = 'Mismatch with number of functionalities.'
                raise DPSemanticError(msg, where=row.functions.where)

        if len(Rs) == 0:
            if len(rs) != 1 and rs_evaluated.value != ():
                msg = 'Because there are no resources, I expected simply "<>".'
                raise DPSemanticError(msg, where=row.resources.where)
        else:
            if len(rs_evaluated) != len(Rs):
                msg = 'Mismatch with number of resources.'
                raise DPSemanticError(msg, where=row.resources.where)

        for cell, Fhave, F in zip(fs, fs_evaluated, Fs):
            try:
                tu.check_leq(Fhave.unit, F)
            except NotLeq:
                msg = 'Dimensionality problem: cannot convert %s to %s.' % (
                    Fhave.unit, F)
                raise DPSemanticError(msg, where=cell.where)

        for cell, Rhave, R in zip(rs, rs_evaluated, Rs):
            try:
                tu.check_leq(Rhave.unit, R)
            except NotLeq:
                msg = 'Dimensionality problem: cannot convert %s to %s.' % (
                    Rhave.unit, R)
                raise DPSemanticError(msg, where=cell.where)

        fvalues_ = [_.cast_value(F) for (_, F) in zip(fs_evaluated, Fs)]
        rvalues_ = [_.cast_value(R) for (_, R) in zip(rs_evaluated, Rs)]

        assert len(fvalues_) == len(fun)
        assert len(rvalues_) == len(res)

        f = tuple(fvalues_)
        r = tuple(rvalues_)

        if len(Fs) == 0:
            f = ()
        if len(Rs) == 0:
            r = ()

        entries.append((i, f, r))

    names = set([name for (name, _, _) in entries])

    M = FiniteCollectionAsSpace(names)
    # use integers
    # entries = [(float(i), b, c) for i, (_, b, c) in enumerate(entries)]

    fnames = [_.fname.value for _ in fun]
    rnames = [_.rname.value for _ in res]

    if len(Fs) == 1:
        F = Fs[0]
        fnames = fnames[0]
        entries = [(a, b[0], c) for (a, b, c) in entries]
    else:
        F = PosetProduct(tuple(Fs))

    if len(Rs) == 1:
        R = Rs[0]
        rnames = rnames[0]
        entries = [(a, b, c[0]) for (a, b, c) in entries]
    else:
        R = PosetProduct(tuple(Rs))

    dp = CatalogueDP(F=F, R=R, I=M, entries=tuple(entries))
    ndp = dpwrap(dp, fnames=fnames, rnames=rnames)
    return ndp
Esempio n. 15
0
def eval_ndp_catalogue(r, context):
    check_isinstance(r, CDP.FromCatalogue)
    # FIXME:need to check for re-ordering
    statements = unwrap_list(r.funres)
    fun = [x for x in statements if isinstance(x, CDP.FunStatement)]
    res = [x for x in statements if isinstance(x, CDP.ResStatement)]

    Fs = [eval_space(_.unit, context) for _ in fun]
    Rs = [eval_space(_.unit, context) for _ in res]

    assert len(fun) + len(res) == len(statements), statements
    tu = get_types_universe()
    table = r.table
    rows = unwrap_list(table.rows)
    entries = []
    for row in rows:
        items = unwrap_list(row)
        name = items[0].value
        expected = 1 + len(fun) + len(res)
        if len(items) != expected:
            msg = 'Row with %d elements does not match expected of elements (%s fun, %s res)' % (
                len(items), len(fun), len(res))
            # msg += ' items: %s' % str(items)
            raise DPSemanticError(msg, where=items[-1].where)
        fvalues0 = items[1:1 + len(fun)]
        rvalues0 = items[1 + len(fun):1 + len(fun) + len(res)]

        fvalues = [eval_constant(_, context) for _ in fvalues0]
        rvalues = [eval_constant(_, context) for _ in rvalues0]

        for cell, Fhave, F in zip(fvalues0, fvalues, Fs):
            try:
                tu.check_leq(Fhave.unit, F)
            except NotLeq as e:
                msg = 'Dimensionality problem: cannot convert %s to %s.' % (
                    Fhave.unit, F)
                ex = lambda msg: DPSemanticError(msg, where=cell.where)
                raise_wrapped(ex, e, msg, compact=True)

        for cell, Rhave, R in zip(rvalues0, rvalues, Rs):
            try:
                tu.check_leq(Rhave.unit, R)
            except NotLeq as e:
                msg = 'Dimensionality problem: cannot convert %s to %s.' % (
                    Rhave.unit, R)
                ex = lambda msg: DPSemanticError(msg, where=cell.where)
                raise_wrapped(ex, e, msg, compact=True)

        fvalues_ = [_.cast_value(F) for (_, F) in zip(fvalues, Fs)]
        rvalues_ = [_.cast_value(R)for (_, R) in zip(rvalues, Rs)]

        assert len(fvalues_) == len(fun)
        assert len(rvalues_) == len(res)

        entries.append((name, tuple(fvalues_), tuple(rvalues_)))

    names = set([name for (name, _, _) in entries])
    M = FiniteCollectionAsSpace(names)
    # use integers
    # entries = [(float(i), b, c) for i, (_, b, c) in enumerate(entries)]

    fnames = [_.fname.value for _ in fun]
    rnames = [_.rname.value for _ in res]

    if len(Fs) == 1:
        F = Fs[0]
        fnames = fnames[0]
        entries = [(a, b[0], c) for (a, b, c) in entries]
    else:
        F = PosetProduct(tuple(Fs))

    if len(Rs) == 1:
        R = Rs[0]
        rnames = rnames[0]
        entries = [(a, b, c[0]) for (a, b, c) in entries]
    else:
        R = PosetProduct(tuple(Rs))

    dp = CatalogueDP(F=F, R=R, I=M, entries=tuple(entries))
    ndp = dpwrap(dp, fnames=fnames, rnames=rnames)
    return ndp
Esempio n. 16
0
File: helpers.py Progetto: rusi/mcdp
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
Esempio n. 17
0
File: helpers.py Progetto: rusi/mcdp
def get_valuewithunits_as_resource(v, context):
    dp = Constant(R=v.unit, value=v.value)
    nres = context.new_res_name('_c')
    ndp = dpwrap(dp, [], nres)
    context.add_ndp(nres, ndp)
    return context.make_resource(nres, nres)
Esempio n. 18
0
def get_valuewithunits_as_resource(v, context):
    dp = Constant(R=v.unit, value=v.value)
    nres = context.new_res_name('_c')
    ndp = dpwrap(dp, [], nres)
    context.add_ndp(nres, ndp)
    return context.make_resource(nres, nres)
Esempio n. 19
0
def eval_ndp_catalogue(r, context):
    check_isinstance(r, CDP.FromCatalogue)
    # FIXME:need to check for re-ordering
    statements = unwrap_list(r.funres)
    fun = [x for x in statements if isinstance(x, CDP.FunStatement)]
    res = [x for x in statements if isinstance(x, CDP.ResStatement)]
    
    Fs = [eval_space(_.unit, context) for _ in fun]
    Rs = [eval_space(_.unit, context) for _ in res]

    assert len(fun) + len(res) == len(statements), statements
    tu = get_types_universe()
    table = r.table
    rows = unwrap_list(table.rows)
    entries = []
    for row in rows:
        items = unwrap_list(row)
        name = items[0].value
        expected = 1 + len(fun) + len(res)
        if len(items) != expected:
            msg = 'Row with %d elements does not match expected of elements (%s fun, %s res)' % (len(items), len(fun), len(res))
            # msg += ' items: %s' % str(items)
            raise DPSemanticError(msg, where=items[-1].where)
        fvalues0 = items[1:1 + len(fun)]
        rvalues0 = items[1 + len(fun):1 + len(fun) + len(res)]

        fvalues = [eval_constant(_, context) for _ in fvalues0]
        rvalues = [eval_constant(_, context) for _ in rvalues0]

        for cell, Fhave, F in zip(fvalues0, fvalues, Fs):
            try:
                tu.check_leq(Fhave.unit, F)
            except NotLeq as e:
                msg = 'Dimensionality problem: cannot convert %s to %s.' % (Fhave.unit, F)
                ex = lambda msg: DPSemanticError(msg, where=cell.where)
                raise_wrapped(ex, e, msg, compact=True)

        for cell, Rhave, R in zip(rvalues0, rvalues, Rs):
            try:
                tu.check_leq(Rhave.unit, R)
            except NotLeq as e:
                msg = 'Dimensionality problem: cannot convert %s to %s.' % (Rhave.unit, R)
                ex = lambda msg: DPSemanticError(msg, where=cell.where)
                raise_wrapped(ex, e, msg, compact=True)

        fvalues_ = [_.cast_value(F) for (_, F) in zip(fvalues, Fs)]
        rvalues_ = [_.cast_value(R)for (_, R) in zip(rvalues, Rs)]

        assert len(fvalues_) == len(fun)
        assert len(rvalues_) == len(res)

        entries.append((name, tuple(fvalues_), tuple(rvalues_)))

    
    names = set([name for (name, _, _) in entries])
    M = FiniteCollectionAsSpace(names)
    # use integers
    # entries = [(float(i), b, c) for i, (_, b, c) in enumerate(entries)]

    fnames = [_.fname.value for  _ in fun]
    rnames = [_.rname.value for  _ in res]

    if len(Fs) == 1:
        F = Fs[0]
        fnames = fnames[0]
        entries = [(a, b[0], c) for (a, b, c) in entries]
    else:
        F = PosetProduct(tuple(Fs))

    if len(Rs) == 1:
        R = Rs[0]
        rnames = rnames[0]
        entries = [(a, b, c[0]) for (a, b, c) in entries]
    else:
        R = PosetProduct(tuple(Rs))

    dp = CatalogueDP(F=F, R=R, I=M, entries=tuple(entries))
    ndp = dpwrap(dp, fnames=fnames, rnames=rnames)
    return ndp
Esempio n. 20
0
File: helpers.py Progetto: rusi/mcdp
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
Esempio n. 21
0
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