dydx 0.1.314 → 0.1.412

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +25 -0
  3. data/.travis.yml +3 -1
  4. data/Gemfile +1 -0
  5. data/README.md +4 -2
  6. data/Rakefile +5 -8
  7. data/dydx.gemspec +13 -13
  8. data/lib/dydx.rb +20 -27
  9. data/lib/dydx/algebra.rb +8 -6
  10. data/lib/dydx/algebra/formula.rb +53 -28
  11. data/lib/dydx/algebra/inverse.rb +2 -2
  12. data/lib/dydx/algebra/operator/formula.rb +0 -1
  13. data/lib/dydx/algebra/operator/general.rb +0 -1
  14. data/lib/dydx/algebra/operator/inverse.rb +0 -1
  15. data/lib/dydx/algebra/operator/num.rb +0 -1
  16. data/lib/dydx/algebra/operator/parts/base.rb +2 -2
  17. data/lib/dydx/algebra/operator/parts/formula.rb +61 -40
  18. data/lib/dydx/algebra/operator/parts/general.rb +83 -32
  19. data/lib/dydx/algebra/operator/parts/inverse.rb +4 -4
  20. data/lib/dydx/algebra/operator/parts/num.rb +16 -11
  21. data/lib/dydx/algebra/operator/parts/symbol.rb +2 -2
  22. data/lib/dydx/algebra/set.rb +82 -122
  23. data/lib/dydx/delta.rb +1 -1
  24. data/lib/dydx/function.rb +1 -1
  25. data/lib/dydx/helper.rb +43 -66
  26. data/lib/dydx/integrand.rb +7 -6
  27. data/lib/dydx/version.rb +1 -1
  28. data/spec/dydx_spec.rb +3 -3
  29. data/spec/lib/algebra/formula_spec.rb +41 -41
  30. data/spec/lib/algebra/operator/parts/base_spec.rb +5 -5
  31. data/spec/lib/algebra/operator/parts/formula_spec.rb +57 -57
  32. data/spec/lib/algebra/operator/parts/inverse_spec.rb +8 -8
  33. data/spec/lib/algebra/set_spec.rb +193 -150
  34. data/spec/lib/delta_spec.rb +23 -25
  35. data/spec/lib/function_spec.rb +4 -6
  36. data/spec/lib/helper_spec.rb +44 -51
  37. data/spec/lib/integrand_spec.rb +12 -10
  38. data/spec/spec_helper.rb +2 -1
  39. metadata +6 -7
  40. data/lib/dydx/algebra/operator/parts.rb +0 -6
  41. data/lib/dydx/algebra/operator/parts/interface.rb +0 -22
@@ -1,7 +1,7 @@
1
1
  module Dydx
2
2
  class Delta
3
3
  attr_accessor :var, :function
4
- def initialize(var=nil, function=nil)
4
+ def initialize(var = nil, function = nil)
5
5
  @var = var
6
6
  @function = function
7
7
  end
@@ -10,7 +10,7 @@ module Dydx
10
10
  self
11
11
  end
12
12
 
13
- def differentiate(sym=:x)
13
+ def differentiate(sym = :x)
14
14
  @algebra.differentiate(sym)
15
15
  end
16
16
  alias_method :d, :differentiate
@@ -1,15 +1,9 @@
1
1
  module Dydx
2
2
  module Helper
3
- OP_SYM_STR = {
4
- addition: :+,
5
- multiplication: :*,
6
- exponentiation: :^
7
- }
8
-
9
3
  SUPER_OPE_RELATION = {
10
4
  :+ => :*,
11
5
  :- => :/,
12
- :* => :^,
6
+ :* => :**,
13
7
  :/ => :|
14
8
  }
15
9
 
@@ -18,95 +12,75 @@ module Dydx
18
12
  :- => :+,
19
13
  :* => :/,
20
14
  :/ => :*,
21
- :^ => :|,
22
- :| => :^
15
+ :** => :|,
16
+ :| => :**
23
17
  }
24
18
 
25
- def inverse_ope(operator)
26
- INVERSE_OPE_RELATION[operator]
19
+ def num?
20
+ is_a?(Num) || is_a?(Numeric)
27
21
  end
28
22
 
29
- def inverse_super_ope(operator)
30
- inverse_ope(operator.super)
23
+ def to_numeric
24
+ is_a?(Num) ? n : self
31
25
  end
