y_petri 2.1.18 → 2.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1c6473b48dec04630c9027b0d3335d18c91a4301
4
- data.tar.gz: ae80469d37a2f373f6c20edf2a0c1955176cc134
3
+ metadata.gz: 925fd4bc4059984743c3a79a05161f8318bb664b
4
+ data.tar.gz: 9df7ce42d2a6d90d196b9b0325ce9f547892b228
5
5
  SHA512:
6
- metadata.gz: 10d7df35e22f132012c75c6b017b17a30788b3d66f01ff72ce6f10fd8bbeae78f664fea8745982e8d0b2666e87044f24c14c0f39486dd1d0a080799137202163
7
- data.tar.gz: b99f52b56838e8a569da1b0e17fc4f624e03108845a90d05cd68894192be34a05f9e83eef1bce4c676af1e9ab5ac6cfe1955560b4b0346892fa719479f195b02
6
+ metadata.gz: d6e49798a1982ffee6b72a5fe210cce73cb30a2dfa32b745cad5d5be27160600cecb6449a786bcff335dfa3b49d3132655c35fb88094716df430c3b66e43c0b9
7
+ data.tar.gz: 56705a76926aa07e3116038dd216427d4bc07dfc512422d9fc354087b8103e6e67a3722f5b80cbec7075a7d194c77bc1dde1ae57e8005f40f03c5a78cc7c6c4a
data/README.md CHANGED
@@ -1,26 +1,93 @@
1
1
  # YPetri
2
2
 
3
- y_petri is a Petri net domain model and simulator
3
+ `YPetri` is a domain model and a simulator of _functional_ _Petri_ _nets_,
4
+ a family of Petri nets, whose transitions have functions attached to them.
4
5
 
5
- ## Installation
6
-
7
- Add this line to your application's Gemfile:
8
-
9
- gem 'y_petri'
10
-
11
- And then execute:
12
-
13
- $ bundle
6
+ ## Usage
14
7
 
15
- Or install it yourself as:
8
+ `YPetri` provides a _domain_ _specific_ _language_ (DSL), that can be loaded by:
9
+ ```ruby
10
+ require 'y_petri'
11
+ include YPetri
12
+ ```
13
+ Now, one can create places:
14
+ ```ruby
15
+ A = Place()
16
+ B = Place()
17
+ places.names # you can shorten this to #pn
18
+ #=> [:A, :B]
19
+ # Setting their marking:
20
+ A.marking = 2
21
+ B.marking = 5
22
+ ```
23
+ And transitions:
24
+ ```ruby
25
+ A2B = Transition stoichiometry: { A: -1, B: 1 }
26
+ #=> #<Transition: A2B (tS) >
27
+ A2B.stoichiometry
28
+ #=> [-1, 1]
29
+ A2B.s
30
+ #=> {:A=>-1, :B=>1}
31
+ A2B.arcs.names
32
+ #=> [:A, :B]
33
+ A2B.timeless?
34
+ #=> true
35
+ A2B.enabled?
36
+ #=> true
37
+ ```
38
+ Explanation of the keywords: _arcs_, _enabled_ are standard Petri net terms,
39
+ _stoichiometry_ means arcs with the amount of tokens to add / take from the
40
+ connected places when the transition fires, _timeless_ means that firing of
41
+ the transition is not defined in time.
16
42
 
17
- $ gem install y_petri
43
+ We can now play the _token_ _game_:
44
+ ```ruby
45
+ places.map &:marking
46
+ #=> [2, 5]
47
+ A2B.fire!
48
+ places.map &:marking
49
+ #=> [1, 6]
50
+ A2B.fire!
51
+ places.map &:marking
52
+ #=> [0, 7]
53
+ ```
18
54
 
19
- ## Usage
55
+ ## Advanced usage
20
56
 
