# -*- generated by 1.0.12 -*-
import da
PatternExpr_188 = da.pat.TuplePattern([da.pat.ConstantPattern('request'), da.pat.FreePattern('c2'), da.pat.FreePattern('p')])
PatternExpr_213 = da.pat.TuplePattern([da.pat.ConstantPattern('release'), da.pat.BoundPattern('_BoundPattern216_'), da.pat.BoundPattern('_BoundPattern217_')])
PatternExpr_246 = da.pat.TuplePattern([da.pat.ConstantPattern('ack'), da.pat.FreePattern('c2'), da.pat.BoundPattern('_BoundPattern250_')])
PatternExpr_282 = da.pat.TuplePattern([da.pat.ConstantPattern('request'), da.pat.FreePattern(None), da.pat.FreePattern('p')])
PatternExpr_330 = da.pat.TuplePattern([da.pat.ConstantPattern('done'), da.pat.BoundPattern('_BoundPattern333_')])
PatternExpr_336 = da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.FreePattern(None), da.pat.FreePattern(None)]), da.pat.TuplePattern([da.pat.ConstantPattern('done'), da.pat.BoundPattern('_BoundPattern346_')])])
PatternExpr_220 = da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.FreePattern(None), da.pat.FreePattern(None)]), da.pat.TuplePattern([da.pat.ConstantPattern('release'), da.pat.BoundPattern('_BoundPattern230_'), da.pat.BoundPattern('_BoundPattern231_')])])
_config_object = {}
import sys

class P(da.DistProcess):

    def __init__(self, procimpl, props):
        super().__init__(procimpl, props)
        self._PReceivedEvent_0 = []
        self._PReceivedEvent_1 = []
        self._PReceivedEvent_2 = []
        self._PReceivedEvent_4 = []
        self._events.extend([da.pat.EventPattern(da.pat.ReceivedEvent, '_PReceivedEvent_0', PatternExpr_188, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_PReceivedEvent_1', PatternExpr_213, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_PReceivedEvent_2', PatternExpr_246, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_PReceivedEvent_3', PatternExpr_282, sources=None, destinations=None, timestamps=None, record_history=None, handlers=[self._P_handler_281]), da.pat.EventPattern(da.pat.ReceivedEvent, '_PReceivedEvent_4', PatternExpr_330, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[])])

    def setup(self, s, nrequests, **rest_411):
        super().setup(s=s, nrequests=nrequests, **rest_411)
        self._state.s = s
        self._state.nrequests = nrequests
        pass

    def run(self):

        def task():
            self.output('in critical section')
        for i in range(self._state.nrequests):
            self.mutex(task)
        self.send(('done', self._id), to=self._state.s)
        super()._label('_st_label_321', block=False)
        p = None

        def UniversalOpExpr_322():
            nonlocal p
            for p in self._state.s:
                if (not PatternExpr_336.match_iter(self._PReceivedEvent_4, _BoundPattern346_=p, SELF_ID=self._id)):
                    return False
            return True
        _st_label_321 = 0
        while (_st_label_321 == 0):
            _st_label_321 += 1
            if UniversalOpExpr_322():
                _st_label_321 += 1
            else:
                super()._label('_st_label_321', block=True)
                _st_label_321 -= 1
        self.output('terminating')

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

        def UniversalOpExpr_186():
            nonlocal c2, p
            for (_, _, (_ConstantPattern205_, c2, p)) in self._PReceivedEvent_0:
                if (_ConstantPattern205_ == 'request'):
                    if (not (PatternExpr_220.match_iter(self._PReceivedEvent_1, _BoundPattern230_=c2, _BoundPattern231_=p, SELF_ID=self._id) or ((c, self._id) < (c2, p)))):
                        return False
            return True
        c2 = p = None

        def UniversalOpExpr_239():
            nonlocal c2, p
            for p in self._state.s:

                def ExistentialOpExpr_244(p):
                    nonlocal c2
                    for (_, _, (_ConstantPattern261_, c2, _BoundPattern264_)) in self._PReceivedEvent_2:
                        if (_ConstantPattern261_ == 'ack'):
                            if (_BoundPattern264_ == p):
                                if (c2 > c):
                                    return True
                    return False
                if (not ExistentialOpExpr_244(p=p)):
                    return False
            return True
        _st_label_184 = 0
        while (_st_label_184 == 0):
            _st_label_184 += 1
            if (UniversalOpExpr_186() and UniversalOpExpr_239()):
                _st_label_184 += 1
            else:
                super()._label('_st_label_184', block=True)
                _st_label_184 -= 1
        super()._label('critical_section', block=False)
        task()
        super()._label('release', block=False)
        self.send(('release', c, self._id), to=self._state.s)

    def _P_handler_281(self, p):
        self.send(('ack', self.logical_clock(), self._id), to=p)
    _P_handler_281._labels = None
    _P_handler_281._notlabels = None

class Node_(da.NodeProcess):

    def __init__(self, procimpl, props):
        super().__init__(procimpl, props)
        self._events.extend([])
    _config_object = {'channel': 'Fifo', 'clock': 'Lamport'}

    def run(self):
        nprocs = (int(sys.argv[1]) if (len(sys.argv) > 1) else 10)
        nrequests = (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}), nrequests))
        self._start(ps)
