Class: YNelson::Agent

Inherits:
Object
  • Object
show all
Defined in:
lib/y_nelson/agent.rb

Overview

YNelson’s user inteface. As the name suggests, represents an agent that manipulates the YNelson world. In his introduction to zz structures, Ted Nelson has remarks regarding the desired UI, such as:

Selection is a pointer to a collection of cells. View consists of selection and a coordinate system. Field<em> is a connected (contiguous) selection. <em>Coordinate system is a collection of oriented dimensions.

Apart from these author’s suggestions, the interface should offer similar functionality as YPetri::Agent – that is, should allow constructing a Petri net with the same commands as YPetri does.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeAgent

Initialization of a YNelson::Agent instance. For YNelson manipulators, the world is always YNelson itself.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/y_nelson/agent.rb', line 31

def initialize
  @world = ::YNelson
  super
  # A hash of sheets. (For the moment being, YNelson acts like a spreadsheet.)
  @sheets = {}
  # Default dimension of this manipulator.
  @default_dimension = YNelson.Dimension( :row )
  # Zz object pointers of this manipulator.
  @primary_point = YNelson::ZzPoint.new
  @secondary_point = YNelson::ZzPoint.new
  # Zz dimension pointers of this manipulator.
  @primary_dimension_point =
    YNelson::DimensionPoint.new YNelson.Dimension( :row )
  @secondary_dimension_point =
    YNelson::DimensionPoint.new YNelson.Dimension( :column )
  @todo = [] # array of blocks
end

Instance Attribute Details

#sheetsObject (readonly)

Now the part related to the zz structure itself, like in module YNelson::Manipulator::ZzRelatedMethods

blah blah

end include YNelson::Manipulator::ZzRelatedMethods



55
56
57
# File 'lib/y_nelson/agent.rb', line 55

def sheets
  @sheets
end

#worldObject (readonly)

Returns the value of attribute world.



17
18
19
# File 'lib/y_nelson/agent.rb', line 17

def world
  @world
end

Instance Method Details

#default_dimensionObject

Now let’s look into the graph visualization.



63
64
65
# File 'lib/y_nelson/agent.rb', line 63

def default_dimension
  @default_dimension
end

#finalizeObject

Executes all @todo closures.



186
187
188
189
190
191
# File 'lib/y_nelson/agent.rb', line 186

def finalize
  while not @todo.empty?
    @todo[-1].call # May raise errors in which case we don't want to pop.
    @todo.pop      # That's why not @todo.pop.call while not @todo.empty?
  end
end

#graphviz(dim1 = primary_dimension_point, dim2 = secondary_dimension_point) ⇒ Object

Define graphviz places.



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/y_nelson/agent.rb', line 95

def graphviz dim1=primary_dimension_point, dim2=secondary_dimension_point
  γ = GraphViz.new :G, type: :digraph  # Create a new graph

  # main        = γ.add_nodes( "main", shape: "box" )
  # parse       = γ.add_nodes( "parse", fillcolor: "yellow", style: "rounded,filled", shape: "diamond" )
  # execute     = γ.add_nodes( "execute", shape: "record", label: "{ a | b | c }", style: "rounded" )
  # init        = γ.add_nodes( "init", fillcolor: "yellow", style: "filled" )

  # set global node options
  γ.node[:color] = "#ddaa66"
  γ.node[:style] = "filled"
  γ.node[:shape] = "box"
  γ.node[:penwidth] = "1"
  γ.node[:fontname] = "Trebuchet MS"
  γ.node[:fontsize] = "8"
  γ.node[:fillcolor] = "#ffeecc"
  γ.node[:fontcolor] = "#775500"
  γ.node[:margin] = "0.0"

  # set global edge options
  γ.edge[:color] = "#999999"
  γ.edge[:weight] = "1"
  γ.edge[:fontsize] = "6"
  γ.edge[:fontcolor] = "#444444"
  γ.edge[:fontname] = "Verdana"
  γ.edge[:dir] = "forward"
  γ.edge[:arrowsize] = "0.5"

  # add zz objects
  place_nodes = places.map.with_object Hash.new do |place, |
    [place] = γ.add_nodes place.name.to_s
  end
  transition_nodes = transitions.map.with_object Hash.new do |transition, |
    [transition] = γ.add_nodes transition.name.to_s
  end
  nodes = place_nodes.merge transition_nodes
  # add edges for selected dimensions
  nodes.each { |instance, node|
    negward_neighbor = instance.( dim1 ).negward.neighbor
    nodes[ negward_neighbor ] << node if negward_neighbor # color 1
    negward_neighbor = instance.( dim2 ).negward.neighbor
    nodes[ negward_neighbor ] << node if negward_neighbor # color 2
  }

  γ.output png: "zz.png"        # Generate output image

  # The last line only works on KDE systems.
  show_file_with_kioclient File.expand_path( '.', "zz.png" )

  # main        = γ.add_nodes( "main", shape: "box" )
  # parse       = γ.add_nodes( "parse", fillcolor: "yellow", style: "rounded,filled", shape: "diamond" )
  # execute     = γ.add_nodes( "execute", shape: "record", label: "{ a | b | c }", style: "rounded" )
  # init        = γ.add_nodes( "init", fillcolor: "yellow", style: "filled" )