21
- y_petri can be used either interactively (in irb with
22
- 'include YPetri'), or from another program. YPetri::Manipulator
23
- provides the command interface.
57
+ A Petri net is mostly used as a wiring diagram of some real-world system. Such
58
+ Petri net can then be used to generate (implicitly or explicitly) a more specific
59
+ simulation of that real-world system. This is represented by `YPetri::Simulation`
60
+ class. If a Petri net with only _timed_ transitions is considered, it can then
61
+ be used to generate (implicitly or explicitly) a system of ordinary differential
62
+ equations (ODE). A Simulation class instance generated from such Petri net can
63
+ then be used to eg. solve the initial value problem by numeric integration of the
64
+ ODE system using one of the available numerical methods:
65
+ ```ruby
66
+ # Start a fresh irb session!
67
+ require 'y_petri'
68
+ include YPetri
69
+ A = Place default_marking: 0.5
70
+ B = Place default_marking: 0.5
71
+ A_pump = Transition s: { A: -1 }, rate: proc { 0.005 }
72
+ B_decay = Transition s: { B: -1 }, rate: 0.05
73
+ net
74
+ #=> #<Net: name: Top, 2pp, 2tt >
75
+ run!
76
+ ```
77
+ Simulation can now be accessed through `simulation` DSL method:
78
+ ```ruby
79
+ simulation
80
+ #=> #<Simulation: time: 60, pp: 2, tt: 2, oid: -XXXXXXXXX>
81
+ simulation.settings
82
+ #=> {:method=>:pseudo_euler, :guarded=>false, :step=>0.1, :sampling=>5, :time=>0..60}
83
+ print_recording
84
+ ```
85
+ If you have `gnuplot` gem installed properly, you can view plots:
86
+ ```ruby
87
+ plot_state
88
+ plot_flux
89
+ ```
90
+ So much for the demo for now! Thanks for trying YPetri!
24
91
 
25
92
  ## Contributing
26
93
 
@@ -252,4 +252,12 @@ class YPetri::Net::DataSet < Hash
252
252
  def inspect
253
253
  to_s
254
254
  end
255
+
256
+ # Pretty print the dataset.
257
+ #
258
+ def print precision: 4, distance: precision + 4
259
+ features.labels.print_as_line precision: precision, distance: distance
260
+ puts '-' * features.size * distance
261
+ records.each.print_as_line precision: precision, distance: distance
262
+ end
255
263
  end # YPetri::Net::Dataset
@@ -1,4 +1,4 @@
1
- #encoding: utf-8
1
+ # encoding: utf-8
2
2
 
3
3
  require_relative 'simulation/matrix'
4
4
  require_relative 'simulation/dependency'
@@ -1,4 +1,4 @@
1
1
  module YPetri
2
- VERSION = "2.1.18"
2
+ VERSION = "2.1.20"
3
3
  DEBUG = false
4
4
  end
@@ -119,7 +119,7 @@ describe YPetri::Simulation do
119
119
  @sim.ts_tt.first.domain.names.must_equal []
120
120
  @sim.timed?.must_equal false
121
121
  @sim.m.must_equal [1, 2]
122
- @sim.pm.must_equal( { A: 1, B: 2 } )
122
+ @sim.p_m.must_equal( { A: 1, B: 2 } )
123
123
  @sim.recording.must_equal( { 0 => [1, 2]} )
124
124
  @sim.simulation_method.must_equal :pseudo_euler
125
125
  @sim.core.must_be_kind_of YPetri::Core
@@ -133,7 +133,7 @@ describe YPetri::Simulation do
133
133
  cl = @sim.send( :transitions ).ts.delta_closure
134
134
  cl.call.must_equal Matrix[ [1], [0] ]
135
135
  @sim.step!
136
- @sim.pm.must_equal( { A: 2, B: 2 } ) # marking of A goes up by 1
136
+ @sim.p_m.must_equal( { A: 2, B: 2 } ) # marking of A goes up by 1
137
137
  @sim.recording.must_equal( { 0 => [1, 2], 1 => [2, 2] } )
138
138
  end
139
139
  end
@@ -277,7 +277,8 @@ describe "timeless simulation" do
277
277
  .must_equal [2.5, 4.5]
278
278
  -> { ds.interpolate( 1.5 ) }.must_raise TypeError
279
279
  ds.reconstruct( event: 2 )
280
- .pm.must_equal( { U: 2.5, V: 4.5 } )
280
+ .p_m.must_equal( { U: 2.5, V: 4.5 } )
281
+ ds.reconstruct( event: 2 ).must_respond_to( :pm )
281
282
  ds.marking.slice( 2..4 ).series
282
283
  .must_equal [[2.5, 2.5, 2.5], [4.5, 5.5, 6.5]]
283
284
  ds.marking.slice( 2..4 )
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: y_petri
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.18
4
+ version: 2.1.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - boris