factbase 0.0.26 → 0.0.28
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/factbase/syntax.rb +2 -1
- data/lib/factbase/term.rb +39 -27
- data/lib/factbase.rb +1 -1
- data/test/factbase/test_query.rb +2 -0
- data/test/factbase/test_syntax.rb +2 -0
- data/test/factbase/test_term.rb +11 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ffdf62af221a65ab9efa6097b01dab23edba0399bc8551757d450ff828f14367
|
4
|
+
data.tar.gz: 175dd8ead3a933305d46c8c4bb657a46efc507db3ad1045bb7495614dedfc1c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ccade318b2db8568b72fcd29dd8d8cc301a791911a749bba8154485e8e95d1a00c2466477ff7e798f8a5146e87e03c69af8493fd05ae38c9463a8ffc9e29da62
|
7
|
+
data.tar.gz: 30730a5e848923b73c98f188142f30f56fd8eec95d8839561a6be01956922f60d9fe46a9dcf361b2f6b4bffca993fd20471bd51f1e2840659ba7bc252c9853b2
|
data/lib/factbase/syntax.rb
CHANGED
@@ -43,6 +43,7 @@ class Factbase::Syntax
|
|
43
43
|
@ast ||= to_ast(@tokens, 0)
|
44
44
|
term = @ast[0]
|
45
45
|
raise 'No terms found' if term.nil?
|
46
|
+
raise 'Not a term' unless term.is_a?(Factbase::Term)
|
46
47
|
term
|
47
48
|
end
|
48
49
|
|
@@ -81,7 +82,7 @@ class Factbase::Syntax
|
|
81
82
|
list = []
|
82
83
|
acc = ''
|
83
84
|
string = false
|
84
|
-
@query.to_s.chars.each do |c|
|
85
|
+
@query.to_s.gsub(/#.*$/, '').chars.each do |c|
|
85
86
|
if ['\'', '"'].include?(c)
|
86
87
|
if string && acc[acc.length - 1] == '\\'
|
87
88
|
acc = acc[0..-2]
|
data/lib/factbase/term.rb
CHANGED
@@ -97,18 +97,12 @@ class Factbase::Term
|
|
97
97
|
|
98
98
|
def exists(fact)
|
99
99
|
assert_args(1)
|
100
|
-
|
101
|
-
raise "A symbol expected: #{o}" unless o.is_a?(Symbol)
|
102
|
-
k = o.to_s
|
103
|
-
!fact[k].nil?
|
100
|
+
!by_symbol(0, fact).nil?
|
104
101
|
end
|
105
102
|
|
106
103
|
def absent(fact)
|
107
104
|
assert_args(1)
|
108
|
-
|
109
|
-
raise "A symbol expected: #{o}" unless o.is_a?(Symbol)
|
110
|
-
k = o.to_s
|
111
|
-
fact[k].nil?
|
105
|
+
by_symbol(0, fact).nil?
|
112
106
|
end
|
113
107
|
|
114
108
|
def eq(fact)
|
@@ -125,29 +119,31 @@ class Factbase::Term
|
|
125
119
|
|
126
120
|
def size(fact)
|
127
121
|
assert_args(1)
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
122
|
+
v = by_symbol(0, fact)
|
123
|
+
return 0 if v.nil?
|
124
|
+
return 1 unless v.is_a?(Array)
|
125
|
+
v.size
|
126
|
+
end
|
127
|
+
|
128
|
+
def type(fact)
|
129
|
+
assert_args(1)
|
130
|
+
v = by_symbol(0, fact)
|
131
|
+
return 'nil' if v.nil?
|
132
|
+
v.class.to_s
|
134
133
|
end
|
135
134
|
|
136
135
|
def arithmetic(op, fact)
|
137
136
|
assert_args(2)
|
138
|
-
|
139
|
-
if
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
v.any? do |vv|
|
149
|
-
vv = vv.floor if vv.is_a?(Time) && op == :==
|
150
|
-
vv.send(op, @operands[1])
|
137
|
+
lefts = the_value(0, fact)
|
138
|
+
return false if lefts.nil?
|
139
|
+
rights = the_value(1, fact)
|
140
|
+
return false if rights.nil?
|
141
|
+
lefts.any? do |l|
|
142
|
+
l = l.floor if l.is_a?(Time) && op == :==
|
143
|
+
rights.any? do |r|
|
144
|
+
r = r.floor if r.is_a?(Time) && op == :==
|
145
|
+
l.send(op, r)
|
146
|
+
end
|
151
147
|
end
|
152
148
|
end
|
153
149
|
|
@@ -156,4 +152,20 @@ class Factbase::Term
|
|
156
152
|
raise "Too many (#{c}) operands for '#{@op}' (#{num} expected)" if c > num
|
157
153
|
raise "Too few (#{c}) operands for '#{@op}' (#{num} expected)" if c < num
|
158
154
|
end
|
155
|
+
|
156
|
+
def by_symbol(pos, fact)
|
157
|
+
o = @operands[pos]
|
158
|
+
raise "A symbol expected at ##{pos}, but provided: #{o}" unless o.is_a?(Symbol)
|
159
|
+
k = o.to_s
|
160
|
+
fact[k]
|
161
|
+
end
|
162
|
+
|
163
|
+
def the_value(pos, fact)
|
164
|
+
v = @operands[pos]
|
165
|
+
v = v.eval(fact) if v.is_a?(Factbase::Term)
|
166
|
+
v = fact[v.to_s] if v.is_a?(Symbol)
|
167
|
+
return v if v.nil?
|
168
|
+
v = [v] unless v.is_a?(Array)
|
169
|
+
v
|
170
|
+
end
|
159
171
|
end
|
data/lib/factbase.rb
CHANGED
data/test/factbase/test_query.rb
CHANGED
@@ -54,9 +54,11 @@ class TestQuery < Minitest::Test
|
|
54
54
|
"(and (lt pi 100) \n\n (gt num 1000))" => 0,
|
55
55
|
'(exists pi)' => 1,
|
56
56
|
'(not (exists hello))' => 3,
|
57
|
+
'(eq "Integer" (type num))' => 2,
|
57
58
|
'(gt (size num) 2)' => 1,
|
58
59
|
'(lt (size num) 2)' => 2,
|
59
60
|
'(eq (size hello) 0)' => 3,
|
61
|
+
'(eq num pi)' => 0,
|
60
62
|
'(absent time)' => 2,
|
61
63
|
'(and (absent time) (exists pi))' => 1,
|
62
64
|
"(and (exists time) (not (\t\texists pi)))" => 1,
|
@@ -45,6 +45,7 @@ class TestSyntax < Minitest::Test
|
|
45
45
|
'(foo)',
|
46
46
|
'(foo (bar) (zz 77) )',
|
47
47
|
"(eq foo \n\n 'Hello, world!'\n)\n",
|
48
|
+
"# this is a comment\n(eq foo # test\n 42)\n\n# another comment\n",
|
48
49
|
"(or ( a 4) (b 5) () (and () (c 5) \t\t(r 7 8s 8is 'Foo')))"
|
49
50
|
].each do |q|
|
50
51
|
Factbase::Syntax.new(q).to_term
|
@@ -90,6 +91,7 @@ class TestSyntax < Minitest::Test
|
|
90
91
|
[
|
91
92
|
'',
|
92
93
|
'(foo',
|
94
|
+
'some text',
|
93
95
|
'"hello, world!',
|
94
96
|
'(foo 7',
|
95
97
|
"(foo 7 'Dude'",
|
data/test/factbase/test_term.rb
CHANGED
@@ -111,6 +111,16 @@ class TestTerm < Minitest::Test
|
|
111
111
|
assert(!t.eval(fact('foo' => 100)))
|
112
112
|
end
|
113
113
|
|
114
|
+
def test_type_matching
|
115
|
+
t = Factbase::Term.new(:type, [:foo])
|
116
|
+
assert_equal('Integer', t.eval(fact('foo' => 42)))
|
117
|
+
assert_equal('Array', t.eval(fact('foo' => [1, 2, 3])))
|
118
|
+
assert_equal('String', t.eval(fact('foo' => 'Hello, world!')))
|
119
|
+
assert_equal('Float', t.eval(fact('foo' => 3.14)))
|
120
|
+
assert_equal('Time', t.eval(fact('foo' => Time.now)))
|
121
|
+
assert_equal('nil', t.eval(fact))
|
122
|
+
end
|
123
|
+
|
114
124
|
def test_or_matching
|
115
125
|
t = Factbase::Term.new(
|
116
126
|
:or,
|
@@ -139,7 +149,7 @@ class TestTerm < Minitest::Test
|
|
139
149
|
|
140
150
|
private
|
141
151
|
|
142
|
-
def fact(map)
|
152
|
+
def fact(map = {})
|
143
153
|
Factbase::Fact.new(Mutex.new, map)
|
144
154
|
end
|
145
155
|
end
|