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.
- checksums.yaml +7 -0
- data/README.md +171 -0
- data/lib/when_exe.rb +78 -47
- data/lib/when_exe/basictypes.rb +752 -747
- data/lib/when_exe/calendarnote.rb +805 -801
- data/lib/when_exe/calendartypes.rb +1583 -1531
- data/lib/when_exe/coordinates.rb +16 -15
- data/lib/when_exe/core/duration.rb +114 -110
- data/lib/when_exe/core/extension.rb +504 -504
- data/lib/when_exe/ephemeris.rb +1917 -1913
- data/lib/when_exe/ephemeris/moon.rb +333 -333
- data/lib/when_exe/ephemeris/notes.rb +389 -387
- data/lib/when_exe/ephemeris/planets.rb +585 -585
- data/lib/when_exe/ephemeris/sun.rb +214 -214
- data/lib/when_exe/googlecalendar.rb +144 -140
- data/lib/when_exe/icalendar.rb +1636 -1636
- data/lib/when_exe/inspect.rb +46 -22
- data/lib/when_exe/locales/akt.rb +176 -176
- data/lib/when_exe/locales/encoding_conversion.rb +134 -126
- data/lib/when_exe/locales/iast.rb +90 -90
- data/lib/when_exe/locales/locale.rb +750 -746
- data/lib/when_exe/locales/transliteration_table.rb +62 -62
- data/lib/when_exe/mini_application.rb +307 -305
- data/lib/when_exe/parts/enumerator.rb +2 -2
- data/lib/when_exe/parts/geometric_complex.rb +397 -397
- data/lib/when_exe/parts/method_cash.rb +224 -224
- data/lib/when_exe/parts/resource.rb +1069 -1071
- data/lib/when_exe/parts/timezone.rb +240 -230
- data/lib/when_exe/region/armenian.rb +56 -56
- data/lib/when_exe/region/babylonian.rb +405 -0
- data/lib/when_exe/region/bahai.rb +146 -146
- data/lib/when_exe/region/balinese.rb +622 -622
- data/lib/when_exe/region/chinese.rb +95 -25
- data/lib/when_exe/region/chinese/calendars.rb +1016 -1016
- data/lib/when_exe/region/chinese/epochs.rb +1 -1
- data/lib/when_exe/region/chinese/twins.rb +803 -795
- data/lib/when_exe/region/christian.rb +824 -824
- data/lib/when_exe/region/coptic.rb +106 -87
- data/lib/when_exe/region/discordian.rb +225 -225
- data/lib/when_exe/region/far_east.rb +188 -188
- data/lib/when_exe/region/french.rb +56 -56
- data/lib/when_exe/region/geologicalage.rb +639 -639
- data/lib/when_exe/region/goddess.rb +58 -58
- data/lib/when_exe/region/indian.rb +1254 -1251
- data/lib/when_exe/region/iranian.rb +8 -8
- data/lib/when_exe/region/islamic.rb +3 -3
- data/lib/when_exe/region/japanese.rb +93 -99
- data/lib/when_exe/region/japanese/calendars.rb +396 -397
- data/lib/when_exe/region/japanese/epochs.rb +26 -26
- data/lib/when_exe/region/japanese/nihon_shoki.rb +71 -71
- data/lib/when_exe/region/japanese/notes.rb +1383 -1386
- data/lib/when_exe/region/japanese/residues.rb +1306 -1306
- data/lib/when_exe/region/japanese/twins.rb +225 -225
- data/lib/when_exe/region/japanese/weeks.rb +112 -0
- data/lib/when_exe/region/javanese.rb +230 -230
- data/lib/when_exe/region/jewish.rb +126 -126
- data/lib/when_exe/region/korean.rb +378 -378
- data/lib/when_exe/region/m17n.rb +114 -113
- data/lib/when_exe/region/martian.rb +258 -255
- data/lib/when_exe/region/mayan.rb +32 -32
- data/lib/when_exe/region/residue.rb +89 -89
- data/lib/when_exe/region/roman.rb +36 -24
- data/lib/when_exe/region/ryukyu.rb +97 -97
- data/lib/when_exe/region/shire.rb +240 -240
- data/lib/when_exe/region/soviet.rb +209 -0
- data/lib/when_exe/region/symmetry.rb +50 -50
- data/lib/when_exe/region/thai.rb +336 -335
- data/lib/when_exe/region/tibetan.rb +316 -315
- data/lib/when_exe/region/vietnamese.rb +440 -439
- data/lib/when_exe/region/weekdate.rb +80 -80
- data/lib/when_exe/region/world.rb +175 -175
- data/lib/when_exe/region/yerm.rb +14 -14
- data/lib/when_exe/region/zoroastrian.rb +203 -203
- data/lib/when_exe/timestandard.rb +707 -681
- data/lib/when_exe/tmduration.rb +338 -330
- data/lib/when_exe/tmobjects.rb +1346 -1325
- data/lib/when_exe/tmposition.rb +2115 -2072
- data/lib/when_exe/tmreference.rb +1693 -1669
- data/lib/when_exe/version.rb +1 -1
- data/link_to_online_documents +1 -1
- data/test/examples/JapanHolidaysRFC6350.ics +1 -1
- data/test/test.rb +67 -61
- data/test/test/basictypes.rb +409 -409
- data/test/test/calendarnote.rb +86 -69
- data/test/test/calendartypes.rb +97 -97
- data/test/test/coordinates.rb +396 -396
- data/test/test/ephemeris.rb +83 -74
- data/test/test/ephemeris/moon.rb +14 -14
- data/test/test/ephemeris/planets.rb +14 -14
- data/test/test/ephemeris/sun.rb +14 -14
- data/test/test/googlecalendar.rb +194 -176
- data/test/test/icalendar.rb +867 -858
- data/test/test/inspect.rb +117 -117
- data/test/test/parts.rb +487 -487
- data/test/test/region/balinese.rb +34 -0
- data/test/test/region/chinese.rb +218 -206
- data/test/test/region/christian.rb +245 -245
- data/test/test/region/coptic.rb +27 -27
- data/test/test/region/french.rb +33 -33
- data/test/test/region/geologicalage.rb +17 -17
- data/test/test/region/indian.rb +57 -57
- data/test/test/region/iran.rb +54 -54
- data/test/test/region/islamic.rb +18 -18
- data/test/test/region/japanese.rb +237 -219
- data/test/test/region/jewish.rb +61 -61
- data/test/test/region/m17n.rb +184 -184
- data/test/test/region/mayan.rb +195 -195
- data/test/test/region/residue.rb +147 -139
- data/test/test/region/thai.rb +116 -116
- data/test/test/region/tibetan.rb +30 -30
- data/test/test/region/vietnamese.rb +102 -102
- data/test/test/region/yerm.rb +146 -146
- data/test/test/timestandard.rb +81 -81
- data/test/test/tmobjects.rb +328 -328
- data/test/test/tmposition.rb +397 -284
- data/test/test/tmreference.rb +157 -157
- metadata +13 -10
|
@@ -322,12 +322,12 @@ module When::Parts
|
|
|
322
322
|
|
|
323
323
|
# 整列して、重複した候補を削除
|
|
324
324
|
#
|
|
325
|
-
# @param
|
|
325
|
+
# @param [Array] list
|
|
326
326
|
# @param [Symbol] direction
|
|
327
327
|
# [ :forward - 昇順 ]
|
|
328
328
|
# [ :reverse - 降順 ]
|
|
329
329
|
#
|
|
330
|
-
# @
|
|
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
|