y_nelson 0.1.5
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 +7 -0
- data/.gitignore +20 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/lib/y_nelson/dimension.rb +43 -0
- data/lib/y_nelson/dimension_point.rb +15 -0
- data/lib/y_nelson/manipulator.rb +360 -0
- data/lib/y_nelson/net.rb +12 -0
- data/lib/y_nelson/place.rb +28 -0
- data/lib/y_nelson/transition.rb +38 -0
- data/lib/y_nelson/version.rb +4 -0
- data/lib/y_nelson/yzz.rb +11 -0
- data/lib/y_nelson/zz.png +0 -0
- data/lib/y_nelson/zz_point.rb +136 -0
- data/lib/y_nelson.rb +146 -0
- data/test/y_nelson_test.rb +121 -0
- data/test/zz.png +0 -0
- data/y_nelson.gemspec +26 -0
- metadata +121 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0d19c1eb4d0fca009913f2c4632ea803aafee8a0
|
4
|
+
data.tar.gz: 2ae45a24959f7041a7017a0ef44ee1f5023f4b44
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e42a83132fbecca38473d47c05ef1e7ecb3d1e134e517c7eda1c18b79b10df80d1d1340eae7e1e896e0027a3dca2339c35b703fb472ea38c5cf7a1874fd29b19
|
7
|
+
data.tar.gz: 51d15c79f5210d76e936dc0777285dccf7447b2a5faa59013822429798776c06ee092771f285af058d0c302a8cff0e9912fed75b4b87238cf32ba7fc4b344f2b
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 boris
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# YNelson
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'y_nelson'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install y_nelson
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# Zz dimension can in principle be any object, in YNelson, special class
|
3
|
+
# Dimension is used.
|
4
|
+
#
|
5
|
+
class YNelson::Dimension
|
6
|
+
class << self
|
7
|
+
alias __new__ new
|
8
|
+
|
9
|
+
# Presents class-owned instances (array).
|
10
|
+
#
|
11
|
+
def instances
|
12
|
+
return @instances ||= []
|
13
|
+
end
|
14
|
+
|
15
|
+
# The #new constructor is changed, so that same instance is returned for
|
16
|
+
# same constructor arguments.
|
17
|
+
#
|
18
|
+
def new *args
|
19
|
+
instances.find { |ɪ| ɪ.object == args } or
|
20
|
+
__new__( *args ).tap { |ɪ| instances << ɪ }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_reader :object
|
25
|
+
|
26
|
+
# Simply assigns array of arguments to @object atrribute.
|
27
|
+
#
|
28
|
+
def initialize *args
|
29
|
+
@object = args
|
30
|
+
end
|
31
|
+
|
32
|
+
# Short instance description string.
|
33
|
+
#
|
34
|
+
def to_s
|
35
|
+
"#<YNelson::Dimension [#{object.join ', '}]>"
|
36
|
+
end
|
37
|
+
end # class YNelson::Dimension
|
38
|
+
|
39
|
+
# Convenience constructor.
|
40
|
+
#
|
41
|
+
def YNelson.Dimension *args
|
42
|
+
YNelson::Dimension.new *args
|
43
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
|
3
|
+
# A pointer to a zz dimension.
|
4
|
+
#
|
5
|
+
class YNelson::DimensionPoint
|
6
|
+
attr_accessor :dimension
|
7
|
+
|
8
|
+
def initialize dimension
|
9
|
+
@dimension = dimension
|
10
|
+
end
|
11
|
+
|
12
|
+
def default_dimension
|
13
|
+
YNelson.default_dimension
|
14
|
+
end
|
15
|
+
end # class YTed::DimensionPoint
|
@@ -0,0 +1,360 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
# YNelson user inteface. Ted Nelson, in his introduction of zz structures, has
|
3
|
+
# remarks regarding a desired UI, such as:
|
4
|
+
#
|
5
|
+
# <em>Selection</em> is a pointer to a collection of cells.
|
6
|
+
# <em>View</em> consists of selection and a coordinate system.
|
7
|
+
# <em>Field<em> is a connected (contiguous) selection.
|
8
|
+
# <em>Coordinate system</em> is a collection of oriented dimensions.
|
9
|
+
#
|
10
|
+
# Apart from that, this manipulator should offer similar functionality as
|
11
|
+
# YPetri::Manipulator - that is, should allow constructing a Petri net
|
12
|
+
# without much ado about zz aspect, just like YPetri does.
|
13
|
+
#
|
14
|
+
class YNelson::Manipulator
|
15
|
+
attr_reader :workspace
|
16
|
+
|
17
|
+
include YPetri::Manipulator::PetriNetRelatedMethods
|
18
|
+
include YPetri::Manipulator::SimulationRelatedMethods
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
# For YNelson manipulators, the workspace is always YNelson itself.
|
22
|
+
@workspace = ::YNelson
|
23
|
+
super
|
24
|
+
# A hash of sheets. For the moment being, YNelson acts as a spreadsheet.
|
25
|
+
@sheets = {}
|
26
|
+
# Default dimension of this manipulator.
|
27
|
+
@default_dimension = YNelson.Dimension :row
|
28
|
+
# Zz object pointers of this manipulator.
|
29
|
+
@primary_point = YNelson::ZzPoint.new
|
30
|
+
@secondary_point = YNelson::ZzPoint.new
|
31
|
+
# Zz dimension pointers of this manipulator.
|
32
|
+
@primary_dimension_point =
|
33
|
+
YNelson::DimensionPoint.new YNelson.Dimension( :row )
|
34
|
+
@secondary_dimension_point =
|
35
|
+
YNelson::DimensionPoint.new YNelson.Dimension( :column )
|
36
|
+
end
|
37
|
+
|
38
|
+
# Now the part related to the zz structure itself, like in
|
39
|
+
# module YNelson::Manipulator::ZzRelatedMethods
|
40
|
+
# blah blah
|
41
|
+
# end
|
42
|
+
# include YNelson::Manipulator::ZzRelatedMethods
|
43
|
+
|
44
|
+
attr_reader :sheets
|
45
|
+
|
46
|
+
# Dimension convenience constructor from
|
47
|
+
delegate( :Dimension,
|
48
|
+
to: :workspace )
|
49
|
+
|
50
|
+
# Creation of a single-output formula known well from spreadseets. Given a
|
51
|
+
# place, it creates a new assignment transition.
|
52
|
+
#
|
53
|
+
def ϝ &block
|
54
|
+
new_place = YNelson::Place.new
|
55
|
+
new_transition = YNelson::Transition.new assignment: true,
|
56
|
+
codomain: new_place,
|
57
|
+
action: block
|
58
|
+
return new_place, new_transition
|
59
|
+
end
|
60
|
+
|
61
|
+
# Now let's look into the graph visualization.
|
62
|
+
|
63
|
+
def default_dimension; @default_dimension end
|
64
|
+
|
65
|
+
def primary_point; @primary_point end
|
66
|
+
alias p1 primary_point
|
67
|
+
|
68
|
+
def secondary_point; @secondary_point end
|
69
|
+
alias p2 secondary_point
|
70
|
+
|
71
|
+
def primary_dimension_point; @primary_dimension_point end
|
72
|
+
alias d1 primary_dimension_point
|
73
|
+
|
74
|
+
def secondary_dimension_point; @secondary_dimension_point end
|
75
|
+
alias d2 secondary_dimension_point
|
76
|
+
|
77
|
+
# Define function to display it with kioclient
|
78
|
+
def visualize *args, █ graphviz *args, &block end
|
79
|
+
|
80
|
+
# Define graphviz places
|
81
|
+
def graphviz dim1=primary_dimension_point, dim2=secondary_dimension_point
|
82
|
+
γ = GraphViz.new :G, type: :digraph # Create a new graph
|
83
|
+
|
84
|
+
# main = γ.add_nodes( "main", shape: "box" )
|
85
|
+
# parse = γ.add_nodes( "parse", fillcolor: "yellow", style: "rounded,filled", shape: "diamond" )
|
86
|
+
# execute = γ.add_nodes( "execute", shape: "record", label: "{ a | b | c }", style: "rounded" )
|
87
|
+
# init = γ.add_nodes( "init", fillcolor: "yellow", style: "filled" )
|
88
|
+
|
89
|
+
# set global node options
|
90
|
+
γ.node[:color] = "#ddaa66"
|
91
|
+
γ.node[:style] = "filled"
|
92
|
+
γ.node[:shape] = "box"
|
93
|
+
γ.node[:penwidth] = "1"
|
94
|
+
γ.node[:fontname] = "Trebuchet MS"
|
95
|
+
γ.node[:fontsize] = "8"
|
96
|
+
γ.node[:fillcolor] = "#ffeecc"
|
97
|
+
γ.node[:fontcolor] = "#775500"
|
98
|
+
γ.node[:margin] = "0.0"
|
99
|
+
|
100
|
+
# set global edge options
|
101
|
+
γ.edge[:color] = "#999999"
|
102
|
+
γ.edge[:weight] = "1"
|
103
|
+
γ.edge[:fontsize] = "6"
|
104
|
+
γ.edge[:fontcolor] = "#444444"
|
105
|
+
γ.edge[:fontname] = "Verdana"
|
106
|
+
γ.edge[:dir] = "forward"
|
107
|
+
γ.edge[:arrowsize] = "0.5"
|
108
|
+
|
109
|
+
# add zz objects
|
110
|
+
place_nodes = places.map.with_object Hash.new do |place, ꜧ|
|
111
|
+
ꜧ[place] = γ.add_nodes place.name.to_s
|
112
|
+
end
|
113
|
+
transition_nodes = transitions.map.with_object Hash.new do |transition, ꜧ|
|
114
|
+
ꜧ[transition] = γ.add_nodes transition.name.to_s
|
115
|
+
end
|
116
|
+
nodes = place_nodes.merge transition_nodes
|
117
|
+
# add edges for selected dimensions
|
118
|
+
nodes.each { |instance, node|
|
119
|
+
negward_neighbor = instance.( dim1 ).negward.neighbor
|
120
|
+
nodes[ negward_neighbor ] << node if negward_neighbor # color 1
|
121
|
+
negward_neighbor = instance.( dim2 ).negward.neighbor
|
122
|
+
nodes[ negward_neighbor ] << node if negward_neighbor # color 2
|
123
|
+
}
|
124
|
+
|
125
|
+
γ.output png: "zz.png" # Generate output image
|
126
|
+
YSupport::KDE.show_file_with_kioclient File.expand_path( '.', "zz.png" )
|
127
|
+
|
128
|
+
# main = γ.add_nodes( "main", shape: "box" )
|
129
|
+
# parse = γ.add_nodes( "parse", fillcolor: "yellow", style: "rounded,filled", shape: "diamond" )
|
130
|
+
# execute = γ.add_nodes( "execute", shape: "record", label: "{ a | b | c }", style: "rounded" )
|
131
|
+
# init = γ.add_nodes( "init", fillcolor: "yellow", style: "filled" )
|
132
|
+
end
|
133
|
+
|
134
|
+
# graphviz [:domain, 0 ], [:codomain, 0]
|
135
|
+
|
136
|
+
# Cell side referencers with r. to primary and secondary point
|
137
|
+
def ξ_posward_side dim=nil; ::YTed::POINT.posward_side dim end
|
138
|
+
alias :ξp :ξ_posward_side
|
139
|
+
def ξ_negward_side dim=nil; ::YTed::POINT.negward_side dim end
|
140
|
+
alias :ξn :ξ_negward_side
|
141
|
+
def ξ2_posward_side dim=nil; ::YTed::POINT2.posward_side dim end
|
142
|
+
alias :ξ2p :ξ2_posward_side
|
143
|
+
def ξ2_negward_side dim=nil; ::YTed::POINT2.negward_side dim end
|
144
|
+
alias :ξ2n :ξ2_negward_side
|
145
|
+
|
146
|
+
# Point walkers
|
147
|
+
def ξ_step_posward dim=nil; ::YTed::POINT.step_posward dim end
|
148
|
+
alias :ξp! :ξ_step_posward
|
149
|
+
def ξ_step_negward dim=nil; ::YTed::POINT.step_negward dim end
|
150
|
+
alias :ξn! :ξ_step_negward
|
151
|
+
def ξ2_step_posward dim=nil; ::YTed::POINT2.step_posward dim end
|
152
|
+
alias :ξ2p! :ξ2_step_posward
|
153
|
+
def ξ2_step_negward dim=nil; ::YTed::POINT2.step_negward dim end
|
154
|
+
alias :ξ2n! :ξ2_step_negward
|
155
|
+
|
156
|
+
# Point rank rewinders
|
157
|
+
# (rewinders without exclamation mark expect block or return enumerator
|
158
|
+
def ξ_rewind_posward *aa, &b; ::YTed::POINT.rewind_posward *aa, &b end
|
159
|
+
alias :ξrp :ξ_rewind_posward
|
160
|
+
def ξ_rewind_negward *aa, &b; ::YTed::POINT.rewind_negward *aa, &b end
|
161
|
+
alias :ξpp :ξ_rewind_posward
|
162
|
+
def ξ2_rewind_posward *aa, &b; ::YTed::POINT.rewind_posward *aa, &b end
|
163
|
+
alias :ξ2rp :ξ2_rewind_posward
|
164
|
+
def ξ2_rewind_negward *aa, &b; ::YTed::POINT.rewind_negward *aa, &b end
|
165
|
+
alias :ξ2pp :ξ2_rewind_posward
|
166
|
+
|
167
|
+
# Point rak rewinters with exclamation mark (no block or enum, just do it)
|
168
|
+
def ξ_rewind_posward! dim=nil; ::YTed::POINT.rewind_posward! dim end
|
169
|
+
alias :ξrn! :ξ_rewind_posward!
|
170
|
+
alias :ξnn! :ξ_rewind_posward!
|
171
|
+
def ξ_rewind_negward! dim=nil; ::YTed::POINT.rewind_negward! dim end
|
172
|
+
alias :ξrn! :ξ_rewind_negward!
|
173
|
+
alias :ξnn! :ξ_rewind_negward!
|
174
|
+
def ξ2_rewind_posward! dim=nil; ::YTed::POINT2.rewind_posward! dim end
|
175
|
+
alias :ξ2rp! :ξ2_rewind_posward!
|
176
|
+
alias :ξ2pp! :ξ2_rewind_posward!
|
177
|
+
def ξ2_rewind_negward! dim=nil; ::YTed::POINT2.rewind_negward! dim end
|
178
|
+
alias :ξ2rn! :ξ2_rewind_negward!
|
179
|
+
alias :ξ2nn! :ξ2_rewind_negward!
|
180
|
+
|
181
|
+
# Neighbor referencers
|
182
|
+
def ξ_posward_neighbor dim=nil; ::YTed::POINT.posward_neighbor dim end
|
183
|
+
alias :ξP :ξ_posward_neighbor
|
184
|
+
def ξ_negward_neighbor dim=nil; ::YTed::POINT.negward_neighbor dim end
|
185
|
+
alias :ξN :ξ_negward_neighbor
|
186
|
+
def ξ2_posward_neighbor dim=nil; ::YTed::POINT2.posward_neighbor dim end
|
187
|
+
alias :ξ2P :ξ2_posward_neighbor
|
188
|
+
def ξ2_negward_neighbor dim=nil; ::YTed::POINT2.negward_neighbor dim end
|
189
|
+
alias :ξ2N :ξ2_negward_neighbor
|
190
|
+
|
191
|
+
# Neighbor redefinition
|
192
|
+
def ξ_redefine_posward_neighbor *args
|
193
|
+
::YTed::POINT.redefine_posward_neighbor *args end
|
194
|
+
alias :ξP! :ξ_redefine_posward_neighbor
|
195
|
+
def ξ_redefine_negward_neighbor *args
|
196
|
+
::YTed::POINT.redefine_negward_neighbor *args end
|
197
|
+
alias :ξN! :ξ_redefine_negward_neighbor
|
198
|
+
def ξ2_redefine_posward_neighbor *args
|
199
|
+
::YTed::POINT2.redefine_posward_neighbor *args end
|
200
|
+
alias :ξ2P! :ξ2_redefine_posward_neighbor
|
201
|
+
def ξ2_redefine_negward_neighbor *args
|
202
|
+
::YTed::POINT2.redefine_negward_neighbor *args end
|
203
|
+
alias :ξ2N! :ξ2_redefine_negward_neighbor
|
204
|
+
|
205
|
+
|
206
|
+
# FIXME these methods do not work well
|
207
|
+
# #rank method creates a rank of connected cells along the given
|
208
|
+
# dimension (named arg :dimension, alias :dΞ ), from values given as array
|
209
|
+
# (named arg :array, alias :ᴀ). The rank is returned as a cell array.
|
210
|
+
def zz_rank( array, dimension )
|
211
|
+
array.map{ |e| ZzCell( e ) }.each_consecutive_pair{ |a, b|
|
212
|
+
a.redefine_neighbors( dimension: dimension, posward: b )
|
213
|
+
}
|
214
|
+
end
|
215
|
+
|
216
|
+
# Zips an array of ZzCells (receiver) with another array of ZzCells
|
217
|
+
# in a given dimension. That is, each cell in the first array is made
|
218
|
+
# to point (have posward neighbor) to the corresponding cell in the
|
219
|
+
# second array.
|
220
|
+
def zz_zip( cell_array, dimension )
|
221
|
+
cell_array.a℈_all_∈( ::YTed::ZzCell )
|
222
|
+
self.a℈_all_∈( ::YTed::ZzCell ).each.with_index{|cell, i|
|
223
|
+
cell.redefine_neighbors( dimension: dimension,
|
224
|
+
posward: cell_array[i] )
|
225
|
+
}
|
226
|
+
end
|
227
|
+
|
228
|
+
# All we need right now is use Zz as a spreadsheet, writing data in rows.
|
229
|
+
|
230
|
+
# FIXME: Zz properites not used at all - classical Ruby data structures
|
231
|
+
# are used instead. ξ is just a holder for sheet name
|
232
|
+
|
233
|
+
# Creates a new row (rank along :row dimension) zipped to current row
|
234
|
+
# along ξ.dim, using the supplied arguments as new row's cell values.
|
235
|
+
def new_zz_row *args
|
236
|
+
args = args[0].first if args.size == 1 and args[0].is_a? Hash
|
237
|
+
previous_row = ( ::YTed::SHEETS[@current_sheet_name][-1] || [] ).dup
|
238
|
+
row = args.map{ |a| ZzCell( a ) }
|
239
|
+
row.each_consecutive_pair{ |a, b| a.P! x: b } # connect along :x
|
240
|
+
row.each{ |e| e.N! y: previous_row.shift } # zip to previous row
|
241
|
+
::YTed::SHEETS[@current_sheet_name] << row
|
242
|
+
if row[0].value.is_a? Symbol then
|
243
|
+
::YTed::SHEETS[@current_sheet_name]
|
244
|
+
.define_singleton_method args[0] { row[1].aE_kind_of ::YPetri::Place }
|
245
|
+
end
|
246
|
+
end
|
247
|
+
alias :→ :new_zz_row
|
248
|
+
|
249
|
+
# #new_zz_sheet creates a new sheet with a single cell holding the sheet's
|
250
|
+
# name and sets main point to it in :col dimenion sheet name as its value
|
251
|
+
def new_zz_sheet( name )
|
252
|
+
@current_sheet_name = name
|
253
|
+
::YTed::SHEETS[name] = []
|
254
|
+
::YTed::SHEETS
|
255
|
+
.define_singleton_method name.to_sym do ::YTed::SHEETS[name] end
|
256
|
+
return ::YTed::SHEETS[name]
|
257
|
+
end
|
258
|
+
|
259
|
+
def make_transitions
|
260
|
+
# require 'debug'
|
261
|
+
# LATER: When walking around the sheets, currently, there is no
|
262
|
+
# protection against references to empty cells
|
263
|
+
@transitions_to_make.map { |prescription|
|
264
|
+
sheet = prescription[:sheet]
|
265
|
+
type = prescription[:type]
|
266
|
+
place = prescription[:place]
|
267
|
+
block = prescription[:assignment_closure]
|
268
|
+
|
269
|
+
case type
|
270
|
+
when :unary_codomain_w_magic_block
|
271
|
+
# PARAMETER MAGIC:
|
272
|
+
# Blocks with specially named input arguments
|
273
|
+
domain = block.parameters.map{ |e| e[1].to_s }.map{ |param|
|
274
|
+
point = ZzPoint.new( place )
|
275
|
+
if SHEETS.keys.include? sheet_name = param.split('_')[0] then
|
276
|
+
# if the name consists of a sheet and parameter name, then ok
|
277
|
+
rest = param[sheet_name.size + 1..-1]
|
278
|
+
point = ZzPoint.new( SHEETS[sheet_name][0][0] )
|
279
|
+
col = [*('a'..'z')].index rest[0]
|
280
|
+
point.rewind_negward! :x
|
281
|
+
if rest.size > 1 then # also change row, asssuming "a0" style
|
282
|
+
point.rewind_negward! :y
|
283
|
+
row = rest[1..-1].to_i
|
284
|
+
row.times { point.step_posward :y }
|
285
|
+
end
|
286
|
+
col.times { point.step_posward :x }
|
287
|
+
point.cell
|
288
|
+
elsif [*('a'..'z')].include? param[0] then
|
289
|
+
# if the name consists of an alphabetic letter...
|
290
|
+
col = [*('a'..'z')].index param[0]
|
291
|
+
point.rewind_negward! :x
|
292
|
+
if param.size > 1 then # also change row, assuming "a0" style
|
293
|
+
point.rewind_negward! :y
|
294
|
+
row = param[1..-1].to_i
|
295
|
+
row.times { point.step_posward :y }
|
296
|
+
end
|
297
|
+
col.times { point.step_posward :x }
|
298
|
+
point.cell
|
299
|
+
elsif param[0] = '_' then
|
300
|
+
# Params named '_1', '_2', ... refer to different rows, same :col,
|
301
|
+
# param named '__' refers to same cell
|
302
|
+
if param == '__' then cell else
|
303
|
+
i = param[1..-1].to_i
|
304
|
+
point.rewind_negward! :y
|
305
|
+
i.times { point.step_posward :x }
|
306
|
+
point.cell
|
307
|
+
end
|
308
|
+
else
|
309
|
+
raise TypeError, "unrecognized magic block parameter: #{param}"
|
310
|
+
end
|
311
|
+
} # block.parameters.map
|
312
|
+
|
313
|
+
# Instantiate the new transition (do not fire it yet):
|
314
|
+
Transition( domain: domain,
|
315
|
+
codomain: [ place ],
|
316
|
+
action_closure: block,
|
317
|
+
assignment_action: true )
|
318
|
+
when :downstream_copy
|
319
|
+
# DOWNSTREAM COPY
|
320
|
+
# A single transition assigning upstream value to the downstream cell
|
321
|
+
Transition( domain: prescription[:domain],
|
322
|
+
codomain: [ place ],
|
323
|
+
action_closure: λ {|v| v },
|
324
|
+
assignment_action: true )
|
325
|
+
else raise "Unknown transition prescription type: #{prescription[:type]}"
|
326
|
+
end
|
327
|
+
} # @transitions_to_make.map
|
328
|
+
end
|
329
|
+
|
330
|
+
# Places an order for a spreadsheet-like assignment transition. The order
|
331
|
+
# will be fullfilled later when #make_transitions method is called.
|
332
|
+
#
|
333
|
+
def new_downstream_cell &block
|
334
|
+
# The place can be instatiated right away
|
335
|
+
place = ZzCell( nil )
|
336
|
+
|
337
|
+
# Transition making requests get remembered in @transitions_to_make:
|
338
|
+
( @transitions_to_make ||= [] ) <<
|
339
|
+
{ place: place,
|
340
|
+
sheet: @current_sheet_name,
|
341
|
+
assignment_closure: block,
|
342
|
+
type: :unary_codomain_w_magic_block }
|
343
|
+
return place
|
344
|
+
end
|
345
|
+
alias :ϝ :new_downstream_cell
|
346
|
+
|
347
|
+
# Places an order for a spreadsheet-lie pure reference to another cell.
|
348
|
+
#
|
349
|
+
def new_downstream_copy( cell )
|
350
|
+
# Again, the place can be instantiated immediately
|
351
|
+
p = ZzCell( nil )
|
352
|
+
|
353
|
+
# And put the transition making request to @transitions_to_make:
|
354
|
+
( @transitions_to_make ||= [] ) <<
|
355
|
+
{ place: p, sheet: @current_sheet_name, domain: cell,
|
356
|
+
type: :downstream_copy }
|
357
|
+
return p
|
358
|
+
end
|
359
|
+
alias :↱ :new_downstream_copy
|
360
|
+
end
|
data/lib/y_nelson/net.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# Represents Petri nets inside the Nelson net.
|
2
|
+
#
|
3
|
+
class YNelson::Net < YPetri::Net
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
# Place, Transition, Net class
|
8
|
+
#
|
9
|
+
def Place; ::YNelson::Place end
|
10
|
+
def Transition; ::YNelson::Transition end
|
11
|
+
def Net; ::YNelson::Net end
|
12
|
+
end # class YNelson::Net
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# YNelson::Place is analogical to a spreadsheet cell. It is based on
|
2
|
+
# YPetri::Place and offers simlar interace.
|
3
|
+
#
|
4
|
+
class YNelson::Place < YPetri::Place
|
5
|
+
include YNelson::Yzz
|
6
|
+
alias call along # .( :dim ) instead of .along( :dim )
|
7
|
+
|
8
|
+
class << self
|
9
|
+
end
|
10
|
+
|
11
|
+
# Subclass of YTed::Zz::Side.
|
12
|
+
#
|
13
|
+
class Side < Side
|
14
|
+
# "Budding": creation of new cells from the cell sides
|
15
|
+
def bud( value: L!, f: nil )
|
16
|
+
# FIXME
|
17
|
+
end
|
18
|
+
alias :>> :bud
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# Place, Transition, Net class
|
24
|
+
#
|
25
|
+
def Place; ::YNelson::Place end
|
26
|
+
def Transition; ::YNelson::Transition end
|
27
|
+
def Net; ::YNelson::Net end
|
28
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# YNelson::Transition is based on YPetri::Transition and offers similar
|
2
|
+
# interface. "Functions", on which transitions of a functional Petri net
|
3
|
+
# are based, are analogical to 'formulas' of a spreadsheet.
|
4
|
+
#
|
5
|
+
class YNelson::Transition < YPetri::Transition
|
6
|
+
include YNelson::Yzz
|
7
|
+
alias call along # .( :dim ) rather than .along( :dim )
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
# YNelson extends this YPetri::Transition private method, so that a zz
|
12
|
+
# connection is automatically created along dimension [:domain, i] for
|
13
|
+
# i-th domain place of the transition.
|
14
|
+
#
|
15
|
+
def inform_upstream_places
|
16
|
+
upstream_places.each_with_index { |p, i|
|
17
|
+
along( YNelson.Dimension self, :domain, i ) >> p
|
18
|
+
}
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
# YNelson extends this YPetri::Transition private method, so that a zz
|
23
|
+
# connection is autimatically created along along dimension [:codomain, i]
|
24
|
+
# for i-th codomain place of the transition.
|
25
|
+
#
|
26
|
+
def inform_downstream_places
|
27
|
+
downstream_places.each_with_index { |p, i|
|
28
|
+
along( YNelson.Dimension self, :codomain, i ) >> p
|
29
|
+
}
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
# Place, Transition, Net class.
|
34
|
+
#
|
35
|
+
def Place; ::YNelson::Place end
|
36
|
+
def Transition; ::YNelson::Transition end
|
37
|
+
def Net; ::YNelson::Net end
|
38
|
+
end
|
data/lib/y_nelson/yzz.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# Represents Petri nets inside the Nelson net.
|
2
|
+
#
|
3
|
+
module YNelson::Yzz
|
4
|
+
include Yzz
|
5
|
+
|
6
|
+
def along *args
|
7
|
+
return super( args[0] ) if
|
8
|
+
args.size == 1 && args[0].is_a?( ::YNelson::Dimension )
|
9
|
+
super( ::YNelson.Dimension *args )
|
10
|
+
end
|
11
|
+
end # module YzzPrepend
|
data/lib/y_nelson/zz.png
ADDED
Binary file
|
@@ -0,0 +1,136 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
|
3
|
+
# A pointer to a Zz object. A glorified variable, basically.
|
4
|
+
#
|
5
|
+
class YNelson::ZzPoint
|
6
|
+
attr_accessor :zz
|
7
|
+
|
8
|
+
# Initialization has one optional argument :zz -- zz object at which the
|
9
|
+
# point should be initialized.
|
10
|
+
#
|
11
|
+
def initialize( zz: nil )
|
12
|
+
@zz = zz
|
13
|
+
end
|
14
|
+
|
15
|
+
delegate :marking, :value, :υ,
|
16
|
+
:marking=, :value=, :υ=,
|
17
|
+
:test_arcs, :codomain, :downstream_transitions,
|
18
|
+
:action_arcs, :domain, :upstream_transitions, :ϝ, # digamma: ϝ
|
19
|
+
:arcs, # :connectivity alias not delegated to avoid confusion
|
20
|
+
:upstream_places, # :precedents, :← not delegated, same reason
|
21
|
+
:downstream_places, # :dependents, :→ aliases not delegated
|
22
|
+
to: :zz
|
23
|
+
alias :v :value
|
24
|
+
|
25
|
+
def default_dimension; YNelson.primary_dimension end
|
26
|
+
|
27
|
+
# Quasi-delegation to zz
|
28
|
+
|
29
|
+
def along dimension=default_dimension
|
30
|
+
zz.along dimension
|
31
|
+
end
|
32
|
+
|
33
|
+
def posward( along: default_dimension )
|
34
|
+
along( along ).posward
|
35
|
+
end
|
36
|
+
alias p posward
|
37
|
+
|
38
|
+
def negward( along: default_dimension )
|
39
|
+
along( along ).negward_side
|
40
|
+
end
|
41
|
+
alias n negward
|
42
|
+
|
43
|
+
def posward_neighbor( along: default_dimension )
|
44
|
+
posward( along: along ).neighbor
|
45
|
+
end
|
46
|
+
alias P posward_neighbor
|
47
|
+
|
48
|
+
def negward_neighbor( along: default_dimension )
|
49
|
+
negward( along: along ).neighbor
|
50
|
+
end
|
51
|
+
alias N negward_neighbor
|
52
|
+
|
53
|
+
def redefine_posward_neighbor( neighbor, along: default_dimension )
|
54
|
+
posward( along: along ) << neighbor
|
55
|
+
end
|
56
|
+
alias P! :redefine_posward_neighbor
|
57
|
+
|
58
|
+
def redefine_negward_neighbor( neighbor, along: default_dimension )
|
59
|
+
negward( along: along ) << neighbor
|
60
|
+
end
|
61
|
+
alias N! :redefine_negward_neighbor
|
62
|
+
|
63
|
+
def bud_posward( value=nil, along: default_dimension )
|
64
|
+
posward( along: along ).bud value
|
65
|
+
end
|
66
|
+
alias bud bud_posward
|
67
|
+
|
68
|
+
def bud_negward( value=nil, along: default_dimension )
|
69
|
+
negward( along: along ).bud value
|
70
|
+
end
|
71
|
+
|
72
|
+
def rank( along: default_dimension )
|
73
|
+
zz.get_rank along: along
|
74
|
+
end
|
75
|
+
|
76
|
+
# Walkers
|
77
|
+
|
78
|
+
def step_posward( along: default_dimension )
|
79
|
+
neighbor = posward_neighbor along: along
|
80
|
+
if neighbor.is_a_zz? then @zz = neighbor else false end
|
81
|
+
end
|
82
|
+
alias step step_posward
|
83
|
+
alias p! step_posward
|
84
|
+
|
85
|
+
def step_negward( along: default_dimension )
|
86
|
+
neighbor = negward_neighbor along: along
|
87
|
+
if neighbor.is_a_zz? then @zz = neighbor else false end
|
88
|
+
end
|
89
|
+
alias n! step_negward
|
90
|
+
|
91
|
+
# Rewinders
|
92
|
+
|
93
|
+
def rewind_posward( along: default_dimension )
|
94
|
+
origin = zz
|
95
|
+
if block_given? then
|
96
|
+
loop { yield zz
|
97
|
+
return :end unless posward_neighbor( along: along ).is_a_zz?
|
98
|
+
return :loop if posward_neighbor( along: along ) == origin
|
99
|
+
step_posward along: along }
|
100
|
+
else # no block given, returns enumerator
|
101
|
+
Enumerator.new { |y|
|
102
|
+
loop { y << zz
|
103
|
+
break :end unless posward_neighbor( along: along ).is_a_zz?
|
104
|
+
break :loop if posward_neighbor( along: along ) == origin
|
105
|
+
step_posward along: along }
|
106
|
+
}
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def rewind_negward( along: default_dimension )
|
111
|
+
origin = zz
|
112
|
+
if block_given? then
|
113
|
+
loop { yield zz
|
114
|
+
return :end unless negward_neighbor( along: along ).is_a_zz?
|
115
|
+
return :loop if negward_neighbor( along: along ) == origin
|
116
|
+
step_negward along: along }
|
117
|
+
else
|
118
|
+
Enumerator.new { |y|
|
119
|
+
loop { y << zz
|
120
|
+
break :end unless negward_neighbor( along: along ).is_a_zz?
|
121
|
+
break :loop if negward_neighbor( along: along ) == origin
|
122
|
+
step_negward along: along }
|
123
|
+
}
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Simple unconditional rewind.
|
128
|
+
|
129
|
+
def rewind_posward!( along: default_dimension )
|
130
|
+
rewind_posward( along: along ) {} # implemented using empty block
|
131
|
+
end
|
132
|
+
|
133
|
+
def rewind_negward!( along: default_dimension )
|
134
|
+
rewind_negward( along: along ) {}
|
135
|
+
end
|
136
|
+
end # class YNelson::ZzPoint
|
data/lib/y_nelson.rb
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'yzz'
|
3
|
+
require 'y_petri'
|
4
|
+
require 'y_support/kde'
|
5
|
+
|
6
|
+
require 'graphviz'
|
7
|
+
|
8
|
+
require_relative 'y_nelson/version'
|
9
|
+
require_relative 'y_nelson/yzz'
|
10
|
+
require_relative 'y_nelson/dimension'
|
11
|
+
require_relative 'y_nelson/place'
|
12
|
+
require_relative 'y_nelson/transition'
|
13
|
+
require_relative 'y_nelson/net'
|
14
|
+
require_relative 'y_nelson/zz_point'
|
15
|
+
require_relative 'y_nelson/dimension_point'
|
16
|
+
require_relative 'y_nelson/manipulator'
|
17
|
+
|
18
|
+
# YNelson is an implementation of a cross between Ted Nelson's Zz structure, and
|
19
|
+
# a functional Petri net (FPN). The resulting data structure, which combines
|
20
|
+
# qualities of FPNs with those of relational databases, I refer to as Nelson net
|
21
|
+
# throughout this text.
|
22
|
+
#
|
23
|
+
# One way to understand Nelson nets is as a genralization of a spreadsheet. In
|
24
|
+
# his explanations of Zz structures, Ted Nelson makes wide use of spreadsheet
|
25
|
+
# metaphors: cells, ranks, rows, columns, cursors, selections... Nelson net
|
26
|
+
# implemented here adds "formulas" to the mix, represented by FPN transitions.
|
27
|
+
#
|
28
|
+
# Nelson net disposes of the arbitrary constraints on FPNs as well as the
|
29
|
+
# orthogonal structure of "cells" seen in most practical spreadsheet
|
30
|
+
# implementations:
|
31
|
+
#
|
32
|
+
# 1. Both places and transitions of the FPN take part in zz structure.
|
33
|
+
# 2. Formula-based transitions are upgraded to standalone FPN transitions.
|
34
|
+
#
|
35
|
+
# The implications of the zz structure differences from ordinary hyperorthogonal
|
36
|
+
# structures hav been, to a degree, explained by Ted Nelson himself. There is a
|
37
|
+
# growing body of literature on zz structure applications, including in
|
38
|
+
# bioinformatics.
|
39
|
+
#
|
40
|
+
# As for functional Petri nets, their power in computing is well recognized (eg.
|
41
|
+
# Funnel, Odersky 2000). FPNs are sometimes just called functional nets, because
|
42
|
+
# Petri originally described his nets as timeless and functionless. However, in
|
43
|
+
# special-purpose applications, such as biochemical applications, to which I
|
44
|
+
# incline, it is appropriate to honor Petri, who designed his nets specifically
|
45
|
+
# with chemical modeling in mind as one of their main applications. In
|
46
|
+
# biochemistry, it is common to call functional nets Petri nets (Miyano, 200?).
|
47
|
+
#
|
48
|
+
module YNelson
|
49
|
+
# Singleton class of YNelson is partial descendant of YPetri::Workspace. More
|
50
|
+
# specifically, it mixes in most YPetri::Workspace instance methods and
|
51
|
+
# provides interface, which should be a superset of YPetri::Workspace. The
|
52
|
+
# difference is, that while YPetri::Workspace can have multiple instances,
|
53
|
+
# representing workdesks, YNelson is a singleton representing relational
|
54
|
+
# database.
|
55
|
+
#
|
56
|
+
class << self
|
57
|
+
# YNelson metaclass includes instance methods of YPetri::Workspace.
|
58
|
+
include YPetri::Workspace::PetriNetRelatedMethods
|
59
|
+
include YPetri::Workspace::SimulationRelatedMethods
|
60
|
+
|
61
|
+
# Allows summoning DSL by 'include YNelson' (like YPetri does).
|
62
|
+
#
|
63
|
+
def included receiver
|
64
|
+
# receiver.instance_variable_set :@NelsonManipulator, Manipulator.new
|
65
|
+
# puts "included in #{receiver}"
|
66
|
+
receiver.module_exec {
|
67
|
+
define_method :nelson_manipulator do
|
68
|
+
singleton_class.instance_variable_get :@NelsonManipulator or
|
69
|
+
( puts "defining Manipulator for #{self} singleton class" if YNelson::DEBUG
|
70
|
+
singleton_class.instance_variable_set :@NelsonManipulator, Manipulator.new )
|
71
|
+
end
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def dimensions; @dimensions end
|
76
|
+
end # class << self
|
77
|
+
|
78
|
+
# Instance variables @Place, @Transition, @Net are expected by
|
79
|
+
# YPetri::Workspace module.
|
80
|
+
@Place, @Transition, @Net = self::Place, self::Transition, self::Net
|
81
|
+
|
82
|
+
# Atypical call to #initialize in the course of module execution.
|
83
|
+
initialize
|
84
|
+
|
85
|
+
delegate( :workspace, to: :nelson_manipulator )
|
86
|
+
|
87
|
+
# Petri net aspect.
|
88
|
+
delegate( :Place, :Transition, :Net,
|
89
|
+
:place, :transition, :pl, :tr,
|
90
|
+
:places, :transitions, :nets,
|
91
|
+
:pp, :tt, :nn,
|
92
|
+
:net_point,
|
93
|
+
:net_selection,
|
94
|
+
:net, :ne,
|
95
|
+
:net_point_reset,
|
96
|
+
:net_point_set,
|
97
|
+
to: :nelson_manipulator )
|
98
|
+
|
99
|
+
# Simulation aspect.
|
100
|
+
delegate( :simulation_point, :ssc_point, :cc_point, :imc_point,
|
101
|
+
:simulation_selection, :ssc_selection,
|
102
|
+
:cc_selection, :imc_selection,
|
103
|
+
:simulations,
|
104
|
+
:clamp_collections,
|
105
|
+
:initial_marking_collections,
|
106
|
+
:simulation_settings_collections,
|
107
|
+
:clamp_collection_names, :cc_names,
|
108
|
+
:initial_marking_collection_names, :imc_names,
|
109
|
+
:simulation_settings_collection_names, :ssc_names,
|
110
|
+
:set_clamp_collection, :set_cc,
|
111
|
+
:set_initial_marking_collection, :set_imc,
|
112
|
+
:set_simulation_settings_collection, :set_ssc,
|
113
|
+
:new_timed_simulation,
|
114
|
+
:clamp_cc, :initial_marking_cc, :simulation_settings_cc,
|
115
|
+
:simulation_point_position,
|
116
|
+
:simulation,
|
117
|
+
:clamp_collection, :cc,
|
118
|
+
:initial_marking_collection, :imc,
|
119
|
+
:simulation_settings_collection, :ssc,
|
120
|
+
:clamp,
|
121
|
+
:initial_marking,
|
122
|
+
:set_step, :set_step_size,
|
123
|
+
:set_time, :set_target_time,
|
124
|
+
:set_sampling,
|
125
|
+
:set_simulation_method,
|
126
|
+
:new_timed_simulation,
|
127
|
+
:run!,
|
128
|
+
:print_recording,
|
129
|
+
:plot,
|
130
|
+
:plot_selected,
|
131
|
+
:plot_state,
|
132
|
+
:plot_flux,
|
133
|
+
to: :nelson_manipulator )
|
134
|
+
|
135
|
+
# Zz aspect.
|
136
|
+
delegate( :Dimension,
|
137
|
+
:ϝ,
|
138
|
+
:default_dimension,
|
139
|
+
:primary_point, :p1,
|
140
|
+
:secondary_point, :p2,
|
141
|
+
:primary_dimension_point, :d1,
|
142
|
+
:secondary_dimension_point, :d2,
|
143
|
+
:visualize,
|
144
|
+
:graphviz,
|
145
|
+
to: :nelson_manipulator )
|
146
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
require 'minitest/spec'
|
5
|
+
require 'minitest/autorun'
|
6
|
+
# tested component itself
|
7
|
+
require './../lib/y_nelson'
|
8
|
+
|
9
|
+
# **************************************************************************
|
10
|
+
# Nelson net test
|
11
|
+
# **************************************************************************
|
12
|
+
#
|
13
|
+
describe YNelson do
|
14
|
+
before do
|
15
|
+
skip
|
16
|
+
@m = YNelson::Manipulator.new
|
17
|
+
@p = @m.Place default_marking: 3.2,
|
18
|
+
marking: 1.1,
|
19
|
+
quantum: 0.1
|
20
|
+
end
|
21
|
+
|
22
|
+
describe YNelson::Dimension do
|
23
|
+
it "should give same instance for same object" do
|
24
|
+
assert_equal YNelson.Dimension( :xxx ), @m.Dimension( :xxx )
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "new transition form correct zz connections with places" do
|
29
|
+
it "should work as expected" do
|
30
|
+
assert_equal [], @p.neighbors
|
31
|
+
assert_equal [], @p.connectivity # 'connectivity' now exclusively a zz keyword
|
32
|
+
t = @m.Transition codomain: @p, action: lambda { 0.1 }, assignment: true
|
33
|
+
assert_equal [ @p ], t.neighbors
|
34
|
+
dim = @m.Dimension( :codomain, 0 )
|
35
|
+
assert_equal @p, t.along( dim ).posward.neighbor
|
36
|
+
# And then, it would be the job of dimension reduction to determine if
|
37
|
+
# some dimensions should be visualized or otherwise used together.
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should work" do
|
42
|
+
# TODO:
|
43
|
+
# has point
|
44
|
+
# has dimension point
|
45
|
+
# can create places
|
46
|
+
@m.Place
|
47
|
+
# can remove places
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "small Nelson net" do
|
51
|
+
before do
|
52
|
+
# TODO:
|
53
|
+
# Create a net of several places and transition
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should work" do
|
57
|
+
# TODO:
|
58
|
+
# exercise the created Nelson net to make sure it works
|
59
|
+
# #set_posward_neighbor
|
60
|
+
# #set_negward_neighbor
|
61
|
+
# #along, #posward, #negward, etc...
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe YNelson::ZzPoint do
|
67
|
+
it "should work" do
|
68
|
+
# TODO
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe YNelson::DimensionPoint do
|
73
|
+
it "should work" do
|
74
|
+
# TODO
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "visualization" do
|
79
|
+
before do
|
80
|
+
@m = YNelson::Manipulator.new
|
81
|
+
@m.Place name: :A, m!: 3.2
|
82
|
+
@m.Place name: :B, m!: 5
|
83
|
+
@m.Transition name: :T1, s: { A: -1, B: 1 }, rate: 1
|
84
|
+
@m.Place name: :C, m!: 7.0
|
85
|
+
@m.Transition name: :T2, s: { B: -1, C: 1 }, rate: 1
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should work" do
|
89
|
+
dim1 = YNelson::Dimension( :domain, 0 )
|
90
|
+
dim2 = YNelson::Dimension( :codomain, 1 )
|
91
|
+
@m.visualize dim1, dim2
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# describe "zz structure with a transition or two" do
|
96
|
+
# before do
|
97
|
+
# new_zz_sheet "koko"
|
98
|
+
# @c1, @c2, @c3 = ZzCell( 1 ), ZzCell( 2 ), ZzCell( 3 )
|
99
|
+
# new_zz_row @c1, @c2, @c3
|
100
|
+
# @c4 = ϝ { |a0, b0, c0| a0 + b0 + c0 }
|
101
|
+
# new_zz_row @c4
|
102
|
+
# end
|
103
|
+
|
104
|
+
# it "should have #make_transitions" do
|
105
|
+
# tt = make_transitions
|
106
|
+
# assert_equal 1, tt.size
|
107
|
+
# t = tt[0]
|
108
|
+
# assert_kind_of ::YPetri::Transition, t
|
109
|
+
# assert t.domain.include? @c1
|
110
|
+
# assert t.domain.include? @c2
|
111
|
+
# assert t.domain.include? @c3
|
112
|
+
# assert_equal nil, @c4.marking
|
113
|
+
# t.fire!
|
114
|
+
# assert_equal 6, @c4.marking
|
115
|
+
# new_zz_sheet "pipi"
|
116
|
+
# @c5 = ϝ { |koko_a0, koko_b0| koko_a0 + koko_b0 }
|
117
|
+
# tt = make_transitions
|
118
|
+
# tt.each &:fire!
|
119
|
+
# assert_equal 3, @c5.value
|
120
|
+
# end
|
121
|
+
# end
|
data/test/zz.png
ADDED
Binary file
|
data/y_nelson.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'y_nelson/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "y_nelson"
|
8
|
+
spec.version = YNelson::VERSION
|
9
|
+
spec.authors = ["boris"]
|
10
|
+
spec.email = ["\"boris@iis.sinica.edu.tw\""]
|
11
|
+
spec.description = %q{Formalization and generalization of a spreadsheet.}
|
12
|
+
spec.summary = %q{A fusion of functional Petri net with a zz structure.}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency 'yzz'
|
22
|
+
spec.add_dependency 'y_petri'
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: y_nelson
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- boris
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-05-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: yzz
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: y_petri
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Formalization and generalization of a spreadsheet.
|
70
|
+
email:
|
71
|
+
- '"boris@iis.sinica.edu.tw"'
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- .gitignore
|
77
|
+
- Gemfile
|
78
|
+
- LICENSE.txt
|
79
|
+
- README.md
|
80
|
+
- Rakefile
|
81
|
+
- lib/y_nelson.rb
|
82
|
+
- lib/y_nelson/dimension.rb
|
83
|
+
- lib/y_nelson/dimension_point.rb
|
84
|
+
- lib/y_nelson/manipulator.rb
|
85
|
+
- lib/y_nelson/net.rb
|
86
|
+
- lib/y_nelson/place.rb
|
87
|
+
- lib/y_nelson/transition.rb
|
88
|
+
- lib/y_nelson/version.rb
|
89
|
+
- lib/y_nelson/yzz.rb
|
90
|
+
- lib/y_nelson/zz.png
|
91
|
+
- lib/y_nelson/zz_point.rb
|
92
|
+
- test/y_nelson_test.rb
|
93
|
+
- test/zz.png
|
94
|
+
- y_nelson.gemspec
|
95
|
+
homepage: ''
|
96
|
+
licenses:
|
97
|
+
- MIT
|
98
|
+
metadata: {}
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - '>='
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
requirements: []
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 2.0.3
|
116
|
+
signing_key:
|
117
|
+
specification_version: 4
|
118
|
+
summary: A fusion of functional Petri net with a zz structure.
|
119
|
+
test_files:
|
120
|
+
- test/y_nelson_test.rb
|
121
|
+
- test/zz.png
|