"""G01: a finite state model. This is sequential, not a thread model."""fromcollectionsimportdequefromdataclassesimportdataclass@dataclass(frozen=True)classStock:available:intsold:int=0defreserve(state:Stock,amount:int)->Stock:ifany(type(x)isnotintorx<0forxin(state.available,state.sold,amount)):raiseValueError("nonnegative mathematical integers required")ifamount>state.available:returnstatereturnStock(state.available-amount,state.sold+amount)defexplore(initial:int,max_amount:int=4)->set[Stock]:if(type(initial)isnotintornot0<=initial<=100ortype(max_amount)isnotintornot0<=max_amount<=100):raiseValueError("finite model bounds must be integers in [0,100]")start=Stock(initial)seen,todo={start},deque([start])whiletodo:state=todo.popleft()foramountinrange(max_amount+1):nxt=reserve(state,amount)ifnxt.available<0ornxt.available+nxt.sold!=initial:raiseAssertionError((state,amount,nxt))ifnxtnotinseen:seen.add(nxt)todo.append(nxt)returnseenif__name__=="__main__":print(sorted(explore(4),key=lambdas:s.sold))