# -*- generated by 1.0.2 -*-
import da
PatternExpr_210 = da.pat.TuplePattern([da.pat.ConstantPattern('Promise'), da.pat.BoundPattern('_BoundPattern213_'), da.pat.FreePattern(None), da.pat.FreePattern(None), da.pat.FreePattern('a')])
PatternExpr_243 = da.pat.TuplePattern([da.pat.ConstantPattern('Promise'), da.pat.BoundPattern('_BoundPattern246_'), da.pat.FreePattern('n'), da.pat.FreePattern('v'), da.pat.FreePattern(None)])
PatternExpr_273 = da.pat.TuplePattern([da.pat.ConstantPattern('Promise'), da.pat.BoundPattern('_BoundPattern276_'), da.pat.BoundPattern('_BoundPattern277_'), da.pat.BoundPattern('_BoundPattern278_'), da.pat.FreePattern('a')])
PatternExpr_327 = da.pat.TuplePattern([da.pat.ConstantPattern('TwoAv'), da.pat.BoundPattern('_BoundPattern330_'), da.pat.BoundPattern('_BoundPattern331_'), da.pat.FreePattern('a')])
PatternExpr_413 = da.pat.TuplePattern([da.pat.ConstantPattern('TwoAv'), da.pat.FreePattern('n'), da.pat.FreePattern('v'), da.pat.FreePattern(None)])
PatternExpr_442 = da.pat.TuplePattern([da.pat.ConstantPattern('TwoAv'), da.pat.BoundPattern('_BoundPattern445_'), da.pat.BoundPattern('_BoundPattern446_'), da.pat.FreePattern('a')])
PatternExpr_470 = da.pat.TuplePattern([da.pat.ConstantPattern('TwoB'), da.pat.BoundPattern('_BoundPattern473_'), da.pat.BoundPattern('_BoundPattern474_')])
PatternExpr_504 = da.pat.TuplePattern([da.pat.ConstantPattern('Done')])
PatternExpr_509 = da.pat.BoundPattern('_BoundPattern510_')
PatternExpr_525 = da.pat.TuplePattern([da.pat.ConstantPattern('Prepare'), da.pat.FreePattern('n'), da.pat.FreePattern('p')])
PatternExpr_544 = da.pat.TuplePattern([da.pat.ConstantPattern('TwoAv'), da.pat.FreePattern('vpn'), da.pat.FreePattern('vv'), da.pat.SelfPattern()])
PatternExpr_595 = da.pat.TuplePattern([da.pat.ConstantPattern('OneC'), da.pat.FreePattern('n'), da.pat.FreePattern('v'), da.pat.FreePattern('p')])
PatternExpr_619 = da.pat.TuplePattern([da.pat.ConstantPattern('TwoAv'), da.pat.BoundPattern('_BoundPattern622_'), da.pat.FreePattern(None), da.pat.SelfPattern()])
PatternExpr_658 = da.pat.TuplePattern([da.pat.ConstantPattern('Promise'), da.pat.FreePattern('n'), da.pat.FreePattern(None), da.pat.FreePattern(None), da.pat.FreePattern(None)])
PatternExpr_696 = da.pat.TuplePattern([da.pat.ConstantPattern('Promise'), da.pat.BoundPattern('_BoundPattern699_'), da.pat.FreePattern('vn'), da.pat.FreePattern('vv'), da.pat.FreePattern(None)])
PatternExpr_726 = da.pat.TuplePattern([da.pat.ConstantPattern('Promise'), da.pat.BoundPattern('_BoundPattern729_'), da.pat.BoundPattern('_BoundPattern730_'), da.pat.BoundPattern('_BoundPattern731_'), da.pat.FreePattern('a')])
PatternExpr_477 = 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('TwoB'), da.pat.BoundPattern('_BoundPattern487_'), da.pat.BoundPattern('_BoundPattern488_')])])
PatternExpr_511 = da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.FreePattern(None), da.pat.BoundPattern('_BoundPattern517_')]), da.pat.TuplePattern([da.pat.ConstantPattern('Done')])])
_config_object = {}
import sys

