when_exe 0.3.6 → 0.3.7

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.
Files changed (117) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +171 -0
  3. data/lib/when_exe.rb +78 -47
  4. data/lib/when_exe/basictypes.rb +752 -747
  5. data/lib/when_exe/calendarnote.rb +805 -801
  6. data/lib/when_exe/calendartypes.rb +1583 -1531
  7. data/lib/when_exe/coordinates.rb +16 -15
  8. data/lib/when_exe/core/duration.rb +114 -110
  9. data/lib/when_exe/core/extension.rb +504 -504
  10. data/lib/when_exe/ephemeris.rb +1917 -1913
  11. data/lib/when_exe/ephemeris/moon.rb +333 -333
  12. data/lib/when_exe/ephemeris/notes.rb +389 -387
  13. data/lib/when_exe/ephemeris/planets.rb +585 -585
  14. data/lib/when_exe/ephemeris/sun.rb +214 -214
  15. data/lib/when_exe/googlecalendar.rb +144 -140
  16. data/lib/when_exe/icalendar.rb +1636 -1636
  17. data/lib/when_exe/inspect.rb +46 -22
  18. data/lib/when_exe/locales/akt.rb +176 -176
  19. data/lib/when_exe/locales/encoding_conversion.rb +134 -126
  20. data/lib/when_exe/locales/iast.rb +90 -90
  21. data/lib/when_exe/locales/locale.rb +750 -746
  22. data/lib/when_exe/locales/transliteration_table.rb +62 -62
  23. data/lib/when_exe/mini_application.rb +307 -305
  24. data/lib/when_exe/parts/enumerator.rb +2 -2
  25. data/lib/when_exe/parts/geometric_complex.rb +397 -397
  26. data/lib/when_exe/parts/method_cash.rb +224 -224
  27. data/lib/when_exe/parts/resource.rb +1069 -1071
  28. data/lib/when_exe/parts/timezone.rb +240 -230
  29. data/lib/when_exe/region/armenian.rb +56 -56
  30. data/lib/when_exe/region/babylonian.rb +405 -0
  31. data/lib/when_exe/region/bahai.rb +146 -146
  32. data/lib/when_exe/region/balinese.rb +622 -622
  33. data/lib/when_exe/region/chinese.rb +95 -25
  34. data/lib/when_exe/region/chinese/calendars.rb +1016 -1016
  35. data/lib/when_exe/region/chinese/epochs.rb +1 -1
  36. data/lib/when_exe/region/chinese/twins.rb +803 -795
  37. data/lib/when_exe/region/christian.rb +824 -824
  38. data/lib/when_exe/region/coptic.rb +106 -87
  39. data/lib/when_exe/region/discordian.rb +225 -225
  40. data/lib/when_exe/region/far_east.rb +188 -188
  41. data/lib/when_exe/region/french.rb +56 -56
  42. data/lib/when_exe/region/geologicalage.rb +639 -639
  43. data/lib/when_exe/region/goddess.rb +58 -58
  44. data/lib/when_exe/region/indian.rb +1254 -1251
  45. data/lib/when_exe/region/iranian.rb +8 -8
  46. data/lib/when_exe/region/islamic.rb +3 -3
  47. data/lib/when_exe/region/japanese.rb +93 -99
  48. data/lib/when_exe/region/japanese/calendars.rb +396 -397
  49. data/lib/when_exe/region/japanese/epochs.rb +26 -26
  50. data/lib/when_exe/region/japanese/nihon_shoki.rb +71 -71
  51. data/lib/when_exe/region/japanese/notes.rb +1383 -1386
  52. data/lib/when_exe/region/japanese/residues.rb +1306 -1306
  53. data/lib/when_exe/region/japanese/twins.rb +225 -225
  54. data/lib/when_exe/region/japanese/weeks.rb +112 -0
  55. data/lib/when_exe/region/javanese.rb +230 -230
  56. data/lib/when_exe/region/jewish.rb +126 -126
  57. data/lib/when_exe/region/korean.rb +378 -378
  58. data/lib/when_exe/region/m17n.rb +114 -113
  59. data/lib/when_exe/region/martian.rb +258 -255
  60. data/lib/when_exe/region/mayan.rb +32 -32
  61. data/lib/when_exe/region/residue.rb +89 -89
  62. data/lib/when_exe/region/roman.rb +36 -24
  63. data/lib/when_exe/region/ryukyu.rb +97 -97
  64. data/lib/when_exe/region/shire.rb +240 -240
  65. data/lib/when_exe/region/soviet.rb +209 -0
  66. data/lib/when_exe/region/symmetry.rb +50 -50
  67. data/lib/when_exe/region/thai.rb +336 -335
  68. data/lib/when_exe/region/tibetan.rb +316 -315
  69. data/lib/when_exe/region/vietnamese.rb +440 -439
  70. data/lib/when_exe/region/weekdate.rb +80 -80
  71. data/lib/when_exe/region/world.rb +175 -175
  72. data/lib/when_exe/region/yerm.rb +14 -14
  73. data/lib/when_exe/region/zoroastrian.rb +203 -203
  74. data/lib/when_exe/timestandard.rb +707 -681
  75. data/lib/when_exe/tmduration.rb +338 -330
  76. data/lib/when_exe/tmobjects.rb +1346 -1325
  77. data/lib/when_exe/tmposition.rb +2115 -2072
  78. data/lib/when_exe/tmreference.rb +1693 -1669
  79. data/lib/when_exe/version.rb +1 -1
  80. data/link_to_online_documents +1 -1
  81. data/test/examples/JapanHolidaysRFC6350.ics +1 -1
  82. data/test/test.rb +67 -61
  83. data/test/test/basictypes.rb +409 -409
  84. data/test/test/calendarnote.rb +86 -69
  85. data/test/test/calendartypes.rb +97 -97
  86. data/test/test/coordinates.rb +396 -396
  87. data/test/test/ephemeris.rb +83 -74
  88. data/test/test/ephemeris/moon.rb +14 -14
  89. data/test/test/ephemeris/planets.rb +14 -14
  90. data/test/test/ephemeris/sun.rb +14 -14
  91. data/test/test/googlecalendar.rb +194 -176
  92. data/test/test/icalendar.rb +867 -858
  93. data/test/test/inspect.rb +117 -117
  94. data/test/test/parts.rb +487 -487
  95. data/test/test/region/balinese.rb +34 -0
  96. data/test/test/region/chinese.rb +218 -206
  97. data/test/test/region/christian.rb +245 -245
  98. data/test/test/region/coptic.rb +27 -27
  99. data/test/test/region/french.rb +33 -33
  100. data/test/test/region/geologicalage.rb +17 -17
  101. data/test/test/region/indian.rb +57 -57
  102. data/test/test/region/iran.rb +54 -54
  103. data/test/test/region/islamic.rb +18 -18
  104. data/test/test/region/japanese.rb +237 -219
  105. data/test/test/region/jewish.rb +61 -61
  106. data/test/test/region/m17n.rb +184 -184
  107. data/test/test/region/mayan.rb +195 -195
  108. data/test/test/region/residue.rb +147 -139
  109. data/test/test/region/thai.rb +116 -116
  110. data/test/test/region/tibetan.rb +30 -30
  111. data/test/test/region/vietnamese.rb +102 -102
  112. data/test/test/region/yerm.rb +146 -146
  113. data/test/test/timestandard.rb +81 -81
  114. data/test/test/tmobjects.rb +328 -328
  115. data/test/test/tmposition.rb +397 -284
  116. data/test/test/tmreference.rb +157 -157
  117. metadata +13 -10