end

#new_simulation(*args) ⇒ Object

Calls #finalize before invoking YPetri::Agent#new_simulation.



26
# File 'lib/y_nelson/agent.rb', line 26

def new_simulation *args; finalize; super end

#new_zz_row(*args) ⇒ Object Also known as:

Creates a new row (rank along :row dimension) zipped to current row along ξ.dim, using the supplied arguments as new row’s cell values.



297
298
299
300
301
302
303
304
305
306
307
308
# File 'lib/y_nelson/agent.rb', line 297

def new_zz_row *args
  args = args[0].first if args.size == 1 and args[0].is_a? Hash
  previous_row = ( ::YTed::SHEETS[@current_sheet_name][-1] || [] ).dup
  row = args.map{ |a| ZzCell( a ) }
  row.each_consecutive_pair{ |a, b| a.P! x: b } # connect along :x
  row.each{ |e| e.N! y: previous_row.shift } # zip to previous row
  ::YTed::SHEETS[@current_sheet_name] << row
  if row[0].value.is_a? Symbol then
    ::YTed::SHEETS[@current_sheet_name]
      .define_singleton_method args[0] { row[1].aE_kind_of ::YPetri::Place }
  end
end

#new_zz_sheet(name) ⇒ Object

#new_zz_sheet creates a new sheet with a single cell holding the sheet’s name and sets main point to it in :col dimenion sheet name as its value



313
314
315
316
317
318
319
# File 'lib/y_nelson/agent.rb', line 313

def new_zz_sheet( name )
  @current_sheet_name = name
  ::YTed::SHEETS[name] = []
  ::YTed::SHEETS
    .define_singleton_method name.to_sym do ::YTed::SHEETS[name] end
  return ::YTed::SHEETS[name]
end

#PAT(*domain, **named_args, &block) ⇒ Object Also known as: ϝ

Creation of a place governed by a single assignment transition. In other words, creation of a place with a unary-output formula known well from spreadsheets. The transition is named automatically by adding “_ϝ” (digamma, resembles mathematical f used to denote functions) suffix to the place’s name, as soon as the place is named. For example,

Fred = PAT Joe do |joe| joe * 2 end

creates a place named “Fred” and an assignment transition named “Fred_ϝ” that keeps Fred equal to 2 times Joe.



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/y_nelson/agent.rb', line 164

def PAT *domain, **named_args, &block
  Place().tap do |p| # place can be instantiated right away
    p.name = named_args.delete :name if named_args.has? :name, syn!: 
    @todo << -> {
      t = AT p, domain: domain, &block
      if p.name then t.name = "#{p.name}" else
        # Rig the hook to name the transition as soon as the place is named.
        p.name_set_hook do |name| transition.name = "#{name}" end
      end
      # Monkey-patch the place with default marking closure.
      p.define_singleton_method :default_marking do
        if has_default_marking? then local_variable_get :@default_marking else
          t.action_closure.( *t.domain.map( &:default_marking ) )
        end
      end
    }
  end
end

#primary_dimension_pointObject Also known as: d1



