An event-driven SIR (Susceptible-Infected-Recovered) epidemic simulation implemented in Gleam using fully autonomous agents. This project demonstrates discrete event systems (DEVS) principles and agent-based modeling.
This is a simulation of how a disease spreads through a population. Each person in the simulation is an autonomous "agent" that:
- Contacts other people at random intervals (with individual contact rates)
- Can become infected when contacting sick people
- Recovers after being sick for some time
- Reports their status changes
The simulation runs in real-time and automatically ends when everyone has recovered.
You need to install Gleam and Erlang. Follow these steps:
- Download Erlang from: https://www.erlang.org/downloads
- Get the Windows installer (e.g.,
otp_win64_26.2.exe) - Run the installer and follow the prompts
- Accept default installation path (usually
C:\Program Files\Erlang OTP\)
Option A: Using Scoop (Recommended)
-
Open PowerShell as Administrator
-
Install Scoop if you don't have it:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression
-
Install Gleam:
scoop install gleam
Option B: Manual Installation
- Download Gleam from: https://github.com/gleam-lang/gleam/releases
- Get the Windows binary (e.g.,
gleam-v1.6.2-x86_64-pc-windows-msvc.zip) - Extract the ZIP file
- Add the extracted folder to your PATH:
- Right-click "This PC" -> Properties -> Advanced System Settings
- Click "Environment Variables"
- Under "System variables", find "Path" and click "Edit"
- Click "New" and add the path where you extracted Gleam
- Click OK on all dialogs
Open a new Command Prompt or PowerShell window and run:
gleam --version
erl -versionBoth should show version numbers without errors.
-
Clone or download this repository
-
Open Command Prompt or PowerShell and navigate to the project folder:
cd path\to\actor
-
Run the simulation:
gleam run
-
Watch the epidemic spread! You'll see output like:
═══════════════════════════════════════ SIR Epidemic Simulation (Event-Driven) ═══════════════════════════════════════ Population: 50 Contacts per person: 10 Initially infected: 3 Contact rate: 2.0 per day (mean, +/-50.0% individual variation) Infection probability: 0.3 Average recovery time: 10.0 days ═══════════════════════════════════════ t=0: Person #9 became infected (from #-1) t=0: Person #8 became infected (from #-1) t=0: Person #27 became infected (from #-1) t=1169: Person #3 became infected (from #8) t=1455: Person #26 became infected (from #27) ... t=45234: Person #19 recovered ═══════════════════════════════════════ Epidemic ended at t=58393ms Total infected over time: 50/50 people Never infected: 0 people ═══════════════════════════════════════
- t=XXX - Logical simulation time in milliseconds (1000ms = 1 simulated day)
- Person #N became infected (from #M) - Person N caught the disease from Person M
- Person #N became infected (from #-1) - Person N was initially infected (no source)
- Person #N recovered - Person N is now immune
- Final statistics - How many people were infected in total
You can adjust parameters in src/actor.gleam at the top of the file:
const population_size = 50 // Number of people
const contacts_per_person = 10 // Social network size
const initial_infected = 3 // How many start sick
const lambda = 2.0 // Mean contacts per day
const lambda_variation = 0.5 // Individual variation (+/-50%)
const beta = 0.3 // Infection probability (0.0-1.0)
const gamma = 0.1 // Recovery rate per dayAfter changing values, run gleam run again to see the new simulation.
This simulation uses the actor model of concurrency:
-
Person Actors (50) - Each person is an independent agent that:
- Has their own contact rate (varies +/-50% from the mean)
- Schedules when to contact others (exponential random distribution)
- Decides whether they get infected based on probability
- Schedules their own recovery time
- Maintains their own logical clock for time synchronization
- Reports status changes
-
Reporter Actor (1) - Tracks the epidemic:
- Counts currently infected people
- Logs all infections and recoveries
- Ends simulation when no one is infected
-
No Global Coordinator - Agents act independently based on events
- No "time steps" or global clock
- Pure message passing between agents
- Events scheduled with
process.send_after() - Logical time synchronized via Lamport-style clocks
Since actors run independently, we use a Lamport-style logical clock to maintain causal ordering:
- Each actor maintains its own
timevalue - Messages carry timestamps
- On receiving a message:
now = max(my_time, message_time) - This ensures causality: if A infects B, then
time(A) < time(B)
This follows DEVS (Discrete Event System Specification) principles - a formal framework for event-driven simulation.
See ARCHITECTURE.md for detailed system design documentation including:
- State diagrams
- Message flow examples
- Design decisions
- Mathematical model parameters
For a detailed code walkthrough (especially useful if you're new to Gleam), see WALKTHROUGH.md.
- Make sure you completed the installation steps above
- Open a new terminal window after installation
- Verify Gleam is in your PATH (see installation steps)
-
Make sure Erlang is installed
-
On Windows, you may need to set ERLANG_HOME environment variable:
ERLANG_HOME=C:\Program Files\Erlang OTP\erts-14.2.1
- This is expected if the epidemic doesn't reach everyone
- Press Ctrl+C to stop the simulation
- Try increasing
beta(infection probability) to make it spread faster
- The simulation runs in real-time (1 second = 1 simulated day)
- Reduce
population_sizefor faster results - Increase
gamma(recovery rate) to make people recover faster
- Official website: https://gleam.run/
- Documentation: https://gleam.run/documentation/
- Language tour: https://tour.gleam.run/
- This is a classic SIR epidemiological model
- Each person is an autonomous agent with individual parameters
- Uses discrete event simulation instead of time-stepping
- Based on DEVS (Discrete Event System Specification)
- Actors are independent processes that communicate via messages
- Each actor has its own state and mailbox
- No shared memory - pure message passing
- Erlang/OTP provides excellent actor support
gleam run # Run the simulation
gleam build # Compile the project
gleam test # Run tests (if any)
gleam format # Format the codeactor/
├── src/
│ └── actor.gleam # Main simulation code (~460 lines)
├── ARCHITECTURE.md # Detailed design documentation
├── WALKTHROUGH.md # Code walkthrough for Gleam beginners
├── README.md # This file
└── gleam.toml # Project configuration
This project demonstrates:
- Event-driven programming
- Actor model concurrency
- Agent-based modeling
- Discrete event simulation (DEVS)
- Epidemiological modeling (SIR model)
- Logical time synchronization (Lamport clocks)