# -*- generated by 1.0.12 -*-
import da
PatternExpr_212 = da.pat.TuplePattern([da.pat.ConstantPattern('Promise'), da.pat.BoundPattern('_BoundPattern215_'), da.pat.FreePattern(None), da.pat.FreePattern(None), da.pat.FreePattern('a')])
PatternExpr_245 = da.pat.TuplePattern([da.pat.ConstantPattern('Promise'), da.pat.BoundPattern('_BoundPattern248_'), da.pat.FreePattern('n'), da.pat.FreePattern('v'), da.pat.FreePattern(None)])
PatternExpr_275 = da.pat.TuplePattern([da.pat.ConstantPattern('Promise'), da.pat.BoundPattern('_BoundPattern278_'), da.pat.BoundPattern('_BoundPattern279_'), da.pat.BoundPattern('_BoundPattern280_'), da.pat.FreePattern('a')])
PatternExpr_330 = da.pat.TuplePattern([da.pat.ConstantPattern('TwoAv'), da.pat.BoundPattern('_BoundPattern333_'), da.pat.BoundPattern('_BoundPattern334_'), da.pat.FreePattern('a')])
PatternExpr_417 = da.pat.TuplePattern([da.pat.ConstantPattern('TwoAv'), da.pat.FreePattern('n'), da.pat.FreePattern('v'), da.pat.FreePattern(None)])
PatternExpr_446 = da.pat.TuplePattern([da.pat.ConstantPattern('TwoAv'), da.pat.BoundPattern('_BoundPattern449_'), da.pat.BoundPattern('_BoundPattern450_'), da.pat.FreePattern('a')])
PatternExpr_474 = da.pat.TuplePattern([da.pat.ConstantPattern('TwoB'), da.pat.BoundPattern('_BoundPattern477_'), da.pat.BoundPattern('_BoundPattern478_')])
PatternExpr_509 = da.pat.TuplePattern([da.pat.ConstantPattern('Done')])
PatternExpr_514 = da.pat.BoundPattern('_BoundPattern515_')
PatternExpr_530 = da.pat.TuplePattern([da.pat.ConstantPattern('Prepare'), da.pat.FreePattern('n'), da.pat.FreePattern('p')])
PatternExpr_549 = da.pat.TuplePattern([da.pat.ConstantPattern('TwoAv'), da.pat.FreePattern('vpn'), da.pat.FreePattern('vv'), da.pat.SelfPattern()])
PatternExpr_601 = da.pat.TuplePattern([da.pat.ConstantPattern('OneC'), da.pat.FreePattern('n'), da.pat.FreePattern('v'), da.pat.FreePattern('p')])
PatternExpr_625 = da.pat.TuplePattern([da.pat.ConstantPattern('TwoAv'), da.pat.BoundPattern('_BoundPattern628_'), da.pat.FreePattern(None), da.pat.SelfPattern()])
PatternExpr_665 = da.pat.TuplePattern([da.pat.ConstantPattern('Promise'), da.pat.FreePattern('n'), da.pat.FreePattern(None), da.pat.FreePattern(None), da.pat.FreePattern(None)])
PatternExpr_703 = da.pat.TuplePattern([da.pat.ConstantPattern('Promise'), da.pat.BoundPattern('_BoundPattern706_'), da.pat.FreePattern('vn'), da.pat.FreePattern('vv'), da.pat.FreePattern(None)])
PatternExpr_733 = da.pat.TuplePattern([da.pat.ConstantPattern('Promise'), da.pat.BoundPattern('_BoundPattern736_'), da.pat.BoundPattern('_BoundPattern737_'), da.pat.BoundPattern('_BoundPattern738_'), da.pat.FreePattern('a')])
PatternExpr_481 = 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('_BoundPattern491_'), da.pat.BoundPattern('_BoundPattern492_')])])
PatternExpr_516 = da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.FreePattern(None), da.pat.BoundPattern('_BoundPattern522_')]), 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_212, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_ProposerReceivedEvent_1', PatternExpr_245, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_ProposerReceivedEvent_2', PatternExpr_275, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_ProposerReceivedEvent_3', PatternExpr_330, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[])])

    def setup(self, acceptors, quorumsize, f, nrounds, timeout, **rest_907):
        super().setup(acceptors=acceptors, quorumsize=quorumsize, f=f, nrounds=nrounds, timeout=timeout, **rest_907)
        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), to=self._state.acceptors)
            super()._label('_st_label_207', block=False)
            _st_label_207 = 0
            self._timer_start()
            while (_st_label_207 == 0):
                _st_label_207 += 1
                if (len({a for (_, _, (_ConstantPattern230_, _BoundPattern232_, _, _, a)) in self._ProposerReceivedEvent_0 if (_ConstantPattern230_ == 'Promise') if (_BoundPattern232_ == self._state.propNum)}) > self._state.quorumsize):
                    super()._label('propose', block=False)
                    (_, voted) = max(({(n, v) for (_, _, (_ConstantPattern264_, _BoundPattern266_, n, v, _)) in self._ProposerReceivedEvent_1 if (_ConstantPattern264_ == 'Promise') if (_BoundPattern266_ == self._state.propNum) if (len({a for (_, _, (_ConstantPattern293_, _BoundPattern295_, _BoundPattern296_, _BoundPattern297_, a)) in self._ProposerReceivedEvent_2 if (_ConstantPattern293_ == 'Promise') if (_BoundPattern295_ == self._state.propNum) if (_BoundPattern296_ == n) if (_BoundPattern297_ == v)}) > self._state.f)} | {(((- 1), self._id), self._state.propVal)}))
                    self.send(('OneC', self._state.propNum, voted, self._id), to=self._state.acceptors)
                    super()._label('_st_label_325', block=False)
                    _st_label_325 = 0
                    self._timer_start()
                    while (_st_label_325 == 0):
                        _st_label_325 += 1
                        if (len({a for (_, _, (_ConstantPattern347_, _BoundPattern349_, _BoundPattern350_, a)) in self._ProposerReceivedEvent_3 if (_ConstantPattern347_ == 'TwoAv') if (_BoundPattern349_ == self._state.propNum) if (_BoundPattern350_ == voted)}) > self._state.quorumsize):
                            super()._label('end', block=False)
                            self.output(('Succeeded proposing %s' % (voted,)))
                            count += 1
                            continue
                            _st_label_325 += 1
                        elif self._timer_expired:
                            self.output('Failed to Propose in time, retrying.')
                            _st_label_325 += 1
                        else:
                            super()._label('_st_label_325', block=True, timeout=self._state.timeout)
                            _st_label_325 -= 1
                    else:
                        if (_st_label_325 != 2):
                            continue
                    if (_st_label_325 != 2):
                        break
                    _st_label_207 += 1
                elif self._timer_expired:
                    self.output('Failed to Prepare in time, retrying.')
                    _st_label_207 += 1
                else:
                    super()._label('_st_label_207', block=True, timeout=self._state.timeout)
                    _st_label_207 -= 1
            else:
                if (_st_label_207 != 2):
                    continue
            if (_st_label_207 != 2):
                break
            self._state.propNum = ((self._state.propNum[0] + 1), self._id)
        self.send(('Done',), to=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_417, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_AcceptorReceivedEvent_1', PatternExpr_446, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.SentEvent, '_AcceptorSentEvent_2', PatternExpr_474, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_AcceptorReceivedEvent_3', PatternExpr_509, sources=[PatternExpr_514], destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_AcceptorReceivedEvent_4', PatternExpr_530, sources=None, destinations=None, timestamps=None, record_history=None, handlers=[self._Acceptor_handler_529]), da.pat.EventPattern(da.pat.SentEvent, '_AcceptorSentEvent_5', PatternExpr_549, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_AcceptorReceivedEvent_6', PatternExpr_601, sources=None, destinations=None, timestamps=None, record_history=None, handlers=[self._Acceptor_handler_600]), da.pat.EventPattern(da.pat.SentEvent, '_AcceptorSentEvent_7', PatternExpr_625, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.SentEvent, '_AcceptorSentEvent_8', PatternExpr_665, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_AcceptorReceivedEvent_9', PatternExpr_703, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_AcceptorReceivedEvent_10', PatternExpr_733, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[])])

    def setup(self, acceptors, proposers, quorumsize, f, **rest_907):
        super().setup(acceptors=acceptors, proposers=proposers, quorumsize=quorumsize, f=f, **rest_907)
        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_414', block=False)
            a = v = n = None

            def ExistentialOpExpr_415():
                nonlocal a, v, n
                for (_, _, (_ConstantPattern435_, n, v, _)) in self._AcceptorReceivedEvent_0:
                    if (_ConstantPattern435_ == 'TwoAv'):
                        if ((len({a for (_, _, (_ConstantPattern463_, _BoundPattern465_, _BoundPattern466_, a)) in self._AcceptorReceivedEvent_1 if (_ConstantPattern463_ == 'TwoAv') if (_BoundPattern465_ == n) if (_BoundPattern466_ == v)}) > self._state.quorumsize) and (not PatternExpr_481.match_iter(self._AcceptorSentEvent_2, _BoundPattern491_=n, _BoundPattern492_=v, SELF_ID=self._id))):
                            return True
                return False
            p = None

            def UniversalOpExpr_501():
                nonlocal p
                for p in self._state.proposers:
                    if (not PatternExpr_516.match_iter(self._AcceptorReceivedEvent_3, _BoundPattern522_=p, SELF_ID=self._id)):
                        return False
                return True
            _st_label_414 = 0
            while (_st_label_414 == 0):
                _st_label_414 += 1
                if ExistentialOpExpr_415():
                    self.send(('TwoB', n, v), to=self._state.peers)
                    _st_label_414 += 1
                elif UniversalOpExpr_501():
                    break
                    _st_label_414 += 1
                else:
                    super()._label('_st_label_414', block=True)
                    _st_label_414 -= 1
            else:
                if (_st_label_414 != 2):
                    continue
            if (_st_label_414 != 2):
                break

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

    def islegal(self, n, v):
        voted = {(vn, vv) for (_, _, (_ConstantPattern722_, _BoundPattern724_, vn, vv, _)) in self._AcceptorReceivedEvent_9 if (_ConstantPattern722_ == 'Promise') if (_BoundPattern724_ == n) if (len({a for (_, _, (_ConstantPattern751_, _BoundPattern753_, _BoundPattern754_, _BoundPattern755_, a)) in self._AcceptorReceivedEvent_10 if (_ConstantPattern751_ == 'Promise') if (_BoundPattern753_ == n) if (_BoundPattern754_ == vn) if (_BoundPattern755_ == vv)}) > self._state.f)}
        if (voted and (not (max(voted)[1] is None))):
            return (v == max(voted)[1])
        else:
            return True

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

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

        def ExistentialOpExpr_623():
            for (_, _, (_ConstantPattern642_, _BoundPattern644_, _, _ConstantPattern646_)) in self._AcceptorSentEvent_7:
                if (_ConstantPattern642_ == 'TwoAv'):
                    if (_BoundPattern644_ == n):
                        if (_ConstantPattern646_ == self._id):
                            if True:
                                return True
            return False
        if ((n >= self.maxpromised()) and self.islegal(n, v) and (not ExistentialOpExpr_623())):
            self.send(('TwoAv', n, v, self._id), to=self._state.peers)
    _Acceptor_handler_600._labels = None
    _Acceptor_handler_600._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)