77
78
79
# File 'lib/y_nelson/agent.rb', line 77

def primary_dimension_point
  @primary_dimension_point
end

#primary_pointObject Also known as: p1



67
68
69
# File 'lib/y_nelson/agent.rb', line 67

def primary_point
  @primary_point
end

#secondary_dimension_pointObject Also known as: d2



82
83
84
# File 'lib/y_nelson/agent.rb', line 82

def secondary_dimension_point
  @secondary_dimension_point
end

#secondary_pointObject Also known as: p2



72
73
74
# File 'lib/y_nelson/agent.rb', line 72

def secondary_point
  @secondary_point
end

#visualize(*args, &block) ⇒ Object

Define function to display it with kioclient.



89
90
91
# File 'lib/y_nelson/agent.rb', line 89

def visualize *args, &block
  graphviz *args, &block
end

#zz_rank(array, dimension) ⇒ Object

FIXME these methods do not work well #rank method creates a rank of connected cells along the given dimension (named arg :dimension, alias :dΞ ), from values given as array (named arg :array, alias :ᴀ). The rank is returned as a cell array.



272
273
274
275
276
# File 'lib/y_nelson/agent.rb', line 272

def zz_rank( array, dimension )
  array.map{ |e| ZzCell( e ) }.each_consecutive_pair{ |a, b|
    a.redefine_neighbors( dimension: dimension, posward: b )
  }
end

#zz_zip(cell_array, dimension) ⇒ Object

Zips an array of ZzCells (receiver) with another array of ZzCells in a given dimension. That is, each cell in the first array is made to point (have posward neighbor) to the corresponding cell in the second array.



282
283
284
285
286
287
288
# File 'lib/y_nelson/agent.rb', line 282

def zz_zip( cell_array, dimension )
  cell_array.a℈_all_∈( ::YTed::ZzCell )
  self.a℈_all_∈( ::YTed::ZzCell ).each.with_index{|cell, i|
    cell.redefine_neighbors( dimension: dimension,
                             posward: cell_array[i] )
  }
end

#ξ2_negward_neighbor(dim = nil) ⇒ Object Also known as: ξ2N



250
# File 'lib/y_nelson/agent.rb', line 250

def ξ2_negward_neighbor dim=nil; ::YTed::POINT2.negward_neighbor dim end

#ξ2_negward_side(dim = nil) ⇒ Object Also known as: ξ2n



205
# File 'lib/y_nelson/agent.rb', line 205

def ξ2_negward_side dim=nil; ::YTed::POINT2.negward_side dim end

#ξ2_posward_neighbor(dim = nil) ⇒ Object Also known as: ξ2P



248
# File 'lib/y_nelson/agent.rb', line 248

def ξ2_posward_neighbor dim=nil; ::YTed::POINT2.posward_neighbor dim end

#ξ2_posward_side(dim = nil) ⇒ Object Also known as: ξ2p



203
# File 'lib/y_nelson/agent.rb', line 203

def ξ2_posward_side dim=nil; ::YTed::POINT2.posward_side dim end

#ξ2_redefine_negward_neighbor(*args) ⇒ Object Also known as: ξ2N!



263
264
# File 'lib/y_nelson/agent.rb', line 263

def ξ2_redefine_negward_neighbor *args
::YTed::POINT2.redefine_negward_neighbor *args end

#ξ2_redefine_posward_neighbor(*args) ⇒ Object Also known as: ξ2P!



260
261
# File 'lib/y_nelson/agent.rb', line 260

def ξ2_redefine_posward_neighbor *args
::YTed::POINT2.redefine_posward_neighbor *args end

#ξ2_rewind_negward(*aa, &b) ⇒ Object



226
# File 'lib/y_nelson/agent.rb', line 226

def ξ2_rewind_negward *aa, &b; ::YTed::POINT.rewind_negward *aa, &b end

#ξ2_rewind_negward!(dim = nil) ⇒ Object Also known as: ξ2rn!, ξ2nn!



239
# File 'lib/y_nelson/agent.rb', line 239

def ξ2_rewind_negward! dim=nil; ::YTed::POINT2.rewind_negward! dim end

#ξ2_rewind_posward(*aa, &b) ⇒ Object Also known as: ξ2rp, ξ2pp



