factbase 0.12.0 → 0.12.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f31200ddcd8de0d737dbabea9aefc051794f86bbae0891f8d624545912972add
4
- data.tar.gz: 7c1688856cde3e72f8e9f53e846b39c7cef508a0df95cc88d0631bfae36ce07f
3
+ metadata.gz: 1ba24c42ea5df6fab3bfcf4477eff165173de5eb224c80e8bd1b1eeda5a9036d
4
+ data.tar.gz: b0f9362eec0b148f451dcbc94012db27ac97a02e4c6fbe48e0303a33d5f46c9e
5
5
  SHA512:
6
- metadata.gz: 26c83d3a288f8106bfe17856bccb9c1bde6b130384e9a4546456a76c1b6a69fff9c49954789aaeee6413f7cfae638d6f1320f1de4f7ac000b3c552b31449ebbd
7
- data.tar.gz: 761d577bc112c4d542667508924406570ff449fbab87af3a18fc0ce7c8a94cccf6d40f400b1b1c3f6bd76d95a51678a680fd17feeee0b89caacbac2b56e8e6f6
6
+ metadata.gz: e6460f586f42569fac5f6dedd783ab68e47f1fc2e7e05932033003586b40339044005d383306fce26f3f56a375d7a33d3a2798d3b84356e76c09550c6375e3d9
7
+ data.tar.gz: c8067f91613d87093ebf824c4800298e2b2e25654fc4ad9b5c3fed4c26e8265e19968a8eac887e5b541de48e5ebc531df6925c4ad73c48b49b1cb80ba429e5b7
@@ -6,7 +6,7 @@
6
6
  require_relative '../lib/factbase'
7
7
 
8
8
  def bench_query(bmk, fb)
9
- total = 500
9
+ total = 20_000
10
10
  total.times do |i|
11
11
  f = fb.insert
12
12
  f.id = i
@@ -15,6 +15,7 @@ def bench_query(bmk, fb)
15
15
  f.cost = rand(1..100)
16
16
  f.foo = rand(0.0..100.0).round(3)
17
17
  f.bar = rand(100..300)
18
+ f.blue = 1 if rand > 0.5
18
19
  f.seenBy = "User#{i}" if i.even?
19
20
  f.zzz = "Extra#{i}" if (i % 10).zero?
20
21
  end
@@ -25,6 +26,7 @@ def bench_query(bmk, fb)
25
26
  '(gt cost 50)',
26
27
  '(eq title \'Object Thinking 5000\')',
27
28
  '(and (eq foo 42.998) (or (gt bar 200) (absent zzz)))',
29
+ '(and (exists foo) (not (exists blue)))',
28
30
  '(eq id (agg (always) (max id)))',
29
31
  '(join "c<=cost,b<=bar" (eq id (agg (always) (max id))))'
30
32
  ].each do |q|
@@ -120,11 +120,20 @@ module Factbase::IndexedTerm
120
120
  end
121
121
  r
122
122
  when :not
123
- r = @operands.first.predict(maps, params)
123
+ if @idx[key].nil?
124
+ yes = @operands.first.predict(maps, params)
125
+ if yes.nil?
126
+ @idx[key] = { r: nil }
127
+ else
128
+ yes = yes.to_a.to_set
129
+ @idx[key] = { r: maps.to_a.reject { |m| yes.include?(m) } }
130
+ end
131
+ end
132
+ r = @idx[key][:r]
124
133
  if r.nil?
125
134
  nil
126
135
  else
127
- (maps & []) | (maps.to_a - r.to_a)
136
+ (maps & []) | r
128
137
  end
129
138
  end
130
139
  end
@@ -14,7 +14,7 @@ require_relative '../factbase/syntax'
14
14
  # to insert a fact without this property to lead to a runtime error. Here is how:
15
15
  #
16
16
  # fb = Factbase.new
17
- # fb = Factabase::Rules.new(fb, '(exists foo)')
17
+ # fb = Factbase::Rules.new(fb, '(exists foo)')
18
18
  # fb.txn do |fbt|
19
19
  # f = fbt.insert
20
20
  # f.bar = 3 # No exception here
@@ -28,9 +28,9 @@ module Factbase::Aggregates
28
28
  def nth(_fact, maps, _fb)
29
29
  assert_args(2)
30
30
  pos = @operands[0]
31
- raise "An integer expected, but #{pos} provided" unless pos.is_a?(Integer)
31
+ raise "An integer is expected, but #{pos} provided" unless pos.is_a?(Integer)
32
32
  k = @operands[1]
33
- raise "A symbol expected, but #{k} provided" unless k.is_a?(Symbol)
33
+ raise "A symbol is expected, but #{k} provided" unless k.is_a?(Symbol)
34
34
  m = maps[pos]
