scml.scml2019.simulators ======================== .. py:module:: scml.scml2019.simulators .. autoapi-nested-parse:: Simulators module implementing factory simulation Classes ------- .. autoapisummary:: scml.scml2019.simulators.FactorySimulator scml.scml2019.simulators.SlowFactorySimulator scml.scml2019.simulators.FastFactorySimulator Functions --------- .. autoapisummary:: scml.scml2019.simulators.transaction scml.scml2019.simulators.temporary_transaction Module Contents --------------- .. py:class:: FactorySimulator(initial_wallet: float, initial_storage: Dict[int, int], n_steps: int, n_products: int, profiles: List[scml.scml2019.common.ManufacturingProfile], max_storage: Optional[int] = None) Bases: :py:obj:`abc.ABC` Simulates a factory allowing for prediction of storage/balance in the future. :param initial_wallet: The initial amount of cash in the wallet :param initial_storage: initial inventory :param n_steps: number of simulation steps :param n_products: number of products in the world :param profiles: all profiles that the factory being simulated can run :param max_storage: maximum available storage space. .. py:attribute:: _n_steps .. py:attribute:: _max_storage :value: None .. py:attribute:: _initial_wallet .. py:attribute:: _initial_storage .. py:attribute:: _profiles .. py:attribute:: _n_products .. py:attribute:: _reserved_storage .. py:method:: _as_array(storage: Dict[int, int]) .. py:property:: max_storage :type: Optional[int] Maximum storage available .. py:property:: n_steps :type: int Number of steps to predict ahead. .. py:property:: initial_wallet :type: float Initial cash in wallet .. py:property:: initial_storage :type: numpy.array Initial inventory .. py:property:: n_lines :abstractmethod: Number of lines .. py:property:: final_balance :type: float :abstractmethod: Final balance given everything scheduled so-far .. py:method:: wallet_to(t: int) -> numpy.array :abstractmethod: Returns the cash in wallet up to and including time t. :param t: Time Returns: .. py:method:: wallet_at(t: int) -> float Returns the cash in wallet *at* a given timestep (given all simulated actions) :param t: Returns: .. py:method:: storage_to(t: int) -> numpy.array :abstractmethod: Returns the storage of all products *up to* time t :param t: Time :returns: An array of size `n_products` * `t` giving the quantity of each product in storage at every step up to `t`. .. py:method:: storage_at(t: int) -> numpy.array Returns the storage of all products *at* time t :param t: Time :returns: An array of size `n_products` giving the quantity of each product in storage at time-step `t`. .. seealso:: `storage_to` `wallet_at` .. py:method:: line_schedules_to(t: int) -> numpy.array :abstractmethod: Returns the schedule of each line up to a given timestep :param t: time :returns: An array of `n_lines` * `t` values giving the schedule up to `t`. Remarks: - A `NO_PRODUCTION` value means no production, otherwise the index of the process being run .. py:method:: line_schedules_at(t: int) -> numpy.array Returns the schedule of each line at a given timestep :param t: time :returns: An array of `n_lines` values giving the schedule up at `t`. Remarks: - A `NO_PRODUCTION` value means no production, otherwise the index of the process being run .. py:method:: total_storage_to(t: int) -> numpy.array The total storage *up to* a given time :param t: time :returns: an array of size `t` giving the total quantity of stored products in the inventory up to timestep `t` .. seealso:: `total_storage_at` `storage_to` .. py:method:: total_storage_at(t: int) -> int The total storage *at* a given time :param t: time :returns: an integer giving the total quantity of stored products in the inventory at timestep `t` .. seealso:: `total_storage_to` `storage_at` .. py:method:: reserved_storage_to(t: int) -> numpy.array Returns the *reserved* storage of all products *up to* time t :param t: Time :returns: An array of size `n_products` * `t` giving the quantity of each product reserved at every step up to `t`. Remarks: - Reserved storage *is counted* in calls to `storage_at` , `total_storage_at` , `storage_to` , `total_storage_to` - Reserving quantities of products is a tool that can be used to avoid double counting availability of given products in the inventory for multiple contracts. .. seealso:: `total_storage_at` `storage_at` `reserved_storage_at` .. py:method:: reserved_storage_at(t: int) -> numpy.array Returns the *reserved* storage of all products *at* time t :param t: Time :returns: An array of size `n_products` giving the quantity of each product reserved at time-step `t`. Remarks: - Reserved storage *is counted* in calls to `storage_at` , `total_storage_at` , `storage_to` , `total_storage_to` - Reserving quantities of products is a tool that can be used to avoid double counting availability of given products in the inventory for multiple contracts. .. seealso:: `total_storage_to` `storage_to` `reserved_storage_at` .. py:method:: available_storage_to(t: int) -> numpy.array Returns the *available* storage of all products *up to* time t. :param t: Time :returns: An array of size `n_products` * `t` giving the quantity of each product available at every step up to `t`. Remarks: - Available storage is defined as the difference between storage and reserved storage. - Reserved storage *is counted* in calls to `storage_at` , `total_storage_at` , `storage_to` , `total_storage_to` - Reserving quantities of products is a tool that can be used to avoid double counting availability of given products in the inventory for multiple contracts. .. seealso:: `total_storage_to` `storage_to` `reserved_storage_to` .. py:method:: available_storage_at(t: int) -> numpy.array Returns the *available* storage of all products *at* time t :param t: Time :returns: An array of size `n_products` giving the quantity of each product available at time-step `t`. Remarks: - Available storage is defined as the difference between storage and reserved storage. - Reserved storage *is counted* in calls to `storage_at` , `total_storage_at` , `storage_to` , `total_storage_to` - Reserving quantities of products is a tool that can be used to avoid double counting availability of given products in the inventory for multiple contracts. .. seealso:: `total_storage_to` `storage_to` `reserved_storage_at` .. py:method:: loans_to(t: int) -> numpy.array :abstractmethod: Returns loans up to time t :param t: time :returns: An array of `t` real numbers giving the loans registered at time-steps up to `t` .. py:method:: loans_at(t: int) -> float Returns loans at time t :param t: time .. py:method:: balance_at(t: int) -> float Returns the balance fo the factory at time t. :param t: time Remarks: - The balance is defined as the cash in wallet minus loans .. seealso:: `loans_at` `wallet_at` .. py:method:: balance_to(t: int) -> numpy.array Returns the balance fo the factory *up to* time t. :param t: time Remarks: - The balance is defined as the cash in wallet minus loans .. seealso:: `loans_to` `wallet_to` .. py:property:: fixed_before :abstractmethod: Gives the time before which the schedule is fixed. .. seealso:: `fix_before` .. py:method:: set_state(t: int, storage: numpy.array, wallet: float, loans: float, line_schedules: numpy.array) -> None :abstractmethod: Sets the current state at the given time-step. It implicitly causes a fix_before(t + 1) :param t: Time step to set the state at :param storage: quantity of every product (array of integers of size `n_products`) :param wallet: Cash in wallet :param loans: Loans :param line_schedules: Line schedules (array of process numbers/NO_PRODUCTION of size `n_lines`) .. py:method:: add_loan(total: float, t: int) -> bool :abstractmethod: Adds a loan at the given time :param total: Total amount of the loan :param t: time step to take the loan :returns: Success or failure Remarks: - Taking a loan is simulated as reception of money. Payment back of the loan is not simulated in this call. To simulate paying back the loan, use `pay` at the times of installment payments. .. py:method:: receive(payment: float, t: int) -> bool Simulates receiving payment at time t :param payment: Amount received :param t: time :returns: Success or failure .. py:method:: pay(payment: float, t: int, ignore_money_shortage: bool = True) -> bool :abstractmethod: Simulate payment at time t :param payment: Amount payed :param t: time :param ignore_money_shortage: If True, shortage in money will be ignored and the wallet can go negative :returns: Success or failure .. py:method:: transport_to(product: int, quantity: int, t: int, ignore_inventory_shortage: bool = True, ignore_space_shortage: bool = True) -> bool :abstractmethod: Simulates transporting products to/from storage at time t :param product: product ID (index) :param quantity: quantity to transport :param t: time :param ignore_inventory_shortage: Ignore shortage in the `product` which may lead to negative storage[product] :param ignore_space_shortage: Ignore the limit on total storage which may lead to total_storage > max_storage :returns: Success or failure .. py:method:: buy(product: int, quantity: int, price: int, t: int, ignore_money_shortage: bool = True, ignore_space_shortage: bool = True) -> bool :abstractmethod: Buy a given quantity of a product for a given price at some time t :param product: Product to buy (ID/index) :param quantity: quantity to buy :param price: unit price :param t: time :param ignore_money_shortage: If True, shortage in money will be ignored and the wallet can go negative :param ignore_space_shortage: Ignore the limit on total storage which may lead to total_storage > max_storage :returns: Success or failure Remarks: - buy cannot ever have inventory shortage .. seealso:: `sell` .. py:method:: sell(product: int, quantity: int, price: int, t: int, ignore_money_shortage: bool = True, ignore_inventory_shortage: bool = True) -> bool :abstractmethod: sell a given quantity of a product for a given price at some time t :param product: Index/ID of the product to be sold :param quantity: quantity to be sold :param price: unit price :param t: time :param ignore_money_shortage: If True, shortage in money will be ignored and the wallet can go negative :param ignore_inventory_shortage: Ignore shortage in the `product` which may lead to negative storage[product] :returns: Success or failure Remarks: - sell cannot ever have space shortage .. seealso:: `buy` .. py:method:: schedule(job: scml.scml2019.common.Job, ignore_inventory_shortage=True, ignore_money_shortage=True, ignore_space_shortage=True, override=True) -> bool :abstractmethod: Simulates scheduling the given job at its `time` and `line` optionally overriding whatever was already scheduled :param job: Production job :param ignore_inventory_shortage: If true shortages in inputs will be ignored :param ignore_money_shortage: If true, shortage in money will be ignored :param ignore_space_shortage: If true, shortage in space will be ignored :param override: Whether the job should override any already registered job at its time-step :returns: Success/failure .. py:method:: reserve(product: int, quantity: int, t: int) -> bool Simulates reserving the given quantity of the given product at times >= t. :param product: Index/ID of the product being reserved :param quantity: quantity being reserved :param t: time :returns: Success/failure Remarks: - Reserved products show in calls to `storage_at` , `total_storage_at` etc. - Reserving a product does nothing more than mark some quantity as reserved for calls to `reserved_storage_at` and `available_storage_at`. - This feature can be used to simulate inventory hiding commands in the real factory and to avoid double counting of inventory when calculating needs for future contracts. .. py:method:: fix_before(t: int) -> bool :abstractmethod: Fix the history before this point :param t: time :returns: Success/failure Remarks: - After this function is called at any time-step `t`, there is no way to change any component of the factory state at any timestep before `t`. - This function is useful for *fixing* any difference between the simulator and the real state (in conjunction with `set_state`). .. seealso:: `set_state` `fixed_before` .. py:method:: bookmark() -> int :abstractmethod: Sets a bookmark to the current location :returns: bookmark ID Remarks: - Bookmarks can be used to implement transactions. .. seealso:: `delete_bookmark` `rollback` `transaction` `temporary_transaction` .. py:method:: rollback(bookmark_id: int) -> bool :abstractmethod: Rolls back to the given bookmark ID :param bookmark_id The bookmark ID returned from bookmark: Remarks: - You can only rollback in the reverse order of bookmarks. If the bookmark ID given here is not the one at the top of the bookmarks stack, the rollback will fail (return False) .. seealso:: `delete_bookmark` `rollback` `transaction` `temporary_transaction` .. py:method:: delete_bookmark(bookmark_id: int) -> bool :abstractmethod: Commits everything since the bookmark so it cannot be rolled back :param bookmark_id The bookmark ID returned from bookmark: :returns: Success/failure Remarks: - You can delete bookmarks in the reverse order of their creation only. If the bookmark ID given here is not the one at the top of the bookmarks stack, the deletion will fail (return False). .. seealso:: `delete_bookmark` `rollback` `transaction` `temporary_transaction` .. py:class:: SlowFactorySimulator(initial_wallet: float, initial_storage: Dict[int, int], n_steps: int, n_products: int, profiles: List[scml.scml2019.common.ManufacturingProfile], max_storage: Optional[int]) Bases: :py:obj:`FactorySimulator` A slow factory simulator that runs an internal factory to find-out what will happen in the future Remarks: - It is *much* faster to always access the properties/methods of this class in ascending time. If that is not the case, each time reversal will cause a complete reset. - It is recommended to call `fix_before` () to fix the past once a production step is completed. That will speed up operations .. py:method:: set_state(t: int, storage: numpy.array, wallet: float, loans: float, line_schedules: numpy.array) -> None Sets the current state at the given time-step. It implicitly causes a fix_before(t + 1) :param t: Time step to set the state at :param storage: quantity of every product (array of integers of size `n_products`) :param wallet: Cash in wallet :param loans: Loans :param line_schedules: Line schedules (array of process numbers/NO_PRODUCTION of size `n_lines`) .. py:method:: delete_bookmark(bookmark_id: int) -> bool Commits everything since the bookmark so it cannot be rolled back :param bookmark_id The bookmark ID returned from bookmark: :returns: Success/failure Remarks: - You can delete bookmarks in the reverse order of their creation only. If the bookmark ID given here is not the one at the top of the bookmarks stack, the deletion will fail (return False). .. seealso:: `delete_bookmark` `rollback` `transaction` `temporary_transaction` .. py:method:: bookmark() -> int Sets a bookmark to the current location :returns: bookmark ID Remarks: - Bookmarks can be used to implement transactions. .. seealso:: `delete_bookmark` `rollback` `transaction` `temporary_transaction` .. py:method:: rollback(bookmark_id: int) -> bool Rolls back to the given bookmark ID :param bookmark_id The bookmark ID returned from bookmark: Remarks: - You can only rollback in the reverse order of bookmarks. If the bookmark ID given here is not the one at the top of the bookmarks stack, the rollback will fail (return False) .. seealso:: `delete_bookmark` `rollback` `transaction` `temporary_transaction` .. py:property:: final_balance :type: float Final balance given everything scheduled so-far .. py:property:: n_lines Number of lines .. py:method:: fix_before(t: int) -> bool Fix the history before this point :param t: time :returns: Success/failure Remarks: - After this function is called at any time-step `t`, there is no way to change any component of the factory state at any timestep before `t`. - This function is useful for *fixing* any difference between the simulator and the real state (in conjunction with `set_state`). .. seealso:: `set_state` `fixed_before` .. py:attribute:: _factory .. py:attribute:: _jobs :type: Dict[int, List[scml.scml2019.common.Job, bool, bool, bool, bool]] .. py:attribute:: _buy_contracts :type: Dict[int, List[int, int, float]] .. py:attribute:: _sell_contracts :type: Dict[int, List[int, int, float]] .. py:attribute:: _payment_updates :type: Dict[int, float] .. py:attribute:: _loans_updates :type: Dict[int, float] .. py:attribute:: _storage_updates :type: Dict[int, Dict[int, int]] .. py:attribute:: _wallet .. py:attribute:: _loans .. py:attribute:: _storage .. py:attribute:: _line_schedules .. py:attribute:: _fixed_before :value: 0 .. py:attribute:: _bookmarks :type: List[_Bookmark] :value: [] .. py:attribute:: _active_bookmark :type: Optional[_Bookmark] :value: None .. py:attribute:: _active_bookmarked_at :type: int :value: -1 .. py:attribute:: _bookmarked_at :type: List[int] :value: [] .. py:attribute:: _saved_states :type: Dict[int, List[_State]] .. py:method:: _update_state() -> None .. py:method:: reset_to(t: int) -> None .. py:method:: goto(t: int) -> None Steps the factory to the end of step t :param t: time Returns: .. py:method:: wallet_to(t: int) -> numpy.array Returns the cash in wallet up to and including time t. :param t: Time Returns: .. py:method:: line_schedules_to(t: int) -> numpy.array Returns the schedule of each line up to a given timestep :param t: time :returns: An array of `n_lines` * `t` values giving the schedule up to `t`. Remarks: - A `NO_PRODUCTION` value means no production, otherwise the index of the process being run .. py:method:: storage_to(t: int) -> numpy.array Returns the storage of all products *up to* time t :param t: Time :returns: An array of size `n_products` * `t` giving the quantity of each product in storage at every step up to `t`. .. py:method:: loans_to(t: int) -> float Returns loans up to time t :param t: time :returns: An array of `t` real numbers giving the loans registered at time-steps up to `t` .. py:method:: add_loan(total: float, t: int) -> bool Adds a loan at the given time :param total: Total amount of the loan :param t: time step to take the loan :returns: Success or failure Remarks: - Taking a loan is simulated as reception of money. Payment back of the loan is not simulated in this call. To simulate paying back the loan, use `pay` at the times of installment payments. .. py:method:: pay(payment: float, t: int, ignore_money_shortage: bool = True) -> bool Simulate payment at time t :param payment: Amount payed :param t: time :param ignore_money_shortage: If True, shortage in money will be ignored and the wallet can go negative :returns: Success or failure .. py:method:: transport_to(product: int, quantity: int, t: int, ignore_inventory_shortage: bool = True, ignore_space_shortage: bool = True) -> bool Simulates transporting products to/from storage at time t :param product: product ID (index) :param quantity: quantity to transport :param t: time :param ignore_inventory_shortage: Ignore shortage in the `product` which may lead to negative storage[product] :param ignore_space_shortage: Ignore the limit on total storage which may lead to total_storage > max_storage :returns: Success or failure .. py:method:: schedule(job: scml.scml2019.common.Job, ignore_inventory_shortage=True, ignore_money_shortage=True, ignore_space_shortage=True, override=True) -> bool Simulates scheduling the given job at its `time` and `line` optionally overriding whatever was already scheduled :param job: Production job :param ignore_inventory_shortage: If true shortages in inputs will be ignored :param ignore_money_shortage: If true, shortage in money will be ignored :param ignore_space_shortage: If true, shortage in space will be ignored :param override: Whether the job should override any already registered job at its time-step :returns: Success/failure .. py:method:: buy(product: int, quantity: int, price: int, t: int, ignore_money_shortage: bool = True, ignore_space_shortage: bool = True) -> bool Buy a given quantity of a product for a given price at some time t :param product: Product to buy (ID/index) :param quantity: quantity to buy :param price: unit price :param t: time :param ignore_money_shortage: If True, shortage in money will be ignored and the wallet can go negative :param ignore_space_shortage: Ignore the limit on total storage which may lead to total_storage > max_storage :returns: Success or failure Remarks: - buy cannot ever have inventory shortage .. seealso:: `sell` .. py:method:: sell(product: int, quantity: int, price: int, t: int, ignore_money_shortage: bool = True, ignore_inventory_shortage: bool = True) -> bool sell a given quantity of a product for a given price at some time t :param product: Index/ID of the product to be sold :param quantity: quantity to be sold :param price: unit price :param t: time :param ignore_money_shortage: If True, shortage in money will be ignored and the wallet can go negative :param ignore_inventory_shortage: Ignore shortage in the `product` which may lead to negative storage[product] :returns: Success or failure Remarks: - sell cannot ever have space shortage .. seealso:: `buy` .. py:property:: fixed_before Gives the time before which the schedule is fixed. .. seealso:: `fix_before` .. py:class:: FastFactorySimulator(initial_wallet: float, initial_storage: Dict[int, int], n_steps: int, n_products: int, profiles: List[scml.scml2019.common.ManufacturingProfile], max_storage: Optional[int]) Bases: :py:obj:`FactorySimulator` A faster implementation of the `FactorySimulator` interface (compared with `SlowFactorySimulator`. .. py:method:: _as_array(storage: Dict[int, int]) -> numpy.array .. py:attribute:: _wallet .. py:attribute:: _loans .. py:attribute:: _storage .. py:attribute:: _total_storage .. py:attribute:: _profiles :value: [] .. py:attribute:: _n_lines .. py:attribute:: _line_schedules .. py:attribute:: _has_jobs .. py:attribute:: _fixed_before :value: 0 .. py:attribute:: _bookmarks :type: List[_FullBookmark] :value: [] .. py:attribute:: _active_bookmark :type: Optional[_FullBookmark] :value: None .. py:method:: init(*args, **kwargs) .. py:property:: fixed_before Gives the time before which the schedule is fixed. .. seealso:: `fix_before` .. py:property:: n_lines Number of lines .. py:property:: final_balance :type: float Final balance given everything scheduled so-far .. py:method:: wallet_to(t: int) -> numpy.array Returns the cash in wallet up to and including time t. :param t: Time Returns: .. py:method:: storage_to(t: int) -> numpy.array Returns the storage of all products *up to* time t :param t: Time :returns: An array of size `n_products` * `t` giving the quantity of each product in storage at every step up to `t`. .. py:method:: line_schedules_to(t: int) -> numpy.array Returns the schedule of each line up to a given timestep :param t: time :returns: An array of `n_lines` * `t` values giving the schedule up to `t`. Remarks: - A `NO_PRODUCTION` value means no production, otherwise the index of the process being run .. py:method:: loans_to(t: int) -> numpy.array Returns loans up to time t :param t: time :returns: An array of `t` real numbers giving the loans registered at time-steps up to `t` .. py:method:: add_loan(total: float, t: int) -> bool Adds a loan at the given time :param total: Total amount of the loan :param t: time step to take the loan :returns: Success or failure Remarks: - Taking a loan is simulated as reception of money. Payment back of the loan is not simulated in this call. To simulate paying back the loan, use `pay` at the times of installment payments. .. py:method:: pay(payment: float, t: int, ignore_money_shortage: bool = True) -> bool Simulate payment at time t :param payment: Amount payed :param t: time :param ignore_money_shortage: If True, shortage in money will be ignored and the wallet can go negative :returns: Success or failure .. py:method:: transport_to(product: int, quantity: int, t: int, ignore_inventory_shortage: bool = True, ignore_space_shortage: bool = True) -> bool Simulates transporting products to/from storage at time t :param product: product ID (index) :param quantity: quantity to transport :param t: time :param ignore_inventory_shortage: Ignore shortage in the `product` which may lead to negative storage[product] :param ignore_space_shortage: Ignore the limit on total storage which may lead to total_storage > max_storage :returns: Success or failure .. py:method:: buy(product: int, quantity: int, price: int, t: int, ignore_money_shortage: bool = True, ignore_space_shortage: bool = True) -> bool Buy a given quantity of a product for a given price at some time t :param product: Product to buy (ID/index) :param quantity: quantity to buy :param price: unit price :param t: time :param ignore_money_shortage: If True, shortage in money will be ignored and the wallet can go negative :param ignore_space_shortage: Ignore the limit on total storage which may lead to total_storage > max_storage :returns: Success or failure Remarks: - buy cannot ever have inventory shortage .. seealso:: `sell` .. py:method:: sell(product: int, quantity: int, price: int, t: int, ignore_money_shortage: bool = True, ignore_inventory_shortage: bool = True) -> bool sell a given quantity of a product for a given price at some time t :param product: Index/ID of the product to be sold :param quantity: quantity to be sold :param price: unit price :param t: time :param ignore_money_shortage: If True, shortage in money will be ignored and the wallet can go negative :param ignore_inventory_shortage: Ignore shortage in the `product` which may lead to negative storage[product] :returns: Success or failure Remarks: - sell cannot ever have space shortage .. seealso:: `buy` .. py:method:: schedule(job: scml.scml2019.common.Job, ignore_inventory_shortage=True, ignore_money_shortage=True, ignore_space_shortage=True, override=True) -> bool Simulates scheduling the given job at its `time` and `line` optionally overriding whatever was already scheduled :param job: Production job :param ignore_inventory_shortage: If true shortages in inputs will be ignored :param ignore_money_shortage: If true, shortage in money will be ignored :param ignore_space_shortage: If true, shortage in space will be ignored :param override: Whether the job should override any already registered job at its time-step :returns: Success/failure .. py:method:: fix_before(t: int) -> bool Fix the history before this point :param t: time :returns: Success/failure Remarks: - After this function is called at any time-step `t`, there is no way to change any component of the factory state at any timestep before `t`. - This function is useful for *fixing* any difference between the simulator and the real state (in conjunction with `set_state`). .. seealso:: `set_state` `fixed_before` .. py:method:: delete_bookmark(bookmark_id: int) -> bool Commits everything since the bookmark so it cannot be rolled back :param bookmark_id The bookmark ID returned from bookmark: :returns: Success/failure Remarks: - You can delete bookmarks in the reverse order of their creation only. If the bookmark ID given here is not the one at the top of the bookmarks stack, the deletion will fail (return False). .. seealso:: `delete_bookmark` `rollback` `transaction` `temporary_transaction` .. py:method:: bookmark() -> int Sets a bookmark to the current location :returns: bookmark ID Remarks: - Bookmarks can be used to implement transactions. .. seealso:: `delete_bookmark` `rollback` `transaction` `temporary_transaction` .. py:method:: rollback(bookmark_id: int) -> bool Rolls back to the given bookmark ID :param bookmark_id The bookmark ID returned from bookmark: Remarks: - You can only rollback in the reverse order of bookmarks. If the bookmark ID given here is not the one at the top of the bookmarks stack, the rollback will fail (return False) .. seealso:: `delete_bookmark` `rollback` `transaction` `temporary_transaction` .. py:method:: set_state(t: int, storage: numpy.array, wallet: float, loans: float, line_schedules: numpy.array) -> None Sets the current state at the given time-step. It implicitly causes a fix_before(t + 1) :param t: Time step to set the state at :param storage: quantity of every product (array of integers of size `n_products`) :param wallet: Cash in wallet :param loans: Loans :param line_schedules: Line schedules (array of process numbers/NO_PRODUCTION of size `n_lines`) .. py:function:: transaction(simulator) Runs the simulated actions then confirms them if they are not rolled back .. py:function:: temporary_transaction(simulator) Runs the simulated actions then rolls them back