# -*- generated by 1.0.2 -*-
import da
PatternExpr_241 = da.pat.TuplePattern([da.pat.ConstantPattern('access'), da.pat.FreePattern('newtok')])
PatternExpr_253 = da.pat.TuplePattern([da.pat.ConstantPattern('request'), da.pat.FreePattern('c'), da.pat.FreePattern('p')])
PatternExpr_280 = da.pat.TuplePattern([da.pat.ConstantPattern('request'), da.pat.FreePattern('c'), da.pat.BoundPattern('_BoundPattern285_')])
PatternExpr_315 = da.pat.TuplePattern([da.pat.ConstantPattern('access'), da.pat.FreePattern(None)])
PatternExpr_336 = da.pat.TuplePattern([da.pat.ConstantPattern('access'), da.pat.FreePattern('token1')])
PatternExpr_358 = da.pat.TuplePattern([da.pat.ConstantPattern('access'), da.pat.FreePattern('token2')])
PatternExpr_420 = da.pat.TuplePattern([da.pat.ConstantPattern('Done')])
PatternExpr_425 = da.pat.BoundPattern('_BoundPattern426_')
PatternExpr_427 = da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.FreePattern(None), da.pat.BoundPattern('_BoundPattern433_')]), da.pat.TuplePattern([da.pat.ConstantPattern('Done')])])
_config_object = {}
import sys

class P(da.DistProcess):

    def __init__(self, procimpl, props):
        super().__init__(procimpl, props)
        self._PReceivedEvent_2 = []
        self._PSentEvent_3 = []
        self._PReceivedEvent_4 = []
        self._PSentEvent_5 = []
        self._PReceivedEvent_6 = []
        self._events.extend([da.pat.EventPattern(da.pat.ReceivedEvent, '_PReceivedEvent_0', PatternExpr_241, sources=None, destinations=None, timestamps=None, record_history=None, handlers=[self._P_handler_240]), da.pat.EventPattern(da.pat.ReceivedEvent, '_PReceivedEvent_1', PatternExpr_253, sources=None, destinations=None, timestamps=None, record_history=None, handlers=[self._P_handler_252]), da.pat.EventPattern(da.pat.ReceivedEvent, '_PReceivedEvent_2', PatternExpr_280, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.SentEvent, '_PSentEvent_3', PatternExpr_315, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_PReceivedEvent_4', PatternExpr_336, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.SentEvent, '_PSentEvent_5', PatternExpr_358, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_PReceivedEvent_6', PatternExpr_420, sources=[PatternExpr_425], destinations=None, timestamps=None, record_history=True, handlers=[])])

    def setup(self, ps, nrounds, orig_token, **rest_515):
        super().setup(ps=ps, nrounds=nrounds, orig_token=orig_token, **rest_515)
        self._state.ps = ps
        self._state.nrounds = nrounds
        self._state.orig_token = orig_token
        self._state.clock = 0
        self._state.token = dict(((p, 0) for p in self._state.ps))

    def run(self):

        def anounce():
            self.output('In cs!')
        if self.token_present():
            self.output("I'm lucky!")
        for i in range(self._state.nrounds):
            self.cs(anounce)
        self.send(('Done',), self._state.ps)
        super()._label('_st_label_411', block=False)
        p = None

        def UniversalOpExpr_412():
            nonlocal p
            for p in self._state.ps:
                if (not PatternExpr_427.match_iter(self._PReceivedEvent_6, _BoundPattern433_=p, SELF_ID=self._id)):
                    return False
            return True
        _st_label_411 = 0
        while (_st_label_411 == 0):
            _st_label_411 += 1
            if UniversalOpExpr_412():
                _st_label_411 += 1
            else:
                super()._label('_st_label_411', block=True)
                _st_label_411 -= 1
        self.output('Done!')

    def cs(self, task):
        super()._label('request', block=False)
        if (not self.token_present()):
            self._state.clock += 1
            self.send(('request', self._state.clock, self._id), self._state.ps)
            super()._label('_st_label_209', block=False)
            _st_label_209 = 0
            while (_st_label_209 == 0):
                _st_label_209 += 1
                if self.token_present():
                    _st_label_209 += 1
                else:
                    super()._label('_st_label_209', block=True)
                    _st_label_209 -= 1
        self._state.token[self._id] = self._state.clock
        task()
        super()._label('release', block=False)
        for p in self._state.ps:
            if (self.request_pending(p) and self.token_present()):
                self.send(('access', self._state.token), p)
                break

    def request_pending(self, p):
        c = None

        def ExistentialOpExpr_278():
            nonlocal c
            for (_, _, (_ConstantPattern296_, c, _BoundPattern299_)) in self._PReceivedEvent_2:
                if (_ConstantPattern296_ == 'request'):
                    if (_BoundPattern299_ == p):
                        if (c > self._state.token[p]):
                            return True
            return False
        return ExistentialOpExpr_278()

    def token_present(self):

        def ExistentialOpExpr_313():
            for (_, _, (_ConstantPattern329_, _)) in self._PSentEvent_3:
                if (_ConstantPattern329_ == 'access'):
                    if True:
                        return True
            return False
        token1 = token2 = None

        def ExistentialOpExpr_334():
            nonlocal token1, token2
            for (_, _, (_ConstantPattern351_, token1)) in self._PReceivedEvent_4:
                if (_ConstantPattern351_ == 'access'):

                    def ExistentialOpExpr_356(token1):
                        nonlocal token2
                        for (_, _, (_ConstantPattern373_, token2)) in self._PSentEvent_5:
                            if (_ConstantPattern373_ == 'access'):
                                if (token2[self._id] > token1[self._id]):
                                    return True
                        return False
                    if (not ExistentialOpExpr_356(token1=token1)):
                        return True
            return False
        return ((self._state.orig_token and (not ExistentialOpExpr_313())) or ExistentialOpExpr_334())

    def _P_handler_240(self, newtok):
        self._state.token = newtok
    _P_handler_240._labels = None
    _P_handler_240._notlabels = None

    def _P_handler_252(self, c, p):
        if (self.request_pending(p) and self.token_present()):
            self.send(('access', self._state.token), p)
    _P_handler_252._labels = None
    _P_handler_252._notlabels = None

class Node_(da.NodeProcess):

    def __init__(self, procimpl, props):
        super().__init__(procimpl, props)
        self._events.extend([])

    def run(self):
        nprocs = (int(sys.argv[1]) if (len(sys.argv) > 1) else 10)
        nrounds = (int(sys.argv[2]) if (len(sys.argv) > 2) else 1)
        ps = self.new(P, num=nprocs)
        p = ps.pop()
        self._setup(ps, ((ps | {p}), nrounds, False))
        self._setup([p], ((ps | {p}), nrounds, True))
        self._start((ps | {p}))