32
26
 
33
- def is_num?
34
- (is_a?(Num) || is_a?(Fixnum) || is_a?(Float)) || (is_a?(Inverse) && x.is_num?)
27
+ def zero?
28
+ [0, 0.0].include?(self) || (is_a?(Num) && n.zero?)
35
29
  end
36
30
 
37
- def is_0?
38
- [0, 0.0].include?(self) || (is_a?(Num) && n.is_0?)
31
+ def one?
32
+ [1, 1.0].include?(self) || (is_a?(Num) && n.one?)
39
33
  end
40
34
 
41
- def is_1?
42
- [1, 1.0].include?(self) || (is_a?(Num) && n.is_1?)
43
- end
44
-
45
- def is_minus1?
46
- [1, -1.0].include?(self)|| (is_a?(Num) && n.is_minus1?)
35
+ def minus1?
36
+ [-1, -1.0].include?(self) || (is_a?(Num) && n.minus1?)
47
37
  end
48
38
 
49
39
  def distributive?(ope1, ope2)
50
- [ope1.super, ope1.inverse_super].include?(ope2)
40
+ [ope1.super, ope1.inv_super].include?(ope2)
51
41
  end
52
42
 
43
+ # TODO: Cyclomatic complexity for combinable? is too high. [17/6]
53
44
  def combinable?(x, operator)
54
45
  case operator
55
46
  when :+
56
- (is_num? && x.is_num?) ||
57
- (formula?(:*) && (f.is_num? || g.is_num?)) && x.is_num? ||
47
+ (num? && x.num?) ||
48
+ (formula?(:*) && (f.num? || g.num?)) && x.num? ||
58
49
  like_term?(x) ||
59
50
  inverse?(:+, x)
60
51
  when :*
61
52
  self == x ||
62
- (is_num? && x.is_num?) ||
53
+ (num? && x.num?) ||
63
54
  inverse?(:*, x)
64
- when :^
65
- (is_num? && x.is_num?) || is_0? || is_1?
55
+ when :**
56
+ (num? && x.num?) || zero? || one?
66
57
  end
67
58
  end
68
59
 
60
+ # TODO: Cyclomatic complexity for combinable? is too high. [9/6]
69
61
  def like_term?(x)
70
- boolean = if self == x
71
- elsif formula?(:*) && include?(x)
72
- elsif x.formula?(:*) && x.include?(self)
73
- elsif ((formula?(:*) && formula?(:*)) && (([f, g] & [x.f, x.g]).any?{|x| x.is_a?(Symbol)}))
74
- else
75
- true
76
- end
77
-
78
- !boolean
79
- end
80
-
81
- def is_multiple_of(x)
82
- if is_0?
83
- e0
84
- elsif self == x
85
- e1
86
- # elsif is_num? && x.is_num? && (self % x == 0)
87
- # _(n / x.n)
88
- elsif multiplication? && (f == x || g == x)
89
- f == x ? g : f
90
- else
91
- false
92
- end
62
+ self == x ||
63
+ formula?(:*) && include?(x) ||
64
+ x.formula?(:*) && x.include?(self)||
65
+ (formula?(:*) && formula?(:*) && !([f, g] & [x.f, x.g]).empty?)
93
66
  end
94
67
 
95
- OP_SYM_STR.each do |operator_name, operator|
96
- define_method("#{operator_name}?") do
97
- is_a?(Formula) && (@operator == operator)
98
- # is_a?(Inverse) && self.operator == operator
99
- end
68
+ # TODO: Cyclomatic complexity for combinable? is too high. [7/6]
69
+ def multiple_of?(x)
70
+ zero? ||
71
+ self == x ||
72
+ (num? && x.num? && self % x == 0) ||
73
+ (formula?(:*) && (f == x || g == x))
100
74
  end
101
75
 
102
76
  def rest(f_or_g)
103
77
  ([:f, :g] - [f_or_g]).first
104
78
  end
105
79
 
106
- def distributable?(operator)
80
+ def distributable?(_operator)
107
81
  end
108
82
 
109
- def inverse?(operator, x=nil)
83
+ def inverse?(operator, x = nil)
110
84
  if is_a?(Algebra::Inverse)
111
85
  self.operator == operator && (self.x == x || x.nil?)