class Proposer(da.DistProcess):

    def __init__(self, procimpl, props):
        super().__init__(procimpl, props)
        self._ProposerReceivedEvent_0 = []
        self._ProposerReceivedEvent_1 = []
        self._ProposerReceivedEvent_2 = []
        self._ProposerReceivedEvent_3 = []
        self._events.extend([da.pat.EventPattern(da.pat.ReceivedEvent, '_ProposerReceivedEvent_0', PatternExpr_210, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_ProposerReceivedEvent_1', PatternExpr_243, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_ProposerReceivedEvent_2', PatternExpr_273, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_ProposerReceivedEvent_3', PatternExpr_327, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[])])

    def setup(self, acceptors, quorumsize, f, nrounds, timeout, **rest_900):
        super().setup(acceptors=acceptors, quorumsize=quorumsize, f=f, nrounds=nrounds, timeout=timeout, **rest_900)
        self._state.acceptors = acceptors
        self._state.quorumsize = quorumsize
        self._state.f = f
        self._state.nrounds = nrounds
        self._state.timeout = timeout
        self._state.propNum = (0, self._id)
        self._state.propVal = self._id

    def run(self):
        count = 0
        while (count < self._state.nrounds):
            self.work()
            super()._label('prepare', block=False)
            self.send(('Prepare', self._state.propNum, self._id), self._state.acceptors)
            super()._label('_st_label_205', block=False)
            _st_label_205 = 0
            self._timer_start()
            while (_st_label_205 == 0):
                _st_label_205 += 1
                if (len({a for (_, _, (_ConstantPattern228_, _BoundPattern230_, _, _, a)) in self._ProposerReceivedEvent_0 if (_ConstantPattern228_ == 'Promise') if (_BoundPattern230_ == self._state.propNum)}) > self._state.quorumsize):
                    super()._label('propose', block=False)
                    (_, voted) = max(({(n, v) for (_, _, (_ConstantPattern262_, _BoundPattern264_, n, v, _)) in self._ProposerReceivedEvent_1 if (_ConstantPattern262_ == 'Promise') if (_BoundPattern264_ == self._state.propNum) if (len({a for (_, _, (_ConstantPattern291_, _BoundPattern293_, _BoundPattern294_, _BoundPattern295_, a)) in self._ProposerReceivedEvent_2 if (_ConstantPattern291_ == 'Promise') if (_BoundPattern293_ == self._state.propNum) if (_BoundPattern294_ == n) if (_BoundPattern295_ == v)}) > self._state.f)} | {(((- 1), self._id), self._state.propVal)}))
                    self.send(('OneC', self._state.propNum, voted, self._id), self._state.acceptors)
                    super()._label('_st_label_322', block=False)
                    _st_label_322 = 0
                    self._timer_start()
                    while (_st_label_322 == 0):
                        _st_label_322 += 1
                        if (len({a for (_, _, (_ConstantPattern344_, _BoundPattern346_, _BoundPattern347_, a)) in self._ProposerReceivedEvent_3 if (_ConstantPattern344_ == 'TwoAv') if (_BoundPattern346_ == self._state.propNum) if (_BoundPattern347_ == voted)}) > self._state.quorumsize):
                            super()._label('end', block=False)
                            self.output(('Succeeded proposing %s' % (voted,)))
                            count += 1
                            continue
                            _st_label_322 += 1
                        elif self._timer_expired:
                            self.output('Failed to Propose in time, retrying.')
                            _st_label_322 += 1
                        else:
                            super()._label('_st_label_322', block=True, timeout=self._state.timeout)
                            _st_label_322 -= 1
                    else:
                        if (_st_label_322 != 2):
                            continue
                    if (_st_label_322 != 2):
                        break
                    _st_label_205 += 1
                elif self._timer_expired:
                    self.output('Failed to Prepare in time, retrying.')
                    _st_label_205 += 1
                else:
                    super()._label('_st_label_205', block=True, timeout=self._state.timeout)
                    _st_label_205 -= 1
            else:
                if (_st_label_205 != 2):
                    continue
            if (_st_label_205 != 2):
                break
            self._state.propNum = ((self._state.propNum[0] + 1), self._id)
        self.send(('Done',), self._state.acceptors)

class Acceptor(da.DistProcess):

    def __init__(self, procimpl, props):
        super().__init__(procimpl, props)
        self._AcceptorReceivedEvent_0 = []
        self._AcceptorReceivedEvent_1 = []
        self._AcceptorSentEvent_2 = []
        self._AcceptorReceivedEvent_3 = []
        self._AcceptorSentEvent_5 = []
        self._AcceptorSentEvent_7 = []
        self._AcceptorSentEvent_8 = []
        self._AcceptorReceivedEvent_9 = []
        self._AcceptorReceivedEvent_10 = []
        self._events.extend([da.pat.EventPattern(da.pat.ReceivedEvent, '_AcceptorReceivedEvent_0', PatternExpr_413, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_AcceptorReceivedEvent_1', PatternExpr_442, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.SentEvent, '_AcceptorSentEvent_2', PatternExpr_470, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_AcceptorReceivedEvent_3', PatternExpr_504, sources=[PatternExpr_509], destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_AcceptorReceivedEvent_4', PatternExpr_525, sources=None, destinations=None, timestamps=None, record_history=None, handlers=[self._Acceptor_handler_524]), da.pat.EventPattern(da.pat.SentEvent, '_AcceptorSentEvent_5', PatternExpr_544, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_AcceptorReceivedEvent_6', PatternExpr_595, sources=None, destinations=None, timestamps=None, record_history=None, handlers=[self._Acceptor_handler_594]), da.pat.EventPattern(da.pat.SentEvent, '_AcceptorSentEvent_7', PatternExpr_619, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.SentEvent, '_AcceptorSentEvent_8', PatternExpr_658, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_AcceptorReceivedEvent_9', PatternExpr_696, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_AcceptorReceivedEvent_10', PatternExpr_726, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[])])

    def setup(self, acceptors, proposers, quorumsize, f, **rest_900):
        super().setup(acceptors=acceptors, proposers=proposers, quorumsize=quorumsize, f=f, **rest_900)
        self._state.acceptors = acceptors
        self._state.proposers = proposers
        self._state.quorumsize = quorumsize
        self._state.f = f
        self._state.peers = (self._state.acceptors | self._state.proposers)

    def run(self):
        while True:
            super()._label('_st_label_410', block=False)
            n = v = a = None

            def ExistentialOpExpr_411():
                nonlocal n, v, a
                for (_, _, (_ConstantPattern431_, n, v, _)) in self._AcceptorReceivedEvent_0:
                    if (_ConstantPattern431_ == 'TwoAv'):
                        if ((len({a for (_, _, (_ConstantPattern459_, _BoundPattern461_, _BoundPattern462_, a)) in self._AcceptorReceivedEvent_1 if (_ConstantPattern459_ == 'TwoAv') if (_BoundPattern461_ == n) if (_BoundPattern462_ == v)}) > self._state.quorumsize) and (not PatternExpr_477.match_iter(self._AcceptorSentEvent_2, _BoundPattern487_=n, _BoundPattern488_=v, SELF_ID=self._id))):
                            return True
                return False
            p = None

            def UniversalOpExpr_496():
                nonlocal p
                for p in self._state.proposers:
                    if (not PatternExpr_511.match_iter(self._AcceptorReceivedEvent_3, _BoundPattern517_=p, SELF_ID=self._id)):
                        return False
                return True
            _st_label_410 = 0
            while (_st_label_410 == 0):
                _st_label_410 += 1
                if ExistentialOpExpr_411():
                    self.send(('TwoB', n, v), self._state.peers)
                    _st_label_410 += 1
                elif UniversalOpExpr_496():
                    break
                    _st_label_410 += 1
                else:
                    super()._label('_st_label_410', block=True)
                    _st_label_410 -= 1
            else:
                if (_st_label_410 != 2):
                    continue
            if (_st_label_410 != 2):
                break

    def maxpromised(self):
        return max(({n for (_, _, (_ConstantPattern676_, n, _, _, _)) in self._AcceptorSentEvent_8 if (_ConstantPattern676_ == 'Promise')} | {((- 2), self._id)}))

    def islegal(self, n, v):
        voted = {(vn, vv) for (_, _, (_ConstantPattern715_, _BoundPattern717_, vn, vv, _)) in self._AcceptorReceivedEvent_9 if (_ConstantPattern715_ == 'Promise') if (_BoundPattern717_ == n) if (len({a for (_, _, (_ConstantPattern744_, _BoundPattern746_, _BoundPattern747_, _BoundPattern748_, a)) in self._AcceptorReceivedEvent_10 if (_ConstantPattern744_ == 'Promise') if (_BoundPattern746_ == n) if (_BoundPattern747_ == vn) if (_BoundPattern748_ == vv)}) > self._state.f)}
        if (voted and (not (max(voted)[1] is None))):
            return (v == max(voted)[1])
        else:
            return True

    def _Acceptor_handler_524(self, n, p):
        if (n > self.maxpromised()):
            (vn, vv) = max(({(vpn, vv) for (_, _, (_ConstantPattern563_, vpn, vv, _ConstantPattern567_)) in self._AcceptorSentEvent_5 if (_ConstantPattern563_ == 'TwoAv') if (_ConstantPattern567_ == self._id)} | {(((- 1), self._id), None)}))
            self.send(('Promise', n, vn, vv, self._id), self._state.peers)
    _Acceptor_handler_524._labels = None
    _Acceptor_handler_524._notlabels = None

    def _Acceptor_handler_594(self, n, v, p):

        def ExistentialOpExpr_617():
            for (_, _, (_ConstantPattern636_, _BoundPattern638_, _, _ConstantPattern640_)) in self._AcceptorSentEvent_7:
                if (_ConstantPattern636_ == 'TwoAv'):
                    if (_BoundPattern638_ == n):
                        if (_ConstantPattern640_ == self._id):
                            if True:
                                return True
            return False
        if ((n >= self.maxpromised()) and self.islegal(n, v) and (not ExistentialOpExpr_617())):
            self.send(('TwoAv', n, v, self._id), self._state.peers)
    _Acceptor_handler_594._labels = None
    _Acceptor_handler_594._notlabels = None

class Node_(da.NodeProcess):

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

    def run(self):
        nproposers = (int(sys.argv[1]) if (len(sys.argv) > 1) else 5)
        nacceptors = (int(sys.argv[2]) if (len(sys.argv) > 2) else 10)
        nrounds = (int(sys.argv[3]) if (len(sys.argv) > 3) else 1)
        timeout = (int(sys.argv[4]) if (len(sys.argv) > 4) else 1)
        f = int(((nacceptors - 1) / 3))
        quorum = int(((nacceptors / 2) + f))
        acceptors = self.new(Acceptor, num=nacceptors)
        proposers = self.new(Proposer, num=nproposers)
        self._setup(acceptors, (acceptors, proposers, quorum, f))
        self._setup(proposers, (acceptors, quorum, f, nrounds, timeout))
        self._start(acceptors)
        self._start(proposers)
