predicate 2.3.0 → 2.5.0

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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -0
  3. data/LICENSE.md +17 -19
  4. data/README.md +433 -0
  5. data/bin/g +2 -0
  6. data/lib/predicate.rb +26 -2
  7. data/lib/predicate/dsl.rb +138 -0
  8. data/lib/predicate/factory.rb +130 -33
  9. data/lib/predicate/grammar.rb +11 -2
  10. data/lib/predicate/grammar.sexp.yml +29 -0
  11. data/lib/predicate/nodes/${op_name}.rb.jeny +12 -0
  12. data/lib/predicate/nodes/and.rb +9 -0
  13. data/lib/predicate/nodes/binary_func.rb +20 -0
  14. data/lib/predicate/nodes/contradiction.rb +2 -7
  15. data/lib/predicate/nodes/dyadic_comp.rb +3 -5
  16. data/lib/predicate/nodes/empty.rb +14 -0
  17. data/lib/predicate/nodes/eq.rb +13 -6
  18. data/lib/predicate/nodes/expr.rb +9 -3
  19. data/lib/predicate/nodes/has_size.rb +14 -0
  20. data/lib/predicate/nodes/identifier.rb +1 -3
  21. data/lib/predicate/nodes/in.rb +9 -8
  22. data/lib/predicate/nodes/intersect.rb +3 -23
  23. data/lib/predicate/nodes/literal.rb +1 -3
  24. data/lib/predicate/nodes/match.rb +1 -21
  25. data/lib/predicate/nodes/nadic_bool.rb +1 -3
  26. data/lib/predicate/nodes/native.rb +1 -3
  27. data/lib/predicate/nodes/not.rb +1 -3
  28. data/lib/predicate/nodes/opaque.rb +1 -3
  29. data/lib/predicate/nodes/qualified_identifier.rb +2 -4
  30. data/lib/predicate/nodes/set_op.rb +26 -0
  31. data/lib/predicate/nodes/subset.rb +11 -0
  32. data/lib/predicate/nodes/superset.rb +11 -0
  33. data/lib/predicate/nodes/tautology.rb +6 -7
  34. data/lib/predicate/nodes/unary_func.rb +16 -0
  35. data/lib/predicate/nodes/var.rb +46 -0
  36. data/lib/predicate/processors.rb +1 -0
  37. data/lib/predicate/processors/qualifier.rb +4 -0
  38. data/lib/predicate/processors/renamer.rb +4 -0
  39. data/lib/predicate/processors/to_s.rb +28 -0
  40. data/lib/predicate/processors/unqualifier.rb +21 -0
  41. data/lib/predicate/sequel/to_sequel.rb +4 -1
  42. data/lib/predicate/sugar.rb +47 -0
  43. data/lib/predicate/version.rb +1 -1
  44. data/spec/dsl/test_dsl.rb +204 -0
  45. data/spec/dsl/test_evaluate.rb +65 -0
  46. data/spec/dsl/test_respond_to_missing.rb +35 -0
  47. data/spec/dsl/test_to_skake_case.rb +38 -0
  48. data/spec/factory/shared/a_comparison_factory_method.rb +1 -0
  49. data/spec/factory/test_${op_name}.rb.jeny +12 -0
  50. data/spec/factory/test_empty.rb +11 -0
  51. data/spec/factory/test_has_size.rb +11 -0
  52. data/spec/factory/test_match.rb +1 -0
  53. data/spec/factory/test_set_ops.rb +18 -0
  54. data/spec/factory/test_var.rb +22 -0
  55. data/spec/factory/test_vars.rb +27 -0
  56. data/spec/nodes/${op_name}.jeny/test_evaluate.rb.jeny +19 -0
  57. data/spec/nodes/empty/test_evaluate.rb +42 -0
  58. data/spec/nodes/eq/test_and.rb +6 -0
  59. data/spec/nodes/has_size/test_evaluate.rb +44 -0
  60. data/spec/nodes/qualified_identifier/test_and_split.rb +1 -1
  61. data/spec/nodes/qualified_identifier/test_free_variables.rb +1 -1
  62. data/spec/predicate/test_and_split.rb +18 -0
  63. data/spec/predicate/test_attr_split.rb +18 -0
  64. data/spec/predicate/test_bool_and.rb +11 -0
  65. data/spec/predicate/test_constant_variables.rb +24 -2
  66. data/spec/predicate/test_constants.rb +24 -0
  67. data/spec/predicate/test_evaluate.rb +205 -3
  68. data/spec/predicate/test_free_variables.rb +1 -1
  69. data/spec/predicate/test_to_hash.rb +40 -0
  70. data/spec/predicate/test_to_s.rb +37 -0
  71. data/spec/predicate/test_unqualify.rb +18 -0
  72. data/spec/sequel/test_to_sequel.rb +16 -0
  73. data/spec/shared/a_predicate.rb +30 -0
  74. data/spec/spec_helper.rb +1 -0
  75. data/spec/test_predicate.rb +68 -33
  76. data/spec/test_readme.rb +80 -0
  77. data/spec/test_sugar.rb +48 -0
  78. data/tasks/test.rake +3 -3
  79. metadata +43 -13
  80. data/spec/factory/test_between.rb +0 -12
  81. data/spec/factory/test_intersect.rb +0 -12