112
86
  elsif x.is_a?(Algebra::Inverse)
@@ -125,6 +99,10 @@ module Dydx
125
99
  [:+, :*].include?(self)
126
100
  end
127
101
 
102
+ def associative?
103
+ [:+, :*].include?(self)
104
+ end
105
+
128
106
  def super
129
107
  SUPER_OPE_RELATION[self] || self
130
108
  end
@@ -133,18 +111,17 @@ module Dydx
133
111
  SUPER_OPE_RELATION.invert[self] || self
134
112
  end
135
113
 
136
- def inverse_super
137
- inverse_super_ope(self) || self
114
+ def inv
115
+ INVERSE_OPE_RELATION[self] || self
116
+ end
117
+
118
+ def inv_super
119
+ self.super.inv
138
120
  end
139
121
  end
140
122
 
141
123
  def ==(x)
142
124
  to_s == x.to_s
143
125
  end
144
-
145
- # Refactor
146
- def **(x)
147
- self ^ (x)
148
- end
149
126
  end
150
127
  end
@@ -1,6 +1,7 @@
1
1
  module Dydx
2
2
  class Integrand
3
3
  attr_accessor :function, :var
4
+
4
5
  def initialize(function, var)
5
6
  @function = function
6
7
  @var = var
@@ -12,21 +13,21 @@ module Dydx
12
13
  b = 1000 if b == Float::INFINITY
13
14
 
14
15
  a, b = [a, b].map(&:to_f)
15
- raise ArgumentError, 'b should be greater than a' if a > b
16
- $int_f = function
16
+ fail ArgumentError, 'b should be greater than a' if a > b
17
+ $temp_cal_f = function
17
18
 
18
19
  n = [n, (b - a) * 2].max
19
20
  n += 1 if n.to_i.odd?
20
21
  h = (b - a) / n
21
- x = ->(i){ a + h * i }
22
+ x = ->(i) { a + h * i }
22
23
 
23
- odd_sum = (1..n - 1).to_a.select(&:odd?).inject(0) { |sum, i| sum += f(x.(i))}
24
- even_sum = (1..n - 1).to_a.select(&:even?).inject(0) { |sum, i| sum += f(x.(i))}
24
+ odd_sum = (1..n - 1).to_a.select(&:odd?).inject(0) { |sum, i| sum += f(x.(i)) }
25
+ even_sum = (1..n - 1).to_a.select(&:even?).inject(0) { |sum, i| sum += f(x.(i)) }
25
26
  round_8( (h / 3) * (f(a) + f(b) + 2 * even_sum + 4 * odd_sum) )
26
27
  end
27
28
 
28
29
  def f(vars)
29
- int_f(vars)
30
+ temp_cal_f(vars)
30
31
  end
31
32
 
32
33
  def round_8(num)
@@ -1,3 +1,3 @@
1
1
  module Dydx
2
- VERSION = "0.1.314"
2
+ VERSION = '0.1.412'
3
3
  end
@@ -6,15 +6,15 @@ describe Dydx do
6
6
  end
7
7
 
8
8
  it 'demo' do
9
- f(x, y) <= x + x*y + y
9
+ f(x, y) <= x + x * y + y
10
10
  expect(f(x, y)).to eq(x * (1 + y) + y)
11
- expect(f(a, 2)).to eq(3*a + 2)
11
+ expect(f(a, 2)).to eq(3 * a + 2)
12
12
  expect(f(1, a + b)).to eq(1 + 2 * ( a + b ))
13
13
  expect(f(1, 2)).to eq(5)
14
14
  expect(d/dx(f(x, y))).to eq(1 + y)
15
15
 
16
16
  g(x) <= sin(x)
17
17
  expect(d/dx(g(x))).to eq(cos(x))
18
- expect(S(g(x), dx)[0, pi/2]).to eq(1.0)
18
+ expect(S(g(x), dx)[0, pi / 2]).to eq(1.0)
19
19
  end
20
20
  end
@@ -1,69 +1,69 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Dydx::Algebra::Formula do
4
- let(:addition) { (:x + :y) }
5
- let(:subtraction) { (:x - :y) }
6
- let(:multiplication){ (:x * :y) }
7
- let(:division) { (:x / :y) }
8
- let(:exponentiation){ (:x ^ :y) }
4
+ let(:addition) { (x + y) }
5
+ let(:subtraction) { (x - y) }
6
+ let(:multiplication) { (x * y) }
7
+ let(:division) { (x / y) }
8
+ let(:exponentiation) { (x ** y) }
9
9
  describe 'Calculate' do
10
10
  context 'With Fixnum' do
11
11
  let(:formula) { (:x + :y) }
12
- it{ expect(formula + 0).to eq(formula) }
13
- it{ expect(formula - 0).to eq(formula) }
14
- it{ expect(formula * 0).to eq(0) }
15
- it{ expect(formula * 1).to eq(formula) }
16
- it{ expect{(formula / 0).to_s}.to raise_error(ZeroDivisionError) }
17
- it{ expect(formula / 1).to eq(formula) }
18
- it{ expect(formula ^ 0).to eq(1) }
12
+ it { expect(formula + 0).to eq(formula) }
13
+ it { expect(formula - 0).to eq(formula) }
14
+ it { expect(formula * 0).to eq(0) }
15
+ it { expect(formula * 1).to eq(formula) }
16
+ it { expect { (formula / 0).to_s }.to raise_error(ZeroDivisionError) }
17
+ it { expect(formula / 1).to eq(formula) }
18
+ it { expect(formula ** 0).to eq(1) }
19
19
  end
20
20
  end
21
21
 
22
22
  describe '#to_s' do
23
- it{ expect(addition.to_s).to eq('( x + y )') }
24
- it{ expect(subtraction.to_s).to eq('( x - y )') }
25
- it{ expect(multiplication.to_s).to eq('( x * y )') }
26
- it{ expect(division.to_s).to eq('( x / y )') }
27
- it{ expect(exponentiation.to_s).to eq('( x ^ y )') }
28
- it{ expect( (addition * multiplication).to_s ).to eq('( ( x + y ) * ( x * y ) )') }
23
+ it { expect(addition.to_s).to eq('( x + y )') }
24
+ it { expect(subtraction.to_s).to eq('( x - y )') }
25
+ it { expect(multiplication.to_s).to eq('( x * y )') }
26
+ it { expect(division.to_s).to eq('( x / y )') }
27
+ it { expect(exponentiation.to_s).to eq('( x ** y )') }
28
+ it { expect((addition * multiplication).to_s).to eq('( ( x + y ) * ( x * y ) )') }
29
29
  end
30
30
 
31
31
  describe '#subst' do
32
- it{ expect((x + y).subst(x: 3, y: 3)).to eq(6) }
33
- it{ expect((x + y).subst(x: 3)).to eq(3 + y) }
34
- it{ expect((x + y + pi).subst(x: 3, y: 3).to_f).to eq(Math::PI + 6) }
32
+ it { expect((x + y).subst(x: 3, y: 3)).to eq(6) }
33
+ it { expect((x + y).subst(x: 3)).to eq(3 + y) }
34
+ it { expect((x + y + pi).subst(x: 3, y: 3).to_f).to eq(Math::PI + 6) }
35
35
  end
36
36
 
37
37
  describe '#differentiate' do
38
- it{ expect(addition.d(:x)).to eq(1) }
39
- it{ expect(addition.d(:y)).to eq(1) }
40
- it{ expect(addition.d(:z)).to eq(0) }
38
+ it { expect(addition.d(x)).to eq(1) }
39
+ it { expect(addition.d(y)).to eq(1) }
40
+ it { expect(addition.d(z)).to eq(0) }
41
41
 
42
- it{ expect(subtraction.d(:x)).to eq(1) }
43
- it{ expect(subtraction.d(:y)).to eq('( - 1 )') }
44
- it{ expect(subtraction.d(:z)).to eq(0) }
42
+ it { expect(subtraction.d(x)).to eq(1) }
43
+ it { expect(subtraction.d(y)).to eq(-1) }
44
+ it { expect(subtraction.d(z)).to eq(0) }
45
45
 
46
- it{ expect(multiplication.d(:x)).to eq(:y) }
47
- it{ expect(multiplication.d(:y)).to eq(:x) }
48
- it{ expect(multiplication.d(:z)).to eq(0) }
46
+ it { expect(multiplication.d(x)).to eq(y) }
47
+ it { expect(multiplication.d(y)).to eq(x) }
48
+ it { expect(multiplication.d(z)).to eq(0) }
49
49
 
