symbolic 0.2.0 → 0.2.1

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.
data/README.rdoc CHANGED
@@ -14,7 +14,7 @@ Currently I've implemented only naive optimizations to simplify math expressions
14
14
  x = var :name => 'x'
15
15
  y = var :name => 'y'
16
16
 
17
- f = symbolic { (4 - 2*(-x) + y*(-1.0))*x - 0*y + 0 - 2 }
17
+ f = (4 - 2*(-x) + y*(-1.0))*x - 0*y + 0 - 2
18
18
  puts f # => (4+2*x-y)*x-2
19
19
 
20
20
  p f.detailed_operations # => {"+"=>1, "-"=>2, "*"=>2}
@@ -26,7 +26,7 @@ Currently I've implemented only naive optimizations to simplify math expressions
26
26
  puts f.value # => 6
27
27
 
28
28
 
29
- g = symbolic { Math.cos(y) }
29
+ g = Symbolic::Math.cos(y)
30
30
  puts g # => cos(y)
31
31
  y.value = 0
32
32
  puts g.value # => 1.0
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ begin
5
5
  require 'jeweler'
6
6
  Jeweler::Tasks.new do |gem|
7
7
  gem.name = "symbolic"
8
- gem.version = '0.2.0'
8
+ gem.version = '0.2.1'
9
9
  gem.summary = 'Symbolic math for ruby'