@@ -0,0 +1,30 @@
1
+ shared_examples_for "a predicate" do
2
+
3
+ let(:w){ [8, 9] }
4
+ let(:x){ 12 }
5
+ let(:y){ 13 }
6
+
7
+ it 'can be negated easily' do
8
+ (!subject).should be_a(Predicate)
9
+ end
10
+
11
+ it 'detects stupid AND' do
12
+ (subject & Predicate.tautology).should be(subject)
13
+ end
14
+
15
+ it 'detects stupid OR' do
16
+ (subject | Predicate.contradiction).should be(subject)
17
+ end
18
+
19
+ it 'has free variables' do
20
+ (fv = subject.free_variables).should be_a(Array)
21
+ (fv - [ :w, :x, :y ]).should be_empty
22
+ end
23
+
24
+ it 'always splits around and trivially when no free variables are touched' do
25
+ top, down = subject.and_split([:z])
26
+ top.should be_tautology
27
+ down.should eq(subject)
28
+ end
29
+
30
+ end
@@ -1,6 +1,7 @@
1
1
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
2
  require "rspec"
3
3
  require 'predicate'
4
+ require_relative 'shared/a_predicate'
4
5
 
5
6
  module Helpers
6
7
 
@@ -1,36 +1,5 @@
1
1
  require 'spec_helper'
2
2
 
3
- shared_examples_for "a predicate" do
4
-
5
- let(:w){ [8, 9] }
6
- let(:x){ 12 }
7
- let(:y){ 13 }
8
-
9
- it 'can be negated easily' do
10
- (!subject).should be_a(Predicate)
11
- end
12
-
13
- it 'detects stupid AND' do
14
- (subject & Predicate.tautology).should be(subject)
15
- end
16
-
17
- it 'detects stupid OR' do
18
- (subject | Predicate.contradiction).should be(subject)
19
- end
20
-
21
- it 'has free variables' do
22
- (fv = subject.free_variables).should be_a(Array)
23
- (fv - [ :w, :x, :y ]).should be_empty
24
- end
25
-
26
- it 'always splits around and trivially when no free variables are touched' do
27
- top, down = subject.and_split([:z])
28
- top.should be_tautology
29
- down.should eq(subject)
30
- end
31
-
32
- end
33
-
34
3
  describe 'Predicate.tautology' do
35
4
  subject{ Predicate.tautology }
36
5
 
@@ -49,7 +18,7 @@ describe "Predicate.comp" do
49
18
  it_should_behave_like "a predicate"
50
19
  end
51
20
 
52
- describe "Predicate.in" do
21
+ describe "Predicate.in, with a list" do
53
22
  subject{ Predicate.in(:x, [2, 3]) }
