ragni-cas 0.2.2 → 0.2.3
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/functions/fnc-base.rb +660 -0
- data/lib/functions/fnc-box-conditions.rb +316 -0
- data/lib/functions/fnc-conditions.rb +365 -0
- data/lib/functions/fnc-piecewise.rb +186 -0
- data/lib/functions/fnc-trig.rb +487 -0
- data/lib/functions/fnc-trsc.rb +196 -0
- data/lib/numbers/constants.rb +358 -0
- data/lib/numbers/variables.rb +211 -0
- data/lib/operators/bary-op.rb +185 -0
- data/lib/operators/nary-op.rb +175 -0
- data/lib/operators/op.rb +285 -0
- data/lib/overloading/fixnum.rb +61 -0
- data/lib/overloading/float.rb +61 -0
- data/lib/ragni-cas.rb +23 -187
- data/lib/version.rb +7 -1
- data.tar.gz.sig +0 -0
- metadata +15 -8
- metadata.gz.sig +0 -0
- data/lib/fnc-base.rb +0 -560
- data/lib/fnc-branch.rb +0 -388
- data/lib/fnc-trig.rb +0 -336
- data/lib/fnc-trsc.rb +0 -126
- data/lib/numbers.rb +0 -390
- data/lib/op.rb +0 -454
@@ -0,0 +1,316 @@
|
|
1
|
+
#!//usr/bin/env ruby
|
2
|
+
|
3
|
+
module CAS
|
4
|
+
# ___ ___ _ _ _ _
|
5
|
+
# | _ ) _____ __/ __|___ _ _ __| (_) |_(_)___ _ _
|
6
|
+
# | _ \/ _ \ \ / (__/ _ \ ' \/ _` | | _| / _ \ ' \
|
7
|
+
# |___/\___/_\_\\___\___/_||_\__,_|_|\__|_\___/_||_|
|
8
|
+
|
9
|
+
##
|
10
|
+
# BoxCondition class constructs a condition of the type:
|
11
|
+
#
|
12
|
+
# ```
|
13
|
+
# L < f(x) < U
|
14
|
+
# ```
|
15
|
+
#
|
16
|
+
# and this is a metaclass for different type of box conditions:
|
17
|
+
#
|
18
|
+
# * open: `a < f(x) < b`
|
19
|
+
# * lower closed: `a ≤ f(x) < b`
|
20
|
+
# * upper closed: `a < f(x) ≤ b`
|
21
|
+
# * closed: `a ≤ f(x) ≤ b`
|
22
|
+
class BoxCondition < CAS::Condition
|
23
|
+
# Contained operation
|
24
|
+
attr_reader :x
|
25
|
+
# Upper bound as `CAS::Constant`
|
26
|
+
attr_reader :lower
|
27
|
+
# Lower bound as `CAs::Constant`
|
28
|
+
attr_reader :upper
|
29
|
+
|
30
|
+
# Initializes a new box condition. A function is required as central term,
|
31
|
+
# while the second and the third elements are lower and upper bounds
|
32
|
+
# as `CAS::Constant`
|
33
|
+
#
|
34
|
+
# * **argument**: `CAS::Op` central term of the box condition
|
35
|
+
# * **argument**: `CAS::Constant` lower bound
|
36
|
+
# * **argument**: `CAS::Constant` upper bound
|
37
|
+
# * **returns**: `CAS::BoxCondition` new instance
|
38
|
+
def initialize(x, lower, upper)
|
39
|
+
if lower.is_a? Numeric
|
40
|
+
lower = CAS::const lower
|
41
|
+
end
|
42
|
+
if upper.is_a? Numeric
|
43
|
+
upper = CAS::const upper
|
44
|
+
end
|
45
|
+
CAS::Help.assert(lower, CAS::Constant)
|
46
|
+
CAS::Help.assert(upper, CAS::Constant)
|
47
|
+
|
48
|
+
CAS::Help.assert(x, CAS::Op)
|
49
|
+
|
50
|
+
lower, upper = upper, lower if lower.x > upper.x
|
51
|
+
|
52
|
+
@lower = lower
|
53
|
+
@upper = upper
|
54
|
+
@x = x
|
55
|
+
end
|
56
|
+
|
57
|
+
# Saves some required elements
|
58
|
+
def representative
|
59
|
+
@lower_cond = @upper_cond = "<"
|
60
|
+
@lower_str = @upper_str = "<"
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns true if one the central function depends upon the expression included
|
65
|
+
#
|
66
|
+
# * **argument**: `CAS::Op` operator to check against for dependencies
|
67
|
+
# * **returns**: `TrueClass` or `FalseClass`
|
68
|
+
def depend?(v)
|
69
|
+
@x.depend? v
|
70
|
+
end
|
71
|
+
|
72
|
+
# Simplify left and right term of the operator
|
73
|
+
#
|
74
|
+
# * **returns**: `CAS::BoxCondition`
|
75
|
+
def simplify
|
76
|
+
@x.simplify
|
77
|
+
return self
|
78
|
+
end
|
79
|
+
|
80
|
+
# Substitute in the central element using a dictionary
|
81
|
+
#
|
82
|
+
# * **returns**: `Hash` of substitutions
|
83
|
+
def subs(fd)
|
84
|
+
@x = @x.subs(fd)
|
85
|
+
return self
|
86
|
+
end
|
87
|
+
|
88
|
+
# Performs the derivative of the box condition. The derivative of
|
89
|
+
# a box condition is a `CAS::Equal` object (the derivative of a constant
|
90
|
+
# is zero):
|
91
|
+
#
|
92
|
+
# ```
|
93
|
+
# d
|
94
|
+
# -- [a < f(x) < b] = f'(x) == 0
|
95
|
+
# dx
|
96
|
+
# ```
|
97
|
+
#
|
98
|
+
# since between the two there is a difference relation.
|
99
|
+
#
|
100
|
+
# * **argument**: `CAS::Op` to perform the derivative
|
101
|
+
def diff(v)
|
102
|
+
CAS::equal(@x.diff(v).simplify, CAS::Zero)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns an array of variables of the central function
|
106
|
+
#
|
107
|
+
# * **returns**: `Array` of `CAS::Variable`
|
108
|
+
def args
|
109
|
+
@x.args
|
110
|
+
end
|
111
|
+
|
112
|
+
# Return true if two BoxConditions are equal, false if different
|
113
|
+
#
|
114
|
+
# * **argument**: `CAS::Op` operator to check against for equality
|
115
|
+
# * **returns**: `TrueClass` or `FalseClass`
|
116
|
+
def ==(cond)
|
117
|
+
return false if not self.class != cond.class
|
118
|
+
return (@x == cond.x and @lower == cond.lower and @upper == cond.upper)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Function call will evaluate left and right functions to solve the
|
122
|
+
# relation
|
123
|
+
#
|
124
|
+
# * **argument**: `Hash` with feed dictionary
|
125
|
+
# * **returns**: `Trueclass` or `Falseclass`
|
126
|
+
def call(_fd)
|
127
|
+
raise CAS::CASError, "This is a virtual method"
|
128
|
+
end
|
129
|
+
|
130
|
+
# Inspector for the class. It is class specific
|
131
|
+
#
|
132
|
+
# * **returns**: `String`
|
133
|
+
def inspect
|
134
|
+
"(#{@lower.inspect} #{@lower_cond} #{@x.inspect} #{@upper_cond} #{@upper.inspect})"
|
135
|
+
end
|
136
|
+
|
137
|
+
# Returns a string that represents the object to be printed
|
138
|
+
#
|
139
|
+
# `String`
|
140
|
+
def to_s
|
141
|
+
"#{@lower} #{@lower_str} #{@x} #{@upper_str} #{@upper}"
|
142
|
+
end
|
143
|
+
|
144
|
+
# Return the code that performs a condition evaluation
|
145
|
+
#
|
146
|
+
# * **returns**: `String`
|
147
|
+
def to_code
|
148
|
+
"((#{@lower.to_code} #{@lower_cond} (#{@x.to_code})) and ((#{@x.to_code}) #{@upper_cond} #{@upper.to_code}))"
|
149
|
+
end
|
150
|
+
end # BoxCondition
|
151
|
+
|
152
|
+
# ___ ___ _ _ _ _ ___
|
153
|
+
# | _ ) _____ __/ __|___ _ _ __| (_) |_(_)___ _ _ / _ \ _ __ ___ _ _
|
154
|
+
# | _ \/ _ \ \ / (__/ _ \ ' \/ _` | | _| / _ \ ' \ (_) | '_ \/ -_) ' \
|
155
|
+
# |___/\___/_\_\\___\___/_||_\__,_|_|\__|_\___/_||_\___/| .__/\___|_||_|
|
156
|
+
# |_|
|
157
|
+
|
158
|
+
##
|
159
|
+
# Implements the box condition with both bounds are open
|
160
|
+
#
|
161
|
+
# ```
|
162
|
+
# a < f(x) < b
|
163
|
+
# ```
|
164
|
+
class BoxConditionOpen < CAS::BoxCondition
|
165
|
+
# Saves some required elements
|
166
|
+
def representative
|
167
|
+
@lower_cond = @upper_cond = @lower_str = @upper_str = "<"
|
168
|
+
self
|
169
|
+
end
|
170
|
+
|
171
|
+
# Function call will evaluate box condition to evaluate
|
172
|
+
# relation
|
173
|
+
#
|
174
|
+
# * **argument**: `Hash` with feed dictionary
|
175
|
+
# * **returns**: `Trueclass` or `Falseclass`
|
176
|
+
def call(fd)
|
177
|
+
x_call = @x.call(fd)
|
178
|
+
return ((@lower.call(fd) < x_call) and (x_call < @upper))
|
179
|
+
end
|
180
|
+
end # BoxConditionOpen
|
181
|
+
|
182
|
+
# ___ ___ _ _ _ _ _ ___ _ _
|
183
|
+
# | _ ) _____ __/ __|___ _ _ __| (_) |_(_)___ _ _ | | _____ __ _____ _ _ / __| |___ ___ ___ __| |
|
184
|
+
# | _ \/ _ \ \ / (__/ _ \ ' \/ _` | | _| / _ \ ' \| |__/ _ \ V V / -_) '_| (__| / _ (_-</ -_) _` |
|
185
|
+
# |___/\___/_\_\\___\___/_||_\__,_|_|\__|_\___/_||_|____\___/\_/\_/\___|_| \___|_\___/__/\___\__,_|
|
186
|
+
|
187
|
+
##
|
188
|
+
# Implements the box condition with lower bound closed and upper open
|
189
|
+
#
|
190
|
+
# ```
|
191
|
+
# a ≤ f(x) < b
|
192
|
+
# ```
|
193
|
+
class BoxConditionLowerClosed < CAS::BoxCondition
|
194
|
+
# Saves some required elements
|
195
|
+
def representative
|
196
|
+
@lower_cond = "<="
|
197
|
+
@lower_str = "≤"
|
198
|
+
@upper_cond = @upper_str = "<"
|
199
|
+
self
|
200
|
+
end
|
201
|
+
|
202
|
+
# Function call will evaluate box condition to evaluate
|
203
|
+
# relation
|
204
|
+
#
|
205
|
+
# * **argument**: `Hash` with feed dictionary
|
206
|
+
# * **returns**: `Trueclass` or `Falseclass`
|
207
|
+
def call(fd)
|
208
|
+
x_call = @x.call(fd)
|
209
|
+
return ((@lower.call(fd) <= x_call) and (x_call < @upper))
|
210
|
+
end
|
211
|
+
end # BoxConditionLowerClosed
|
212
|
+
|
213
|
+
# ___ ___ _ _ _ _ _ _ ___ _ _
|
214
|
+
# | _ ) _____ __/ __|___ _ _ __| (_) |_(_)___ _ _| | | |_ __ _ __ ___ _ _ / __| |___ ___ ___ __| |
|
215
|
+
# | _ \/ _ \ \ / (__/ _ \ ' \/ _` | | _| / _ \ ' \ |_| | '_ \ '_ \/ -_) '_| (__| / _ (_-</ -_) _` |
|
216
|
+
# |___/\___/_\_\\___\___/_||_\__,_|_|\__|_\___/_||_\___/| .__/ .__/\___|_| \___|_\___/__/\___\__,_|
|
217
|
+
# |_| |_|
|
218
|
+
|
219
|
+
##
|
220
|
+
# Implements the box condition with lower bound open and upper closed
|
221
|
+
#
|
222
|
+
# ```
|
223
|
+
# a < f(x) ≤ b
|
224
|
+
# ```
|
225
|
+
class BoxConditionUpperClosed < CAS::BoxCondition
|
226
|
+
# Saves some required elements
|
227
|
+
def representative
|
228
|
+
@lower_cond = @lower_str = "<"
|
229
|
+
@upper_cond = "<="
|
230
|
+
@upper_str = "≤"
|
231
|
+
self
|
232
|
+
end
|
233
|
+
|
234
|
+
# Function call will evaluate box condition to evaluate
|
235
|
+
# relation
|
236
|
+
#
|
237
|
+
# * **argument**: `Hash` with feed dictionary
|
238
|
+
# * **returns**: `Trueclass` or `Falseclass`
|
239
|
+
def call(fd)
|
240
|
+
x_call = @x.call(fd)
|
241
|
+
return ((@lower.call(fd) < x_call) and (x_call <= @upper))
|
242
|
+
end
|
243
|
+
end # BoxConditionUpperClosed
|
244
|
+
|
245
|
+
# ___ ___ _ _ _ _ ___ _ _
|
246
|
+
# | _ ) _____ __/ __|___ _ _ __| (_) |_(_)___ _ _ / __| |___ ___ ___ __| |
|
247
|
+
# | _ \/ _ \ \ / (__/ _ \ ' \/ _` | | _| / _ \ ' \ (__| / _ (_-</ -_) _` |
|
248
|
+
# |___/\___/_\_\\___\___/_||_\__,_|_|\__|_\___/_||_\___|_\___/__/\___\__,_|
|
249
|
+
|
250
|
+
##
|
251
|
+
# Implements the box condition with both bounds closed
|
252
|
+
#
|
253
|
+
# ```
|
254
|
+
# a ≤ f(x) ≤ b
|
255
|
+
# ```
|
256
|
+
class BoxConditionClosed < CAS::BoxCondition
|
257
|
+
# Saves some required elements
|
258
|
+
def representative
|
259
|
+
@lower_cond = @upper_cond = "<="
|
260
|
+
@lower_str = @upper_str = "≤"
|
261
|
+
self
|
262
|
+
end
|
263
|
+
|
264
|
+
# Function call will evaluate box condition to evaluate
|
265
|
+
# relation
|
266
|
+
#
|
267
|
+
# * **argument**: `Hash` with feed dictionary
|
268
|
+
# * **returns**: `Trueclass` or `Falseclass`
|
269
|
+
def call(fd)
|
270
|
+
x_call = @x.call(fd)
|
271
|
+
return ((@lower.call(fd) <= x_call) and (x_call <= @upper))
|
272
|
+
end
|
273
|
+
end # BoxConditionUpperClosed
|
274
|
+
|
275
|
+
# Shortcut for creating a new box condition. It requires four arguments:
|
276
|
+
#
|
277
|
+
# * **argument**: `CAS::Op` function for condition
|
278
|
+
# * **argument**: `CAS::Constant` lower limit
|
279
|
+
# * **argument**: `CAs::Constant` upper limit
|
280
|
+
# * **argument**: `Symbol` of condition type it can be:
|
281
|
+
# - `:closed` for `CAs::BoxConditionClosed`
|
282
|
+
# - `:open` for `CAs::BoxConditionOpen`
|
283
|
+
# - `:upper_closed` for `CAs::BoxConditionUpperClosed`
|
284
|
+
# - `:lower_closed` for `CAs::BoxConditionLowerClosed`
|
285
|
+
# * **returns**: `CAS::BoxCondition` new instance
|
286
|
+
def self.box(x, a, b, type=:closed)
|
287
|
+
case type
|
288
|
+
when :closed
|
289
|
+
return CAS::BoxConditionClosed.new(x, a, b)
|
290
|
+
when :open
|
291
|
+
return CAS::BoxConditionOpen.new(x, a, b)
|
292
|
+
when :upper_closed
|
293
|
+
return CAS::BoxConditionUpperClosed.new(x, a, b)
|
294
|
+
when :lower_closed
|
295
|
+
return CAS::BoxConditionLowerClosed.new(x, a, b)
|
296
|
+
else
|
297
|
+
raise CAS::CASError, "Unknown box condition type"
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
class Op
|
302
|
+
# Shortcut for creating a new box condition. It requires limits and type:
|
303
|
+
#
|
304
|
+
# * **argument**: `CAS::Constant` lower limit
|
305
|
+
# * **argument**: `CAs::Constant` upper limit
|
306
|
+
# * **argument**: `Symbol` of condition type it can be:
|
307
|
+
# - `:closed` for `CAs::BoxConditionClosed`
|
308
|
+
# - `:open` for `CAs::BoxConditionOpen`
|
309
|
+
# - `:upper_closed` for `CAs::BoxConditionUpperClosed`
|
310
|
+
# - `:lower_closed` for `CAs::BoxConditionLowerClosed`
|
311
|
+
# * **returns**: `CAS::BoxCondition` new instance
|
312
|
+
def limit(a, b, type=:closed)
|
313
|
+
return CAS::box(self, a, b, type)
|
314
|
+
end
|
315
|
+
end # Op
|
316
|
+
end
|
@@ -0,0 +1,365 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module CAS
|
4
|
+
# ___ _ _ _ _
|
5
|
+
# / __|___ _ _ __| (_) |_(_)___ _ _
|
6
|
+
# | (__/ _ \ ' \/ _` | | _| / _ \ ' \
|
7
|
+
# \___\___/_||_\__,_|_|\__|_\___/_||_|
|
8
|
+
|
9
|
+
##
|
10
|
+
# Condition class is a pseudo-class for all the other kind of conditions:
|
11
|
+
#
|
12
|
+
# * Equal
|
13
|
+
# * Greater
|
14
|
+
# * GreaterEqual
|
15
|
+
# * Smaller
|
16
|
+
# * SmallerEqual
|
17
|
+
#
|
18
|
+
# When derivated, the two functions (that can be considered as the difference of two elements)
|
19
|
+
# are derived autonoumouosly. A condition is composed by:
|
20
|
+
#
|
21
|
+
# * left function (x)
|
22
|
+
# * right function (y)
|
23
|
+
# * type of condition
|
24
|
+
class Condition
|
25
|
+
# Left hand side
|
26
|
+
attr_reader :x
|
27
|
+
# Right hand side
|
28
|
+
attr_reader :y
|
29
|
+
|
30
|
+
# Initializer for a new condition. The condition is implicit in the class, thus a
|
31
|
+
# pure `CAS::Condition` cannot be used.
|
32
|
+
#
|
33
|
+
# * **argument**: `CAS::Op` left argument
|
34
|
+
# * **argument**: `CAS::Op` right argument
|
35
|
+
# * **returns**: `CAS::Condition` new instance
|
36
|
+
def initialize(x, y)
|
37
|
+
@x = x
|
38
|
+
@y = y
|
39
|
+
self.representative
|
40
|
+
end
|
41
|
+
|
42
|
+
# Saves some required elements
|
43
|
+
def representative
|
44
|
+
@cond_type = "??"
|
45
|
+
@cond_repr = "??"
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
# Function call will evaluate left and right functions to solve the
|
50
|
+
# relation
|
51
|
+
#
|
52
|
+
# * **argument**: `Hash` with feed dictionary
|
53
|
+
# * **returns**: `Trueclass` or `Falseclass`
|
54
|
+
def call(_fd)
|
55
|
+
raise CAS::CASError, "This is a virtual method"
|
56
|
+
end
|
57
|
+
|
58
|
+
# Inspector for the class. It is class specific
|
59
|
+
#
|
60
|
+
# * **returns**: `String`
|
61
|
+
def inspect
|
62
|
+
"#{self.class}(#{@x.inspect}, #{@y.inspect})"
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns a string that represents the object to be printed
|
66
|
+
#
|
67
|
+
# `String`
|
68
|
+
def to_s
|
69
|
+
"(#{@x} #{@cond_repr} #{@y})"
|
70
|
+
end
|
71
|
+
|
72
|
+
# Return the code that performs a condition evaluation
|
73
|
+
#
|
74
|
+
# * **returns**: `String`
|
75
|
+
def to_code
|
76
|
+
"(#{@x} #{@cond_type} #{@y})"
|
77
|
+
end
|
78
|
+
|
79
|
+
# Returns an array of variables of the two functions in the condition
|
80
|
+
#
|
81
|
+
# * **returns**: `Array` of `CAS::Variable`
|
82
|
+
def args
|
83
|
+
(@x.args + @y.args).uniq
|
84
|
+
end
|
85
|
+
|
86
|
+
# Performs the derivative of the two elements:
|
87
|
+
#
|
88
|
+
# ```
|
89
|
+
# d
|
90
|
+
# -- [f(x) > g(y)] = f'(x) > g'(x)
|
91
|
+
# dx
|
92
|
+
# ```
|
93
|
+
#
|
94
|
+
# since between the two there is a difference relation.
|
95
|
+
#
|
96
|
+
# * **argument**: `CAS::Op` to perform the derivative
|
97
|
+
def diff(v)
|
98
|
+
CAS::Help.assert v, CAS::Op
|
99
|
+
|
100
|
+
@x.diff(v)
|
101
|
+
@y.diff(v)
|
102
|
+
self.simplify
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns true if one of the two functions depends upon the expression included
|
106
|
+
#
|
107
|
+
# * **argument**: `CAS::Op` operator to check against for dependencies
|
108
|
+
# * **returns**: `TrueClass` or `FalseClass`
|
109
|
+
def depend?(v)
|
110
|
+
CAS::Help.assert v, CAS::Op
|
111
|
+
|
112
|
+
@x.depend?(v) or @y.depend?(v)
|
113
|
+
end
|
114
|
+
|
115
|
+
# Return true if two functions are equal, false if different
|
116
|
+
#
|
117
|
+
# * **argument**: `CAS::Op` operator to check against for equality
|
118
|
+
# * **returns**: `TrueClass` or `FalseClass`
|
119
|
+
def ==(op)
|
120
|
+
CAS::Help.assert(op, CAS::Op)
|
121
|
+
|
122
|
+
# condB = (@x == op.y) and (@y == op.x)
|
123
|
+
return ((@x == op.x) and (@y == op.y) and (self.class == op.class))
|
124
|
+
end
|
125
|
+
|
126
|
+
# Simplify left and right term of the operator
|
127
|
+
#
|
128
|
+
# * **returns**: `CAS::Condition`
|
129
|
+
def simplify
|
130
|
+
@x.simplify
|
131
|
+
@y.simplify
|
132
|
+
return self
|
133
|
+
end
|
134
|
+
|
135
|
+
# Substitute in the two elements using a dictionary
|
136
|
+
#
|
137
|
+
# * **returns**: `Hash` of substitutions
|
138
|
+
def subs(fd)
|
139
|
+
CAS::Help.assert(fd, Hash)
|
140
|
+
@x.subs(fd)
|
141
|
+
@y.subs(fd)
|
142
|
+
return self
|
143
|
+
end
|
144
|
+
|
145
|
+
# Returns the dot graphviz representation of the code
|
146
|
+
#
|
147
|
+
# * **returns**: `String`
|
148
|
+
def dot_graph(node)
|
149
|
+
cls = "#{self.class.to_s.gsub("CAS::", "")}_#{self.object_id}"
|
150
|
+
"#{cls} -> #{@x.dot_graph node}\n #{cls} -> #{@y.dot_graph node}"
|
151
|
+
end
|
152
|
+
end # Condition
|
153
|
+
|
154
|
+
# ___ _
|
155
|
+
# | __|__ _ _ _ __ _| |
|
156
|
+
# | _|/ _` | || / _` | |
|
157
|
+
# |___\__, |\_,_\__,_|_|
|
158
|
+
# |_|
|
159
|
+
|
160
|
+
##
|
161
|
+
# This class is a Condition for two equal function
|
162
|
+
class Equal < CAS::Condition
|
163
|
+
# Saves some required elements
|
164
|
+
def representative
|
165
|
+
@cond_type, @cond_repr = "==", "≡"
|
166
|
+
self
|
167
|
+
end
|
168
|
+
|
169
|
+
# Function call will evaluate left and right functions to solve the
|
170
|
+
# relation
|
171
|
+
#
|
172
|
+
# * **argument**: `Hash` with feed dictionary
|
173
|
+
# * **returns**: `Trueclass` or `Falseclass`
|
174
|
+
def call(fd)
|
175
|
+
CAS::Help.assert fd, Hash
|
176
|
+
|
177
|
+
return (@x.call(fd) == @y.call(fd))
|
178
|
+
end
|
179
|
+
|
180
|
+
# Return true if two functions are equal, false if different
|
181
|
+
#
|
182
|
+
# * **argument**: `CAS::Op` operator to check against for equality
|
183
|
+
# * **returns**: `TrueClass` or `FalseClass`
|
184
|
+
def ==(op)
|
185
|
+
CAS::Help.assert(op, CAS::Op)
|
186
|
+
cond_f = ((@x == op.x) and (@y == op.y)) or ((@x == op.y) and (@y == op.x))
|
187
|
+
return (cond_f and (self.class == op.class))
|
188
|
+
end
|
189
|
+
end # Equal
|
190
|
+
|
191
|
+
# ___ _ _
|
192
|
+
# / __|_ __ __ _| | |___ _ _
|
193
|
+
# \__ \ ' \/ _` | | / -_) '_|
|
194
|
+
# |___/_|_|_\__,_|_|_\___|_|
|
195
|
+
|
196
|
+
##
|
197
|
+
# This class is a Condition for left smaller function
|
198
|
+
class Smaller < CAS::Condition
|
199
|
+
# Saves some required elements
|
200
|
+
def representative
|
201
|
+
@cond_type = @cond_repr = "<"
|
202
|
+
self
|
203
|
+
end
|
204
|
+
|
205
|
+
# Function call will evaluate left and right functions to solve the
|
206
|
+
# relation
|
207
|
+
#
|
208
|
+
# * **argument**: `Hash` with feed dictionary
|
209
|
+
# * **returns**: `Trueclass` or `Falseclass`
|
210
|
+
def call(fd)
|
211
|
+
CAS::Help.assert fd, Hash
|
212
|
+
|
213
|
+
return (@x.call(fd) < @y.call(fd))
|
214
|
+
end
|
215
|
+
end # Smaller
|
216
|
+
|
217
|
+
# ___ _
|
218
|
+
# / __|_ _ ___ __ _| |_ ___ _ _
|
219
|
+
# | (_ | '_/ -_) _` | _/ -_) '_|
|
220
|
+
# \___|_| \___\__,_|\__\___|_|
|
221
|
+
|
222
|
+
##
|
223
|
+
# This class is a Condition for right smaller function
|
224
|
+
class Greater < CAS::Condition
|
225
|
+
# Saves some required elements
|
226
|
+
def representative
|
227
|
+
@cond_type = @cond_repr = ">"
|
228
|
+
self
|
229
|
+
end
|
230
|
+
|
231
|
+
# Function call will evaluate left and right functions to solve the
|
232
|
+
# relation
|
233
|
+
#
|
234
|
+
# * **argument**: `Hash` with feed dictionary
|
235
|
+
# * **returns**: `Trueclass` or `Falseclass`
|
236
|
+
def call(fd)
|
237
|
+
CAS::Help.assert fd, Hash
|
238
|
+
|
239
|
+
return (@x.call(fd) > @y.call(fd))
|
240
|
+
end
|
241
|
+
end # Greater
|
242
|
+
|
243
|
+
# ___ _ _ ___ _
|
244
|
+
# / __|_ __ __ _| | |___ _ _| __|__ _ _ _ __ _| |
|
245
|
+
# \__ \ ' \/ _` | | / -_) '_| _|/ _` | || / _` | |
|
246
|
+
# |___/_|_|_\__,_|_|_\___|_| |___\__, |\_,_\__,_|_|
|
247
|
+
# |_|
|
248
|
+
|
249
|
+
##
|
250
|
+
# This class is a Condition for left smaller or equal function
|
251
|
+
class SmallerEqual < CAS::Condition
|
252
|
+
# Saves some required elements
|
253
|
+
def representative
|
254
|
+
@cond_type = "<="
|
255
|
+
@cond_repr = "≤"
|
256
|
+
self
|
257
|
+
end
|
258
|
+
|
259
|
+
# Function call will evaluate left and right functions to solve the
|
260
|
+
# relation
|
261
|
+
#
|
262
|
+
# * **argument**: `Hash` with feed dictionary
|
263
|
+
# * **returns**: `Trueclass` or `Falseclass`
|
264
|
+
def call(fd)
|
265
|
+
CAS::Help.assert fd, Hash
|
266
|
+
|
267
|
+
return (@x.call(fd) <= @y.call(fd))
|
268
|
+
end
|
269
|
+
end # SmallerEqual
|
270
|
+
|
271
|
+
# ___ _ ___ _
|
272
|
+
# / __|_ _ ___ __ _| |_ ___ _ _| __|__ _ _ _ __ _| |
|
273
|
+
# | (_ | '_/ -_) _` | _/ -_) '_| _|/ _` | || / _` | |
|
274
|
+
# \___|_| \___\__,_|\__\___|_| |___\__, |\_,_\__,_|_|
|
275
|
+
# |_|
|
276
|
+
|
277
|
+
##
|
278
|
+
# This class is a condition for right smaller or equal function
|
279
|
+
class GreaterEqual < CAS::Condition
|
280
|
+
# Saves some required elements
|
281
|
+
def representative
|
282
|
+
@cond_type = ">="
|
283
|
+
@cond_repr = "≥"
|
284
|
+
self
|
285
|
+
end
|
286
|
+
|
287
|
+
# Function call will evaluate left and right functions to solve the
|
288
|
+
# relation
|
289
|
+
#
|
290
|
+
# * **argument**: `Hash` with feed dictionary
|
291
|
+
# * **returns**: `Trueclass` or `Falseclass`
|
292
|
+
def call(fd)
|
293
|
+
CAS::Help.assert fd, Hash
|
294
|
+
|
295
|
+
return (@x.call(fd) >= @y.call(fd))
|
296
|
+
end
|
297
|
+
end # SmallerEqual
|
298
|
+
|
299
|
+
# Shortcut creates a `CAS::Equal` object
|
300
|
+
def self.equal(x, y)
|
301
|
+
CAS::Equal.new(x, y)
|
302
|
+
end
|
303
|
+
|
304
|
+
# Shortcut creates a `CAS::Greater` object
|
305
|
+
def self.greater(x, y)
|
306
|
+
CAS::Greater.new(x, y)
|
307
|
+
end
|
308
|
+
|
309
|
+
# Shortcut creates a `CAS::GreaterEqual` object
|
310
|
+
def self.greater_equal(x, y)
|
311
|
+
CAS::GreaterEqual.new(x, y)
|
312
|
+
end
|
313
|
+
|
314
|
+
# Shortcut creates `CAS::Smaller` object
|
315
|
+
def self.smaller(x, y)
|
316
|
+
CAS::Smaller.new(x, y)
|
317
|
+
end
|
318
|
+
|
319
|
+
# Shortcut creates a `CAs::SmallerEqual` object
|
320
|
+
def self.smaller_equal(x, y)
|
321
|
+
CAS::SmallerEqual.new(x, y)
|
322
|
+
end
|
323
|
+
|
324
|
+
class Op
|
325
|
+
# Shortcut for creating equality condition.
|
326
|
+
#
|
327
|
+
# * **argument**: `CAS::Op` ther element of the condition
|
328
|
+
# * **returns**: `CAS::Equal` new instance
|
329
|
+
def equal(v)
|
330
|
+
CAS.equal(self, v)
|
331
|
+
end
|
332
|
+
|
333
|
+
# Shortcut for creating greater kind condition.
|
334
|
+
#
|
335
|
+
# * **argument**: `CAS::Op` ther element of the condition
|
336
|
+
# * **returns**: `CAS::Greater` new instance
|
337
|
+
def greater(v)
|
338
|
+
CAS.greater(self, v)
|
339
|
+
end
|
340
|
+
|
341
|
+
# Shortcut for creating a smaller kind condition.
|
342
|
+
#
|
343
|
+
# * **argument**: `CAS::Op` ther element of the condition
|
344
|
+
# * **returns**: `CAS::Smaller` new instance
|
345
|
+
def smaller(v)
|
346
|
+
CAS.smaller(self, v)
|
347
|
+
end
|
348
|
+
|
349
|
+
# Shortcut for creating a greater equal kind condition.
|
350
|
+
#
|
351
|
+
# * **argument**: `CAS::Op` ther element of the condition
|
352
|
+
# * **returns**: `CAS::GreaterEqual` new instance
|
353
|
+
def greater_equal(v)
|
354
|
+
CAS.greater_equal(self, v)
|
355
|
+
end
|
356
|
+
|
357
|
+
# Shortcut for creating a smaller equal kind condition.
|
358
|
+
#
|
359
|
+
# * **argument**: `CAS::Op` ther element of the condition
|
360
|
+
# * **returns**: `CAS::SmallerEqual` new instance
|
361
|
+
def smaller_equal(v)
|
362
|
+
CAS.smaller_equal(self, v)
|
363
|
+
end
|
364
|
+
end # Op
|
365
|
+
end
|