when_exe 0.4.1 → 0.4.2

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 (96) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +36 -33
  3. data/bin/locales.rb +1 -1
  4. data/bin/make_ttl.rb.config +1 -1
  5. data/lib/when_exe.rb +27 -16
  6. data/lib/when_exe/basictypes.rb +772 -771
  7. data/lib/when_exe/calendartypes.rb +1485 -1453
  8. data/lib/when_exe/coordinates.rb +5 -0
  9. data/lib/when_exe/core/compatibility.rb +1 -1
  10. data/lib/when_exe/core/duration.rb +147 -116
  11. data/lib/when_exe/core/extension.rb +499 -497
  12. data/lib/when_exe/ephemeris.rb +1952 -1951
  13. data/lib/when_exe/ephemeris/eclipse.rb +5 -4
  14. data/lib/when_exe/ephemeris/notes.rb +457 -421
  15. data/lib/when_exe/ephemeris/planets.rb +585 -585
  16. data/lib/when_exe/ephemeris/sun.rb +214 -214
  17. data/lib/when_exe/google_api.rb +153 -0
  18. data/lib/when_exe/icalendar.rb +1640 -1632
  19. data/lib/when_exe/inspect.rb +42 -20
  20. data/lib/when_exe/linkeddata.rb +28 -7
  21. data/lib/when_exe/locales/autoload.rb +2 -1
  22. data/lib/when_exe/locales/locale.rb +35 -15
  23. data/lib/when_exe/locales/zh.rb +77 -0
  24. data/lib/when_exe/mini_application.rb +3 -1
  25. data/lib/when_exe/{googlecalendar.rb → obsolete/googlecalendar.rb} +144 -144
  26. data/lib/when_exe/parts/enumerator.rb +498 -486
  27. data/lib/when_exe/parts/geometric_complex.rb +397 -397
  28. data/lib/when_exe/parts/timezone.rb +246 -241
  29. data/lib/when_exe/region/armenian.rb +55 -56
  30. data/lib/when_exe/region/babylonian.rb +406 -405
  31. data/lib/when_exe/region/bahai.rb +107 -106
  32. data/lib/when_exe/region/balinese.rb +624 -622
  33. data/lib/when_exe/region/chinese.rb +1071 -1026
  34. data/lib/when_exe/region/chinese/epochs.rb +28 -28
  35. data/lib/when_exe/region/chinese/notes.rb +219 -0
  36. data/lib/when_exe/region/chinese/twins.rb +803 -803
  37. data/lib/when_exe/region/christian.rb +21 -15
  38. data/lib/when_exe/region/coptic.rb +107 -106
  39. data/lib/when_exe/region/discordian.rb +218 -218
  40. data/lib/when_exe/region/east_asian.rb +1 -1
  41. data/lib/when_exe/region/french.rb +126 -56
  42. data/lib/when_exe/region/geologicalage.rb +639 -639
  43. data/lib/when_exe/region/goddess.rb +60 -58
  44. data/lib/when_exe/region/hanke_henry.rb +2 -2
  45. data/lib/when_exe/region/indian.rb +1225 -1222
  46. data/lib/when_exe/region/international_fixed.rb +96 -97
  47. data/lib/when_exe/region/iranian.rb +206 -203
  48. data/lib/when_exe/region/islamic.rb +102 -102
  49. data/lib/when_exe/region/japanese.rb +126 -71
  50. data/lib/when_exe/region/japanese/epochs.rb +426 -426
  51. data/lib/when_exe/region/japanese/notes.rb +101 -81
  52. data/lib/when_exe/region/japanese/residues.rb +1345 -1311
  53. data/lib/when_exe/region/japanese/twins.rb +225 -225
  54. data/lib/when_exe/region/japanese/weeks.rb +112 -112
  55. data/lib/when_exe/region/javanese.rb +230 -230
  56. data/lib/when_exe/region/jewish.rb +130 -131
  57. data/lib/when_exe/region/m17n.rb +114 -114
  58. data/lib/when_exe/region/martian.rb +258 -258
  59. data/lib/when_exe/region/mayan.rb +11 -8
  60. data/lib/when_exe/region/pax.rb +4 -5
  61. data/lib/when_exe/region/pope.rb +1 -1
  62. data/lib/when_exe/region/positivist.rb +100 -100
  63. data/lib/when_exe/region/residue.rb +162 -162
  64. data/lib/when_exe/region/roman.rb +333 -333
  65. data/lib/when_exe/region/{soviet.rb → russian.rb} +221 -209
  66. data/lib/when_exe/region/shire.rb +222 -223
  67. data/lib/when_exe/region/symmetry.rb +50 -50
  68. data/lib/when_exe/region/thai.rb +336 -336
  69. data/lib/when_exe/region/tibetan.rb +315 -316
  70. data/lib/when_exe/region/tranquility.rb +207 -208
  71. data/lib/when_exe/region/vanishing_leprechaun.rb +3 -1
  72. data/lib/when_exe/region/vietnamese.rb +449 -440
  73. data/lib/when_exe/region/weekdate.rb +80 -80
  74. data/lib/when_exe/region/world.rb +170 -171
  75. data/lib/when_exe/region/world_season.rb +89 -89
  76. data/lib/when_exe/region/yerm.rb +3 -3
  77. data/lib/when_exe/region/zoroastrian.rb +205 -205
  78. data/lib/when_exe/timestandard.rb +708 -707
  79. data/lib/when_exe/tmduration.rb +338 -338
  80. data/lib/when_exe/tmobjects.rb +1356 -1356
  81. data/lib/when_exe/tmposition.rb +66 -31
  82. data/lib/when_exe/version.rb +16 -2
  83. data/test/examples/Residue.m17n +83 -83
  84. data/test/examples/Terms.m17n +2 -2
  85. data/test/test.rb +2 -2
  86. data/test/test/google_api.rb +65 -0
  87. data/test/test/linkeddata.rb +1 -1
  88. data/test/test/{googlecalendar.rb → obsolete/googlecalendar.rb} +194 -194
  89. data/test/test/region/indian.rb +90 -85
  90. data/test/test/region/m17n.rb +7 -7
  91. data/test/test/region/mayan.rb +195 -195
  92. data/test/test/region/residue.rb +153 -153
  93. data/test/test/tmposition.rb +11 -1
  94. data/when_exe.gemspec +2 -2
  95. metadata +95 -8
  96. data/test/test.rb.config +0 -1
@@ -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-2015 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