35
35
  return nil if m.nil?
36
36
  m[k.to_s]
@@ -39,7 +39,7 @@ module Factbase::Aggregates
39
39
  def first(_fact, maps, _fb)
40
40
  assert_args(1)
41
41
  k = @operands[0]
42
- raise "A symbol expected, but #{k} provided" unless k.is_a?(Symbol)
42
+ raise "A symbol is expected, but #{k} provided" unless k.is_a?(Symbol)
43
43
  first = maps[0]
44
44
  return nil if first.nil?
45
45
  first[k.to_s]
@@ -47,7 +47,7 @@ module Factbase::Aggregates
47
47
 
48
48
  def sum(_fact, maps, _fb)
49
49
  k = @operands[0]
50
- raise "A symbol expected, but '#{k}' provided" unless k.is_a?(Symbol)
50
+ raise "A symbol is expected, but '#{k}' provided" unless k.is_a?(Symbol)
51
51
  sum = 0
52
52
  maps.each do |m|
53
53
  vv = m[k.to_s]
@@ -63,9 +63,9 @@ module Factbase::Aggregates
63
63
  def agg(fact, maps, fb)
64
64
  assert_args(2)
65
65
  selector = @operands[0]
66
- raise "A term expected, but '#{selector}' provided" unless selector.is_a?(Factbase::Term)
66
+ raise "A term is expected, but '#{selector}' provided" unless selector.is_a?(Factbase::Term)
67
67
  term = @operands[1]
68
- raise "A term expected, but '#{term}' provided" unless term.is_a?(Factbase::Term)
68
+ raise "A term is expected, but '#{term}' provided" unless term.is_a?(Factbase::Term)
69
69
  subset = fb.query(selector, maps).each(fb, fact).to_a
70
70
  term.evaluate(nil, subset, fb)
71
71
  end
@@ -73,7 +73,7 @@ module Factbase::Aggregates
73
73
  def empty(fact, maps, fb)
74
74
  assert_args(1)
75
75
  term = @operands[0]
76
- raise "A term expected, but '#{term}' provided" unless term.is_a?(Factbase::Term)
76
+ raise "A term is expected, but '#{term}' provided" unless term.is_a?(Factbase::Term)
77
77
  # rubocop:disable Lint/UnreachableLoop
78
78
  fb.query(term, maps).each(fb, fact) do
79
79
  return false
@@ -84,7 +84,7 @@ module Factbase::Aggregates
84
84
 
85
85
  def _best(maps)
86
86
  k = @operands[0]
87
- raise "A symbol expected, but #{k} provided" unless k.is_a?(Symbol)
87
+ raise "A symbol is expected, but #{k} provided" unless k.is_a?(Symbol)
88
88
  best = nil
89
89
  maps.each do |m|
90
90
  vv = m[k.to_s]
@@ -14,7 +14,7 @@ module Factbase::Aliases
14
14
  def as(fact, maps, fb)
15
15
  assert_args(2)
16
16
  a = @operands[0]
17
- raise "A symbol expected as first argument of 'as'" unless a.is_a?(Symbol)
17
+ raise "A symbol is expected as first argument of 'as'" unless a.is_a?(Symbol)
18
18
  vv = _values(1, fact, maps, fb)
19
19
  vv&.each { |v| fact.send(:"#{a}=", v) }
20
20
  true
@@ -23,13 +23,13 @@ module Factbase::Aliases
23
23
  def join(fact, maps, fb)
24
24
  assert_args(2)
25
25
  jumps = @operands[0]
26
- raise "A string expected as first argument of 'join'" unless jumps.is_a?(String)
26
+ raise "A string is expected as first argument of 'join'" unless jumps.is_a?(String)
27
27
  jumps = jumps.split(',')
28
28
  .map(&:strip)
29
29
  .map { |j| j.split('<=').map(&:strip) }
30
30
  .map { |j| j.size == 1 ? [j[0], j[0]] : j }
31
31
  term = @operands[1]
32
- raise "A term expected, but '#{term}' provided" unless term.is_a?(Factbase::Term)
32
+ raise "A term is expected, but '#{term}' provided" unless term.is_a?(Factbase::Term)
33
33
  subset = fb.query(term, maps).each(fb, fact).to_a
34
34
  subset.each do |s|
35
35
  jumps.each do |to, from|
@@ -14,7 +14,7 @@ module Factbase::Debug
14
14
  def traced(fact, maps, fb)
15
15
  assert_args(1)
16
16
  t = @operands[0]
17
- raise "A term expected, but '#{t}' provided" unless t.is_a?(Factbase::Term)
17
+ raise "A term is expected, but '#{t}' provided" unless t.is_a?(Factbase::Term)
18
18
  r = t.evaluate(fact, maps, fb)