10
10
  gem.description = %Q{Symbolic math can be really helpful if you want to simplify some giant equation or if you don't want to get a performance hit re-evaluating big math expressions every time when few variables change.}
11
11
  gem.email = "ravwar@gmail.com"
data/lib/symbolic.rb CHANGED
@@ -1,57 +1,58 @@
1
+ Symbolic = Module.new
2
+
3
+ require 'symbolic/operation'
4
+ require 'symbolic/operation/unary'
5
+ require 'symbolic/operation/unary/minus'
6
+ require 'symbolic/operation/binary'
7
+ require 'symbolic/operation/binary/addition'
8
+ require 'symbolic/operation/binary/subtraction'
9
+ require 'symbolic/operation/binary/multiplication'
10
+ require 'symbolic/operation/binary/division'
11
+ require 'symbolic/operation/binary/exponentiation'
12
+
13
+ require 'symbolic/coerced'
14
+ require 'symbolic/variable'
15
+ require 'symbolic/function'
16
+ require 'symbolic/math'
17
+
18
+ require 'extensions/kernel'
19
+ require 'extensions/numeric'
20
+ require 'extensions/matrix'
21
+
1
22
  module Symbolic
2
- def self.operations
3
- { :* => :multiplication,
4
- :+ => :addition,
5
- :- => :subtraction,
6
- :/ => :division }
23
+ def -@
24
+ Operation::Unary::Minus.for self
7
25
  end
8
26
 
9
- operations.each do |sign, name|
10
- method = <<-CODE
11
- def #{sign}(value)
12
- Optimization.#{name} self, value
13
- end
14
- CODE
15
- class_eval method, __FILE__, __LINE__
27
+ def +@
28
+ self
16
29
  end
17
30
 
18
- def self.math_operations
19
- [:cos, :sin]
31
+ def +(var)
32
+ Operation::Binary::Addition.for self, var
20
33
  end
21
34
 
22
- def -@
23
- UnaryMinus.create self
35
+ def -(var)
36
+ Operation::Binary::Subtraction.for self, var
24
37
  end
25
38
 
26
- def +@
27
- self
39
+ def *(var)
40
+ Operation::Binary::Multiplication.for self, var
28
41
  end
29
42
 
30
- def coerce(numeric)
31
- return Coerced.new(self), numeric
43
+ def /(var)
44
+ Operation::Binary::Division.for self, var
45
+ end
46
+
47
+ def **(var)
48
+ Operation::Binary::Exponentiation.for self, var
32
49
  end
33
50
 
34
- def undefined?
35
- !value
51
+ def coerce(numeric)
52
+ return Coerced.new(self), numeric
36
53
  end
37
54
 
38
55
  def operations
39
56
  detailed_operations.values.inject(0) {|sum,it| sum + it }
40
57
  end
41
- end
42
-
43
- require 'symbolic/coerced'
44
- require 'symbolic/optimization'
45
- require 'symbolic/optimization/base'
46
- require 'symbolic/optimization/addition'
47
- require 'symbolic/optimization/subtraction'
48
- require 'symbolic/optimization/multiplication'
49
- require 'symbolic/optimization/division'
50
- require 'symbolic/variable'
51
- require 'symbolic/expression'
52
- require 'symbolic/method'
53
- require 'symbolic/unary_minus'
54
-
55
- require 'extensions/kernel'
56
- require 'extensions/numeric'
57
- require 'extensions/matrix'
58
+ end
@@ -4,13 +4,24 @@ module Symbolic
4
4
  @symbolic = symbolic
5
5
  end
6
6
 
7
- Symbolic.operations.each do |sign, name|
8
- method = <<-CODE
9
- def #{sign}(numeric)
10
- Optimization.#{name} numeric, @symbolic
11
- end
12
- CODE
13
- class_eval method, __FILE__, __LINE__
14
- end # Symbolic.operations.each
15
- end # Coerced
16
- end # Symbolic
7
+ def +(numeric)
8
+ Operation::Binary::Addition.for numeric, @symbolic
9
+ end
10
+
11
+ def -(numeric)
12
+ Operation::Binary::Subtraction.for numeric, @symbolic
13
+ end
14
+
15
+ def *(numeric)
16
+ Operation::Binary::Multiplication.for numeric, @symbolic
17
+ end
18
+
19
+ def /(numeric)
20
+ Operation::Binary::Division.for numeric, @symbolic
21
+ end
22
+
23
+ def **(numeric)
24
+ Operation::Binary::Exponentiation.for numeric, @symbolic
25
+ end
26
+ end
27
+ end
@@ -1,7 +1,6 @@
1
1
  module Symbolic
2
- class Method
2
+ class Function
3
3
  include Symbolic
4
-
5
4
  def initialize(variable, operation)
6
5
  @variable, @operation = variable, operation
7
6
  end
@@ -0,0 +1,9 @@
1
+ module Symbolic::Math
2
+ def self.cos(argument)
3
+ Symbolic::Function.new argument, :cos
4
+ end
5
+
6
+ def self.sin(argument)
7
+ Symbolic::Function.new argument, :sin
8
+ end
9
+ end
@@ -0,0 +1,48 @@
1
+ class Symbolic::Operation
2
+ include Symbolic
3
+
4
+ def self.for(*args)
5
+ simplify(*args) || new(*args)
6
+ end
7
+
8
+ def self.negative?(var)
9
+ var.is_a?(Unary::Minus) || (var.is_a?(Numeric) && var < 0)
10
+ end
11
+
12
+ private
13
+
14
+ def operation(expression)
15
+ case expression
16
+ when Unary::Minus then :unary_minus
17
+ when Binary::Addition then :addition
18
+ when Binary::Subtraction then :subtraction
19
+ when Binary::Multiplication then :multiplication
20
+ when Binary::Division then :division
21
+ when Symbolic::Variable then :variable
22
+ end
23
+ end
24
+
25
+ def unary_minus?(expression)
26
+ operation(expression) == :unary_minus
27
+ end
28
+
29
+ def addition?(expression)
30
+ operation(expression) == :addition
31
+ end
32
+
33
+ def subtraction?(expression)
34
+ operation(expression) == :subtraction
35
+ end
36
+
37
+ def multiplication?(expression)
38
+ operation(expression) == :multiplication
39
+ end
40
+
41
+ def division?(expression)
42
+ operation(expression) == :division
43
+ end
44
+
45
+ def variable?(expression)
46
+ operation(expession) == :variable
47
+ end
48
+ end
@@ -0,0 +1,64 @@
1
+ class Symbolic::Operation::Binary < Symbolic::Operation
2
+ def self.simplify(var1, var2)
3
+ simplify_first_arg(var1, var2) || simplify_second_arg(var1, var2)
4
+ end
5
+
6
+ def self.symmetric
7
+ def self.simplify(var1, var2)
8
+ simplify_first_arg(var1, var2) || simplify_first_arg(var2, var1)
9
+ end
10
+
11
+ def ==(object)
12
+ (object.class == self.class) &&
13
+ ((object.var1 == @var1 && object.var2 == @var2) || (object.var1 == @var2 && object.var2 == @var1))
14
+ end
15
+ end
16
+
17
+ def self.brackets_for(*operations)
18
+ def brackets(var)
19
+ operations.include?(operation var) ? "(#{var})" : var.to_s
20
+ end
21
+ end
22
+
23
+ def initialize(var1, var2)
24
+ @var1, @var2 = var1, var2
25
+ end
26
+
27
+ def variables
28
+ @var1.variables | @var2.variables
29
+ end
30
+
31
+ def undefined_variables
32
+ variables.select {|it| it.value.nil? }
33
+ end
34
+
35
+ def value
36
+ @var1.value.send sign, @var2.value if undefined_variables.empty?
37
+ end
38
+
39
+ def detailed_operations
40
+ operations_of(@var1).tap {|it| it.merge!(operations_of @var2)[sign] += 1 }
41
+ end
42
+
43
+ def to_s
44
+ "#{brackets @var1}#{sign}#{brackets @var2}"
45
+ end
46
+
47
+ def ==(object)
48
+ (object.class == self.class) && (object.var1 == @var1 && object.var2 == @var2)
49
+ end
50
+
51
+ protected
52
+
53
+ attr_reader :var1, :var2
54
+
55
+ private
56
+
57
+ def operations_of(var)
58
+ var.is_a?(Symbolic) ? var.detailed_operations : Hash.new(0)
59
+ end
60
+
61
+ def brackets(var)
62
+ var.to_s
63
+ end
64
+ end
@@ -0,0 +1,15 @@
1
+ class Symbolic::Operation::Binary::Addition < Symbolic::Operation::Binary
2
+ symmetric
3
+
4
+ def self.simplify_first_arg(var1, var2)
5
+ if var1 == 0
6
+ var2
7
+ elsif negative?(var1)
8
+ var2 - var1.abs
9
+ end
10
+ end
11
+
12
+ def sign
13
+ '+'
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ class Symbolic::Operation::Binary::Division < Symbolic::Operation::Binary
2
+ brackets_for :unary_minus, :addition, :subtraction
3
+
4
+ def self.simplify_first_arg(var1, var2)
5
+ if var1 == 0
6
+ 0
7
+ elsif negative?(var1)
8
+ -(var1.abs / var2)
9
+ end
10
+ end
11
+
12
+ def self.simplify_second_arg(var1, var2)
13
+ if var2 == 1
14
+ var1
15
+ elsif negative?(var2)
16
+ -(var1 / var2.abs)
17
+ end
18
+ end
19
+
20
+ def sign
21
+ '/'
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ class Symbolic::Operation::Binary::Exponentiation < Symbolic::Operation::Binary
2
+ brackets_for :unary_minus, :addition, :subtraction, :multiplication, :division
3
+
4
+ def self.simplify_first_arg(var1, var2)
5
+ # add conditional for negative?(var1) and even or odd values of var2
6
+ if var1 == 0
7
+ 0
8
+ elsif var1 == 1
9
+ 1
10
+ end
11
+ end
12
+
13
+ def self.simplify_second_arg(var1, var2)
14
+ if var2 == 0
15
+ 1
16
+ elsif var2 == 1
17
+ var1
18
+ end
19
+ end
20
+
21
+ def sign
22
+ '**'
23
+ end
24
+ end
@@ -0,0 +1,42 @@
1
+ class Symbolic::Operation::Binary::Multiplication < Symbolic::Operation::Binary
2
+ symmetric
3
+ brackets_for :unary_minus, :addition, :subtraction
4
+
5
+ def self.simplify_first_arg(var1, var2)
6
+ if var1 == 0
7
+ 0
8
+ elsif var1 == 1
9
+ var2
10
+ elsif negative?(var1)
11
+ -(var1.abs * var2)
12
+ end
13
+ end
14
+
15
+ def sign
16
+ '*'
17
+ end
18
+
19
+ # def initialize(var1, var2)
20
+ # super
21
+ # coef, numerators, denominators = unite_factors factors_of(var1), factors_of(var2)
22
+ # end
23
+
24
+ def unite_factors(factors1, factors2)
25
+ c1, n1, d1 = factors1
26
+ c2, n2, d2 = factors2
27
+ return c1*c2, n1+n2, d1+d2
28
+ end
29
+
30
+ def factors_of(var)
31
+ case var
32
+ when Numeric
33
+ [var, [], []]
34
+ when Unary::Minus
35
+ unite_factors [-1, [], []], factors_of(var.abs)
36
+ when Binary::Multiplication
37
+ [var.coef, var.nominators, var.denominators]
38
+ else
39
+ [[], [var], []]
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,17 @@
1
+ class Symbolic::Operation::Binary::Subtraction < Symbolic::Operation::Binary
2
+ def self.simplify_first_arg(var1, var2)
3
+ -var2 if var1 == 0
4
+ end
5
+
6
+ def self.simplify_second_arg(var1, var2)
7
+ if var2 == 0
8
+ var1
9
+ elsif negative?(var2)
10
+ var1 + var2.abs
11
+ end
12
+ end
13
+
14
+ def sign
15
+ '-'
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ class Symbolic::Operation::Unary < Symbolic::Operation
2
+ def initialize(expression)
3
+ @expression = expression
4
+ end
5
+
6
+ def variables
7
+ @expression.variables
8
+ end
9
+
10
+ def undefined_variables
11
+ @expression.undefined_variables
12
+ end
13
+ end
@@ -0,0 +1,32 @@
1
+ class Symbolic::Operation
2
+ class Unary::Minus < Unary
3
+ def self.simplify(expression)
4
+ expression.abs if expression.is_a? Unary::Minus
5
+ end
6
+
7
+ def abs
8
+ # TODO: implement Symbolic#abs
9
+ @expression
10
+ end
11
+
12
+ def to_s
13
+ if [:variable, :multiplication, :division].include? operation(@expression)
14
+ "-#{@expression}"
15
+ else
16
+ "(-#{@expression})"
17
+ end
18
+ end
19
+
20
+ def value
21
+ -@expression.value if undefined_variables.empty?
22
+ end
23
+
24
+ def ==(object)
25
+ object.is_a?(Unary::Minus) && object.abs == @expression
26
+ end
27
+
28
+ def detailed_operations
29
+ @expression.detailed_operations.tap {|it| it['-@'] += 1}
30
+ end
31
+ end
32
+ end
@@ -1,7 +1,6 @@
1
1
  module Symbolic
2
2
  class Variable
3
3
  include Symbolic
4
-
5
4
  attr_accessor :name, :proc
6
5
  attr_writer :value
7
6
 
@@ -7,7 +7,15 @@ describe "Symbolic" do
7
7
  end
8
8
 
9
9
  def expression(string)
10
- eval string.gsub(/[a-z]+/, '@\0')
10
+ eval string.gsub(/[xy]/, '@\0')
11
+ end
12
+
13
+ def self.should_equal(conditions)
14
+ conditions.each do |non_optimized, optimized|
15
+ it non_optimized do
16
+ expression(non_optimized).should == expression(optimized)
17
+ end
18
+ end
11
19
  end
12
20
 
13
21
  describe "evaluation (x=1, y=2):" do
@@ -39,18 +47,13 @@ describe "Symbolic" do
39
47
  'y/2' => 1,
40
48
  'x/2.0' => 0.5,
41
49
  '-2/x' => -2,
42
- '4/(-y)' => -2
50
+ '4/(-y)' => -2,
51
+ 'x**2' => 1,
52
+ '4**y' => 16,
53
+ 'y**x' => 2
43
54
  end
44
55
 
45
56
  describe "optimization:" do
46
- def self.should_equal(conditions)
47
- conditions.each do |non_optimized, optimized|
48
- it non_optimized do
49
- expression(non_optimized).should == expression(optimized)
50
- end
51
- end
52
- end
53
-
54
57
  should_equal \
55
58
  '-(-x)' => 'x',
56
59
 
@@ -81,7 +84,22 @@ describe "Symbolic" do
81
84
  '-x*y' => '-(x*y)',
82
85
  '(-x)*(-y)' => 'x*y',
83
86
 
84
- 'x / 1' => 'x'
87
+ '0 / x' => '0',
88
+ 'x / 1' => 'x',
89
+
90
+ '0**x' => '0',
91
+ '1**x' => '1',
92
+ 'x**0' => '1',
93
+ 'x**1' => 'x'
94
+ end
95
+
96
+ describe 'general methods:' do
97
+ should_equal \
98
+ 'x.variables' => '[x]',
99
+ '(-(x-y)).variables' => '[x,y]',
100
+ '(x+y).undefined_variables' => '[]',
101
+ '(-x-4*y+5-y/x).detailed_operations' =>
102
+ '{"+" => 1, "-" => 2, "*" => 1, "/" => 1, "-@" => 1}'
85
103
  end
86
104
 
87
105
  describe "formulas" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: symbolic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - brainopia
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-12-07 00:00:00 +03:00
12
+ date: 2009-12-08 00:00:00 +03:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -39,15 +39,17 @@ files:
39
39
  - lib/extensions/numeric.rb
40
40
  - lib/symbolic.rb
41
41
  - lib/symbolic/coerced.rb
42
- - lib/symbolic/expression.rb
43
- - lib/symbolic/method.rb
44
- - lib/symbolic/optimization.rb
45
- - lib/symbolic/optimization/addition.rb
46
- - lib/symbolic/optimization/base.rb
47
- - lib/symbolic/optimization/division.rb
48
- - lib/symbolic/optimization/multiplication.rb
49
- - lib/symbolic/optimization/subtraction.rb
50
- - lib/symbolic/unary_minus.rb
42
+ - lib/symbolic/function.rb
43
+ - lib/symbolic/math.rb
44
+ - lib/symbolic/operation.rb
45
+ - lib/symbolic/operation/binary.rb
46
+ - lib/symbolic/operation/binary/addition.rb
47
+ - lib/symbolic/operation/binary/division.rb
48
+ - lib/symbolic/operation/binary/exponentiation.rb
49
+ - lib/symbolic/operation/binary/multiplication.rb
50
+ - lib/symbolic/operation/binary/subtraction.rb
51
+ - lib/symbolic/operation/unary.rb
52
+ - lib/symbolic/operation/unary/minus.rb
51
53
  - lib/symbolic/variable.rb
52
54
  - spec/spec.opts
53
55
  - spec/spec_helper.rb
@@ -1,66 +0,0 @@
1
- module Symbolic
2
- class Expression
3
- include Symbolic
4
-
5
- attr_reader :var1, :var2, :operation
6
-
7
- def initialize(var1, var2, operation)
8
- @var1, @var2, @operation = var1, var2, operation
9
- end
10
-
11
- def to_s
12
- "#{brackets @var1}#{@operation}#{brackets @var2}"
13
- end
14
-
15
- def plus?
16
- @operation == '+'
17
- end
18
-
19
- def minus?
20
- @operation == '-'
21
- end
22
-
23
- def multiply?
24
- @operation == '*'
25
- end
26
-
27
- def divide?
28
- @operation == '/'
29
- end
30
-
31
- def value
32
- @var1.value.send @operation, @var2.value if undefined_variables.empty?
33
- end
34
-
35
- def variables
36
- @var1.variables | @var2.variables
37
- end
38
-
39
- def undefined_variables
40
- variables.select &:undefined?
41
- end
42
-
43
- def ==(object)
44
- object.is_a?(Expression) && (object.operation == @operation) &&
45
- ((object.var1 == @var1 && object.var2 == @var2) || ((plus? || multiply?) && (object.var1 == @var2 && object.var2 == @var1)))
46
- end
47
-
48
- def detailed_operations
49
- operations_of(@var1).tap {|it| it.merge!(operations_of @var2)[@operation] += 1 }
50
- end
51
-
52
- private
53
-
54
- def brackets(var)
55
- brackets_conditional(var) ? "(#{var})" : var.to_s
56
- end
57
-
58
- def brackets_conditional(var)
59
- %w(* /).include?(@operation) && (var.is_a?(UnaryMinus) || var.is_a?(Expression) && (var.plus? || var.minus?))
60
- end
61
-
62
- def operations_of(var)
63
- var.is_a?(Symbolic) ? var.detailed_operations : Hash.new(0)
64
- end
65
- end
66
- end
@@ -1,12 +0,0 @@
1
- module Symbolic
2
- module Optimization
3
- Symbolic.operations.each do |operation_sign, operation_name|
4
- method = <<-CODE
5
- def #{operation_name}(var1, var2)
6
- #{operation_name.to_s.capitalize}.optimize(var1, var2) || Expression.new(var1, var2, '#{operation_sign}')
7
- end
8
- CODE
9
- instance_eval method, __FILE__, __LINE__
10
- end
11
- end
12
- end
@@ -1,15 +0,0 @@
1
- module Symbolic::Optimization::Addition
2
- extend Symbolic::Optimization::Base
3
-
4
- def self.optimize_first_arg(var1, var2)
5
- if var1 == 0
6
- var2
7
- elsif negative?(var1)
8
- var2 - var1.abs
9
- end
10
- end
11
-
12
- def self.optimize_second_arg(var1, var2)
13
- optimize_first_arg var2, var1
14
- end
15
- end
@@ -1,9 +0,0 @@
1
- module Symbolic::Optimization::Base
2
- def optimize(var1, var2)
3
- optimize_first_arg(var1, var2) || optimize_second_arg(var1, var2)
4
- end
5
-
6
- def negative?(var)
7
- var.is_a?(Symbolic::UnaryMinus) || (var.is_a?(Numeric) && var < 0)
8
- end
9
- end
@@ -1,19 +0,0 @@
1
- module Symbolic::Optimization::Division
2
- extend Symbolic::Optimization::Base
3
-
4
- def self.optimize_first_arg(var1, var2)
5
- if var1 == 0
6
- 0
7
- elsif negative?(var1)
8
- -(var1.abs / var2)
9
- end
10
- end
11
-
12
- def self.optimize_second_arg(var1, var2)
13
- if var2 == 1
14
- var1
15
- elsif negative?(var2)
16
- -(var1 / var2.abs)
17
- end
18
- end
19
- end
@@ -1,17 +0,0 @@
1
- module Symbolic::Optimization::Multiplication
2
- extend Symbolic::Optimization::Base
3
-
4
- def self.optimize_first_arg(var1, var2)
5
- if var1 == 0
6
- 0
7
- elsif var1 == 1
8
- var2
9
- elsif negative?(var1)
10
- -(var1.abs * var2)
11
- end
12
- end
13
-
14
- def self.optimize_second_arg(var1, var2)
15
- optimize_first_arg var2, var1
16
- end
17
- end
@@ -1,15 +0,0 @@
1
- module Symbolic::Optimization::Subtraction
2
- extend Symbolic::Optimization::Base
3
-
4
- def self.optimize_first_arg(var1, var2)
5
- -var2 if var1 == 0
6
- end
7
-
8
- def self.optimize_second_arg(var1, var2)
9
- if var2 == 0
10
- var1
11
- elsif negative?(var2)
12
- var1 + var2.abs
13
- end
14
- end
15
- end
@@ -1,46 +0,0 @@
1
- module Symbolic
2
- class UnaryMinus
3
- include Symbolic
4
-
5
- def self.create(var)
6
- var.is_a?(UnaryMinus) ? var.abs : new(var)
7
- end
8
-
9
- def initialize(variable)
10
- @variable = variable
11
- end
12
-
13
- def to_s
14
- if @variable.is_a? Variable
15
- "-#{@variable}"
16
- else
17
- "(-#{@variable})"
18
- end
19
- end
20
-
21
- def abs
22
- # TODO: add a common method for Symbolic which will point to an instance of Abs(magnitude) class
23
- @variable
24
- end
25
-
26
- def value
27
- -@variable.value if undefined_variables.empty?
28
- end
29
-
30
- def variables
31
- @variable.variables
32
- end
33
-
34
- def undefined_variables
35
- @variable.undefined_variables
36
- end
37
-
38
- def ==(object)
39
- object.is_a?(UnaryMinus) && object.abs == @variable
40
- end
41
-
42
- def detailed_operations
43
- @variable.detailed_operations.tap {|it| it['-@'] += 1}
44
- end
45
- end
46
- end