54
23
 
55
24
  it_should_behave_like "a predicate"
@@ -59,6 +28,36 @@ describe "Predicate.in" do
59
28
  end
60
29
  end
61
30
 
31
+ describe "Predicate.in, with an inclusive range" do
32
+ subject{ Predicate.in(:x, 1..10) }
33
+
34
+ it_should_behave_like "a predicate"
35
+
36
+ it 'should be a shortcut over comparisons' do
37
+ expect(subject).to eql(Predicate.gte(:x, 1) & Predicate.lte(:x, 10))
38
+ end
39
+ end
40
+
41
+ describe "Predicate.in, with an exclusive range" do
42
+ subject{ Predicate.in(:x, 1...10) }
43
+
44
+ it_should_behave_like "a predicate"
45
+
46
+ it 'should be a shortcut over comparisons' do
47
+ expect(subject).to eql(Predicate.gte(:x, 1) & Predicate.lt(:x, 10))
48
+ end
49
+ end
50
+
51
+ describe "Predicate.in, with an empty range" do
52
+ subject{ Predicate.in(:x, 1...1) }
53
+
54
+ it_should_behave_like "a predicate"
55
+
56
+ it 'should be a contradiction' do
57
+ expect(subject).to eql(Predicate.contradiction)
58
+ end
59
+ end
60
+
62
61
  describe "Predicate.among" do
63
62
  subject{ Predicate.among(:x, [2, 3]) }
64
63
 
@@ -66,7 +65,19 @@ describe "Predicate.among" do
66
65
  end
67
66
 
68
67
  describe "Predicate.intersect" do
69
- subject{ Predicate.intersect(:w, [2, 3]) }
68
+ subject{ Predicate.intersect(:x, [2, 3]) }
69
+
70
+ it_should_behave_like "a predicate"
71
+ end
72
+
73
+ describe "Predicate.subset" do
74
+ subject{ Predicate.subset(:x, [2, 3]) }
75
+
76
+ it_should_behave_like "a predicate"
77
+ end
78
+
79
+ describe "Predicate.superset" do
80
+ subject{ Predicate.superset(:x, [2, 3]) }
70
81
 
71
82
  it_should_behave_like "a predicate"
72
83
  end
@@ -136,3 +147,27 @@ describe "Predicate.not" do
136
147
 
137
148
  it_should_behave_like "a predicate"
138
149
  end
150
+
151
+ describe "Predicate.dsl" do
152
+ subject{ Predicate.dsl{ eq(:x, 6) & lte(:y, 5)} }
153
+
154
+ it_should_behave_like "a predicate"
155
+ end
156
+
157
+ describe "Predicate.empty" do
158
+ subject{ Predicate.empty(:x) }
159
+
160
+ it_should_behave_like "a predicate"
161
+ end
162
+
163
+ describe "Predicate.has_size" do
164
+ subject{ Predicate.has_size(:x, 1..10) }
165
+
166
+ it_should_behave_like "a predicate"
167
+ end
168
+
169
+ #jeny(predicate) describe "Predicate.${op_name}" do
170
+ #jeny(predicate) subject{ Predicate.${op_name}(TODO) }
171
+ #jeny(predicate)
172
+ #jeny(predicate) it_should_behave_like "a predicate"
173
+ #jeny(predicate) end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+ require 'ostruct'
3
+
4
+ describe "README" do
5
+
6
+ it 'has a correct first example' do
7
+ p = Predicate.eq(:x, 2) & !Predicate.lte(:y, 3)
8
+ expect(p.evaluate(:x => 2, :y => 6)).to eql(true)
9
+ expect(p.evaluate(:x => 2, :y => 3)).to eql(false)
10
+ end
11
+
12
+ it 'has a correct second example' do
13
+ p = Predicate.dsl{
14
+ eq(:x, 2) & !lte(:y, 3)
15
+ }
16
+ expect(p.evaluate(:x => 2, :y => 6)).to eql(true)
17
+ expect(p.evaluate(:x => 2, :y => 3)).to eql(false)
18
+ end
19
+
20
+ it 'has a correct third example' do
21
+ p1 = Predicate.gt(:x, 1) & Predicate.lt(:x, 10)
22
+ p2 = Predicate.dsl{
23
+ gt(:x, 1) & lt(:x, 10)
24
+ }
25
+ p3 = Predicate.currying(:x){
26
+ gt(1) & lt(10)
27
+ }
28
+ [p1, p2, p3].all?{|p|
29
+ expect(p.evaluate(:x => 0)).to eql(false)
30
+ expect(p.evaluate(:x => 6)).to eql(true)
31
+ expect(p.evaluate(:x => 22)).to eql(false)
32
+ }
33
+ end
34
+
35
+ it 'has a correct fourth example' do
36
+ p = Predicate.currying{
37
+ gt(1) & lt(10)
38
+ }
39
+ expect(p.evaluate(0)).to eql(false)
40
+ expect(p.evaluate(6)).to eql(true)
41
+ expect(p.evaluate(22)).to eql(false)
42
+ end
43
+
44
+ it 'has a correct fifth example' do
45
+ x, y = Predicate.vars("items.0.price", "items.1.price")
46
+ p = Predicate.eq(x, 6) & Predicate.lt(y, 10)
47
+ expect(p.evaluate({
48
+ items: [
49
+ { name: "Candy", price: 6 },
50
+ { name: "Crush", price: 4 }
51
+ ]
52
+ })).to eql(true)
53
+ end
54
+
55
+ it 'has a correct sixth example' do
56
+ xyz = Predicate.var([:x, :y, :z], :dig)
57
+ p = Predicate.eq(xyz, 2)
58
+ expect(p.evaluate({ x: { y: { z: 2 } } })).to eql(true)
59
+ end
60
+
61
+ it 'has a correct seventh example' do
62
+ class C
63
+ attr_reader :x
64
+ def initialize(x)
65
+ @x = x
66
+ end
67
+ end
68
+
69
+ [:send, :public_send].each do |semantics|
70
+ xy = Predicate.var([:x, :y], semantics)
71
+ p = Predicate.eq(xy, 2)
72
+ expect(p.evaluate(C.new(OpenStruct.new(y: 2)))).to eql(true)
73
+
74
+ xy = Predicate.var("x.y", semantics)
75
+ p = Predicate.eq(xy, 2)
76
+ expect(p.evaluate(C.new(OpenStruct.new(y: 2)))).to eql(true)
77
+ end
78
+ end
79
+
80
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Predicate.min_size" do
4
+ subject{ Predicate.min_size(:x, 1) }
5
+
6
+ it 'works as expected' do
7
+ expect(subject).to eq(Predicate.has_size(:x, Range.new(1, nil)))
8
+ expect(subject.call(x: "")).to eq(false)
9
+ expect(subject.call(x: "1")).to eq(true)
10
+ end
11
+ end if RUBY_VERSION >= "2.6"
12
+
13
+ describe "Predicate.min_size" do
14
+ subject{ Predicate.min_size(:x, 1) }
15
+
16
+ it 'works as expected' do
17
+ expect(subject.call(x: "")).to eq(false)
18
+ expect(subject.call(x: "1")).to eq(true)
19
+ end
20
+ end if RUBY_VERSION < "2.6"
21
+
22
+ describe "Predicate.max_size" do
23
+ subject{ Predicate.max_size(:x, 10) }
24
+
25
+ it 'works as expected' do
26
+ expect(subject).to eq(Predicate.has_size(:x, 0..10))
27
+ expect(subject.call(x: "")).to eq(true)
28
+ expect(subject.call(x: "01234567891")).to eq(false)
29
+ end
30
+ end
31
+
32
+ describe "Predicate.is_null" do
33
+ subject{ Predicate.is_null(:x) }
34
+
35
+ it 'works as expected' do
36
+ expect(subject).to eq(Predicate.eq(:x, nil))
37
+ expect(subject.call(x: nil)).to eq(true)
38
+ expect(subject.call(x: "01234567891")).to eq(false)
39
+ end
40
+ end
41
+
42
+ #jeny(sugar) describe "Predicate.${op_name}" do
43
+ #jeny(sugar) subject{ Predicate.${op_name}(TODO) }
44
+ #jeny(sugar)
45
+ #jeny(sugar) it 'works as expected' do
46
+ #jeny(sugar) expect(subject).to eq(TODO)
47
+ #jeny(sugar) end
48
+ #jeny(sugar) end
@@ -1,9 +1,9 @@
1
1
  namespace :test do
