rubylog 2.0pre1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 variables do not have a value, it is not substituted.
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]]
@@ -19,8 +19,8 @@ module Rubylog
19
19
  end
20
20
 
21
21
  class ExistenceError < RubylogError
22
- def initialize clause
23
- super "Predicate #{clause.inspect} does not exist"
22
+ def initialize goal
23
+ super "Predicate #{goal.inspect} does not exist"
24
24
  end
25
25
  end
26
26
 
@@ -1,4 +1,4 @@
1
- module Rubylog::Clause
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 :cut do
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
@@ -1,7 +1,7 @@
1
1
  class Proc
2
2
 
3
- # Clause methods
4
- include Rubylog::Clause
3
+ # Goal methods
4
+ include Rubylog::Goal
5
5
 
6
6
  def prove
7
7
  yield if call_with_rubylog_variables
@@ -14,8 +14,8 @@ class Symbol
14
14
  # Term methods
15
15
  include Rubylog::Term
16
16
 
17
- # Clause methods
18
- include Rubylog::Clause
17
+ # Goal methods
18
+ include Rubylog::Goal
19
19
 
20
20
  def prove
21
21
  predicate.call { yield }
@@ -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 :cut do
21
+ catch :rubylog_cut do
18
22
 
19
23
  # for each rule
20
24
  each do |rule|
data/lib/rubylog/rule.rb CHANGED
@@ -10,6 +10,10 @@ module Rubylog
10
10
  @body = body
11
11
  end
12
12
 
13
+ def inspect
14
+ "#{head.inspect}.if(#{body.inspect})"
15
+ end
16
+
13
17
  # CompoundTerm methods
14
18
  include Rubylog::CompoundTerm
15
19
  def rubylog_clone &block
@@ -51,8 +51,8 @@ module Rubylog
51
51
  # Assertable methods
52
52
  include Rubylog::Assertable
53
53
 
54
- # Clause methods
55
- include Rubylog::Clause
54
+ # Goal methods
55
+ include Rubylog::Goal
56
56
 
57
57
  def prove
58
58
  count = 0
@@ -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
- # we bind the other to self (this order comes from
77
- # inriasuite_spec#unify)
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
- # Clause methods
113
- include Clause
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
- catch :cut do
125
- v.prove{yield}
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
@@ -10,7 +10,7 @@ require 'rubylog/tracing'
10
10
 
11
11
  # interfaces
12
12
  require 'rubylog/term'
13
- require 'rubylog/clause'
13
+ require 'rubylog/goal'
14
14
  require 'rubylog/assertable'
15
15
  require 'rubylog/compound_term'
16
16
 
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.0pre1"
8
+ s.version = "2.0.0"
9
9
 
10
- s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
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-02"
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",
@@ -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]]].) do
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(:A) }
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(:B) and B == Rubylog::Variable.new(:B) }
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
- check { "#{S[/\A(.*)\.rb/]}".filename_in("lib").map{S} == ["rubylog.rb"] }
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 clauses" do
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 clauses with equal values" do
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 clauses with different values" do
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 clauses with variables and equal values" do
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 clauses with variables and equal values #2" do
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 clauses with variables and different values" do
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 clauses with variables and different values #2" do
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 clauses with repeated variables #1" do
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 clauses with repeated variables #1" do
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
@@ -34,7 +34,7 @@ describe Array, :rubylog=>true do
34
34
  a = A
35
35
  b = B
36
36
  can_unify [*a], [*b] do
37
- b.value.should equal a
37
+ a.value.should equal b
38
38
  end
39
39
  end
40
40
 
@@ -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 the other gettin bound" do
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
- b.should be_bound
65
- b.value.should equal a
66
- a.should_not be_bound
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