50
- it{ expect(division.d(:x)).to eq(1/:y) }
51
- it{ expect(division.d(:y)).to eq('( - ( x / ( y ^ 2 ) ) )') }
52
- it{ expect(division.d(:z)).to eq(0) }
50
+ it { expect(division.d(x)).to eq(1 / y) }
51
+ it { expect(division.d(y)).to eq(- ( x / y ** 2 ) ) }
52
+ it { expect(division.d(z)).to eq(0) }
53
53
 
54
- it{ expect(exponentiation.d(:x).to_s).to eq('( y * ( x ^ ( y - 1 ) ) )') }
55
- it{ expect(exponentiation.d(:y)).to eq((:x ^ :y) * log(:x)) }
56
- it{ expect(exponentiation.d(:z)).to eq(0) }
54
+ it { expect(exponentiation.d(x)).to eq(y * x ** ( y - 1 )) }
55
+ it { expect(exponentiation.d(y)).to eq(x ** y * log(x)) }
56
+ it { expect(exponentiation.d(z)).to eq(0) }
57
57
  end
58
58
 
59
59
  describe '#include?' do
60
- it{ expect(addition.include?(:x)).to be_true }
61
- it{ expect(addition.include?(:z)).to be_false }
60
+ it { expect(addition.include?(x)).to be true }
61
+ it { expect(addition.include?(z)).to be false }
62
62
  end
63
63
 
64
64
  describe '#openable?' do
65
- it{ expect((:x + :y).openable?(:*, :x)).to be_true }
66
- it{ expect((:x + :y).openable?(:*, :y)).to be_true }
67
- it{ expect((:x + :y).openable?(:*, :z)).to be_false }
65
+ it { expect((x + y).openable?(:*, x)).to be true }
66
+ it { expect((x + y).openable?(:*, y)).to be true }
67
+ it { expect((x + y).openable?(:*, z)).to be false }
68
68
  end
69
69
  end
