abstract class Quartz::DTSS::AtomicModel

Overview

This class represent a PDTSS atomic model.

Included Modules

Defined in:

quartz/dtss/atomic.cr

Constructors

Class Method Summary

Instance Method Summary

Macro Summary

Instance methods inherited from module Quartz::Verifiable

clear_errors clear_errors, errors errors, invalid?(context : Symbol | Nil = nil) : Bool invalid?, valid?(context : Symbol | Nil = nil) : Bool valid?

Instance methods inherited from module Quartz::Observable

add_observer(observer : Observer) add_observer, count_observers count_observers, delete_observer(observer : Observer) : Bool delete_observer, notify_observers(info = nil) notify_observers

Instance methods inherited from module Quartz::Coupleable

add_input_port(name) add_input_port, add_output_port(name) add_output_port, add_port(port : InputPort)
add_port(port : OutputPort)
add_port
, each_input_port(&) each_input_port, each_output_port(&) each_output_port, input_port(name : Name) : InputPort input_port, input_port?(name : Name) : InputPort | Nil input_port?, input_port_list : Array(InputPort) input_port_list, input_port_names input_port_names, output_port(name : Name) : OutputPort output_port, output_port?(name : Name) : OutputPort | Nil output_port?, output_port_list : Array(OutputPort) output_port_list, output_port_names output_port_names, remove_input_port(name) remove_input_port, remove_output_port(name) remove_output_port, remove_port(port : InputPort)
remove_port(port : OutputPort)
remove_port

Instance methods inherited from class Quartz::Model

accept(visitor : Visitor) accept, accept_children(visitor) accept_children, inspect(io) inspect, name : Name name, name=(name : Name) name=, processor : Processor | Nil processor, processor=(processor : Processor | Nil) processor=, processor? : Processor | Nil | Nil processor?, to_s(io) to_s

Constructor methods inherited from class Quartz::Model

new(name : Name) new

Instance methods inherited from class Reference

==(other : Quartz::Any) ==

Instance methods inherited from class Object

===(other : Quartz::Any) ===

Constructor Detail

def self.new(name, state) #

[View source]
def self.new(pull : JSON::PullParser) #

[View source]
def self.new(name) #

[View source]

Class Method Detail

def self.check(*attributes : Symbol, **kwargs) #

[View source]
def self.check_with(klass : Verifiers::RuntimeValidator.class, **kwargs) #

Passes the model off to the class or classes specified and allows them to add errors based on more complex conditions.

class MyModel
  include Quartz::Verifiable
  check_with MyVerifier
end

class MyVerifier < Quartz::Verifiers::RuntimeChecker
  def validate(model)
    if some_test
      model.errors.add(:phase, "This model state is invalid")
    end
  end

  # ...
end

[View source]
def self.check_with(klass : Verifiers::EachChecker.class, *attributes : Symbol, **kwargs) #

Passes the model off to the class or classes specified and allows them to add errors based on more complex conditions.

class MyModel
  include Quartz::Verifiable
  check_with MyVerifier
end

class MyVerifier < Quartz::Verifiers::EachChecker
  def check_each(model, attribute, value)
    if some_test
      model.errors.add(attribute, "This model attribute is invalid")
    end
  end

  # ...
end

[View source]
def self.clear_verifiers #

[View source]
def self.from_json(io : IO) #

[View source]
def self.from_json(str : String) #

[View source]
def self.precision_scale : Scale #

[View source]
def self.time_delta : Duration #

[View source]
def self.time_delta=(time_delta : Duration) #

[View source]
def self.verifiers #

[View source]

Instance Method Detail

def dup_state #

def elapsed : Duration #

This attribute is updated automatically along simulation and represents the elapsed time since the last transition.


[View source]
def elapsed=(elapsed : Duration) #

This attribute is updated automatically along simulation and represents the elapsed time since the last transition.


[View source]
def inspect(io) #

[View source]
def model_precision : Scale #

Returns the precision associated with the class.


[View source]
abstract def output #

The output function (λ)

Override this method to implement the appropriate behavior of your model. See #post to send values to output ports.

Example:

def output
  post(42, :output)
end

[View source]
def state #

def time_delta : Duration #

[View source]
def to_json(json : JSON::Builder) #

[View source]
abstract def transition(messages : Hash(InputPort, Array(Any))) #