2
+ require 'rspec/core/rake_task'
2
3
 
3
4
  desc %q{Run all RSpec tests}
4
- task :unit do
5
- require 'rspec'
6
- RSpec::Core::Runner.run(%w[-I. -Ilib -Ispec --pattern=spec/**/test_*.rb --color .])
5
+ RSpec::Core::RakeTask.new(:unit) do |t|
6
+ t.rspec_opts = %w[-I. -Ilib -Ispec --pattern=spec/**/test_*.rb --color .]
7
7
  end
8
8
 
9
9
  task :all => :"unit"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: predicate
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernard Lambeau
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-21 00:00:00.000000000 Z
11
+ date: 2020-12-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sexpr
@@ -30,28 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10'
33
+ version: '13'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10'
40
+ version: '13'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '3.6'
47
+ version: '3'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '3.6'
54
+ version: '3'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: sequel
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -89,18 +89,25 @@ extra_rdoc_files: []
89
89
  files:
90
90
  - Gemfile
91
91
  - LICENSE.md
92
+ - README.md
92
93
  - Rakefile
94
+ - bin/g
93
95
  - lib/predicate.rb
96
+ - lib/predicate/dsl.rb
94
97
  - lib/predicate/factory.rb
95
98
  - lib/predicate/grammar.rb
96
99
  - lib/predicate/grammar.sexp.yml
100
+ - lib/predicate/nodes/${op_name}.rb.jeny
97
101
  - lib/predicate/nodes/and.rb
102
+ - lib/predicate/nodes/binary_func.rb
98
103
  - lib/predicate/nodes/contradiction.rb
99
104
  - lib/predicate/nodes/dyadic_comp.rb
105
+ - lib/predicate/nodes/empty.rb
100
106
  - lib/predicate/nodes/eq.rb
101
107
  - lib/predicate/nodes/expr.rb
102
108
  - lib/predicate/nodes/gt.rb
103
109
  - lib/predicate/nodes/gte.rb
110
+ - lib/predicate/nodes/has_size.rb
104
111
  - lib/predicate/nodes/identifier.rb
105
112
  - lib/predicate/nodes/in.rb
106
113
  - lib/predicate/nodes/intersect.rb
@@ -115,30 +122,42 @@ files:
115
122
  - lib/predicate/nodes/opaque.rb
116
123
  - lib/predicate/nodes/or.rb
117
124
  - lib/predicate/nodes/qualified_identifier.rb
125
+ - lib/predicate/nodes/set_op.rb
126
+ - lib/predicate/nodes/subset.rb
127
+ - lib/predicate/nodes/superset.rb
118
128
  - lib/predicate/nodes/tautology.rb
129
+ - lib/predicate/nodes/unary_func.rb
130
+ - lib/predicate/nodes/var.rb
119
131
  - lib/predicate/placeholder.rb
120
132
  - lib/predicate/processors.rb
121
133
  - lib/predicate/processors/binder.rb
122
134
  - lib/predicate/processors/qualifier.rb
123
135
  - lib/predicate/processors/renamer.rb
124
136
  - lib/predicate/processors/to_s.rb
137
+ - lib/predicate/processors/unqualifier.rb
125
138
  - lib/predicate/sequel.rb
126
139
  - lib/predicate/sequel/to_sequel.rb
140
+ - lib/predicate/sugar.rb
127
141
  - lib/predicate/version.rb