@@ -1,8 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Dydx::Algebra::Operator::Parts::Base do
4
- it{ expect((:x + :x).to_s).to eq('( 2 * x )') }
5
- it{ expect((:x - :x).to_s).to eq('0') }
6
- it{ expect((:x * :x).to_s).to eq('( x ^ 2 )') }
7
- it{ expect((:x / :x).to_s).to eq('1') }
8
- end
4
+ it { expect((:x + :x).to_s).to eq('( 2 * x )') }
5
+ it { expect((:x - :x).to_s).to eq('0') }
6
+ it { expect((:x * :x).to_s).to eq('( x ** 2 )') }
7
+ it { expect((:x / :x).to_s).to eq('1') }
8
+ end
@@ -1,63 +1,63 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Dydx::Algebra::Operator::Parts::Formula do
4
- it{ expect(((:a * :b) + (:a * :c)).to_s).to eq('( a * ( b + c ) )') }
5
- it{ expect(((:a * :b) + (:c * :a)).to_s).to eq('( a * ( b + c ) )') }
6
- it{ expect(((:b * :a) + (:c * :a)).to_s).to eq('( a * ( b + c ) )') }
7
- it{ expect(((:b * :a) + (:a * :c)).to_s).to eq('( a * ( b + c ) )') }
8
- it{ expect(((:a * :b) - (:a * :c)).to_s).to eq('( a * ( b - c ) )') }
9
- it{ expect(((:a * :b) - (:c * :a)).to_s).to eq('( a * ( b - c ) )') }
10
- it{ expect(((:b * :a) - (:c * :a)).to_s).to eq('( a * ( b - c ) )') }
11
- it{ expect(((:b * :a) - (:a * :c)).to_s).to eq('( a * ( b - c ) )') }
12
-
13
- it{ expect(((:a ^ :b) * (:a ^ :c)).to_s).to eq('( a ^ ( b + c ) )') }
14
- it{ expect(((:a ^ :b) * (:c ^ :a)).to_s).to eq('( ( a ^ b ) * ( c ^ a ) )') }
15
- it{ expect(((:b ^ :a) * (:c ^ :a)).to_s).to eq('( ( b * c ) ^ a )') }
16
- it{ expect(((:b ^ :a) * (:a ^ :c)).to_s).to eq('( ( b ^ a ) * ( a ^ c ) )') }
17
- it{ expect(((:a ^ :b) / (:a ^ :c)).to_s).to eq('( a ^ ( b - c ) )') }
18
- it{ expect(((:a ^ :b) / (:c ^ :a)).to_s).to eq('( ( a ^ b ) / ( c ^ a ) )') }
19
- it{ expect(((:b ^ :a) / (:c ^ :a)).to_s).to eq('( ( b / c ) ^ a )') }
20
- it{ expect(((:b ^ :a) / (:a ^ :c)).to_s).to eq('( ( b ^ a ) / ( a ^ c ) )') }
21
-
22
- it{ expect(((:x - 2) + 2).to_s).to eq('x') }
23
- it{ expect(((:x + 2) - 2).to_s).to eq('x') }
24
- it{ expect(((:x * 2) / 2).to_s).to eq('x') }
25
- it{ expect(((:x / 2) * 2).to_s).to eq('x') }
26
-
27
- it{ expect((2 + (:x - 2)).to_s).to eq('x') }
28
- it{ expect((2 - (:x + 2)).to_s).to eq('( - x )') }
29
- it{ expect((2 * (:x / 2)).to_s).to eq('x') }
30
- it{ expect((2 / (:x * 2)).to_s).to eq('( 1 / x )') }
31
-
32
- it{ expect(((:x + :y) + :y).to_s).to eq('( ( 2 * y ) + x )') }
33
- it{ expect(((:y + :x) + :y).to_s).to eq('( ( 2 * y ) + x )') }
34
- it{ expect(((:x - :y) - :y).to_s).to eq('( x - ( 2 * y ) )') }
35
- it{ expect(((:y - :x) - :y).to_s).to eq('( - x )') }
36
- it{ expect(((:y * :x) * :y).to_s).to eq('( ( y ^ 2 ) * x )') }
37
- it{ expect(((:x * :y) * :y).to_s).to eq('( ( y ^ 2 ) * x )') }
38
- it{ expect(((:x / :y) / :y).to_s).to eq('( x / ( y ^ 2 ) )') }
39
- it{ expect(((:y / :x) / :y).to_s).to eq('( 1 / x )') }
40
-
41
- it{ expect((:y + (:x + :y)).to_s).to eq('( ( 2 * y ) + x )') }
42
- it{ expect((:y + (:y + :x)).to_s).to eq('( ( 2 * y ) + x )') }
43
- it{ expect((:y - (:x - :y)).to_s).to eq('( ( 2 * y ) - x )') }
44
- it{ expect((:y - (:y - :x)).to_s).to eq('x') }
45
- it{ expect((:y * (:y * :x)).to_s).to eq('( ( y ^ 2 ) * x )') }
46
- it{ expect((:y * (:x * :y)).to_s).to eq('( ( y ^ 2 ) * x )') }
47
- it{ expect((:y - (:x - :y)).to_s).to eq('( ( 2 * y ) - x )') }
48
- it{ expect((:y - (:y - :x)).to_s).to eq('x') }
49
-
50
- it{ expect((x + 3) * 2).to eq(x * 2 + 6) }
51
- # it{ expect((x - 3) * 2).to eq(x * 2 - 6) }
52
- it{ expect((x + 3) * 2).to eq(x * 2 + 6) }
53
- it{ expect((x + 3) * 2).to eq(x * 2 + 6) }
54
-
55
- it{ expect(((:x * 2) ^ 2).to_s).to eq('( 4 * ( x ^ 2 ) )') }
56
- it{ expect(((:x / 2) ^ 2).to_s).to eq('( ( x ^ 2 ) / 4 )') }
57
-
58
- it{ expect((3*x + 4*(x^2)+ 4*x).to_s).to eq('( ( 7 * x ) + ( 4 * ( x ^ 2 ) ) )') }
4
+ it { expect(a * b + a * c).to eq('( a * ( b + c ) )') }
5
+ it { expect(a * b + c * a).to eq('( a * ( b + c ) )') }
6
+ it { expect(b * a + c * a).to eq('( a * ( b + c ) )') }
7
+ it { expect(b * a + a * c).to eq('( a * ( b + c ) )') }
8
+ it { expect(a * b - a * c).to eq('( a * ( b - c ) )') }
9
+ it { expect(a * b - c * a).to eq('( a * ( b - c ) )') }
10
+ it { expect(b * a - c * a).to eq('( a * ( b - c ) )') }
11
+ it { expect(b * a - a * c).to eq('( a * ( b - c ) )') }
12
+
13
+ it { expect(a ** b * a ** c).to eq('( a ** ( b + c ) )') }
14
+ it { expect(a ** b * c ** a).to eq('( ( a ** b ) * ( c ** a ) )') }
15
+ it { expect(b ** a * c ** a).to eq('( ( b * c ) ** a )') }
16
+ it { expect(b ** a * a ** c).to eq('( ( b ** a ) * ( a ** c ) )') }
17
+ it { expect(a ** b / a ** c).to eq('( a ** ( b - c ) )') }
18
+ it { expect(a ** b / c ** a).to eq('( ( a ** b ) / ( c ** a ) )') }
19
+ it { expect(b ** a / c ** a).to eq('( ( b / c ) ** a )') }
20
+ it { expect(b ** a / a ** c).to eq('( ( b ** a ) / ( a ** c ) )') }
21
+
22
+ it { expect(((:x - 2) + 2).to_s).to eq('x') }
23
+ it { expect(((:x + 2) - 2).to_s).to eq('x') }
24
+ it { expect(((:x * 2) / 2).to_s).to eq('x') }
25
+ it { expect(((:x / 2) * 2).to_s).to eq('x') }
26
+
27
+ it { expect((2 + (:x - 2)).to_s).to eq('x') }
28
+ it { expect((2 - (:x + 2)).to_s).to eq('( - x )') }
29
+ it { expect((2 * (:x / 2)).to_s).to eq('x') }
30
+ it { expect((2 / (:x * 2)).to_s).to eq('( 1 / x )') }
31
+
32
+ it { expect((x + y) + y).to eq('( ( 2 * y ) + x )') }
33
+ it { expect((y + x) + y).to eq('( ( 2 * y ) + x )') }
34
+ it { expect((x - y) - y).to eq('( x - ( 2 * y ) )') }
35
+ it { expect((y - x) - y).to eq('( - x )') }
36
+ it { expect((y * x) * y).to eq('( ( y ** 2 ) * x )') }
37
+ it { expect((x * y) * y).to eq('( ( y ** 2 ) * x )') }
38
+ it { expect((x / y) / y).to eq('( x / ( y ** 2 ) )') }
39
+ it { expect((y / x) / y).to eq('( 1 / x )') }
40
+
41
+ it { expect(y + (x + y)).to eq('( ( 2 * y ) + x )') }
42
+ it { expect(y + (y + x)).to eq('( ( 2 * y ) + x )') }
43
+ it { expect(y - (x - y)).to eq('( ( 2 * y ) - x )') }
44
+ it { expect(y - (y - x)).to eq(x) }
45
+ it { expect(y * (y * x)).to eq('( ( y ** 2 ) * x )') }
46
+ it { expect(y * (x * y)).to eq('( ( y ** 2 ) * x )') }
47
+ it { expect(y - (x - y)).to eq('( ( 2 * y ) - x )') }
48
+ it { expect(y - (y - x)).to eq(x) }
49
+
50
+ it { expect((x + 3) * 2).to eq(x * 2 + 6) }
51
+ # it { expect((x - 3) * 2).to eq(x * 2 - 6) }
52
+ it { expect((x + 3) * 2).to eq(x * 2 + 6) }
53
+ it { expect((x + 3) * 2).to eq(x * 2 + 6) }
54
+
55
+ it { expect((x * 2) ** 2).to eq( 4 * x ** 2 ) }
56
+ it { expect((x / 2) ** 2).to eq( x ** 2 / 4 ) }
57
+
58
+ it { expect((3 * x + 4 * (x ** 2) + 4 * x).to_s).to eq('( ( 7 * x ) + ( 4 * ( x ** 2 ) ) )') }
59
59
 
60
60
  # TODO:
61
- it{ expect((2 ^ (:x * 2)).to_s).to eq('( 2 ^ ( 2 * x ) )') }
62
- it{ expect((2 ^ (:x / 2)).to_s).to eq('( 2 ^ ( x / 2 ) )') }
61
+ it { expect((2 ** (:x * 2)).to_s).to eq('( 2 ** ( 2 * x ) )') }
62
+ it { expect((2 ** (:x / 2)).to_s).to eq('( 2 ** ( x / 2 ) )') }
63
63
  end