rubylog 1.0.0 → 2.0pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +3 -12
- data/Gemfile.lock +22 -48
- data/README.rdoc +38 -38
- data/README.rdoc.orig +284 -0
- data/RELEASE_NOTES.rdoc +51 -0
- data/Rakefile +14 -18
- data/TODO.txt +0 -0
- data/VERSION +1 -1
- data/examples/a_plus_b.rb +6 -0
- data/examples/checkmate.rb +88 -0
- data/examples/combination.rb +17 -0
- data/examples/dcg.rb +3 -2
- data/examples/dcg2.rb +2 -2
- data/{logic → examples}/directory_structure_logic.rb +3 -5
- data/examples/dirlist.rb +4 -0
- data/examples/divisors.rb +6 -0
- data/examples/enumerators.rb +3 -3
- data/examples/factorial.rb +2 -3
- data/examples/file_search.rb +14 -0
- data/examples/hanoi.rb +4 -5
- data/examples/hello.rb +6 -4
- data/examples/mice.rb +92 -0
- data/examples/mice2.rb +19 -0
- data/examples/n_queens.rb +32 -0
- data/examples/object_oriented.rb +14 -0
- data/examples/palindrome_detection.rb +18 -0
- data/examples/parsing.rb +6 -4
- data/examples/permutation.rb +12 -0
- data/examples/prefix.rb +13 -0
- data/examples/primality_by_division.rb +22 -0
- data/examples/primitives.rb +10 -8
- data/examples/sieve_of_eratosthenes.rb +14 -0
- data/examples/string_interpolation.rb +4 -0
- data/examples/sudoku.rb +52 -0
- data/examples/tracing.rb +19 -0
- data/lib/rspec/rubylog.rb +29 -0
- data/lib/rubylog/assertable.rb +24 -0
- data/lib/rubylog/builtins/arithmetics.rb +63 -0
- data/lib/rubylog/builtins/assumption.rb +71 -0
- data/lib/rubylog/builtins/ensure.rb +13 -0
- data/lib/rubylog/builtins/file_system.rb +30 -8
- data/lib/rubylog/builtins/logic.rb +69 -38
- data/lib/rubylog/builtins/reflection.rb +35 -50
- data/lib/rubylog/builtins/term.rb +15 -17
- data/lib/rubylog/builtins.rb +11 -0
- data/lib/rubylog/clause.rb +19 -0
- data/lib/rubylog/{interfaces/composite_term.rb → compound_term.rb} +3 -3
- data/lib/rubylog/context.rb +24 -0
- data/lib/rubylog/context_creation.rb +71 -0
- data/lib/rubylog/context_modules/checks.rb +35 -0
- data/lib/rubylog/context_modules/demonstration.rb +16 -0
- data/lib/rubylog/context_modules/predicates.rb +86 -0
- data/lib/rubylog/context_modules/primitives.rb +18 -0
- data/lib/rubylog/context_modules/thats.rb +13 -0
- data/lib/rubylog/default_context.rb +9 -0
- data/lib/rubylog/dsl/array_splat.rb +11 -3
- data/lib/rubylog/dsl/primitives.rb +24 -12
- data/lib/rubylog/dsl/thats.rb +6 -0
- data/lib/rubylog/dsl/variables.rb +56 -21
- data/lib/rubylog/errors.rb +26 -15
- data/lib/rubylog/mixins/array.rb +95 -62
- data/lib/rubylog/mixins/kernel.rb +3 -2
- data/lib/rubylog/mixins/method.rb +0 -1
- data/lib/rubylog/mixins/object.rb +2 -1
- data/lib/rubylog/mixins/proc.rb +9 -12
- data/lib/rubylog/mixins/string.rb +15 -23
- data/lib/rubylog/mixins/symbol.rb +7 -24
- data/lib/rubylog/nullary_predicates.rb +3 -0
- data/lib/rubylog/predicate.rb +53 -0
- data/lib/rubylog/primitive.rb +15 -0
- data/lib/rubylog/procedure.rb +42 -0
- data/lib/rubylog/rule.rb +24 -0
- data/lib/rubylog/structure.rb +19 -38
- data/lib/rubylog/{interfaces/term.rb → term.rb} +2 -7
- data/lib/rubylog/tracing.rb +75 -0
- data/lib/rubylog/variable.rb +31 -12
- data/lib/rubylog.rb +36 -32
- data/rubylog.gemspec +92 -84
- data/spec/inriasuite_spec.rb +906 -9
- data/spec/integration/custom_classes_spec.rb +61 -0
- data/spec/integration/dsl_spec.rb +38 -0
- data/spec/integration/recursion_spec.rb +14 -0
- data/spec/integration/theory_as_module_spec.rb +20 -0
- data/spec/integration/theory_as_module_with_include_spec.rb +14 -0
- data/spec/rspec/rubylog_spec.rb +75 -0
- data/spec/rubylog/assertable_spec.rb +111 -0
- data/spec/rubylog/builtins/arithmetics_spec.rb +94 -0
- data/spec/rubylog/builtins/assumption_spec.rb +70 -0
- data/spec/rubylog/builtins/ensure_spec.rb +8 -0
- data/spec/rubylog/builtins/file_system_spec.rb +40 -0
- data/spec/rubylog/builtins/logic_spec.rb +340 -0
- data/spec/rubylog/builtins/reflection_spec.rb +43 -0
- data/spec/rubylog/builtins/term_spec.rb +85 -0
- data/spec/rubylog/context_modules/demonstration_spec.rb +132 -0
- data/spec/rubylog/context_modules/predicates_spec.rb +57 -0
- data/spec/rubylog/context_modules/thats_spec.rb +94 -0
- data/spec/rubylog/dsl/array_splat_spec.rb +15 -0
- data/spec/rubylog/dsl/primitives_spec.rb +43 -0
- data/spec/rubylog/errors_spec.rb +18 -0
- data/spec/{unification_spec.rb → rubylog/interfaces/term_spec.rb} +8 -9
- data/spec/rubylog/mixins/array_spec.rb +80 -0
- data/spec/rubylog/mixins/composite_term_spec.rb +66 -0
- data/spec/rubylog/mixins/proc_spec.rb +59 -0
- data/spec/rubylog/mixins/string_spec.rb +48 -0
- data/spec/rubylog/mixins/symbol_spec.rb +9 -0
- data/spec/{clause_spec.rb → rubylog/structure_spec.rb} +16 -15
- data/spec/rubylog/term_spec.rb +7 -0
- data/spec/rubylog/tracing_spec.input +27 -0
- data/spec/rubylog/tracing_spec.rb +44 -0
- data/spec/rubylog/variable_spec.rb +279 -0
- data/spec/spec_helper.rb +1 -0
- data/vimrc +11 -0
- metadata +103 -123
- data/README.hu.rb +0 -58
- data/bin/rubylog +0 -18
- data/examples/theory.rb +0 -32
- data/lib/rubylog/builtins/default.rb +0 -10
- data/lib/rubylog/dsl.rb +0 -70
- data/lib/rubylog/interfaces/assertable.rb +0 -16
- data/lib/rubylog/interfaces/callable.rb +0 -18
- data/lib/rubylog/interfaces/predicate.rb +0 -8
- data/lib/rubylog/interfaces/procedure.rb +0 -60
- data/lib/rubylog/mixins/class.rb +0 -11
- data/lib/rubylog/simple_procedure.rb +0 -8
- data/lib/rubylog/theory.rb +0 -422
- data/logic/builtins/file_system_logic.rb +0 -23
- data/logic/builtins/reflection_logic.rb +0 -40
- data/logic/dereference_logic.rb +0 -23
- data/logic/dsl_logic.rb +0 -29
- data/logic/errors_logic.rb +0 -9
- data/logic/guard_logic.rb +0 -115
- data/logic/list_logic.rb +0 -55
- data/logic/map_logic.rb +0 -15
- data/logic/multitheory.rb +0 -23
- data/logic/recursion_logic.rb +0 -12
- data/logic/string_logic.rb +0 -41
- data/logic/thats_logic.rb +0 -51
- data/logic/variable_logic.rb +0 -24
- data/spec/bartak_guide_spec.rb +0 -86
- data/spec/builtins/all_spec.rb +0 -99
- data/spec/builtins/and_spec.rb +0 -22
- data/spec/builtins/array_spec.rb +0 -16
- data/spec/builtins/branch_or_spec.rb +0 -27
- data/spec/builtins/cut_spec.rb +0 -44
- data/spec/builtins/fail_spec.rb +0 -5
- data/spec/builtins/false_spec.rb +0 -5
- data/spec/builtins/in_spec.rb +0 -38
- data/spec/builtins/is_false_spec.rb +0 -12
- data/spec/builtins/is_spec.rb +0 -26
- data/spec/builtins/matches_spec.rb +0 -23
- data/spec/builtins/or_spec.rb +0 -22
- data/spec/builtins/splits_to.rb +0 -18
- data/spec/builtins/then_spec.rb +0 -27
- data/spec/builtins/true_spec.rb +0 -5
- data/spec/compilation_spec.rb +0 -61
- data/spec/custom_classes_spec.rb +0 -43
- data/spec/dereference.rb +0 -10
- data/spec/queries_spec.rb +0 -150
- data/spec/recursion_spec.rb +0 -18
- data/spec/ruby_code_spec.rb +0 -52
- data/spec/rules_spec.rb +0 -97
- data/spec/theory_spec.rb +0 -29
- data/spec/variable_spec.rb +0 -26
@@ -0,0 +1,340 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "logic builtins", :rubylog => true do
|
4
|
+
before do
|
5
|
+
predicate_for Symbol, ".likes() .happy"
|
6
|
+
end
|
7
|
+
|
8
|
+
specify "true" do
|
9
|
+
:john.happy.if :true
|
10
|
+
:john.should be_happy
|
11
|
+
end
|
12
|
+
|
13
|
+
specify "fail" do
|
14
|
+
:john.happy.if :fail
|
15
|
+
:john.should_not be_happy
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "false" do
|
19
|
+
specify do
|
20
|
+
:john.happy.if :true.false
|
21
|
+
:john.should_not be_happy
|
22
|
+
end
|
23
|
+
|
24
|
+
specify do
|
25
|
+
:john.happy.if :fail.false
|
26
|
+
:john.should be_happy
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "and" do
|
31
|
+
it "works 1" do
|
32
|
+
:john.happy.if :fail.and :true
|
33
|
+
:john.should_not be_happy
|
34
|
+
end
|
35
|
+
|
36
|
+
it "works 2" do
|
37
|
+
:john.happy.if :true.and :fail
|
38
|
+
:john.should_not be_happy
|
39
|
+
end
|
40
|
+
|
41
|
+
it "works 3" do
|
42
|
+
:john.happy.if :fail.and :fail
|
43
|
+
:john.should_not be_happy
|
44
|
+
end
|
45
|
+
|
46
|
+
it "works 4" do
|
47
|
+
:john.happy.if :true.and :true
|
48
|
+
:john.should be_happy
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
describe "or" do
|
54
|
+
it "works 1" do
|
55
|
+
:john.happy.if :fail.or :true
|
56
|
+
:john.should be_happy
|
57
|
+
end
|
58
|
+
|
59
|
+
it "works 2" do
|
60
|
+
:john.happy.if :true.or :fail
|
61
|
+
:john.should be_happy
|
62
|
+
end
|
63
|
+
|
64
|
+
it "works 3" do
|
65
|
+
:john.happy.if :fail.or :fail
|
66
|
+
:john.should_not be_happy
|
67
|
+
end
|
68
|
+
|
69
|
+
it "works 4" do
|
70
|
+
:john.happy.if :true.or :true
|
71
|
+
:john.should be_happy
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
describe "branch or" do
|
77
|
+
it "works 1" do
|
78
|
+
:john.happy.if :fail
|
79
|
+
:john.happy.if :true
|
80
|
+
:john.should be_happy
|
81
|
+
end
|
82
|
+
|
83
|
+
it "works 2" do
|
84
|
+
:john.happy.if :true
|
85
|
+
:john.happy.if :fail
|
86
|
+
:john.should be_happy
|
87
|
+
end
|
88
|
+
|
89
|
+
it "works 3" do
|
90
|
+
:john.happy.if :fail
|
91
|
+
:john.happy.if :fail
|
92
|
+
:john.should_not be_happy
|
93
|
+
end
|
94
|
+
|
95
|
+
it "works 4" do
|
96
|
+
:john.happy.if :true
|
97
|
+
:john.happy.if :true
|
98
|
+
:john.should be_happy
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "iff" do
|
103
|
+
it "works 1" do
|
104
|
+
:john.happy.if :fail.iff :true
|
105
|
+
:john.should_not be_happy
|
106
|
+
end
|
107
|
+
|
108
|
+
it "works 2" do
|
109
|
+
:john.happy.if :true.iff :fail
|
110
|
+
:john.should_not be_happy
|
111
|
+
end
|
112
|
+
|
113
|
+
it "works 3" do
|
114
|
+
:john.happy.if :fail.iff :fail
|
115
|
+
:john.should be_happy
|
116
|
+
end
|
117
|
+
|
118
|
+
it "works 4" do
|
119
|
+
:john.happy.if :true.iff :true
|
120
|
+
:john.should be_happy
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "cut" do
|
125
|
+
it "works with branch or" do
|
126
|
+
:john.happy.if :true.and :cut!.and :fail
|
127
|
+
:john.happy.if :true
|
128
|
+
:john.should_not be_happy
|
129
|
+
end
|
130
|
+
it "works with branch or (control)" do
|
131
|
+
:john.happy.if :true.and :fail
|
132
|
+
:john.happy.if :true
|
133
|
+
:john.should be_happy
|
134
|
+
end
|
135
|
+
|
136
|
+
it "works with or" do
|
137
|
+
:john.happy.if((:true.and :cut!.and :fail).or :true)
|
138
|
+
:john.should_not be_happy
|
139
|
+
end
|
140
|
+
|
141
|
+
it "works with or (control)" do
|
142
|
+
:john.happy.if((:true.and :fail).or :true)
|
143
|
+
:john.should be_happy
|
144
|
+
end
|
145
|
+
|
146
|
+
it "returns true with branch or" do
|
147
|
+
:john.happy.if :true.and :cut!.and :true
|
148
|
+
:john.happy.if :true
|
149
|
+
:john.should be_happy
|
150
|
+
end
|
151
|
+
it "returns true with branch or (control)" do
|
152
|
+
:john.happy.if :true.and :true
|
153
|
+
:john.happy.if :true
|
154
|
+
:john.should be_happy
|
155
|
+
end
|
156
|
+
|
157
|
+
it "returns true with or" do
|
158
|
+
:john.happy.if((:true.and :cut!.and :true).or :true)
|
159
|
+
:john.should be_happy
|
160
|
+
end
|
161
|
+
|
162
|
+
it "returns true with or (control)" do
|
163
|
+
:john.happy.if((:true.and :true).or :true)
|
164
|
+
:john.should be_happy
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe "all,any,one,none,every" do
|
169
|
+
before do
|
170
|
+
:john.likes! :water
|
171
|
+
:john.likes! :beer
|
172
|
+
|
173
|
+
:jane.likes! :water
|
174
|
+
:jane.likes! :milk
|
175
|
+
:jane.likes! :beer
|
176
|
+
|
177
|
+
:jeff.likes! :water
|
178
|
+
:jeff.likes! :absinth
|
179
|
+
|
180
|
+
:todd.likes! :milk
|
181
|
+
|
182
|
+
@predicates = [:all, :any, :one, :none]
|
183
|
+
@names = :john, :jane, :jeff, :todd
|
184
|
+
@good =
|
185
|
+
[
|
186
|
+
[[1,1,0,0], [0,1,0,0], [0,0,1,0], [0,1,0,1]], # all
|
187
|
+
[[1,1,1,0], [1,1,1,1], [1,1,1,0], [0,1,0,1]], # any
|
188
|
+
[[0,0,1,0], [0,0,1,1], [1,1,0,0], [0,1,0,1]], # one
|
189
|
+
[[0,0,0,1], [0,0,0,0], [0,0,0,1], [1,0,1,0]] # none
|
190
|
+
]
|
191
|
+
end
|
192
|
+
|
193
|
+
it "work" do
|
194
|
+
@predicates.map{|p| @names.map{|n| @names.map{|m|
|
195
|
+
(n.likes(K).send p, m.likes(K)).true? ? 1 : 0
|
196
|
+
}}}.should == @good
|
197
|
+
end
|
198
|
+
|
199
|
+
it "mimic well enumerators' predicates" do
|
200
|
+
@predicates.map{|p| @names.map{|n| @names.map{|m|
|
201
|
+
n.likes(K).map{K}.send(:"#{p}?"){|x| m.likes?(x) } ? 1 : 0
|
202
|
+
}}}.should == @good
|
203
|
+
end
|
204
|
+
|
205
|
+
|
206
|
+
|
207
|
+
specify "all works" do
|
208
|
+
(:john.likes(X).all(:john.likes(X))).true?.should be_true
|
209
|
+
(:john.likes(X).all(:jane.likes(X))).true?.should be_true
|
210
|
+
(:john.likes(X).all(:jeff.likes(X))).true?.should_not be_true
|
211
|
+
(:john.likes(X).all(:todd.likes(X))).true?.should_not be_true
|
212
|
+
|
213
|
+
(:jane.likes(X).all(:john.likes(X))).true?.should_not be_true
|
214
|
+
(:jane.likes(X).all(:jane.likes(X))).true?.should be_true
|
215
|
+
(:jane.likes(X).all(:jeff.likes(X))).true?.should_not be_true
|
216
|
+
(:jane.likes(X).all(:todd.likes(X))).true?.should_not be_true
|
217
|
+
|
218
|
+
(:jeff.likes(X).all(:john.likes(X))).true?.should_not be_true
|
219
|
+
(:jeff.likes(X).all(:jane.likes(X))).true?.should_not be_true
|
220
|
+
(:jeff.likes(X).all(:jeff.likes(X))).true?.should be_true
|
221
|
+
(:jeff.likes(X).all(:todd.likes(X))).true?.should_not be_true
|
222
|
+
|
223
|
+
(:todd.likes(X).all(:john.likes(X))).true?.should_not be_true
|
224
|
+
(:todd.likes(X).all(:jane.likes(X))).true?.should be_true
|
225
|
+
(:todd.likes(X).all(:jeff.likes(X))).true?.should_not be_true
|
226
|
+
(:todd.likes(X).all(:todd.likes(X))).true?.should be_true
|
227
|
+
end
|
228
|
+
|
229
|
+
specify "all works with procs" do
|
230
|
+
(:john.likes(X).all{:john.likes?(X)}).true?.should be_true
|
231
|
+
(:john.likes(X).all{:jane.likes?(X)}).true?.should be_true
|
232
|
+
(:john.likes(X).all{:jeff.likes?(X)}).true?.should_not be_true
|
233
|
+
(:john.likes(X).all{:todd.likes?(X)}).true?.should_not be_true
|
234
|
+
|
235
|
+
(:jane.likes(X).all{:john.likes?(X)}).true?.should_not be_true
|
236
|
+
(:jane.likes(X).all{:jane.likes?(X)}).true?.should be_true
|
237
|
+
(:jane.likes(X).all{:jeff.likes?(X)}).true?.should_not be_true
|
238
|
+
(:jane.likes(X).all{:todd.likes?(X)}).true?.should_not be_true
|
239
|
+
|
240
|
+
(:jeff.likes(X).all{:john.likes?(X)}).true?.should_not be_true
|
241
|
+
(:jeff.likes(X).all{:jane.likes?(X)}).true?.should_not be_true
|
242
|
+
(:jeff.likes(X).all{:jeff.likes?(X)}).true?.should be_true
|
243
|
+
(:jeff.likes(X).all{:todd.likes?(X)}).true?.should_not be_true
|
244
|
+
|
245
|
+
(:todd.likes(X).all{:john.likes?(X)}).true?.should_not be_true
|
246
|
+
(:todd.likes(X).all{:jane.likes?(X)}).true?.should be_true
|
247
|
+
(:todd.likes(X).all{:jeff.likes?(X)}).true?.should_not be_true
|
248
|
+
(:todd.likes(X).all{:todd.likes?(X)}).true?.should be_true
|
249
|
+
end
|
250
|
+
|
251
|
+
it "can be called with global functor syntax" do
|
252
|
+
all(:john.likes(X), :jane.likes(X)).true?.should be_true
|
253
|
+
all(:jane.likes(X), :john.likes(X)).true?.should_not be_true
|
254
|
+
any(:jane.likes(X), :todd.likes(X)).true?.should be_true
|
255
|
+
any(:john.likes(X), :todd.likes(X)).true?.should_not be_true
|
256
|
+
end
|
257
|
+
|
258
|
+
it "one, any, none can be called unarily" do
|
259
|
+
one(:john.likes(X)).true?.should_not be_true
|
260
|
+
one(:jane.likes(X)).true?.should_not be_true
|
261
|
+
one(:jeff.likes(X)).true?.should_not be_true
|
262
|
+
one(:todd.likes(X)).true?.should be_true
|
263
|
+
one(:jim.likes(X)).true?.should_not be_true
|
264
|
+
|
265
|
+
any(:john.likes(X)).true?.should be_true
|
266
|
+
any(:jane.likes(X)).true?.should be_true
|
267
|
+
any(:jeff.likes(X)).true?.should be_true
|
268
|
+
any(:todd.likes(X)).true?.should be_true
|
269
|
+
any(:jim.likes(X)).true?.should_not be_true
|
270
|
+
|
271
|
+
none(:john.likes(X)).true?.should_not be_true
|
272
|
+
none(:jane.likes(X)).true?.should_not be_true
|
273
|
+
none(:jeff.likes(X)).true?.should_not be_true
|
274
|
+
none(:todd.likes(X)).true?.should_not be_true
|
275
|
+
none(:jim.likes(X)).true?.should be_true
|
276
|
+
end
|
277
|
+
|
278
|
+
it "does not hijack variables" do
|
279
|
+
A.is(X.is(5)).and(A.all{X<10}).true?.should == true
|
280
|
+
end
|
281
|
+
|
282
|
+
describe "every" do
|
283
|
+
specify "works like all" do
|
284
|
+
every(:john.likes(X),:john.likes(X)).true?.should be_true
|
285
|
+
every(:john.likes(X),:jane.likes(X)).true?.should be_true
|
286
|
+
every(:john.likes(X),:jeff.likes(X)).true?.should_not be_true
|
287
|
+
every(:john.likes(X),:todd.likes(X)).true?.should_not be_true
|
288
|
+
|
289
|
+
every(:jane.likes(X),:john.likes(X)).true?.should_not be_true
|
290
|
+
every(:jane.likes(X),:jane.likes(X)).true?.should be_true
|
291
|
+
every(:jane.likes(X),:jeff.likes(X)).true?.should_not be_true
|
292
|
+
every(:jane.likes(X),:todd.likes(X)).true?.should_not be_true
|
293
|
+
|
294
|
+
every(:jeff.likes(X),:john.likes(X)).true?.should_not be_true
|
295
|
+
every(:jeff.likes(X),:jane.likes(X)).true?.should_not be_true
|
296
|
+
every(:jeff.likes(X),:jeff.likes(X)).true?.should be_true
|
297
|
+
every(:jeff.likes(X),:todd.likes(X)).true?.should_not be_true
|
298
|
+
|
299
|
+
every(:todd.likes(X),:john.likes(X)).true?.should_not be_true
|
300
|
+
every(:todd.likes(X),:jane.likes(X)).true?.should be_true
|
301
|
+
every(:todd.likes(X),:jeff.likes(X)).true?.should_not be_true
|
302
|
+
every(:todd.likes(X),:todd.likes(X)).true?.should be_true
|
303
|
+
end
|
304
|
+
|
305
|
+
specify "works like all with procs" do
|
306
|
+
every(:john.likes(X)){:john.likes?(X)}.true?.should be_true
|
307
|
+
every(:john.likes(X)){:jane.likes?(X)}.true?.should be_true
|
308
|
+
every(:john.likes(X)){:jeff.likes?(X)}.true?.should_not be_true
|
309
|
+
every(:john.likes(X)){:todd.likes?(X)}.true?.should_not be_true
|
310
|
+
|
311
|
+
every(:jane.likes(X)){:john.likes?(X)}.true?.should_not be_true
|
312
|
+
every(:jane.likes(X)){:jane.likes?(X)}.true?.should be_true
|
313
|
+
every(:jane.likes(X)){:jeff.likes?(X)}.true?.should_not be_true
|
314
|
+
every(:jane.likes(X)){:todd.likes?(X)}.true?.should_not be_true
|
315
|
+
|
316
|
+
every(:jeff.likes(X)){:john.likes?(X)}.true?.should_not be_true
|
317
|
+
every(:jeff.likes(X)){:jane.likes?(X)}.true?.should_not be_true
|
318
|
+
every(:jeff.likes(X)){:jeff.likes?(X)}.true?.should be_true
|
319
|
+
every(:jeff.likes(X)){:todd.likes?(X)}.true?.should_not be_true
|
320
|
+
|
321
|
+
every(:todd.likes(X)){:john.likes?(X)}.true?.should_not be_true
|
322
|
+
every(:todd.likes(X)){:jane.likes?(X)}.true?.should be_true
|
323
|
+
every(:todd.likes(X)){:jeff.likes?(X)}.true?.should_not be_true
|
324
|
+
every(:todd.likes(X)){:todd.likes?(X)}.true?.should be_true
|
325
|
+
end
|
326
|
+
|
327
|
+
|
328
|
+
specify "can be used for assumptions" do
|
329
|
+
predicate_for Symbol, ".good"
|
330
|
+
# assumptions reverse the order
|
331
|
+
every(:john.likes(X), X.good.assumed).and(Y.good).map{Y}.should == [:beer, :water]
|
332
|
+
end
|
333
|
+
|
334
|
+
end
|
335
|
+
|
336
|
+
|
337
|
+
|
338
|
+
end
|
339
|
+
|
340
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "rubylog/builtins/reflection"
|
3
|
+
|
4
|
+
describe "reflection builtins", :rubylog => true do
|
5
|
+
before do
|
6
|
+
predicate_for String, ".likes() .drinks()"
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "fact" do
|
10
|
+
specify do
|
11
|
+
"John".likes! "beer"
|
12
|
+
check "John".likes("beer").fact
|
13
|
+
check { A.likes(B).fact.map{A.likes(B)} == ["John".likes("beer")] }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "follows_from" do
|
18
|
+
specify do
|
19
|
+
A.drinks(B).if A.likes(B)
|
20
|
+
check A.drinks(B).follows_from A.likes(B)
|
21
|
+
check {A.drinks(B).follows_from(K).map{K} == [A.likes(B)] }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "structure" do
|
26
|
+
specify do
|
27
|
+
check A.likes(B).structure(A.likes(B).predicate, :likes, [A,B])
|
28
|
+
check { A.likes(B).structure(P,X,Y).map{[P,X,Y]} == [[A.likes.predicate, :likes, [A,B]]] }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "structures with variable functor and partial argument list" do
|
33
|
+
specify do
|
34
|
+
check { K.structure(ANY.drinks(ANY).predicate, :drinks, ["John", "beer"]).map{K} == ["John".drinks("beer")] }
|
35
|
+
check { K.structure(Rubylog::Procedure.new(:drinks, 2), A,[*B]).
|
36
|
+
and(A.is(:drinks)).
|
37
|
+
and(B.is(["John","beer"])).
|
38
|
+
map{K} == ["John".drinks("beer")] }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Term builtins", :rubylog => true do
|
4
|
+
before do
|
5
|
+
predicate_for Symbol, ".likes"
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "in" do
|
9
|
+
before do
|
10
|
+
:john.likes! :beer
|
11
|
+
:jane.likes! :milk
|
12
|
+
end
|
13
|
+
|
14
|
+
it "works for variables" do
|
15
|
+
(A.likes(B).and(B.in [])).map{[A,B]}.should == []
|
16
|
+
(A.likes(B).and(B.in [:milk])).map{[A,B]}.should == [[:jane, :milk]]
|
17
|
+
(A.likes(B).and(B.in [:beer])).map{[A,B]}.should == [[:john, :beer]]
|
18
|
+
(A.likes(B).and(B.in [:milk, :beer])).map{[A,B]}.should == [[:john, :beer], [:jane, :milk]]
|
19
|
+
end
|
20
|
+
|
21
|
+
it "works with blocks" do
|
22
|
+
(A.likes(B).and(B.in {[]})).map{[A,B]}.should == []
|
23
|
+
(A.likes(B).and(B.in {[A,:milk]})).map{[A,B]}.should == [[:jane, :milk]]
|
24
|
+
(A.likes(B).and(B.in {[:beer]})).map{[A,B]}.should == [[:john, :beer]]
|
25
|
+
(A.likes(B).and(B.in {[B]})).map{[A,B]}.should == [[:john, :beer], [:jane, :milk]]
|
26
|
+
end
|
27
|
+
|
28
|
+
it "works as iterator" do
|
29
|
+
(A.in{[1,3,4]}).map{A}.should == [1,3,4]
|
30
|
+
(A.in [1,3,4]).map{A}.should == [1,3,4]
|
31
|
+
end
|
32
|
+
|
33
|
+
it "works as search" do
|
34
|
+
(1.in{[1,3,4]}).to_a.should == [nil]
|
35
|
+
(2.in{[1,3,4]}).to_a.should == []
|
36
|
+
(1.in [1,3,4]).to_a.should == [nil]
|
37
|
+
(2.in [1,3,4]).to_a.should == []
|
38
|
+
end
|
39
|
+
|
40
|
+
it "works with clauses" do
|
41
|
+
(A.likes(B).and B.in{:john.likes(X).map{X}}).map{[A,B]}.should == [[:john, :beer]]
|
42
|
+
end
|
43
|
+
|
44
|
+
it "checks instatiation" do
|
45
|
+
expect { 5.in(B).map{B} }.to raise_error Rubylog::InstantiationError
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "not_in" do
|
51
|
+
specify do
|
52
|
+
(1.not_in{[1,3,4]}).to_a.should == []
|
53
|
+
(2.not_in{[1,3,4]}).to_a.should == [nil]
|
54
|
+
(1.not_in [1,3,4]).to_a.should == []
|
55
|
+
(2.not_in [1,3,4]).to_a.should == [nil]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "is" do
|
60
|
+
before do
|
61
|
+
:john.likes! :beer
|
62
|
+
:jane.likes! :milk
|
63
|
+
end
|
64
|
+
|
65
|
+
it "works for variables" do
|
66
|
+
(A.likes(B).and(B.is :milk)).map{[A,B]}.should == [[:jane, :milk]]
|
67
|
+
(A.likes(B).and(:milk.is B)).map{[A,B]}.should == [[:jane, :milk]]
|
68
|
+
end
|
69
|
+
|
70
|
+
it "works as calculation" do
|
71
|
+
(A.is {|| 4+4}).map{A}.should == [8]
|
72
|
+
(A.is {4+4}).map{A}.should == [8]
|
73
|
+
(A.is(4).and A.is{2*2}).map{A}.should == [4]
|
74
|
+
(A.is(4).and A.is{2*3}).map{A}.should == []
|
75
|
+
end
|
76
|
+
|
77
|
+
it "works as calculation with vars" do
|
78
|
+
(A.is(4).and B.is{A*4}).map{[A,B]}.should == [[4,16]]
|
79
|
+
(A.is(4).and A.is{A*1}).map{A}.should == [4]
|
80
|
+
(A.is(4).and A.is{A*2}).map{A}.should == []
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe "queries", :rubylog=>true do
|
4
|
+
before do
|
5
|
+
predicate_for Symbol, ".likes(Drink)"
|
6
|
+
end
|
7
|
+
|
8
|
+
it "can be run with true?" do
|
9
|
+
true?(:john.likes :beer).should be_false
|
10
|
+
:john.likes! :beer
|
11
|
+
true?(:john.likes :beer).should be_true
|
12
|
+
end
|
13
|
+
|
14
|
+
it "can be run with question mark" do
|
15
|
+
:john.likes?(:beer).should be_false
|
16
|
+
:john.likes! :beer
|
17
|
+
:john.likes?(:beer).should be_true
|
18
|
+
end
|
19
|
+
|
20
|
+
it "can be run with true?" do
|
21
|
+
(:john.likes(:beer)).true?.should be_false
|
22
|
+
:john.likes! :beer
|
23
|
+
(:john.likes(:beer)).true?.should be_true
|
24
|
+
end
|
25
|
+
|
26
|
+
it "can be run with solve" do
|
27
|
+
result = false
|
28
|
+
solve(:john.likes(:beer)) { result = true }
|
29
|
+
result.should == false
|
30
|
+
:john.likes! :beer
|
31
|
+
solve(:john.likes(:beer)) { result = true }
|
32
|
+
result.should == true
|
33
|
+
end
|
34
|
+
|
35
|
+
it "work with variables" do
|
36
|
+
:john.likes?(X).should be_false
|
37
|
+
:john.likes! :water
|
38
|
+
:john.likes?(X).should be_true
|
39
|
+
end
|
40
|
+
|
41
|
+
it "yield all solutions" do
|
42
|
+
:john.likes! :beer
|
43
|
+
:john.likes! :milk
|
44
|
+
|
45
|
+
k=[]
|
46
|
+
(:john.likes X).each{k << X}
|
47
|
+
k.should == [:beer, :milk]
|
48
|
+
end
|
49
|
+
|
50
|
+
it "yield all solutions with solve" do
|
51
|
+
:john.likes! :beer
|
52
|
+
:john.likes! :milk
|
53
|
+
|
54
|
+
k=[]
|
55
|
+
(:john.likes X).solve{k << X}
|
56
|
+
k.should == [:beer, :milk]
|
57
|
+
end
|
58
|
+
|
59
|
+
it "yield all solutions with solve and multiple vars and multiple block parameters" do
|
60
|
+
:john.likes! :beer
|
61
|
+
:jane.likes! :milk
|
62
|
+
:jane.likes! :water
|
63
|
+
|
64
|
+
k=[]
|
65
|
+
(X.likes Y).solve{k << [X,Y]}
|
66
|
+
k.should == [[:john, :beer], [:jane, :milk], [:jane, :water]]
|
67
|
+
end
|
68
|
+
|
69
|
+
it "ignore don't-care variables" do
|
70
|
+
:john.likes! :beer
|
71
|
+
|
72
|
+
k=[]
|
73
|
+
ANYONE.likes(X).each{k << [ANYONE,X]}
|
74
|
+
k.should == [[ANYONE, :beer]]
|
75
|
+
|
76
|
+
k=[]
|
77
|
+
X.likes(ANYTHING).each{k << [X,ANYTHING]}
|
78
|
+
k.should == [[:john, ANYTHING]]
|
79
|
+
end
|
80
|
+
|
81
|
+
it "leaves unboud variables as they are" do
|
82
|
+
res = []
|
83
|
+
A.likes(B).if {res << A << B }
|
84
|
+
A.likes? :beer
|
85
|
+
res.should eql [A,:beer]
|
86
|
+
end
|
87
|
+
|
88
|
+
it "substitutes deeper variables" do
|
89
|
+
res = []
|
90
|
+
A.likes(B).if {res << A << B; true}
|
91
|
+
(A.is(:john).and B.is(:swimming.in C).and \
|
92
|
+
C.is(:sea).and A.likes B).map{[A,B,C]}.should == [[:john,:swimming.in(:sea),:sea]]
|
93
|
+
res.should == [:john, :swimming.in(:sea)]
|
94
|
+
end
|
95
|
+
|
96
|
+
it "leaves deeper unboud variables as they are" do
|
97
|
+
res = []
|
98
|
+
A.likes(B).if {res << A << B; true}
|
99
|
+
(A.is(:john).and B.is(:swimming.in C).and A.likes B).map{[A,B,C]}.should eql [[:john,:swimming.in(C),C]]
|
100
|
+
res.should == [:john, :swimming.in(C)]
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "support Enumerable" do
|
104
|
+
before do
|
105
|
+
:john.likes! :beer
|
106
|
+
:john.likes! :milk
|
107
|
+
end
|
108
|
+
|
109
|
+
it "#all?, #any? and #none?" do
|
110
|
+
(:john.likes A).all?{Symbol===A}.should be_true
|
111
|
+
(:john.likes A).all?{A == :beer}.should be_false
|
112
|
+
(:john.likes A).all?{A == :beer or A == :milk}.should be_true
|
113
|
+
(:john.likes A).any?{A == :beer}.should be_true
|
114
|
+
(:john.likes A).any?{A == :milk}.should be_true
|
115
|
+
(:john.likes A).any?{A == :water}.should be_false
|
116
|
+
(:john.likes A).none?{A == :water}.should be_true
|
117
|
+
(:john.likes A).none?{A == :beer}.should be_false
|
118
|
+
end
|
119
|
+
|
120
|
+
it "#to_a" do
|
121
|
+
(:john.likes A).to_a.should == [nil, nil]
|
122
|
+
(X.likes A).to_a.should == [nil, nil]
|
123
|
+
(ANYONE.likes A).to_a.should == [nil, nil]
|
124
|
+
end
|
125
|
+
|
126
|
+
it "#map" do
|
127
|
+
(:john.likes A).map{A.to_s}.should == ['beer', 'milk']
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Rubylog::ContextModules::Predicates, :rubylog=>true do
|
4
|
+
describe "#predicate_for" do
|
5
|
+
|
6
|
+
specify "can accept humanized predicate" do
|
7
|
+
predicate_for String, ".long"
|
8
|
+
L.long.if { L.length > 10 }
|
9
|
+
"0123456789".should_not be_long
|
10
|
+
"01234567890".should be_long
|
11
|
+
end
|
12
|
+
|
13
|
+
specify "can accept space-separated predicates" do
|
14
|
+
predicate_for String, ".long .short"
|
15
|
+
L.long.if { L.length > 10 }
|
16
|
+
L.short.unless L.long
|
17
|
+
"01234567890".should_not be_short
|
18
|
+
end
|
19
|
+
|
20
|
+
specify "can accept list of predicates" do
|
21
|
+
predicate_for String, ".long", ".short"
|
22
|
+
L.long.if { L.length > 10 }
|
23
|
+
L.short.unless L.long
|
24
|
+
"01234567890".should_not be_short
|
25
|
+
end
|
26
|
+
|
27
|
+
specify "can accept array of predicates" do
|
28
|
+
predicate_for String, %w".long .short"
|
29
|
+
L.long.if { L.length > 10 }
|
30
|
+
L.short.unless L.long
|
31
|
+
"01234567890".should_not be_short
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#humanize_indicator" do
|
36
|
+
specify { humanize_indicator([:fail,0]).should == ":fail" }
|
37
|
+
specify { humanize_indicator([:false,1]).should == ".false" }
|
38
|
+
specify { humanize_indicator([:and,2]).should == ".and()" }
|
39
|
+
specify { humanize_indicator([:splits,3]).should == ".splits(,)" }
|
40
|
+
specify { humanize_indicator([:is,4]).should == ".is(,,)" }
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#unhumanize_indicator" do
|
44
|
+
specify { unhumanize_indicator(":fail" ).should == [:fail,0] }
|
45
|
+
specify { unhumanize_indicator(".false" ).should == [:false,1] }
|
46
|
+
specify { unhumanize_indicator(".and()" ).should == [:and,2] }
|
47
|
+
specify { unhumanize_indicator(".splits(,)" ).should == [:splits,3] }
|
48
|
+
specify { unhumanize_indicator(".is(,,)" ).should == [:is,4] }
|
49
|
+
|
50
|
+
describe "with comment variables" do
|
51
|
+
specify { unhumanize_indicator("Predicate.false" ).should == [:false,1] }
|
52
|
+
specify { unhumanize_indicator("a.and(b)" ).should == [:and,2] }
|
53
|
+
specify { unhumanize_indicator("LIST.splits(HEAD,TAIL)" ).should == [:splits,3] }
|
54
|
+
specify { unhumanize_indicator("C.is(A,OP,B)" ).should == [:is,4] }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|