19
19
  puts "#{self} -> #{r}"
20
20
  r
@@ -25,12 +25,12 @@ module Factbase::Debug
25
25
  message = @operands[0]
26
26
  unless message.is_a?(String)
27
27
  raise ArgumentError,
28
- "A string expected as first argument of 'assert', but '#{message}' provided"
28
+ "A string is expected as first argument of 'assert', but '#{message}' provided"
29
29
  end
30
30
  t = @operands[1]
31
31
  unless t.is_a?(Factbase::Term)
32
32
  raise ArgumentError,
33
- "A term expected as second argument of 'assert', but '#{t}' provided"
33
+ "A term is expected as second argument of 'assert', but '#{t}' provided"
34
34
  end
35
35
  result = t.evaluate(fact, maps, fb)
36
36
  # Convert result to boolean-like evaluation
@@ -119,6 +119,6 @@ module Factbase::Logical
119
119
  val = val[0] if val.respond_to?(:each)
120
120
  return false if val.nil?
121
121
  return val if val.is_a?(TrueClass) || val.is_a?(FalseClass)
122
- raise "Boolean expected, while #{val.class} received from #{@operands[pos]}"
122
+ raise "Boolean is expected, while #{val.class} received from #{@operands[pos]}"
123
123
  end
124
124
  end
@@ -25,10 +25,10 @@ module Factbase::Strings
25
25
  assert_args(2)
26
26
  str = _values(0, fact, maps, fb)
27
27
  return false if str.nil?
28
- raise 'Exactly one string expected' unless str.size == 1
28
+ raise 'Exactly one string is expected' unless str.size == 1
29
29
  re = _values(1, fact, maps, fb)
30
30
  raise 'Regexp is nil' if re.nil?
31
- raise 'Exactly one regexp expected' unless re.size == 1
31
+ raise 'Exactly one regexp is expected' unless re.size == 1
32
32
  str[0].to_s.match?(re[0])
33
33
  end
34
34
  end
@@ -9,5 +9,5 @@
9
9
  # License:: MIT
10
10
  class Factbase
11
11
  # Current version of the gem (changed by .rultor.yml on every release)
12
- VERSION = '0.12.0' unless const_defined?(:VERSION)
12
+ VERSION = '0.12.1' unless const_defined?(:VERSION)
13
13
  end
data/lib/factbase.rb CHANGED
@@ -102,8 +102,8 @@ class Factbase
102
102
  #
103
103
  # A fact, when inserted, is empty. It doesn't contain any properties.
104
104
  #
105
- # The operation is thread-safe, meaning that you different threads may
106
- # insert facts parallel without breaking the consistency of the factbase.
105
+ # The operation is thread-safe, meaning that different threads may
106
+ # insert facts in parallel without breaking the consistency of the factbase.
107
107
  #
108
108
  # @return [Factbase::Fact] The fact just inserted
109
109
  def insert
@@ -20,7 +20,7 @@ class TestDebug < Factbase::Test
20
20
 
21
21
  def test_traced_raises
22
22
  e = assert_raises(StandardError) { Factbase::Term.new(:traced, ['foo']).evaluate(fact, [], Factbase.new) }
23
- assert_match(/A term expected, but 'foo' provided/, e.message)
23
+ assert_match(/A term is expected, but 'foo' provided/, e.message)
24
24
  end
25
25
 
26
26
  def test_traced_raises_when_too_many_args
@@ -81,7 +81,7 @@ class TestDebug < Factbase::Test
81
81
  assert_raises(StandardError) do
82
82
  Factbase::Term.new(:assert, [123, Factbase::Term.new(:gt, [:foo, 0])]).evaluate(fact, [], Factbase.new)
83
83
  end
84
- assert_match(/A string expected as first argument of 'assert', but '123' provided/, e.message)
84
+ assert_match(/A string is expected as first argument of 'assert', but '123' provided/, e.message)
85
85
  end
86
86
 
87
87
  def test_assert_raises_when_second_arg_not_term
@@ -89,7 +89,7 @@ class TestDebug < Factbase::Test
89
89
  assert_raises(StandardError) do
90
90
  Factbase::Term.new(:assert, %w[message not_a_term]).evaluate(fact, [], Factbase.new)
91
91
  end
92
- assert_match(/A term expected as second argument of 'assert', but 'not_a_term' provided/, e.message)
92
+ assert_match(/A term is expected as second argument of 'assert', but 'not_a_term' provided/, e.message)
93
93
  end
94
94
 
95
95
  def test_assert_raises_when_too_few_args
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: factbase
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.12.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko