when_exe 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
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