[View source]

Macro Detail

macro input(*names) #

Defines default input ports for each of the given arguments. Those default input ports will be available in all instances, including instances of subclasses (meaning that ports are inherited).

Writing:

class MyModel < AtomicModel
  input port_name
end

Is the same as writing:

class MyModel < AtomicModel
  def initialize(name)
    super(name)
    add_input_port :port_name
  end
end

The arguments can be string literals, symbol literals or plain names. However, they will be converted to symbol literals when the model is instantiated.

class MyModel < AtomicModel
  input :in1, "in2", in3
end

[View source]
macro output(*names) #

Defines default output ports for each of the given arguments. Those default output ports will be available in all instances, including instances of subclasses (meaning that ports are inherited).

Writing:

class MyModel < AtomicModel
  output port_name
end

Is the same as writing:

class MyModel < AtomicModel
  def initialize(name)
    super(name)
    add_output_port :port_name
  end
end

The arguments can be string literals, symbol literals or plain names. However, they will be converted to symbols literals when the model is instantiated.

class MyModel < AtomicModel
  output :out1, "out2", out3
end

[View source]
macro state_initialize(&block) #

The state_initialize macro defines an initialization block that is automatically included in all constructor defined in the included type and its subclasses.

It can be used to initialize state variables declared using the state_var macro.

Example :

class MyModel < AtomicModel
  state_var x : Int32
  state_var y : Int32

  state_initialize do
    @x = 0
    @y = 0
  end

[View source]
macro state_var(prop, **nopts, &block) #

The state_var macro defines a state variable of a model. Its primary usage is to identify which instance variables are part of the state of the model.

This allows to automatically define state retrieval methods, state serialization/deserialization methods and state initialization methods which will be used for simulation distribution purposes, for constructing model hierarchies from a file, or to allow changing initial state for model parameter exploration.

Usage

state_var must receive a type declaration which will be used to declare instance variables :

class MyModel < AtomicModel
  state_var x : Int32
  state_var y : Int32
end

Default values can be passed using the type declaration notation or through a block :

class MyModel < AtomicModel
  state_var x : Int32 = 0
  state_var y : Int32 = 0
  state_var z : Int32 { (rand * 100 + 1).to_i32 }
  state_var ß : Int32 { x * 42 }
end

Note from previous example that the initialization block of ß is allowed to reference the value of another state variable.

If default values are omitted, a chance is given to initialize those state variables through the state_initialize macro :

class MyModel < AtomicModel
  state_var x : Int32
  state_var y : Int32

  state_initialize do
    @x = 0
    @y = 0
  end
end

Multiple calls to state_var for the same variable is allowed. Previous properties are inherited and overlapping propertings are overwritten. The following example :

class MyModel < AtomicModel
  state_var sigma : Duration = Duration::INFINITY
  state_var sigma { Duration.infinity(self.class.precision) }
end

Defines the sigma state variable as a Duration type with a default value determined by the initialization block.

This is particularly useful in case a model inherits another model :

class BaseModel < AtomicModel
  state_var sigma : Duration = Duration::INFINITY
end

class MyModel < BaseModel
  state_var sigma = Quartz.duration(85, milli)
end

All initialize methods defined in the included type and its subclasses will be redefined to include the body of the given block. Note that the block content is always included at the top of the method definition. Thus, if you define :

class MyModel < AtomicModel
  state_var x : Int32
  state_var y : Int32

  state_initialize do
    @x = 0
    @y = 0
  end

  def initialize(name)
    super(name)
    add_input_port("in")
  end
end

The constructor will be automatically redefined to :

  def initialize(name)
    @x = 0
    @y = 0
    super(name)
    add_input_port("in")
  end
end

Options

Along with the type declaration, state_var also accept a hash or named tuple literal whose keys corresponds to the following options :

  • visibility: used to restrict the visibility of the getter that is defined for this state variable (:private or :protected). No restriction is applied by default (public) :
state_var hidden : Bool = true, visibility: :private
  • converter: specify an alternate type for parsing and generation. Examples of converters are Time::Format and Time::EpochConverter for Time.
state_var timestamp : Time, converter: Time::EpochConverter

Code generation

A getter is generated for each declared state variable, whose visibility can be restricted through the visibility option.

When the type definition is complete, a struct wrapping all state variables is defined for convenience.


[View source]