# -*- generated by 1.0.6 -*-
import da
PatternExpr_192 = da.pat.TuplePattern([da.pat.ConstantPattern('ack'), da.pat.FreePattern('c'), da.pat.BoundPattern('_BoundPattern197_')])
PatternExpr_235 = da.pat.TuplePattern([da.pat.ConstantPattern('request'), da.pat.FreePattern('c'), da.pat.BoundPattern('_BoundPattern239_')])
PatternExpr_265 = da.pat.TuplePattern([da.pat.ConstantPattern('request'), da.pat.FreePattern('c'), da.pat.FreePattern('p')])
PatternExpr_279 = da.pat.TuplePattern([da.pat.ConstantPattern('request'), da.pat.FreePattern('c'), da.pat.SelfPattern()])
PatternExpr_309 = da.pat.TuplePattern([da.pat.ConstantPattern('ack'), da.pat.FreePattern('c2'), da.pat.BoundPattern('_BoundPattern314_')])
PatternExpr_385 = da.pat.TuplePattern([da.pat.ConstantPattern('Done')])
PatternExpr_390 = da.pat.BoundPattern('_BoundPattern392_')
PatternExpr_393 = da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.FreePattern(None), da.pat.BoundPattern('_BoundPattern399_')]), da.pat.TuplePattern([da.pat.ConstantPattern('Done')])])
PatternExpr_475 = da.pat.TuplePattern([da.pat.ConstantPattern('Done')])
PatternExpr_480 = da.pat.BoundPattern('_BoundPattern481_')
PatternExpr_482 = da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.FreePattern(None), da.pat.BoundPattern('_BoundPattern488_')]), 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_0 = []
        self._PReceivedEvent_1 = []
        self._PSentEvent_3 = []
        self._PReceivedEvent_4 = []
        self._PReceivedEvent_5 = []
        self._events.extend([da.pat.EventPattern(da.pat.ReceivedEvent, '_PReceivedEvent_0', PatternExpr_192, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_PReceivedEvent_1', PatternExpr_235, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_PReceivedEvent_2', PatternExpr_265, sources=None, destinations=None, timestamps=None, record_history=None, handlers=[self._P_handler_264]), da.pat.EventPattern(da.pat.SentEvent, '_PSentEvent_3', PatternExpr_279, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_PReceivedEvent_4', PatternExpr_309, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_PReceivedEvent_5', PatternExpr_385, sources=[PatternExpr_390], destinations=None, timestamps=None, record_history=True, handlers=[])])

    def setup(self, s, n, **rest_499):
        super().setup(s=s, n=n, **rest_499)
        self._state.s = s
        self._state.n = n
        pass

    def run(self):

        def anounce():
            self.output('In cs!')
        for i in range(self._state.n):
            self.cs(anounce)
        self.send(('Done',), to=self.parent())
        super()._label('_st_label_382', block=False)
        _st_label_382 = 0
        while (_st_label_382 == 0):
            _st_label_382 += 1
            if PatternExpr_393.match_iter(self._PReceivedEvent_5, _BoundPattern399_=self.parent(), SELF_ID=self._id):
                _st_label_382 += 1
            else:
                super()._label('_st_label_382', block=True)
                _st_label_382 -= 1

    def cs(self, task):
        super()._label('request', block=False)
        ownc = self.logical_clock()
        self.send(('request', ownc, self._id), to=self._state.s)
        super()._label('cs', block=False)
        c = p = None

        def UniversalOpExpr_184():
            nonlocal c, p
            for p in self._state.s:

                def ExistentialOpExpr_190(p):
                    nonlocal c
                    for (_, _, (_ConstantPattern208_, c, _BoundPattern211_)) in self._PReceivedEvent_0:
                        if (_ConstantPattern208_ == 'ack'):
                            if (_BoundPattern211_ == p):
                                if (c > ownc):
                                    return True
                    return False
                if (not ExistentialOpExpr_190(p=p)):
                    return False
            return True
        _st_label_183 = 0
        while (_st_label_183 == 0):
            _st_label_183 += 1
            if UniversalOpExpr_184():
                _st_label_183 += 1
            else:
                super()._label('cs', block=True)
                _st_label_183 -= 1
        task()
        super()._label('release', block=False)
        self.output('Release!')

        def ExistentialOpExpr_233(p):
            for (_, _, (_ConstantPattern250_, c, _BoundPattern253_)) in self._PReceivedEvent_1:
                if (_ConstantPattern250_ == 'request'):
                    if (_BoundPattern253_ == p):
                        if ((c, p) >= (ownc, self._id)):
                            return True
            return False
        self.send(('ack', self.logical_clock(), self._id), to={p for p in self._state.s if ExistentialOpExpr_233(p=p)})

    def _P_handler_264(self, c, p):

        def UniversalOpExpr_302(c):
            for p in self._state.s:

                def ExistentialOpExpr_307(p, c):
                    for (_, _, (_ConstantPattern325_, c2, _BoundPattern328_)) in self._PReceivedEvent_4:
                        if (_ConstantPattern325_ == 'ack'):
                            if (_BoundPattern328_ == p):
                                if (c2 > c):
                                    return True
                    return False
                if (not ExistentialOpExpr_307(p=p, c=c)):
                    return False
            return True
        ownc = max(({c for (_, _, (_ConstantPattern295_, c, _ConstantPattern298_)) in self._PSentEvent_3 if (_ConstantPattern295_ == 'request') if (_ConstantPattern298_ == self._id) if (not UniversalOpExpr_302(c=c))} | {(- 1)}))
        if ((ownc == (- 1)) or ((c, p) < (ownc, self._id))):
            self.send(('ack', self.logical_clock(), self._id), to=p)
    _P_handler_264._labels = None
    _P_handler_264._notlabels = None

class Node_(da.NodeProcess):

    def __init__(self, procimpl, props):
        super().__init__(procimpl, props)
        self._Node_ReceivedEvent_0 = []
        self._events.extend([da.pat.EventPattern(da.pat.ReceivedEvent, '_Node_ReceivedEvent_0', PatternExpr_475, sources=[PatternExpr_480], destinations=None, timestamps=None, record_history=True, handlers=[])])
    _config_object = {'clock': 'Lamport'}

    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)
        for p in ps:
            self._setup({p}, ((ps - {p}), nrounds))
        self._start(ps)
        super()._label('_st_label_467', block=False)
        p = None

        def UniversalOpExpr_468():
            nonlocal p
            for p in ps:
                if (not PatternExpr_482.match_iter(self._Node_ReceivedEvent_0, _BoundPattern488_=p)):
                    return False
            return True
        _st_label_467 = 0
        while (_st_label_467 == 0):
            _st_label_467 += 1
            if UniversalOpExpr_468():
                _st_label_467 += 1
            else:
                super()._label('_st_label_467', block=True)
                _st_label_467 -= 1
        self.output('All processes done.')
        self.send(('Done',), to=ps)
