add binary operators
This commit is contained in:
parent
6ebfc505c4
commit
a98a6d6d1e
9 changed files with 131 additions and 1 deletions
|
@ -8,12 +8,23 @@ module Logic
|
|||
end
|
||||
|
||||
def self.class_from_name(name)
|
||||
[Constant, Empty]
|
||||
[Constant, Empty, LessThan, LessThanEq, Eq, GreaterThanEq, GreaterThan, EmptyOperator]
|
||||
.find { |c| c.name == name }
|
||||
end
|
||||
|
||||
def ds_eq(left, right) = Logic::Eq.new(left, right)
|
||||
|
||||
def greater_than(left, right) = Logic::GreaterThan.new(left, right)
|
||||
|
||||
def greater_than_eq(left, right) = Logic::GreaterThanEq.new(left, right)
|
||||
|
||||
def less_than(left, right) = Logic::LessThan.new(left, right)
|
||||
|
||||
def less_than_eq(left, right) = Logic::LessThanEq.new(left, right)
|
||||
|
||||
def constant(value) = Logic::Constant.new(value)
|
||||
|
||||
def empty = Logic::Empty.new
|
||||
|
||||
def empty_operator(left, right) = Logic::EmptyOperator.new(left, right)
|
||||
end
|
||||
|
|
46
app/models/logic/binary_operator.rb
Normal file
46
app/models/logic/binary_operator.rb
Normal file
|
@ -0,0 +1,46 @@
|
|||
class Logic::BinaryOperator < Logic::Term
|
||||
attr_reader :left, :right
|
||||
|
||||
def initialize(left, right)
|
||||
@left, @right = left, right
|
||||
end
|
||||
|
||||
def to_h
|
||||
{
|
||||
"op" => self.class.name,
|
||||
"left" => @left.to_h,
|
||||
"right" => @right.to_h
|
||||
}
|
||||
end
|
||||
|
||||
def self.from_h(h)
|
||||
self.new(Logic.from_h(h['left']), Logic.from_h(h['right']))
|
||||
end
|
||||
|
||||
def errors(stable_ids = [])
|
||||
errors = []
|
||||
|
||||
if @left.type != :number || @right.type != :number
|
||||
errors += ["les types sont incompatibles : #{self}"]
|
||||
end
|
||||
|
||||
errors + @left.errors(stable_ids) + @right.errors(stable_ids)
|
||||
end
|
||||
|
||||
def type = :boolean
|
||||
|
||||
def compute(champs = [])
|
||||
l = @left.compute(champs)
|
||||
r = @right.compute(champs)
|
||||
|
||||
l.send(operation, r)
|
||||
end
|
||||
|
||||
def to_s = "(#{@left} #{operation} #{@right})"
|
||||
|
||||
def ==(other)
|
||||
self.class == other.class &&
|
||||
@left == other.left &&
|
||||
@right == other.right
|
||||
end
|
||||
end
|
7
app/models/logic/empty_operator.rb
Normal file
7
app/models/logic/empty_operator.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
class Logic::EmptyOperator < Logic::BinaryOperator
|
||||
def to_s = "empty operator"
|
||||
|
||||
def type = :empty
|
||||
|
||||
def errors(_stable_ids = nil) = ['empty']
|
||||
end
|
3
app/models/logic/greater_than.rb
Normal file
3
app/models/logic/greater_than.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
class Logic::GreaterThan < Logic::BinaryOperator
|
||||
def operation = :>
|
||||
end
|
3
app/models/logic/greater_than_eq.rb
Normal file
3
app/models/logic/greater_than_eq.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
class Logic::GreaterThanEq < Logic::BinaryOperator
|
||||
def operation = :>=
|
||||
end
|
3
app/models/logic/less_than.rb
Normal file
3
app/models/logic/less_than.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
class Logic::LessThan < Logic::BinaryOperator
|
||||
def operation = :<
|
||||
end
|
3
app/models/logic/less_than_eq.rb
Normal file
3
app/models/logic/less_than_eq.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
class Logic::LessThanEq < Logic::BinaryOperator
|
||||
def operation = :<=
|
||||
end
|
52
spec/models/logic/binary_operator_spec.rb
Normal file
52
spec/models/logic/binary_operator_spec.rb
Normal file
|
@ -0,0 +1,52 @@
|
|||
include Logic
|
||||
|
||||
describe Logic::BinaryOperator do
|
||||
let(:two_greater_than_one) { greater_than(constant(2), constant(1))}
|
||||
|
||||
describe '#type' do
|
||||
it { expect(two_greater_than_one.type).to eq(:boolean) }
|
||||
end
|
||||
|
||||
describe '#to_s' do
|
||||
it { expect(two_greater_than_one.to_s).to eq('(2 > 1)') }
|
||||
end
|
||||
|
||||
describe '#==' do
|
||||
it { expect(two_greater_than_one).to eq(greater_than(constant(2), constant(1))) }
|
||||
it { expect(two_greater_than_one).not_to eq(greater_than(constant(1), constant(2))) }
|
||||
end
|
||||
|
||||
describe '#errors' do
|
||||
it { expect(greater_than(constant(1), constant(true)).errors).to eq(['les types sont incompatibles : (1 > true)']) }
|
||||
end
|
||||
end
|
||||
|
||||
describe Logic::GreaterThan do
|
||||
it 'computes' do
|
||||
expect(greater_than(constant(1), constant(1)).compute).to be(false)
|
||||
expect(greater_than(constant(2), constant(1)).compute).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
describe Logic::GreaterThanEq do
|
||||
it 'computes' do
|
||||
expect(greater_than_eq(constant(0), constant(1)).compute).to be(false)
|
||||
expect(greater_than_eq(constant(1), constant(1)).compute).to be(true)
|
||||
expect(greater_than_eq(constant(2), constant(1)).compute).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
describe Logic::LessThan do
|
||||
it 'computes' do
|
||||
expect(less_than(constant(1), constant(1)).compute).to be(false)
|
||||
expect(less_than(constant(1), constant(2)).compute).to be(true)
|
||||
end
|
||||
end
|
||||
|
||||
describe Logic::LessThanEq do
|
||||
it 'computes' do
|
||||
expect(less_than_eq(constant(0), constant(1)).compute).to be(true)
|
||||
expect(less_than_eq(constant(1), constant(1)).compute).to be(true)
|
||||
expect(less_than_eq(constant(2), constant(1)).compute).to be(false)
|
||||
end
|
||||
end
|
|
@ -6,5 +6,7 @@ describe Logic do
|
|||
expect(Logic.from_json(constant(1).to_json)).to eq(constant(1))
|
||||
|
||||
expect(Logic.from_h(empty.to_h)).to eq(empty)
|
||||
|
||||
expect(Logic.from_h(greater_than(constant(1), constant(2)).to_h)).to eq(greater_than(constant(1), constant(2)))
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue