rubylog 1.0.0 → 2.0pre1
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.
- 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
|