142
+ - spec/dsl/test_dsl.rb
143
+ - spec/dsl/test_evaluate.rb
144
+ - spec/dsl/test_respond_to_missing.rb
145
+ - spec/dsl/test_to_skake_case.rb
128
146
  - spec/factory/shared/a_comparison_factory_method.rb
129
147
  - spec/factory/shared/a_predicate_ast_node.rb
148
+ - spec/factory/test_${op_name}.rb.jeny
130
149
  - spec/factory/test_and.rb
131
- - spec/factory/test_between.rb
132
150
  - spec/factory/test_comp.rb
133
151
  - spec/factory/test_contradiction.rb
152
+ - spec/factory/test_empty.rb
134
153
  - spec/factory/test_eq.rb
135
154
  - spec/factory/test_factor_predicate.rb
136
155
  - spec/factory/test_from_hash.rb
137
156
  - spec/factory/test_gt.rb
138
157
  - spec/factory/test_gte.rb
158
+ - spec/factory/test_has_size.rb
139
159
  - spec/factory/test_identifier.rb
140
160
  - spec/factory/test_in.rb
141
- - spec/factory/test_intersect.rb
142
161
  - spec/factory/test_literal.rb
143
162
  - spec/factory/test_lt.rb
144
163
  - spec/factory/test_lte.rb
@@ -148,14 +167,20 @@ files:
148
167
  - spec/factory/test_not.rb
149
168
  - spec/factory/test_or.rb
150
169
  - spec/factory/test_qualified_identifier.rb
170
+ - spec/factory/test_set_ops.rb
151
171
  - spec/factory/test_tautology.rb
172
+ - spec/factory/test_var.rb
173
+ - spec/factory/test_vars.rb
152
174
  - spec/grammar/test_match.rb
153
175
  - spec/grammar/test_sexpr.rb
176
+ - spec/nodes/${op_name}.jeny/test_evaluate.rb.jeny
154
177
  - spec/nodes/and/test_and.rb
155
178
  - spec/nodes/and/test_and_split.rb
156
179
  - spec/nodes/and/test_attr_split.rb
157
180
  - spec/nodes/dyadic_comp/test_and_split.rb
181
+ - spec/nodes/empty/test_evaluate.rb
158
182
  - spec/nodes/eq/test_and.rb
183
+ - spec/nodes/has_size/test_evaluate.rb
159
184
  - spec/nodes/identifier/test_and_split.rb
160
185
  - spec/nodes/identifier/test_free_variables.rb
161
186
  - spec/nodes/identifier/test_name.rb
@@ -182,16 +207,22 @@ files:
182
207
  - spec/predicate/test_qualify.rb
183
208
  - spec/predicate/test_rename.rb
184
209
  - spec/predicate/test_tautology.rb
210
+ - spec/predicate/test_to_hash.rb
211
+ - spec/predicate/test_to_s.rb
212
+ - spec/predicate/test_unqualify.rb
185
213
  - spec/sequel/test_to_sequel.rb
214
+ - spec/shared/a_predicate.rb
186
215
  - spec/spec_helper.rb
187
216
  - spec/test_predicate.rb
217
+ - spec/test_readme.rb
218
+ - spec/test_sugar.rb
188
219
  - tasks/gem.rake
189
220
  - tasks/test.rake
190
221
  homepage: http://github.com/enspirit/predicate
191
222
  licenses:
192
223
  - MIT
193
224
  metadata: {}
194
- post_install_message:
225
+ post_install_message:
195
226
  rdoc_options: []
196
227
  require_paths:
197
228
  - lib
@@ -206,9 +237,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
206
237
  - !ruby/object:Gem::Version
207
238
  version: '0'
208
239
  requirements: []
209
- rubyforge_project:
210
- rubygems_version: 2.7.6
211
- signing_key:
240
+ rubygems_version: 3.1.4
241
+ signing_key:
212
242
  specification_version: 4
213
243
  summary: Predicate provides a simple class and processors to encode and manipulate
214
244
  (tuple) predicates