Skip to content

Enforce monotonic time invariant in event scheduling#3343

Merged
quaquel merged 4 commits intomesa:mainfrom
souro26:time-monotonicity
Feb 18, 2026
Merged

Enforce monotonic time invariant in event scheduling#3343
quaquel merged 4 commits intomesa:mainfrom
souro26:time-monotonicity

Conversation

@souro26
Copy link
Copy Markdown
Contributor

@souro26 souro26 commented Feb 18, 2026

Summary

This PR enforces a monotonic time invariant in the event scheduling system. It prevents one-off and recurring events from being scheduled at times earlier than the model’s current simulation time. This ensures the model clock cannot move backwards during execution.

Fixes #3342

Bug / Issue

It was previously possible to run the model forward (e.g., to time 10), schedule a new event at an earlier time (e.g., time 3) and then execute that event, causing the model clock to move backward. There is no rollback mechanism in the execution model, so this behavior violates expected time semantics.

Implementation

The fix enforces the invariant at the scheduling boundary:

  • In Model.schedule_event, a ValueError is raised if time < self.time
  • In Model.schedule_recurring, a ValueError is raised if schedule.start is not None and schedule.start < self.time

This ensures both one-off and recurring schedules cannot be initialized in the past. This is enforced at the API boundary rather than inside _advance_time, preventing invalid events from entering the event list in the first place.

Testing

Added tests in tests/test_model.py for verification. Normal forward scheduling behavior remains unchanged All time-related tests pass.

Additional Notes

This change formalizes time monotonicity as an invariant of the scheduling system. It does not alter normal forward execution behavior. This preserves consistency with the discrete event execution model, which does not support rollback or reversible time progression.

@quaquel quaquel added bug Release notes label backport-candidate PRs we might want to backport to an earlier branch labels Feb 18, 2026
raise ValueError(
f"Cannot schedule event at time {time}, current time is {self.time}"
)
event = Event(time, function, priority=priority)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
event = Event(time, function, priority=priority)
raise ValueError(
f"Cannot schedule event in the past. Scheduled time is {time}, but current time is {self.time}"
)

Comment on lines +428 to +431
raise ValueError(
f"Cannot start recurring schedule at time {schedule.start}, "
f"current time is {self.time}"
)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
raise ValueError(
f"Cannot start recurring schedule at time {schedule.start}, "
f"current time is {self.time}"
)
raise ValueError(
f"Cannot start recurring schedule in the past. Start time is {schedule.start}, "
f"current time is {self.time}"
)

Copy link
Copy Markdown
Member

@quaquel quaquel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Please look at the suggested change to the message and add raises to the docstring.

@github-actions
Copy link
Copy Markdown

Performance benchmarks:

Model Size Init time [95% CI] Run time [95% CI]
BoltzmannWealth small 🔵 -1.0% [-1.5%, -0.6%] 🔵 +1.4% [+1.1%, +1.8%]
BoltzmannWealth large 🔵 -2.0% [-2.6%, -1.4%] 🔵 -2.2% [-2.6%, -1.7%]
Schelling small 🔵 -0.1% [-0.3%, +0.2%] 🔵 +0.3% [+0.2%, +0.5%]
Schelling large 🔵 -1.3% [-2.0%, -0.7%] 🔵 +0.9% [-0.5%, +2.3%]
WolfSheep small 🔵 +0.3% [+0.1%, +0.5%] 🔵 +1.2% [+1.0%, +1.3%]
WolfSheep large 🔵 -0.5% [-1.3%, +0.3%] 🔵 +1.0% [+0.3%, +2.1%]
BoidFlockers small 🔵 +1.0% [+0.3%, +1.6%] 🔵 +1.3% [+1.1%, +1.5%]
BoidFlockers large 🔵 +2.1% [+1.6%, +2.5%] 🔵 +1.8% [+1.5%, +2.0%]

@souro26
Copy link
Copy Markdown
Contributor Author

souro26 commented Feb 18, 2026

@quaquel i made the changes you recommended, thanks for the review.

@quaquel quaquel merged commit 6b5e723 into mesa:main Feb 18, 2026
13 of 14 checks passed
Krishsharma179 pushed a commit to Krishsharma179/mesa that referenced this pull request Feb 21, 2026
@EwoutH EwoutH mentioned this pull request Mar 13, 2026
42 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-candidate PRs we might want to backport to an earlier branch bug Release notes label

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Event scheduling allows execution of events in the past violating time monotonicity

2 participants