Ejemplo n.º 1
0
def FairSelect(*guards):
    """ 
    It sorts the list of guards in order based on the history for
    the chosen guards in this FairSelect located at a specific line in a specific process.

    Internally it invokes a priority select on the new order of guards.
    
    Timer and Skip guards are placed with lowest priority, since it does make sence to make them
    fair.
    """
    alt_key = str(current_process_id()) + '_' + str(
        inspect.currentframe().f_back.f_lineno)
    A = AltHistory()
    H = A.get_history(alt_key)

    L = []
    L_last = []
    for item in guards:
        try:
            chan_name = item.g[0].channel.name
            if H.has_key(chan_name):
                L.append((H[chan_name], item.g))
            else:
                L.append((0, item.g))
        except AttributeError:
            try:
                L_last.append(item.g)
            except AttributeError:
                raise Exception(
                    'Can not use ' + str(item) +
                    ' as guard. Only use *Guard types for AltSelect')
    L.sort()
    L = [x[1] for x in L] + L_last

    if pycsp.current.trace:
        import pycsp.common.trace as trace
        a = trace.Alternation(L)
        a.set_execute_frame(-3)
    else:
        a = Alternation(L)
        a.set_execute_frame(-2)

    result = a.execute()
    try:
        chan_name = result[0].channel.name
        A.update_history(alt_key, chan_name)
    except:
        # Can not record skip or timer guard.
        pass
    return result
Ejemplo n.º 2
0
def FairSelect(*guards):
    """ 
    It sorts the list of guards in order based on the history for
    the chosen guards in this FairSelect located at a specific line in a specific process.

    Internally it invokes a priority select on the new order of guards.
    
    Timer and Skip guards are placed with lowest priority, since it does make sence to make them
    fair.
    """
    alt_key = str(current_process_id()) + '_' + str(inspect.currentframe().f_back.f_lineno)
    A = AltHistory()
    H = A.get_history(alt_key)

    L = []
    L_last = []
    for item in guards:
        try:
            chan_name = item.g[0].channel.name
            if H.has_key(chan_name):
                L.append((H[chan_name], item.g))
            else:
                L.append((0, item.g))
        except AttributeError:
            try:
                L_last.append(item.g)
            except AttributeError:
                raise Exception('Can not use ' + str(item) + ' as guard. Only use *Guard types for AltSelect')
    L.sort()
    L = [x[1] for x in L] + L_last

    if pycsp.current.trace:
        import pycsp.common.trace as trace
        a = trace.Alternation(L)
        a._set_execute_frame(-3)
    else:
        a = Alternation(L)
        a._set_execute_frame(-2)

    result =  a.execute()
    try:
        chan_name = result[0].channel.name
        A.update_history(alt_key, chan_name)
    except:
        # Can not record skip or timer guard.
        pass
    return result
Ejemplo n.º 3
0
    def Buffer(self, cin, cout, N):
        queue = deque()
        poisoned = False
        retired = False
        while True:
            try:
                import pycsp.current
                if pycsp.current.trace:
                    TraceMsg(len(queue))

                # Handling poison / retire
                if (poisoned or retired):
                    if len(queue):
                        try:
                            cout(queue.popleft())
                        except:
                            if poisoned:
                                poison(cin, cout)
                            if retired:
                                retire(cin, cout)
                    else:
                        if poisoned:
                            poison(cin, cout)
                        if retired:
                            retire(cin, cout)
                        return  # quit
                # Queue empty
                elif len(queue) == 0:
                    queue.append(cin())
                # Queue not full and not empty
                elif len(queue) < N:
                    g, msg = Alternation([(cout, queue[0], None),
                                          (cin, None)]).select()
                    if g == cin:
                        queue.append(msg)
                    else:
                        queue.popleft()
                # Queue full
                else:
                    cout(queue.popleft())
            except ChannelPoisonException as e:
                poisoned = True
            except ChannelRetireException as e:
                retired = True