@@ -322,12 +322,12 @@ module When::Parts
322
322
 
323
323
  # 整列して、重複した候補を削除
324
324
  #
325
- # @param list [Array]
325
+ # @param [Array] list
326
326
  # @param [Symbol] direction
327
327
  # [ :forward - 昇順 ]
328
328
  # [ :reverse - 降順 ]
329
329
  #
330
- # @param [Array]
330
+ # @return [Array]
331
331
  # @note
332
332
  # eql? はオーバーライドしない
333
333
  #
@@ -1,397 +1,397 @@
1
- # -*- coding: utf-8 -*-
2
- =begin
3
- Copyright (C) 2011-2013 Takashi SUGA
4
-
5
- You may use and/or modify this file according to the license described in the LICENSE.txt file included in this archive.
6
- =end
7
-
8
- require 'when_exe/parts/method_cash'
9
- require 'when_exe/tmduration'
10
-
11
- #
12
- # 本ライブラリのための諸々の部品
13
- #
14
- module When::Parts
15
-
16
- #
17
- # 任意個の端点から構成する [Range] の subclass
18
- #
19
- class GeometricComplex < Range
20
-
21
- include Comparable
22
-
23
- # 範囲の反転
24
- # @return [Boolean]
25
- # [ true - 反転する ]
26
- # [ false - 反転しない ]
27
- #
28
- # @note
29
- # 無限の過去(-Infinity)を範囲に含むか否かと同値である
30
- #
31
- attr_reader :reverse
32
-
33
- #
34
- # When::Parts::GeometricComplex を構成する端点の Array
35
- #
36
- # @return [Array<Array<Comparable, Boolean>>]
37
- # - Comparable - 端点
38
- # - Boolean
39
- # @reverse == true の場合
40
- # true - 範囲に含まない
41
- # false - 範囲に含む
42
- # @reverse == false の場合
43
- # true - 範囲に含む
44
- # false - 範囲に含まない
45
- #
46
- # @example +[[3,true],[4,false]] は Range(3+...4)に対応する
47
- #
48
- attr_reader :node
49
-
50
- # 最小の端点
51
- #
52
- # @param [Comparable] default 端点が-∞の場合に返すべき値(指定がなければ nil)
53
- #
54
- # @return [Comparable] 最小の端点
55
- #
56
- # @note
57
- # 含むか否かに関わらず、最小の端点を返す。
58
- # default が指定されているが有効な区間がない場合、nil を返す。
59
- #
60
- def first(default=nil)
61
- return (@node.length==0) ? nil : @node[0][0] unless default # 互換性
62
- if reverse
63
- return default
64
- else
65
- (@node.length==0) ? nil : @node[0][0]
66
- end
67
- end
68
- alias :begin :first
69
-
70
- # 最大の端点
71
- #
72
- # @param [Comparable] default 端点が+∞場合に返すべき値(指定がなければ nil)
73
- #
74
- # @return [Comparable] 最大の端点
75
- #
76
- # @note
77
- # 含むか否かに関わらず、最大の端点を返す
78
- # default が指定されているが有効な区間がない場合、nil を返す
79
- #
80
- def last(default=nil)
81
- return (@node.length==0) ? nil : @node[-1][0] unless default # 互換性
82
- if reverse
83
- return (@node.length[0]==0) ? default : @node[-1][0]
84
- else
85
- return nil if (@node.length==0)
86
- return (@node.length[0]==1) ? default : @node[-1][0]
87
- end
88
- end
89
- alias :end :last
90
-
91
- # 端点が範囲に含まれるか?
92
- #
93
- # @param [Integer] index 端点の番号(デフォルト : -1 - 最大の端点)
94
- #
95
- # @return [Boolean]
96
- # [ true - 含まれる ]
97
- # [ false - 含まれない ]
98
- #
99
- def exclude_end?(index=-1)
100
- (@node.length==0) ? nil : !@node[index][1] ^ @reverse
101
- end
102
-
103
- # 分解能
104
- #
105
- # @return [Integer] 最小の端点の分解能を返す
106
- #
107
- # @note
108
- # 分解能がない場合は、When::SYSTEM を返す
109
- #
110
- def precision
111
- @node[0] && @node[0][0].respond_to?(:precision) ? @node[0][0].precision : When::SYSTEM
112
- end
113
-
114
- # 範囲を反転する
115
- #
116
- # @return [When::Parts::GeometricComplex]
117
- #
118
- def -@
119
- GeometricComplex.new(self, true)
120
- end
121
-
122
- # 最小の端点と other を比較する
123
- #
124
- # @param [Comparable] other 比較対象
125
- #
126
- # @return [Integer] 比較結果を 負, 0, 正の値で返す
127
- #
128
- def <=>(other)
129
- first <=> other
130
- end
131
-
132
- # 和集合
133
- #
134
- # @param [Range, When::Parts::GeometricComplex] other
135
- #
136
- # @return [When::Parts::GeometricComplex] self と other の和集合を返す
137
- #
138
- def |(other)
139
- other = GeometricComplex.new(other) unless other.kind_of?(GeometricComplex)
140
- return self if self.reverse && self.node.length==0
141
- return other | self if !self.reverse && other.reverse
142
- copy = self.node.dup
143
- ref = other.node.dup
144
- max = _max(copy.shift.dup, ref.shift.dup) if (other.reverse)
145
- rev = max ? false : @reverse
146
- while (ref.length > 0) do
147
- first, last, *ref = ref
148
- updated = _upper(copy, first, rev)
149
- updated += _lower(copy, last, rev) if last
150
- copy = updated
151
- end
152
- copy = _lower(copy, max, true) if max
153
- return GeometricComplex.new(copy, self.reverse)
154
- end
155
-
156
- # 共通集合
157
- #
158
- # @param [Range, When::Parts::GeometricComplex] other
159
- #
160
- # @return [When::Parts::GeometricComplex] self と other の共通集合を返す
161
- #
162
- def &(other)
163
- -(-self | -other)
164
- end
165
-
166
- # ISO19108 の TM オブジェクトに変換する
167
- #
168
- # @param [Hash] options When::TM::TemporalPosition の生成を行う場合に使用する
169
- # (see {When::TM::TemporalPosition._instance})
170
- #
171
- # @return [When::TM::Node, When::TM::Edge, When::TM::TopologicalComplex]
172
- #
173
- def to_tm_object(options={})
174
- return nil unless !@reverse && @node.length>0 && @node.length[0]==0
175
- objects = []
176
- primitives = @node.dup
177
- while (primitives) do
178
- first, last, primitives = primitives
179
- if (first[0].eql?(last[0]))
180
- objects = When::TM::Node.new(When::TM::Instant.new(When.when?(first[0],options)))
181
- else
182
- objects = When::TM::Edge.new(When::TM::Node.new(When::TM::Instant.new(When.when?(first[0],options))),
183
- When::TM::Node.new(When::TM::Instant.new(When.when?(last[0],options))))
184
- end
185
- end
186
- return objects[0] if objects.length==1
187
- return When::TM::TopologicalComplex.new(objects)
188
- rescue NameError
189
- raise NameError, "Please require 'when_exe' to use Temporal Objects Package"
190
- end
191
-
192
- # 範囲に含まれるか?
193
- #
194
- # @param [Comparable] other 判断する Comparable
195
- #
196
- # @return [Boolean]
197
- # [ true - 範囲に含まれる ]
198
- # [ false - 範囲に含まれない ]
199
- #
200
- # @note 制限事項
201
- # When::TM::TopologicalComplex どうしの包含判定は、和集合がもとの範囲と等しいか
202
- # で判断している。分解能が When::SYSTEM でない場合、論理的には等しいものが、
203
- # 内部表現が異なるために等しくないとみなされる事があり、その場合 true であるべき
204
- # ものを false と誤判断する。実行速度上の制約もあり、現時点では対策しない。
205
- #
206
- def include?(other)
207
- if (other.kind_of?(Comparable) && !other.kind_of?(GeometricComplex))
208
- return (_include_point?(other) != false)
209
- else
210
- other = GeometricComplex.new(other) unless other.kind_of?(GeometricComplex)
211
- return _include_range?(other)
212
- end
213
- end
214
- alias :=== :include?
215
-
216
- # Enumerator._exclude 専用
217
- # @private
218
- def _include?(other)
219
- if (other.kind_of?(Comparable) && !other.kind_of?(GeometricComplex))
220
- return _include_point?(other)
221
- else
222
- other = GeometricComplex.new(other) unless other.kind_of?(GeometricComplex)
223
- return _include_range?(other) && _include_point?(other.first)
224
- end
225
- end
226
-
227
- # オブジェクトの生成
228
- #
229
- # @overload initialize(range, reverse=false)
230
- # @param [Range] range
231
- #
232
- # @overload initialize(point, reverse=false)
233
- # range = Range(point..point) と同じ
234
- # @param [Comparable] point
235
- #
236
- # @overload initialize(first, last, reverse=false)
237
- # range = Range(first...last) と同じ
238
- # @param [Comparable] first
239
- # @param [Comparable] last
240
- #
241
- # @overload initialize(first, duration, reverse=false)
242
- # range = Range(first...(first+duration)) と同じ
243
- # @param [Comparable] first
244
- # @param [When::TM::Duration] duration
245
- #
246
- # @overload initialize(other, reverse=false)
247
- # もとの When::Parts::GeometricComplex のコピー
248
- # @param [When::Parts::GeometricComplex] other
249
- #
250
- # @overload initialize(node, reverse=false)
251
- # 指定した node 構造の When::Parts::GeometricComplex を生成
252
- # @param [Array<Array<Comparable, Boolean>>] note
253
- # - Comparable - 端点
254
- # - Boolean
255
- # @reverse == true の場合
256
- # true - 範囲に含まない
257
- # false - 範囲に含む
258
- # @reverse == false の場合
259
- # true - 範囲に含む
260
- # false - 範囲に含まない
261
- # @note
262
- # すべての呼び出しパターンに共通の最終引数 reverse を付けることができる
263
- # reverse [Boolean]
264
- # true - 反転する
265
- # false - 反転しない
266
- #
267
- def initialize(*args)
268
-
269
- @reverse = (args[-1]==true || args[-1]==false) ? args.pop : false
270
-
271
- case args[0]
272
- when GeometricComplex
273
- @node = args[0].node
274
- @reverse ^= args[0].reverse
275
- return super(self.first||-Float::INFINITY, self.last||+Float::INFINITY, exclude_end?)
276
-
277
- when Array
278
- @node = args[0]
279
- return super(self.first||-Float::INFINITY, self.last||+Float::INFINITY, exclude_end?)
280
-
281
- when Range
282
- first = [args[0].first, true]
283
- last = [args[0].last, !args[0].exclude_end?]
284
-
285
- when Comparable
286
- first, last, rest = args
287
- raise ArgumentError, "Too many argument: #{rest}" if rest
288
- first = [first, true]
289
- case last
290
- when Comparable ; last = [last, false]
291
- when When::TM::Duration ; last = [first[0] + last, false]
292
- when nil ; last = first
293
- else ; raise TypeError, "Irregal GeometricComplex Type for last element: #{last.class}"
294
- end
295
-
296
- when nil ;
297
- else ; raise TypeError, "Irregal GeometricComplex Type: #{first.class}"
298
- end
299
-
300
- first, last = last, first if (first && last && first[0] > last[0])
301
- @node = []
302
- @node << first if first
303
- @node << last if last
304
- super(self.first||-Float::INFINITY, self.last||+Float::INFINITY, exclude_end?)
305
- end
306
-
307
- private
308
-
309
- def _include_range?(other)
310
- union = self | other
311
- return false unless self.node == union.node
312
- return self.reverse == union.reverse
313
- end
314
-
315
- def _include_point?(other)
316
- @node.each_index do |i|
317
- current = @node[i]
318
- verify = other <=> current[0]
319
- if (verify < 0)
320
- return false if ((i[0]==0) ^ @reverse)
321
- return @node[[0,i-1].max][0]
322
- elsif (verify == 0)
323
- return false unless (@reverse ^ current[1])
324
- return current[0]
325
- end
326
- end
327
- return (@reverse ? nil : false) if @node.length==0
328
- return false if ((@node.length[0]==0) ^ @reverse)
329
- return @node[-1][0]
330
- end
331
-
332
- def _upper(node, point, reverse)
333
- node = node.dup
334
- point = point.dup
335
- point[1] = !point[1] if reverse
336
- node.each_index do |i|
337
- if (_verify(point, node[i], reverse) <= 0)
338
- node[i..-1] = ((i[0]==0) ^ reverse) ? [point] : []
339
- return node
340
- end
341
- end
342
- node.push(point) if (node.length[0]==0) ^ @everse
343
- return node
344
- end
345
-
346
- def _lower(node, point, reverse)
347
- node = node.dup
348
- point = point.dup
349
- point[1] = !point[1] if reverse
350
- (node.length-1).downto(0) do |i|
351
- if (_verify(point, node[i], reverse) >= 0)
352
- node[0..i] = ((i[0]==1) ^ reverse) ? [point] : []
353
- return node
354
- end
355
- end
356
- node.unshift(point) if (node.length[0]==0) ^ reverse
357
- return node
358
- end
359
-
360
- def _verify(point, node, reverse)
361
- verify = point[0] <=> node[0]
362
- return verify unless verify == 0
363
- if point[0].respond_to?(:precision) && node[0].respond_to?(:precision)
364
- point[0] = node[0] if point[0].precision >= node[0].precision
365
- end
366
- if reverse
367
- point[1] &= node[1]
368
- else
369
- point[1] |= node[1]
370
- end
371
- return verify
372
- end
373
-
374
- def _max(p1, p2)
375
- p1[1] = !p1[1]
376
- p2[1] = !p2[1]
377
- verify = p1[0] <=> p2[0]
378
- return p1 if (verify>0)
379
- return p2 if (verify<0)
380
- p1[1] |= p2[1]
381
- return p1
382
- end
383
-
384
- # その他のメソッド
385
- # When::Parts::GeometricComplex で定義されていないメソッドは
386
- # 処理を first (type: When::TM::(Temporal)Position) に委譲する
387
- #
388
- def method_missing(name, *args, &block)
389
- self.class.module_eval %Q{
390
- def #{name}(*args, &block)
391
- first.send("#{name}", *args, &block)
392
- end
393
- } unless When::Parts::MethodCash.escape(name)
394
- first.send(name, *args, &block)
395
- end
396
- end
397
- end
1
+ # -*- coding: utf-8 -*-
2
+ =begin
3
+ Copyright (C) 2011-2013 Takashi SUGA
4
+
5
+ You may use and/or modify this file according to the license described in the LICENSE.txt file included in this archive.
6
+ =end
7
+
8
+ require 'when_exe/parts/method_cash'
9
+ require 'when_exe/tmduration'
10
+
11
+ #
12
+ # 本ライブラリのための諸々の部品
13
+ #
14
+ module When::Parts
15
+
16
+ #
17
+ # 任意個の端点から構成する [Range] の subclass
18
+ #
19
+ class GeometricComplex < Range
20
+
21
+ include Comparable
22
+
23
+ # 範囲の反転
24
+ # @return [Boolean]
25
+ # [ true - 反転する ]
26
+ # [ false - 反転しない ]
27
+ #
28
+ # @note
29
+ # 無限の過去(-Infinity)を範囲に含むか否かと同値である
30
+ #
31
+ attr_reader :reverse
32
+
33
+ #
34
+ # When::Parts::GeometricComplex を構成する端点の Array
35
+ #
36
+ # @return [Array<Array<Comparable, Boolean>>]
37
+ # - Comparable - 端点
38
+ # - Boolean
39
+ # @reverse == true の場合
40
+ # true - 範囲に含まない
41
+ # false - 範囲に含む
42
+ # @reverse == false の場合
43
+ # true - 範囲に含む
44
+ # false - 範囲に含まない
45
+ #
46
+ # @example +[[3,true],[4,false]] は Range(3+...4)に対応する
47
+ #
48
+ attr_reader :node
49
+
50
+ # 最小の端点
51
+ #
52
+ # @param [Comparable] default 端点が-∞の場合に返すべき値(指定がなければ nil)
53
+ #
54
+ # @return [Comparable] 最小の端点
55
+ #
56
+ # @note
57
+ # 含むか否かに関わらず、最小の端点を返す。
58
+ # default が指定されているが有効な区間がない場合、nil を返す。
59
+ #
60
+ def first(default=nil)
61
+ return (@node.length==0) ? nil : @node[0][0] unless default # 互換性
62
+ if reverse
63
+ return default
64
+ else
65
+ (@node.length==0) ? nil : @node[0][0]
66
+ end
67
+ end
68
+ alias :begin :first
69
+
70
+ # 最大の端点
71
+ #
72
+ # @param [Comparable] default 端点が+∞場合に返すべき値(指定がなければ nil)
73
+ #
74
+ # @return [Comparable] 最大の端点
75
+ #
76
+ # @note
77
+ # 含むか否かに関わらず、最大の端点を返す
78
+ # default が指定されているが有効な区間がない場合、nil を返す
79
+ #
80
+ def last(default=nil)
81
+ return (@node.length==0) ? nil : @node[-1][0] unless default # 互換性
82
+ if reverse
83
+ return (@node.length[0]==0) ? default : @node[-1][0]
84
+ else
85
+ return nil if (@node.length==0)
86
+ return (@node.length[0]==1) ? default : @node[-1][0]
87
+ end
88
+ end
89
+ alias :end :last
90
+
91
+ # 端点が範囲に含まれるか?
92
+ #
93
+ # @param [Integer] index 端点の番号(デフォルト : -1 - 最大の端点)
94
+ #
95
+ # @return [Boolean]
96
+ # [ true - 含まれる ]
97
+ # [ false - 含まれない ]
98
+ #
99
+ def exclude_end?(index=-1)
100
+ (@node.length==0) ? nil : !@node[index][1] ^ @reverse
101
+ end
102
+
103
+ # 分解能
104
+ #
105
+ # @return [Integer] 最小の端点の分解能を返す
106
+ #
107
+ # @note
108
+ # 分解能がない場合は、When::SYSTEM を返す
109
+ #
110
+ def precision
111
+ @node[0] && @node[0][0].respond_to?(:precision) ? @node[0][0].precision : When::SYSTEM
112
+ end
113
+
114
+ # 範囲を反転する
115
+ #
116
+ # @return [When::Parts::GeometricComplex]
117
+ #
118
+ def -@
119
+ GeometricComplex.new(self, true)
120
+ end
121
+
122
+ # 最小の端点と other を比較する
123
+ #
124
+ # @param [Comparable] other 比較対象
125
+ #
126
+ # @return [Integer] 比較結果を 負, 0, 正の値で返す
127
+ #
128
+ def <=>(other)
129
+ first <=> other
130
+ end
131
+
132
+ # 和集合
133
+ #
134
+ # @param [Range, When::Parts::GeometricComplex] other
135
+ #
136
+ # @return [When::Parts::GeometricComplex] self と other の和集合を返す
137
+ #
138
+ def |(other)
139
+ other = GeometricComplex.new(other) unless other.kind_of?(GeometricComplex)
140
+ return self if self.reverse && self.node.length==0
141
+ return other | self if !self.reverse && other.reverse
142
+ copy = self.node.dup
143
+ ref = other.node.dup
144
+ max = _max(copy.shift.dup, ref.shift.dup) if (other.reverse)
145
+ rev = max ? false : @reverse
146
+ while (ref.length > 0) do
147
+ first, last, *ref = ref
148
+ updated = _upper(copy, first, rev)
149
+ updated += _lower(copy, last, rev) if last
150
+ copy = updated
151
+ end
152
+ copy = _lower(copy, max, true) if max
153
+ return GeometricComplex.new(copy, self.reverse)
154
+ end
155
+
156
+ # 共通集合
157
+ #
158
+ # @param [Range, When::Parts::GeometricComplex] other
159
+ #
160
+ # @return [When::Parts::GeometricComplex] self と other の共通集合を返す
161
+ #
162
+ def &(other)
163
+ -(-self | -other)
164
+ end
165
+
166
+ # ISO19108 の TM オブジェクトに変換する
167
+ #
168
+ # @param [Hash] options When::TM::TemporalPosition の生成を行う場合に使用する
169
+ # (see {When::TM::TemporalPosition._instance})
170
+ #
171
+ # @return [When::TM::Node, When::TM::Edge, When::TM::TopologicalComplex]
172
+ #
173
+ def to_tm_object(options={})
174
+ return nil unless !@reverse && @node.length>0 && @node.length[0]==0
175
+ objects = []
176
+ primitives = @node.dup
177
+ while (primitives) do
178
+ first, last, primitives = primitives
179
+ if (first[0].eql?(last[0]))
180
+ objects = When::TM::Node.new(When::TM::Instant.new(When.when?(first[0],options)))
181
+ else
182
+ objects = When::TM::Edge.new(When::TM::Node.new(When::TM::Instant.new(When.when?(first[0],options))),
183
+ When::TM::Node.new(When::TM::Instant.new(When.when?(last[0],options))))
184
+ end
185
+ end
186
+ return objects[0] if objects.length==1
187
+ return When::TM::TopologicalComplex.new(objects)
188
+ rescue NameError
189
+ raise NameError, "Please require 'when_exe' to use Temporal Objects Package"
190
+ end
191
+
192
+ # 範囲に含まれるか?
193
+ #
194
+ # @param [Comparable] other 判断する Comparable
195
+ #
196
+ # @return [Boolean]
197
+ # [ true - 範囲に含まれる ]
198
+ # [ false - 範囲に含まれない ]
199
+ #
200
+ # @note 制限事項
201
+ # When::TM::TopologicalComplex どうしの包含判定は、和集合がもとの範囲と等しいか
202
+ # で判断している。分解能が When::SYSTEM でない場合、論理的には等しいものが、
203
+ # 内部表現が異なるために等しくないとみなされる事があり、その場合 true であるべき
204
+ # ものを false と誤判断する。実行速度上の制約もあり、現時点では対策しない。
205
+ #
206
+ def include?(other)
207
+ if (other.kind_of?(Comparable) && !other.kind_of?(GeometricComplex))
208
+ return (_include_point?(other) != false)
209
+ else
210
+ other = GeometricComplex.new(other) unless other.kind_of?(GeometricComplex)
211
+ return _include_range?(other)
212
+ end
213
+ end
214
+ alias :=== :include?
215
+
216
+ # Enumerator._exclude 専用
217
+ # @private
218
+ def _include?(other)
219
+ if (other.kind_of?(Comparable) && !other.kind_of?(GeometricComplex))
220
+ return _include_point?(other)
221
+ else
222
+ other = GeometricComplex.new(other) unless other.kind_of?(GeometricComplex)
223
+ return _include_range?(other) && _include_point?(other.first)
224
+ end
225
+ end
226
+
227
+ # オブジェクトの生成
228
+ #
229
+ # @overload initialize(range, reverse=false)
230
+ # @param [Range] range
231
+ #
232
+ # @overload initialize(point, reverse=false)
233
+ # range = Range(point..point) と同じ
234
+ # @param [Comparable] point
235
+ #
236
+ # @overload initialize(first, last, reverse=false)
237
+ # range = Range(first...last) と同じ
238
+ # @param [Comparable] first
239
+ # @param [Comparable] last
240
+ #
241
+ # @overload initialize(first, duration, reverse=false)
242
+ # range = Range(first...(first+duration)) と同じ
243
+ # @param [Comparable] first
244
+ # @param [When::TM::Duration] duration
245
+ #
246
+ # @overload initialize(other, reverse=false)
247
+ # もとの When::Parts::GeometricComplex のコピー
248
+ # @param [When::Parts::GeometricComplex] other
249
+ #
250
+ # @overload initialize(node, reverse=false)
251
+ # 指定した node 構造の When::Parts::GeometricComplex を生成
252
+ # @param [Array<Array<Comparable, Boolean>>] note
253
+ # - Comparable - 端点
254
+ # - Boolean
255
+ # @reverse == true の場合
256
+ # true - 範囲に含まない
257
+ # false - 範囲に含む
258
+ # @reverse == false の場合
259
+ # true - 範囲に含む
260
+ # false - 範囲に含まない
261
+ # @note
262
+ # すべての呼び出しパターンに共通の最終引数 reverse を付けることができる
263
+ # reverse [Boolean]
264
+ # true - 反転する
265
+ # false - 反転しない
266
+ #
267
+ def initialize(*args)
268
+
269
+ @reverse = (args[-1]==true || args[-1]==false) ? args.pop : false
270
+
271
+ case args[0]
272
+ when GeometricComplex
273
+ @node = args[0].node
274
+ @reverse ^= args[0].reverse
275
+ return super(self.first||-Float::INFINITY, self.last||+Float::INFINITY, exclude_end?)
276
+
277
+ when Array
278
+ @node = args[0]
279
+ return super(self.first||-Float::INFINITY, self.last||+Float::INFINITY, exclude_end?)
280
+
281
+ when Range
282
+ first = [args[0].first, true]
283
+ last = [args[0].last, !args[0].exclude_end?]
284
+
285
+ when Comparable
286
+ first, last, rest = args
287
+ raise ArgumentError, "Too many argument: #{rest}" if rest
288
+ first = [first, true]
289
+ case last
290
+ when Comparable ; last = [last, false]
291
+ when When::TM::Duration ; last = [first[0] + last, false]
292
+ when nil ; last = first
293
+ else ; raise TypeError, "Irregal GeometricComplex Type for last element: #{last.class}"
294
+ end
295
+
296
+ when nil ;
297
+ else ; raise TypeError, "Irregal GeometricComplex Type: #{first.class}"
298
+ end
299
+
300
+ first, last = last, first if (first && last && first[0] > last[0])
301
+ @node = []
302
+ @node << first if first
303
+ @node << last if last
304
+ super(self.first||-Float::INFINITY, self.last||+Float::INFINITY, exclude_end?)
305
+ end
306
+
307
+ private
308
+
309
+ def _include_range?(other)
310
+ union = self | other
311
+ return false unless self.node == union.node
312
+ return self.reverse == union.reverse
313
+ end
314
+
315
+ def _include_point?(other)
316
+ @node.each_index do |i|
317
+ current = @node[i]
318
+ verify = other <=> current[0]
319
+ if (verify < 0)
320
+ return false if ((i[0]==0) ^ @reverse)
321
+ return @node[[0,i-1].max][0]
322
+ elsif (verify == 0)
323
+ return false unless (@reverse ^ current[1])
324
+ return current[0]
325
+ end
326
+ end
327
+ return (@reverse ? nil : false) if @node.length==0
328
+ return false if ((@node.length[0]==0) ^ @reverse)
329
+ return @node[-1][0]
330
+ end
331
+
332
+ def _upper(node, point, reverse)
333
+ node = node.dup
334
+ point = point.dup
335
+ point[1] = !point[1] if reverse
336
+ node.each_index do |i|
337
+ if (_verify(point, node[i], reverse) <= 0)
338
+ node[i..-1] = ((i[0]==0) ^ reverse) ? [point] : []
339
+ return node
340
+ end
341
+ end
342
+ node.push(point) if (node.length[0]==0) ^ @everse
343
+ return node
344
+ end
345
+
346
+ def _lower(node, point, reverse)
347
+ node = node.dup
348
+ point = point.dup
349
+ point[1] = !point[1] if reverse
350
+ (node.length-1).downto(0) do |i|
351
+ if (_verify(point, node[i], reverse) >= 0)
352
+ node[0..i] = ((i[0]==1) ^ reverse) ? [point] : []
353
+ return node
354
+ end
355
+ end
356
+ node.unshift(point) if (node.length[0]==0) ^ reverse
357
+ return node
358
+ end
359
+
360
+ def _verify(point, node, reverse)
361
+ verify = point[0] <=> node[0]
362
+ return verify unless verify == 0
363
+ if point[0].respond_to?(:precision) && node[0].respond_to?(:precision)
364
+ point[0] = node[0] if point[0].precision >= node[0].precision
365
+ end
366
+ if reverse
367
+ point[1] &= node[1]
368
+ else
369
+ point[1] |= node[1]
370
+ end
371
+ return verify
372
+ end
373
+
374
+ def _max(p1, p2)
375
+ p1[1] = !p1[1]
376
+ p2[1] = !p2[1]
377
+ verify = p1[0] <=> p2[0]
378
+ return p1 if (verify>0)
379
+ return p2 if (verify<0)
380
+ p1[1] |= p2[1]
381
+ return p1
382
+ end
383
+
384
+ # その他のメソッド
385
+ # When::Parts::GeometricComplex で定義されていないメソッドは
386
+ # 処理を first (type: When::TM::(Temporal)Position) に委譲する
387
+ #
388
+ def method_missing(name, *args, &block)
389
+ self.class.module_eval %Q{
390
+ def #{name}(*args, &block)
391
+ first.send("#{name}", *args, &block)
392
+ end
393
+ } unless When::Parts::MethodCash.escape(name)
394
+ first.send(name, *args, &block)
395
+ end
396
+ end
397
+ end