Quick Start Guide
Learn how to use SimASM for discrete event simulation in just a few minutes.
1. Installation
Install SimASM using pip:
pip install simasm
2. Your First Model
SimASM models consist of domains (entity types), variables, rules, and an initialization block. Here's a simple counter example:
// counter.simasm - A simple counter model
domain Object
var counter: Nat
var max_value: Nat
main rule step =
if counter < max_value then
counter := counter + 1
print counter
endif
endrule
init:
counter := 0
max_value := 10
endinit
3. Running in Python
Use the SimASM Python API to run your model:
import simasm
# Define the model source
model_source = """
domain Object
var counter: Nat
var max_value: Nat
main rule step =
if counter < max_value then
counter := counter + 1
endif
endrule
init:
counter := 0
max_value := 10
endinit
"""
# Register and run the model
simasm.register_model("counter", model_source)
result = simasm.run_model(model_source, steps=15)
print(result)
4. Using Jupyter Notebooks
SimASM provides cell magic for Jupyter notebooks:
# First cell - import SimASM (registers magic automatically)
import simasm
# Second cell - define a model using cell magic
%%simasm model --name mm1_queue
import Random as rnd
import Stdlib as lib
domain Object
domain Customer <: Object
var queue: List<Customer>
var server_busy: Bool
var total_served: Nat
var interarrival: rnd.exponential(1.0) as "arrivals"
var service_time: rnd.exponential(0.8) as "service"
main rule step =
// Arrivals handled by event scheduler
if not server_busy and lib.length(queue) > 0 then
server_busy := true
endif
endrule
init:
queue := []
server_busy := false
total_served := 0
endinit
# Third cell - run an experiment
%%simasm experiment
experiment QueueTest:
model := "mm1_queue"
replication:
count: 5
warm_up_time: 100
run_length: 1000
seed_strategy: "incremental"
base_seed: 42
endreplication
statistics:
stat avg_queue:
expression: "lib.length(queue)"
aggregation: time_average
endstat
endstatistics
output:
format: "json"
file_path: "results.json"
endoutput
endexperiment
5. Queue Model Example
Here's a more complete M/M/1 queue model demonstrating key SimASM features:
// mm1_queue.simasm - M/M/1 Queueing Model
import Random as rnd
import Stdlib as lib
// Define entity types
domain Object
domain Customer <: Object
// State variables
var queue: List<Customer>
var server_busy: Bool
var customers_served: Nat
var sim_time: Real
// Random streams
var interarrival: rnd.exponential(1.0) as "arrivals"
var service: rnd.exponential(0.8) as "service"
// Derived function for queue length
derived function queue_length(): Nat =
lib.length(queue)
// Rule for customer arrival
rule arrive(c: Customer) =
queue := lib.add(queue, c)
endrule
// Rule for starting service
rule start_service() =
if not server_busy and queue_length() > 0 then
server_busy := true
queue := lib.remove(queue, lib.first(queue))
endif
endrule
// Rule for completing service
rule complete_service() =
server_busy := false
customers_served := customers_served + 1
endrule
// Main simulation step
main rule step =
// Process events in priority order
start_service()
endrule
// Initialize the model
init:
queue := []
server_busy := false
customers_served := 0
sim_time := 0.0
endinit
6. Model Verification
SimASM can verify behavioral equivalence between two models using W-stutter equivalence:
// verification_spec.simasm
verification QueueEquivalence:
models:
import ModelA from "queue_eg.simasm"
import ModelB from "queue_acd.simasm"
endmodels
seed: 42
labels:
label queue_empty for ModelA: "queue_length() == 0"
label queue_empty for ModelB: "marking == 0"
label server_busy for ModelA: "server_busy == true"
label server_busy for ModelB: "server_state == BUSY"
endlabels
observables:
observable queue_state:
ModelA -> queue_empty
ModelB -> queue_empty
endobservable
observable server_state:
ModelA -> server_busy
ModelB -> server_busy
endobservable
endobservables
check:
type: stutter_equivalence
run_length: 1000
timeout: 60
endcheck
output:
format: "json"
file_path: "verification_result.json"
include_counterexample: true
endoutput
endverification
7. Key Concepts
Domains define entity types. Use
<: for inheritance:
domain Customer <: Object
Variables hold mutable state:
var name: Type
Rules define state transitions. The
main rule is executed each simulation step.
Random Streams use
rnd.distribution(params) as "name" for reproducible randomness.
Library Functions are accessed via
lib.* (e.g., lib.length(), lib.add()).
Next Steps
- Syntax Reference - Complete language documentation
- Playground - Try SimASM in your browser
- GitHub - Source code and examples