Ejemplo n.º 4
0
def PriSelect(*guards):
    """
    PriSelect is a wrapper to Alternation with a much more intuitive
    interface. 
    It performs a prioritized choice from a list of guard objects and
    returns a tuple with the selected channel end and the read msg if
    there is one, otherwise None.

    >>> from __init__ import *

    >>> C = Channel()
    >>> cin = C.reader()

    >>> ch_end, msg = PriSelect(InputGuard(cin), SkipGuard())

    >>> if ch_end == cin:
    ...     print msg
    ... else:
    ...     print msg == None
    True


    PriSelect supports skip, timeout, input and output guards.

    >>> @choice 
    ... def callback(type, channel_input = None):
    ...    print type, channel_input

    >>> A, B = Channel('A'), Channel('B')
    >>> cin, cout = A.reader(), B.writer()
    >>> g1 = InputGuard(cin, action=callback('input'))
    >>> g2 = OutputGuard(cout, msg=[range(10),range(100)], action=callback('output'))
    >>> g3 = TimeoutGuard(seconds=0.1, action=callback('timeout'))
    
    >>> _ = PriSelect(g1, g2, g3)
    timeout None
    

    Note that PriSelect always performs the guard that was chosen,
    i.e. channel input or output is executed within the PriSelect so
    even the empty choice with an PriSelect or where
    the results are simply ignored, still performs the guarded input or
    output.

    >>> L = []

    >>> @choice 
    ... def action(channel_input):
    ...     L.append(channel_input)

    >>> @process
    ... def P1(cout, n=5):
    ...     for i in range(n):
    ...         cout(i)
    
    >>> @process
    ... def P2(cin1, cin2, n=10):
    ...     for i in range(n):
    ...         _ = AltSelect( InputGuard(cin1, action=action()), InputGuard(cin2, action=action()) )
                
    >>> C1, C2 = Channel(), Channel()
    >>> Parallel(P1(C1.writer()), P1(C2.writer()), P2(C1.reader(), C2.reader()))

    >>> len(L)
    10

    >>> L.sort()
    >>> L
    [0, 0, 1, 1, 2, 2, 3, 3, 4, 4]
    """
    L = []
    # Build guard list
    for item in guards:
        try:
            L.append(item.g)
        except AttributeError:
            raise Exception(
                'Cannot use ' + str(item) +
                ' as guard. Only use *Guard types for Pri/AltSelect')

    if pycsp.current.trace:
        import pycsp.common.trace as trace
        a = trace.Alternation(L)
        a.set_execute_frame(-3)
    else:
        a = Alternation(L)
        a.set_execute_frame(-2)

    return a.execute()
Ejemplo n.º 5
0
def PriSelect(*guards):
    """
    PriSelect is a wrapper to Alternation with a much more intuitive
    interface. 
    It performs a prioritized choice from a list of guard objects and
    returns a tuple with the selected channel end and the read msg if
    there is one, otherwise None.

    >>> from __init__ import *

    >>> C = Channel()
    >>> cin = C.reader()

    >>> ch_end, msg = PriSelect(InputGuard(cin), SkipGuard())

    >>> if ch_end == cin:
    ...     print msg
    ... else:
    ...     print msg == None
    True


    PriSelect supports skip, timeout, input and output guards.

    >>> @choice 
    ... def callback(type, channel_input = None):
    ...    print type, channel_input

    >>> A, B = Channel('A'), Channel('B')
    >>> cin, cout = A.reader(), B.writer()
    >>> g1 = InputGuard(cin, action=callback('input'))
    >>> g2 = OutputGuard(cout, msg=[range(10),range(100)], action=callback('output'))
    >>> g3 = TimeoutGuard(seconds=0.1, action=callback('timeout'))
    
    >>> _ = PriSelect(g1, g2, g3)
    timeout None
    

    Note that PriSelect always performs the guard that was chosen,
    i.e. channel input or output is executed within the PriSelect so
    even the empty choice with an PriSelect or where
    the results are simply ignored, still performs the guarded input or
    output.

    >>> L = []

    >>> @choice 
    ... def action(channel_input):
    ...     L.append(channel_input)

    >>> @process
    ... def P1(cout, n=5):
    ...     for i in range(n):
    ...         cout(i)
    
    >>> @process
    ... def P2(cin1, cin2, n=10):
    ...     for i in range(n):
    ...         _ = AltSelect( InputGuard(cin1, action=action()), InputGuard(cin2, action=action()) )
                
    >>> C1, C2 = Channel(), Channel()
    >>> Parallel(P1(C1.writer()), P1(C2.writer()), P2(C1.reader(), C2.reader()))

    >>> len(L)
    10

    >>> L.sort()
    >>> L
    [0, 0, 1, 1, 2, 2, 3, 3, 4, 4]
    """
    L = []
    # Build guard list
    for item in guards:
        try:
            L.append(item.g)
        except AttributeError:
            raise Exception('Cannot use ' + str(item) + ' as guard. Only use *Guard types for Pri/AltSelect')

    if pycsp.current.trace:
        import pycsp.common.trace as trace
        a = trace.Alternation(L)
        a._set_execute_frame(-3)
    else:
        a = Alternation(L)
        a._set_execute_frame(-2)

    return a.execute()