224
# File 'lib/y_nelson/agent.rb', line 224

def ξ2_rewind_posward *aa, &b; ::YTed::POINT.rewind_posward *aa, &b end

#ξ2_rewind_posward!(dim = nil) ⇒ Object Also known as: ξ2rp!, ξ2pp!



236
# File 'lib/y_nelson/agent.rb', line 236

def ξ2_rewind_posward! dim=nil; ::YTed::POINT2.rewind_posward! dim end

#ξ2_step_negward(dim = nil) ⇒ Object Also known as: ξ2n!



215
# File 'lib/y_nelson/agent.rb', line 215

def ξ2_step_negward dim=nil; ::YTed::POINT2.step_negward dim end

#ξ2_step_posward(dim = nil) ⇒ Object Also known as: ξ2p!



213
# File 'lib/y_nelson/agent.rb', line 213

def ξ2_step_posward dim=nil; ::YTed::POINT2.step_posward dim end

#ξ_negward_neighbor(dim = nil) ⇒ Object Also known as: ξN



246
# File 'lib/y_nelson/agent.rb', line 246

def ξ_negward_neighbor dim=nil; ::YTed::POINT.negward_neighbor dim end

#ξ_negward_side(dim = nil) ⇒ Object Also known as: ξn



201
# File 'lib/y_nelson/agent.rb', line 201

def ξ_negward_side dim=nil; ::YTed::POINT.negward_side dim end

#ξ_posward_neighbor(dim = nil) ⇒ Object Also known as: ξP

Neighbor referencers



244
# File 'lib/y_nelson/agent.rb', line 244

def ξ_posward_neighbor dim=nil; ::YTed::POINT.posward_neighbor dim end

#ξ_posward_side(dim = nil) ⇒ Object Also known as: ξp

Cell side referencers with r. to primary and secondary point



199
# File 'lib/y_nelson/agent.rb', line 199

def ξ_posward_side dim=nil; ::YTed::POINT.posward_side dim end

#ξ_redefine_negward_neighbor(*args) ⇒ Object Also known as: ξN!



257
258
# File 'lib/y_nelson/agent.rb', line 257

def ξ_redefine_negward_neighbor *args
::YTed::POINT.redefine_negward_neighbor *args end

#ξ_redefine_posward_neighbor(*args) ⇒ Object Also known as: ξP!

Neighbor redefinition



254
255
# File 'lib/y_nelson/agent.rb', line 254

def ξ_redefine_posward_neighbor *args
::YTed::POINT.redefine_posward_neighbor *args end

#ξ_rewind_negward(*aa, &b) ⇒ Object



222
# File 'lib/y_nelson/agent.rb', line 222

def ξ_rewind_negward *aa, &b; ::YTed::POINT.rewind_negward *aa, &b end

#ξ_rewind_negward!(dim = nil) ⇒ Object Also known as: ξrn!, ξnn!



233
# File 'lib/y_nelson/agent.rb', line 233

def ξ_rewind_negward! dim=nil; ::YTed::POINT.rewind_negward! dim end

#ξ_rewind_posward(*aa, &b) ⇒ Object Also known as: ξrp, ξpp

Point rank rewinders (rewinders without exclamation mark expect block or return enumerator



220
# File 'lib/y_nelson/agent.rb', line 220

def ξ_rewind_posward *aa, &b; ::YTed::POINT.rewind_posward *aa, &b end

#ξ_rewind_posward!(dim = nil) ⇒ Object

Point rak rewinters with exclamation mark (no block or enum, just do it)



230
# File 'lib/y_nelson/agent.rb', line 230

def ξ_rewind_posward! dim=nil; ::YTed::POINT.rewind_posward! dim end

#ξ_step_negward(dim = nil) ⇒ Object Also known as: ξn!



211
# File 'lib/y_nelson/agent.rb', line 211

def ξ_step_negward dim=nil; ::YTed::POINT.step_negward dim end

#ξ_step_posward(dim = nil) ⇒ Object Also known as: ξp!

Point walkers



209
# File 'lib/y_nelson/agent.rb', line 209

def ξ_step_posward dim=nil; ::YTed::POINT.step_posward dim end