rubylog 2.0pre1 → 2.0.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.
- data/README.rdoc +197 -98
- data/RELEASE_NOTES.rdoc +3 -4
- data/VERSION +1 -1
- data/examples/mice.rb +2 -2
- data/examples/tracing.rb +2 -2
- data/lib/rubylog/builtins/ensure.rb +1 -1
- data/lib/rubylog/builtins/logic.rb +47 -25
- data/lib/rubylog/compound_term.rb +12 -2
- data/lib/rubylog/context_modules/predicates.rb +2 -36
- data/lib/rubylog/dsl/indicators.rb +36 -0
- data/lib/rubylog/dsl/variables.rb +1 -1
- data/lib/rubylog/errors.rb +2 -2
- data/lib/rubylog/{clause.rb → goal.rb} +2 -2
- data/lib/rubylog/mixins/proc.rb +2 -2
- data/lib/rubylog/mixins/symbol.rb +2 -2
- data/lib/rubylog/procedure.rb +5 -1
- data/lib/rubylog/rule.rb +4 -0
- data/lib/rubylog/structure.rb +2 -2
- data/lib/rubylog/variable.rb +29 -9
- data/lib/rubylog.rb +1 -1
- data/rubylog.gemspec +8 -4
- data/spec/inriasuite_spec.rb +1 -3
- data/spec/integration/dsl_spec.rb +2 -2
- data/spec/rubylog/builtins/logic_spec.rb +42 -0
- data/spec/rubylog/builtins/term_spec.rb +0 -4
- data/spec/rubylog/context_modules/predicates_spec.rb +0 -22
- data/spec/rubylog/context_modules/thats_spec.rb +1 -1
- data/spec/rubylog/dsl/indicators_spec.rb +26 -0
- data/spec/rubylog/interfaces/term_spec.rb +9 -9
- data/spec/rubylog/mixins/array_spec.rb +1 -1
- data/spec/rubylog/procedure_spec.rb +11 -0
- data/spec/rubylog/rule_spec.rb +13 -0
- data/spec/rubylog/variable_spec.rb +21 -4
- metadata +21 -17
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'rubylog/rule'
|
2
|
+
require 'rubylog/dsl/indicators'
|
2
3
|
|
3
4
|
|
4
5
|
module Rubylog
|
@@ -42,44 +43,9 @@ module Rubylog
|
|
42
43
|
flatten.
|
43
44
|
map{|str|str.split(" ")}.
|
44
45
|
flatten.
|
45
|
-
map{|i| unhumanize_indicator(i)}.
|
46
|
+
map{|i| Rubylog::DSL::Indicators.unhumanize_indicator(i)}.
|
46
47
|
each {|i| yield i }
|
47
48
|
end
|
48
|
-
|
49
|
-
|
50
|
-
# Makes human-friendly output from the indicator
|
51
|
-
# For example, .and()
|
52
|
-
def humanize_indicator indicator
|
53
|
-
return indicator if String === indicator
|
54
|
-
functor, arity = indicator
|
55
|
-
if arity > 1
|
56
|
-
".#{functor}(#{ ','*(arity-2) })"
|
57
|
-
elsif arity == 1
|
58
|
-
".#{functor}"
|
59
|
-
elsif arity == 0
|
60
|
-
":#{functor}"
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
# Makes internal representation from predicate indicator
|
65
|
-
#
|
66
|
-
# For example, <tt>.and()</tt> becomes <tt>[:and,2]</tt>
|
67
|
-
def unhumanize_indicator indicator
|
68
|
-
case indicator
|
69
|
-
when Array
|
70
|
-
indicator
|
71
|
-
when /\A:(\w+)\z/
|
72
|
-
[:"#{$1}",0]
|
73
|
-
when /\A\w*\.(\w+)\z/
|
74
|
-
[:"#{$1}",1]
|
75
|
-
when /\A\w*\.(\w+)\(\w*((,\w*)*)\)\z/
|
76
|
-
[:"#{$1}",$2.count(",")+2]
|
77
|
-
else
|
78
|
-
raise ArgumentError, "invalid indicator: #{indicator.inspect}"
|
79
|
-
end
|
80
|
-
|
81
|
-
end
|
82
|
-
|
83
49
|
end
|
84
50
|
end
|
85
51
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Rubylog::DSL
|
2
|
+
module Indicators
|
3
|
+
# Makes human-friendly output from the indicator
|
4
|
+
# For example, .and()
|
5
|
+
def self.humanize_indicator indicator
|
6
|
+
return indicator if String === indicator
|
7
|
+
functor, arity = indicator
|
8
|
+
if arity > 1
|
9
|
+
".#{functor}(#{ ','*(arity-2) })"
|
10
|
+
elsif arity == 1
|
11
|
+
".#{functor}"
|
12
|
+
elsif arity == 0
|
13
|
+
":#{functor}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Makes internal representation from predicate indicator
|
18
|
+
#
|
19
|
+
# For example, <tt>.and()</tt> becomes <tt>[:and,2]</tt>
|
20
|
+
def self.unhumanize_indicator indicator
|
21
|
+
case indicator
|
22
|
+
when Array
|
23
|
+
indicator
|
24
|
+
when /\A:(\w+)\z/
|
25
|
+
[:"#{$1}",0]
|
26
|
+
when /\A\w*\.(\w+)\z/
|
27
|
+
[:"#{$1}",1]
|
28
|
+
when /\A\w*\.(\w+)\(\w*((,\w*)*)\)\z/
|
29
|
+
[:"#{$1}",$2.count(",")+2]
|
30
|
+
else
|
31
|
+
raise ArgumentError, "invalid indicator: #{indicator.inspect}"
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -15,7 +15,7 @@ module Rubylog::DSL
|
|
15
15
|
# A.is(5).map{A} # => [5]
|
16
16
|
# B.is(5).and(A.is([2,B])).map{A} # => [[2,5]]
|
17
17
|
#
|
18
|
-
# When
|
18
|
+
# When a variable does not have a value, it is not substituted.
|
19
19
|
#
|
20
20
|
# A.is(B).map{A} # => [B]
|
21
21
|
# B.is(C).and(A.is([2,B])).map{A} # => [[2,C]]
|
data/lib/rubylog/errors.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
module Rubylog::
|
1
|
+
module Rubylog::Goal
|
2
2
|
# Clients should implement this method.
|
3
3
|
# Yields for each possible solution of the predicate
|
4
4
|
def prove
|
@@ -12,7 +12,7 @@ module Rubylog::Clause
|
|
12
12
|
|
13
13
|
def solve &block
|
14
14
|
goal = rubylog_match_variables
|
15
|
-
catch :
|
15
|
+
catch :rubylog_cut do
|
16
16
|
goal.prove { block.call_with_rubylog_variables(goal.rubylog_variables) if block }
|
17
17
|
end
|
18
18
|
end
|
data/lib/rubylog/mixins/proc.rb
CHANGED
data/lib/rubylog/procedure.rb
CHANGED
@@ -7,6 +7,10 @@ module Rubylog
|
|
7
7
|
@rules = rules
|
8
8
|
end
|
9
9
|
|
10
|
+
def inspect
|
11
|
+
"#{Rubylog::DSL::Indicators.humanize_indicator([functor,arity])}: #{@rules.inspect}"
|
12
|
+
end
|
13
|
+
|
10
14
|
def method_missing name, *args, &block
|
11
15
|
@rules.send name, *args, &block
|
12
16
|
end
|
@@ -14,7 +18,7 @@ module Rubylog
|
|
14
18
|
# accepts the *args of the called structure
|
15
19
|
def call *args
|
16
20
|
# catch cuts
|
17
|
-
catch :
|
21
|
+
catch :rubylog_cut do
|
18
22
|
|
19
23
|
# for each rule
|
20
24
|
each do |rule|
|
data/lib/rubylog/rule.rb
CHANGED
data/lib/rubylog/structure.rb
CHANGED
data/lib/rubylog/variable.rb
CHANGED
@@ -16,10 +16,12 @@ module Rubylog
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def inspect
|
19
|
+
return "#{@name}=#{@value.inspect}" if @bound
|
20
|
+
|
19
21
|
if @guards.empty?
|
20
22
|
@name.to_s
|
21
23
|
else
|
22
|
-
"#{@name}#{@guards}"
|
24
|
+
"#{@name}#{@guards.inspect}"
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
@@ -56,6 +58,7 @@ module Rubylog
|
|
56
58
|
# values are variables, unifies them with the other being bound to the
|
57
59
|
# receiver. If one of them is a variable, it gets bound to the other value.
|
58
60
|
# If none of them is a variable, they are checked for equality with eql?.
|
61
|
+
# Succeeds if other is the same object as the receiver.
|
59
62
|
#
|
60
63
|
def rubylog_unify other
|
61
64
|
# check if we are bound
|
@@ -71,11 +74,13 @@ module Rubylog
|
|
71
74
|
|
72
75
|
# if the other is a variable
|
73
76
|
if other.is_a? Rubylog::Variable
|
77
|
+
# succeed if same object
|
78
|
+
(yield; return) if self.equal? other
|
79
|
+
|
74
80
|
# we union our guards with the other's
|
75
81
|
other.append_guards guards do
|
76
|
-
#
|
77
|
-
|
78
|
-
other.bind_to self do
|
82
|
+
# and bind to the other
|
83
|
+
bind_to other do
|
79
84
|
yield
|
80
85
|
end
|
81
86
|
end
|
@@ -109,8 +114,8 @@ module Rubylog
|
|
109
114
|
end
|
110
115
|
end
|
111
116
|
|
112
|
-
#
|
113
|
-
include
|
117
|
+
# Goal methods
|
118
|
+
include Goal
|
114
119
|
|
115
120
|
def prove
|
116
121
|
v = rubylog_dereference
|
@@ -120,10 +125,25 @@ module Rubylog
|
|
120
125
|
unless v.rubylog_variables
|
121
126
|
v = v.rubylog_match_variables
|
122
127
|
end
|
123
|
-
|
124
|
-
|
125
|
-
|
128
|
+
|
129
|
+
caught_cut = false
|
130
|
+
|
131
|
+
catch :rubylog_cut do
|
132
|
+
v.prove do
|
133
|
+
# intercept cuts that come from the yield
|
134
|
+
catch :rubylog_no_cut do
|
135
|
+
catch :rubylog_cut do
|
136
|
+
yield
|
137
|
+
throw :rubylog_no_cut
|
138
|
+
end
|
139
|
+
caught_cut = true
|
140
|
+
end
|
141
|
+
break if caught_cut
|
142
|
+
end
|
126
143
|
end
|
144
|
+
|
145
|
+
# pass through cut if one was caught from yield
|
146
|
+
throw :rubylog_cut if caught_cut
|
127
147
|
end
|
128
148
|
|
129
149
|
|
data/lib/rubylog.rb
CHANGED
data/rubylog.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "rubylog"
|
8
|
-
s.version = "2.
|
8
|
+
s.version = "2.0.0"
|
9
9
|
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new("
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Bern\u{e1}t Kall\u{f3}"]
|
12
|
-
s.date = "2013-05-
|
12
|
+
s.date = "2013-05-07"
|
13
13
|
s.description = "Rubylog is a Prolog-like DSL for Ruby."
|
14
14
|
s.email = "kallo.bernat@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -66,7 +66,6 @@ Gem::Specification.new do |s|
|
|
66
66
|
"lib/rubylog/builtins/logic.rb",
|
67
67
|
"lib/rubylog/builtins/reflection.rb",
|
68
68
|
"lib/rubylog/builtins/term.rb",
|
69
|
-
"lib/rubylog/clause.rb",
|
70
69
|
"lib/rubylog/compound_term.rb",
|
71
70
|
"lib/rubylog/context.rb",
|
72
71
|
"lib/rubylog/context_creation.rb",
|
@@ -77,10 +76,12 @@ Gem::Specification.new do |s|
|
|
77
76
|
"lib/rubylog/context_modules/thats.rb",
|
78
77
|
"lib/rubylog/default_context.rb",
|
79
78
|
"lib/rubylog/dsl/array_splat.rb",
|
79
|
+
"lib/rubylog/dsl/indicators.rb",
|
80
80
|
"lib/rubylog/dsl/primitives.rb",
|
81
81
|
"lib/rubylog/dsl/thats.rb",
|
82
82
|
"lib/rubylog/dsl/variables.rb",
|
83
83
|
"lib/rubylog/errors.rb",
|
84
|
+
"lib/rubylog/goal.rb",
|
84
85
|
"lib/rubylog/mixins/array.rb",
|
85
86
|
"lib/rubylog/mixins/hash.rb",
|
86
87
|
"lib/rubylog/mixins/kernel.rb",
|
@@ -185,6 +186,7 @@ Gem::Specification.new do |s|
|
|
185
186
|
"spec/rubylog/context_modules/predicates_spec.rb",
|
186
187
|
"spec/rubylog/context_modules/thats_spec.rb",
|
187
188
|
"spec/rubylog/dsl/array_splat_spec.rb",
|
189
|
+
"spec/rubylog/dsl/indicators_spec.rb",
|
188
190
|
"spec/rubylog/dsl/primitives_spec.rb",
|
189
191
|
"spec/rubylog/errors_spec.rb",
|
190
192
|
"spec/rubylog/interfaces/term_spec.rb",
|
@@ -193,6 +195,8 @@ Gem::Specification.new do |s|
|
|
193
195
|
"spec/rubylog/mixins/proc_spec.rb",
|
194
196
|
"spec/rubylog/mixins/string_spec.rb",
|
195
197
|
"spec/rubylog/mixins/symbol_spec.rb",
|
198
|
+
"spec/rubylog/procedure_spec.rb",
|
199
|
+
"spec/rubylog/rule_spec.rb",
|
196
200
|
"spec/rubylog/structure_spec.rb",
|
197
201
|
"spec/rubylog/term_spec.rb",
|
198
202
|
"spec/rubylog/tracing_spec.input",
|
data/spec/inriasuite_spec.rb
CHANGED
@@ -870,9 +870,7 @@ describe "inriasuite", :rubylog=>true do
|
|
870
870
|
specify %(['='(X,1),[[X <-- 1]]].) do
|
871
871
|
X.is(1).map{X}.should eql [1]
|
872
872
|
end
|
873
|
-
specify %(['='(X,Y),[[Y <-- X]]].)
|
874
|
-
X.is(Y).map{Y}.should eql [X]
|
875
|
-
end
|
873
|
+
specify %(['='(X,Y),[[Y <-- X]]].), pending: "This happens the other way around in Rubylog, X will be bound to Y."
|
876
874
|
specify %([('='(X,Y),'='(X,abc)),[[X <-- abc, Y <-- abc]]].) do
|
877
875
|
X.is(Y).and(X.is(:abc)).map{[X,Y]}.should eql [[:abc,:abc]]
|
878
876
|
end
|
@@ -29,9 +29,9 @@ describe "Rubylog dsl", :rubylog=>true do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
describe "variables" do
|
32
|
-
check A.is(ANY).and{ A == Rubylog::Variable.new(:
|
32
|
+
check A.is(ANY).and{ A == Rubylog::Variable.new(:ANY) }
|
33
33
|
check A.is(4) .and{ A == 4 }
|
34
|
-
check B.is(A) .and{ A == Rubylog::Variable.new(:
|
34
|
+
check B.is(A) .and{ A == Rubylog::Variable.new(:A) and B == Rubylog::Variable.new(:A) }
|
35
35
|
check B.is(ANY).and{ A == Rubylog::Variable.new(:A) }
|
36
36
|
end
|
37
37
|
|
@@ -163,6 +163,29 @@ describe "logic builtins", :rubylog => true do
|
|
163
163
|
:john.happy.if((:true.and :true).or :true)
|
164
164
|
:john.should be_happy
|
165
165
|
end
|
166
|
+
|
167
|
+
it "works after variable calls" do
|
168
|
+
(A.is(:true).and A.and :cut!.and :fail).or(:true).true?.should be_false
|
169
|
+
end
|
170
|
+
|
171
|
+
it "works after variable calls (control)" do
|
172
|
+
(A.is(:true).and A.and :fail).or(:true).true?.should be_true
|
173
|
+
end
|
174
|
+
|
175
|
+
it "works after variable calls (branch or)" do
|
176
|
+
:john.happy.if A.is(:true).and A.and :cut!.and :fail
|
177
|
+
:john.happy.if :true
|
178
|
+
:john.should_not be_happy
|
179
|
+
end
|
180
|
+
|
181
|
+
it "works after variable calls with multiple solutions of the variable" do
|
182
|
+
(A.is(B.is(4).or(B.is(6))).and A.and :cut!).map{B}.should == [4]
|
183
|
+
end
|
184
|
+
|
185
|
+
it "works after variable calls with multiple solutions of the variable (control)" do
|
186
|
+
(A.is(B.is(4).or(B.is(6))).and A).map{B}.should == [4,6]
|
187
|
+
end
|
188
|
+
|
166
189
|
end
|
167
190
|
|
168
191
|
describe "all,any,one,none,every" do
|
@@ -280,6 +303,13 @@ describe "logic builtins", :rubylog => true do
|
|
280
303
|
end
|
281
304
|
|
282
305
|
describe "every" do
|
306
|
+
specify "works as infix" do
|
307
|
+
:john.likes(X).every(:john.likes(X)).true?.should be_true
|
308
|
+
:john.likes(X).every(:jane.likes(X)).true?.should be_true
|
309
|
+
:john.likes(X).every(:jeff.likes(X)).true?.should_not be_true
|
310
|
+
:john.likes(X).every(:todd.likes(X)).true?.should_not be_true
|
311
|
+
end
|
312
|
+
|
283
313
|
specify "works like all" do
|
284
314
|
every(:john.likes(X),:john.likes(X)).true?.should be_true
|
285
315
|
every(:john.likes(X),:jane.likes(X)).true?.should be_true
|
@@ -331,6 +361,18 @@ describe "logic builtins", :rubylog => true do
|
|
331
361
|
every(:john.likes(X), X.good.assumed).and(Y.good).map{Y}.should == [:beer, :water]
|
332
362
|
end
|
333
363
|
|
364
|
+
specify "passes variables" do
|
365
|
+
solve N.is(5).and K.in{1..N}.every {N.should eql 5}
|
366
|
+
end
|
367
|
+
|
368
|
+
specify "passes variables" do
|
369
|
+
solve N.is(5).and K.in{1..N}.every L.in{1..N}
|
370
|
+
end
|
371
|
+
|
372
|
+
specify "passes variables if b contains the variable" do
|
373
|
+
solve N.is(5).and every I.in{2..N}, K.is{N/I}
|
374
|
+
end
|
375
|
+
|
334
376
|
end
|
335
377
|
|
336
378
|
|
@@ -37,10 +37,6 @@ describe "Term builtins", :rubylog => true do
|
|
37
37
|
(2.in [1,3,4]).to_a.should == []
|
38
38
|
end
|
39
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
40
|
it "checks instatiation" do
|
45
41
|
expect { 5.in(B).map{B} }.to raise_error Rubylog::InstantiationError
|
46
42
|
end
|
@@ -32,26 +32,4 @@ describe Rubylog::ContextModules::Predicates, :rubylog=>true do
|
|
32
32
|
end
|
33
33
|
end
|
34
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
35
|
end
|
@@ -32,7 +32,7 @@ describe "thats", :rubylog=>true do
|
|
32
32
|
describe "files" do
|
33
33
|
check { "#{S[String, thats.start_with?(".")]}".filename_in(".").map{S}.include? ".gitignore" }
|
34
34
|
check { not "#{S[String, thats.start_with?(".")]}". dirname_in(".").map{S}.include? "lib" }
|
35
|
-
|
35
|
+
specify { "#{S[/\A(.*)\.rb/]}".filename_in("lib").map{S}.should == ["rubylog.rb"] }
|
36
36
|
end
|
37
37
|
|
38
38
|
describe "factorial" do
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Rubylog::DSL::Indicators do
|
4
|
+
describe "#humanize_indicator" do
|
5
|
+
specify { Rubylog::DSL::Indicators.humanize_indicator([:fail,0]).should == ":fail" }
|
6
|
+
specify { Rubylog::DSL::Indicators.humanize_indicator([:false,1]).should == ".false" }
|
7
|
+
specify { Rubylog::DSL::Indicators.humanize_indicator([:and,2]).should == ".and()" }
|
8
|
+
specify { Rubylog::DSL::Indicators.humanize_indicator([:splits,3]).should == ".splits(,)" }
|
9
|
+
specify { Rubylog::DSL::Indicators.humanize_indicator([:is,4]).should == ".is(,,)" }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#unhumanize_indicator" do
|
13
|
+
specify { Rubylog::DSL::Indicators.unhumanize_indicator(":fail" ).should == [:fail,0] }
|
14
|
+
specify { Rubylog::DSL::Indicators.unhumanize_indicator(".false" ).should == [:false,1] }
|
15
|
+
specify { Rubylog::DSL::Indicators.unhumanize_indicator(".and()" ).should == [:and,2] }
|
16
|
+
specify { Rubylog::DSL::Indicators.unhumanize_indicator(".splits(,)" ).should == [:splits,3] }
|
17
|
+
specify { Rubylog::DSL::Indicators.unhumanize_indicator(".is(,,)" ).should == [:is,4] }
|
18
|
+
|
19
|
+
describe "with comment variables" do
|
20
|
+
specify { Rubylog::DSL::Indicators.unhumanize_indicator("Predicate.false" ).should == [:false,1] }
|
21
|
+
specify { Rubylog::DSL::Indicators.unhumanize_indicator("a.and(b)" ).should == [:and,2] }
|
22
|
+
specify { Rubylog::DSL::Indicators.unhumanize_indicator("LIST.splits(HEAD,TAIL)" ).should == [:splits,3] }
|
23
|
+
specify { Rubylog::DSL::Indicators.unhumanize_indicator("C.is(A,OP,B)" ).should == [:is,4] }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -23,50 +23,50 @@ describe "unification", :rubylog=>true do
|
|
23
23
|
:john.rubylog_unify(:mary) { result = true }
|
24
24
|
result.should == false
|
25
25
|
end
|
26
|
-
it "works on
|
26
|
+
it "works on structures" do
|
27
27
|
result = false
|
28
28
|
(:john.likes :beer).rubylog_unify(A.likes B) { result = true }
|
29
29
|
result.should == true
|
30
30
|
end
|
31
|
-
it "works on
|
31
|
+
it "works on structures with equal values" do
|
32
32
|
result = false
|
33
33
|
(:john.likes :beer).rubylog_unify(:john.likes :beer) { result = true }
|
34
34
|
result.should == true
|
35
35
|
end
|
36
|
-
it "works on
|
36
|
+
it "works on structures with different values" do
|
37
37
|
result = false
|
38
38
|
(:john.likes :beer).rubylog_unify(:john.likes :milk) { result = true }
|
39
39
|
result.should == false
|
40
40
|
end
|
41
|
-
it "works on
|
41
|
+
it "works on structures with variables and equal values" do
|
42
42
|
result = false
|
43
43
|
(:john.likes :beer).rubylog_unify(X.likes :beer) { result = true }
|
44
44
|
result.should == true
|
45
45
|
end
|
46
|
-
it "works on
|
46
|
+
it "works on structures with variables and equal values #2" do
|
47
47
|
result = false
|
48
48
|
(:john.likes :beer).rubylog_unify(:john.likes DRINK) { result = true }
|
49
49
|
result.should == true
|
50
50
|
end
|
51
|
-
it "works on
|
51
|
+
it "works on structures with variables and different values" do
|
52
52
|
result = false
|
53
53
|
(:john.likes :beer).rubylog_unify(X.likes :milk) { result = true }
|
54
54
|
result.should == false
|
55
55
|
end
|
56
|
-
it "works on
|
56
|
+
it "works on structures with variables and different values #2" do
|
57
57
|
result = false
|
58
58
|
(:john.likes :beer).rubylog_unify(:jane.likes D) { result = true }
|
59
59
|
result.should == false
|
60
60
|
end
|
61
61
|
|
62
|
-
it "works on
|
62
|
+
it "works on structures with repeated variables #1" do
|
63
63
|
result = false
|
64
64
|
(A.likes A).rubylog_match_variables.rubylog_unify(:john.likes :jane) { result = true }
|
65
65
|
result.should == false
|
66
66
|
(A.likes A).rubylog_match_variables.rubylog_unify(:john.likes :john) { result = true }
|
67
67
|
result.should == true
|
68
68
|
end
|
69
|
-
it "works on
|
69
|
+
it "works on structures with repeated variables #1" do
|
70
70
|
result = false
|
71
71
|
(:john.likes :jane).rubylog_unify(A.likes(A).rubylog_match_variables) { result = true }
|
72
72
|
result.should == false
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "rubylog/procedure"
|
3
|
+
|
4
|
+
describe Rubylog::Procedure, rubylog:true do
|
5
|
+
describe "#inspect" do
|
6
|
+
it "returns a human-readable output" do
|
7
|
+
predicate_for String, ".likes()"
|
8
|
+
A.likes(B).predicate.inspect.should == ".likes(): []"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rubylog/rule'
|
3
|
+
|
4
|
+
describe Rubylog::Rule, rubylog:true do
|
5
|
+
describe "#inspect" do
|
6
|
+
it "returns a human-readable output" do
|
7
|
+
predicate_for String, ".likes()"
|
8
|
+
A.likes(B).if B.is(:water)
|
9
|
+
|
10
|
+
A.likes(B).predicate[0].inspect.should == "A.likes(B).if(B.is(:water))"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -57,13 +57,13 @@ describe Rubylog::Variable, :rubylog=>true do
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
it "unifies with another unbound variable with
|
60
|
+
it "unifies with another unbound variable with getting bound" do
|
61
61
|
a=A
|
62
62
|
b=B
|
63
63
|
a.rubylog_unify(b) do
|
64
|
-
|
65
|
-
|
66
|
-
|
64
|
+
a.should be_bound
|
65
|
+
a.value.should equal b
|
66
|
+
b.should_not be_bound
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
@@ -86,6 +86,23 @@ describe Rubylog::Variable, :rubylog=>true do
|
|
86
86
|
end
|
87
87
|
end
|
88
88
|
end
|
89
|
+
|
90
|
+
it "unifies with self" do
|
91
|
+
a=A
|
92
|
+
a.rubylog_unify(a) do
|
93
|
+
a.should_not be_bound
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
it "unifies with another bound to self" do
|
98
|
+
a=A
|
99
|
+
b=B
|
100
|
+
a.rubylog_unify(b) do
|
101
|
+
b.rubylog_unify(a) do
|
102
|
+
b.should_not be_bound
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
89
106
|
end
|
90
107
|
|
91
108
|
describe "dereferencing" do
|