rubylog 2.0.1 → 2.1.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.
Files changed (81) hide show
  1. data/Gemfile +2 -0
  2. data/Gemfile.lock +10 -0
  3. data/README.rdoc +1 -1
  4. data/RELEASE_NOTES.rdoc +7 -4
  5. data/VERSION +1 -1
  6. data/{examples → benchmark}/benchmark.rb +1 -0
  7. data/{examples → benchmark}/benchmark/compiled_not_indexed.rb +0 -0
  8. data/{examples → benchmark}/benchmark/compiled_sequence_indexed.rb +0 -0
  9. data/{examples → benchmark}/benchmark/indexed_procedure.rb +0 -0
  10. data/{examples → benchmark}/benchmark/prolog.rb +0 -0
  11. data/benchmark/benchmark/pure.rb +28 -0
  12. data/bin/rubylog +14 -0
  13. data/examples/a_plus_b.rb +2 -2
  14. data/examples/dcg.rb +22 -26
  15. data/examples/dcg2.rb +25 -30
  16. data/examples/divisors.rb +1 -3
  17. data/examples/factorial.rb +8 -15
  18. data/examples/file_search.rb +14 -13
  19. data/examples/hanoi.rb +1 -3
  20. data/examples/hu/csaladfa.rb +0 -4
  21. data/examples/n_queens.rb +17 -22
  22. data/examples/palindrome_detection.rb +1 -2
  23. data/examples/parsing.rb +19 -23
  24. data/examples/permutation.rb +1 -3
  25. data/examples/primality_by_division.rb +2 -2
  26. data/examples/sieve_of_eratosthenes.rb +2 -2
  27. data/examples/string_interpolation.rb +0 -3
  28. data/examples/tracing.rb +0 -4
  29. data/lib/rubylog/builtins/assumption.rb +2 -1
  30. data/lib/rubylog/builtins/file_system.rb +1 -1
  31. data/lib/rubylog/default_context.rb +3 -5
  32. data/lib/rubylog/mixins/kernel.rb +9 -1
  33. data/lib/rubylog/rubylog_files.rb +7 -0
  34. data/rubylog.gemspec +17 -22
  35. data/spec/inriasuite_spec.rb +851 -847
  36. data/spec/integration/dsl_spec.rb +32 -29
  37. data/spec/rspec/rubylog_spec.rb +46 -52
  38. data/spec/rubylog/assertable_spec.rb +92 -90
  39. data/spec/rubylog/builtins/arithmetics_spec.rb +92 -90
  40. data/spec/rubylog/builtins/assumption_spec.rb +59 -57
  41. data/spec/rubylog/builtins/ensure_spec.rb +6 -4
  42. data/spec/rubylog/builtins/file_system_spec.rb +41 -39
  43. data/spec/rubylog/builtins/logic_spec.rb +308 -306
  44. data/spec/rubylog/builtins/reflection_spec.rb +31 -29
  45. data/spec/rubylog/builtins/term_spec.rb +62 -60
  46. data/spec/rubylog/context_modules/demonstration_spec.rb +108 -106
  47. data/spec/rubylog/context_modules/predicates_spec.rb +29 -27
  48. data/spec/rubylog/context_modules/thats_spec.rb +77 -75
  49. data/spec/rubylog/dsl/array_splat_spec.rb +11 -9
  50. data/spec/rubylog/dsl/indicators_spec.rb +23 -21
  51. data/spec/rubylog/dsl/primitives_spec.rb +30 -28
  52. data/spec/rubylog/errors_spec.rb +13 -11
  53. data/spec/rubylog/interfaces/term_spec.rb +78 -76
  54. data/spec/rubylog/mixins/array_spec.rb +60 -58
  55. data/spec/rubylog/mixins/composite_term_spec.rb +55 -53
  56. data/spec/rubylog/mixins/proc_spec.rb +48 -46
  57. data/spec/rubylog/mixins/string_spec.rb +45 -43
  58. data/spec/rubylog/mixins/symbol_spec.rb +7 -5
  59. data/spec/rubylog/procedure_spec.rb +8 -6
  60. data/spec/rubylog/rule_spec.rb +10 -8
  61. data/spec/rubylog/structure_spec.rb +73 -71
  62. data/spec/rubylog/term_spec.rb +5 -3
  63. data/spec/rubylog/tracing_spec.rb +35 -33
  64. data/spec/rubylog/variable_spec.rb +249 -247
  65. data/spec/spec_helper.rb +4 -0
  66. metadata +54 -43
  67. data/examples/benchmark/pure.rb +0 -26
  68. data/examples/checkmate.rb +0 -88
  69. data/examples/combination.rb +0 -17
  70. data/examples/directory_structure_logic.rb +0 -17
  71. data/examples/dirlist.rb +0 -4
  72. data/examples/enumerators.rb +0 -30
  73. data/examples/hello.rb +0 -17
  74. data/examples/mice.rb +0 -92
  75. data/examples/mice2.rb +0 -37
  76. data/examples/object_oriented.rb +0 -14
  77. data/examples/prefix.rb +0 -13
  78. data/examples/primitives.rb +0 -26
  79. data/examples/sudoku.rb +0 -17
  80. data/spec/integration/theory_as_module_spec.rb +0 -20
  81. data/spec/integration/theory_as_module_with_include_spec.rb +0 -14
@@ -1,43 +1,45 @@
1
1
  require "spec_helper"
2
2
  require "rubylog/builtins/reflection"
3
3
 
4
- describe "reflection builtins", :rubylog => true do
5
- before do
6
- predicate_for String, ".likes() .drinks()"
7
- end
4
+ module RubylogSpec
5
+ describe "reflection builtins", :rubylog => true do
6
+ before do
7
+ predicate_for String, ".likes() .drinks()"
8
+ end
8
9
 
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")] }
10
+ describe "fact" do
11
+ specify do
12
+ "John".likes! "beer"
13
+ check "John".likes("beer").fact
14
+ check { A.likes(B).fact.map{A.likes(B)} == ["John".likes("beer")] }
15
+ end
14
16
  end
15
- end
16
17
 
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)] }
18
+ describe "follows_from" do
19
+ specify do
20
+ A.drinks(B).if A.likes(B)
21
+ check A.drinks(B).follows_from A.likes(B)
22
+ check {A.drinks(B).follows_from(K).map{K} == [A.likes(B)] }
23
+ end
22
24
  end
23
- end
24
25
 
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]]] }
26
+ describe "structure" do
27
+ specify do
28
+ check A.likes(B).structure(A.likes(B).predicate, :likes, [A,B])
29
+ check { A.likes(B).structure(P,X,Y).map{[P,X,Y]} == [[A.likes.predicate, :likes, [A,B]]] }
30
+ end
29
31
  end
30
- end
31
32
 
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")] }
33
+ describe "structures with variable functor and partial argument list" do
34
+ specify do
35
+ check { K.structure(ANY.drinks(ANY).predicate, :drinks, ["John", "beer"]).map{K} == ["John".drinks("beer")] }
36
+ check { K.structure(Rubylog::Procedure.new(:drinks, 2), A,[*B]).
37
+ and(A.is(:drinks)).
38
+ and(B.is(["John","beer"])).
39
+ map{K} == ["John".drinks("beer")] }
40
+ end
39
41
  end
40
- end
41
42
 
42
43
 
44
+ end
43
45
  end
@@ -1,81 +1,83 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Term builtins", :rubylog => true do
4
- before do
5
- predicate_for Symbol, ".likes"
6
- end
7
-
8
- describe "in" do
3
+ module RubylogSpec
4
+ describe "Term builtins", :rubylog => true do
9
5
  before do
10
- :john.likes! :beer
11
- :jane.likes! :milk
6
+ predicate_for Symbol, ".likes"
12
7
  end
13
8
 
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
9
+ describe "in" do
10
+ before do
11
+ :john.likes! :beer
12
+ :jane.likes! :milk
13
+ end
20
14
 
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
15
+ it "works for variables" do
16
+ (A.likes(B).and(B.in [])).map{[A,B]}.should == []
17
+ (A.likes(B).and(B.in [:milk])).map{[A,B]}.should == [[:jane, :milk]]
18
+ (A.likes(B).and(B.in [:beer])).map{[A,B]}.should == [[:john, :beer]]
19
+ (A.likes(B).and(B.in [:milk, :beer])).map{[A,B]}.should == [[:john, :beer], [:jane, :milk]]
20
+ end
27
21
 
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
22
+ it "works with blocks" do
23
+ (A.likes(B).and(B.in {[]})).map{[A,B]}.should == []
24
+ (A.likes(B).and(B.in {[A,:milk]})).map{[A,B]}.should == [[:jane, :milk]]
25
+ (A.likes(B).and(B.in {[:beer]})).map{[A,B]}.should == [[:john, :beer]]
26
+ (A.likes(B).and(B.in {[B]})).map{[A,B]}.should == [[:john, :beer], [:jane, :milk]]
27
+ end
32
28
 
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
29
+ it "works as iterator" do
30
+ (A.in{[1,3,4]}).map{A}.should == [1,3,4]
31
+ (A.in [1,3,4]).map{A}.should == [1,3,4]
32
+ end
39
33
 
40
- it "checks instatiation" do
41
- expect { 5.in(B).map{B} }.to raise_error Rubylog::InstantiationError
42
- end
34
+ it "works as search" do
35
+ (1.in{[1,3,4]}).to_a.should == [nil]
36
+ (2.in{[1,3,4]}).to_a.should == []
37
+ (1.in [1,3,4]).to_a.should == [nil]
38
+ (2.in [1,3,4]).to_a.should == []
39
+ end
43
40
 
44
- end
41
+ it "checks instatiation" do
42
+ expect { 5.in(B).map{B} }.to raise_error Rubylog::InstantiationError
43
+ end
45
44
 
46
- describe "not_in" do
47
- specify do
48
- (1.not_in{[1,3,4]}).to_a.should == []
49
- (2.not_in{[1,3,4]}).to_a.should == [nil]
50
- (1.not_in [1,3,4]).to_a.should == []
51
- (2.not_in [1,3,4]).to_a.should == [nil]
52
45
  end
53
- end
54
46
 
55
- describe "is" do
56
- before do
57
- :john.likes! :beer
58
- :jane.likes! :milk
47
+ describe "not_in" do
48
+ specify do
49
+ (1.not_in{[1,3,4]}).to_a.should == []
50
+ (2.not_in{[1,3,4]}).to_a.should == [nil]
51
+ (1.not_in [1,3,4]).to_a.should == []
52
+ (2.not_in [1,3,4]).to_a.should == [nil]
53
+ end
59
54
  end
60
55
 
61
- it "works for variables" do
62
- (A.likes(B).and(B.is :milk)).map{[A,B]}.should == [[:jane, :milk]]
63
- (A.likes(B).and(:milk.is B)).map{[A,B]}.should == [[:jane, :milk]]
64
- end
56
+ describe "is" do
57
+ before do
58
+ :john.likes! :beer
59
+ :jane.likes! :milk
60
+ end
65
61
 
66
- it "works as calculation" do
67
- (A.is {|| 4+4}).map{A}.should == [8]
68
- (A.is {4+4}).map{A}.should == [8]
69
- (A.is(4).and A.is{2*2}).map{A}.should == [4]
70
- (A.is(4).and A.is{2*3}).map{A}.should == []
71
- end
62
+ it "works for variables" do
63
+ (A.likes(B).and(B.is :milk)).map{[A,B]}.should == [[:jane, :milk]]
64
+ (A.likes(B).and(:milk.is B)).map{[A,B]}.should == [[:jane, :milk]]
65
+ end
66
+
67
+ it "works as calculation" do
68
+ (A.is {|| 4+4}).map{A}.should == [8]
69
+ (A.is {4+4}).map{A}.should == [8]
70
+ (A.is(4).and A.is{2*2}).map{A}.should == [4]
71
+ (A.is(4).and A.is{2*3}).map{A}.should == []
72
+ end
73
+
74
+ it "works as calculation with vars" do
75
+ (A.is(4).and B.is{A*4}).map{[A,B]}.should == [[4,16]]
76
+ (A.is(4).and A.is{A*1}).map{A}.should == [4]
77
+ (A.is(4).and A.is{A*2}).map{A}.should == []
78
+ end
72
79
 
73
- it "works as calculation with vars" do
74
- (A.is(4).and B.is{A*4}).map{[A,B]}.should == [[4,16]]
75
- (A.is(4).and A.is{A*1}).map{A}.should == [4]
76
- (A.is(4).and A.is{A*2}).map{A}.should == []
77
80
  end
78
81
 
79
82
  end
80
-
81
83
  end
@@ -1,132 +1,134 @@
1
1
  require "spec_helper"
2
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
3
+ module RubylogSpec
4
+ describe "queries", :rubylog=>true do
5
+ before do
6
+ predicate_for Symbol, ".likes(Drink)"
7
+ end
25
8
 
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
9
+ it "can be run with true?" do
10
+ true?(:john.likes :beer).should be_false
11
+ :john.likes! :beer
12
+ true?(:john.likes :beer).should be_true
13
+ end
34
14
 
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
15
+ it "can be run with question mark" do
16
+ :john.likes?(:beer).should be_false
17
+ :john.likes! :beer
18
+ :john.likes?(:beer).should be_true
19
+ end
40
20
 
41
- it "yield all solutions" do
42
- :john.likes! :beer
43
- :john.likes! :milk
21
+ it "can be run with true?" do
22
+ (:john.likes(:beer)).true?.should be_false
23
+ :john.likes! :beer
24
+ (:john.likes(:beer)).true?.should be_true
25
+ end
44
26
 
45
- k=[]
46
- (:john.likes X).each{k << X}
47
- k.should == [:beer, :milk]
48
- end
27
+ it "can be run with solve" do
28
+ result = false
29
+ solve(:john.likes(:beer)) { result = true }
30
+ result.should == false
31
+ :john.likes! :beer
32
+ solve(:john.likes(:beer)) { result = true }
33
+ result.should == true
34
+ end
49
35
 
50
- it "yield all solutions with solve" do
51
- :john.likes! :beer
52
- :john.likes! :milk
36
+ it "work with variables" do
37
+ :john.likes?(X).should be_false
38
+ :john.likes! :water
39
+ :john.likes?(X).should be_true
40
+ end
53
41
 
54
- k=[]
55
- (:john.likes X).solve{k << X}
56
- k.should == [:beer, :milk]
57
- end
42
+ it "yield all solutions" do
43
+ :john.likes! :beer
44
+ :john.likes! :milk
58
45
 
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
46
+ k=[]
47
+ (:john.likes X).each{k << X}
48
+ k.should == [:beer, :milk]
49
+ end
63
50
 
64
- k=[]
65
- (X.likes Y).solve{k << [X,Y]}
66
- k.should == [[:john, :beer], [:jane, :milk], [:jane, :water]]
67
- end
51
+ it "yield all solutions with solve" do
52
+ :john.likes! :beer
53
+ :john.likes! :milk
68
54
 
69
- it "ignore don't-care variables" do
70
- :john.likes! :beer
55
+ k=[]
56
+ (:john.likes X).solve{k << X}
57
+ k.should == [:beer, :milk]
58
+ end
71
59
 
72
- k=[]
73
- ANYONE.likes(X).each{k << [ANYONE,X]}
74
- k.should == [[ANYONE, :beer]]
60
+ it "yield all solutions with solve and multiple vars and multiple block parameters" do
61
+ :john.likes! :beer
62
+ :jane.likes! :milk
63
+ :jane.likes! :water
75
64
 
76
- k=[]
77
- X.likes(ANYTHING).each{k << [X,ANYTHING]}
78
- k.should == [[:john, ANYTHING]]
79
- end
65
+ k=[]
66
+ (X.likes Y).solve{k << [X,Y]}
67
+ k.should == [[:john, :beer], [:jane, :milk], [:jane, :water]]
68
+ end
80
69
 
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
70
+ it "ignore don't-care variables" do
71
+ :john.likes! :beer
87
72
 
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
73
+ k=[]
74
+ ANYONE.likes(X).each{k << [ANYONE,X]}
75
+ k.should == [[ANYONE, :beer]]
95
76
 
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
77
+ k=[]
78
+ X.likes(ANYTHING).each{k << [X,ANYTHING]}
79
+ k.should == [[:john, ANYTHING]]
80
+ end
102
81
 
103
- describe "support Enumerable" do
104
- before do
105
- :john.likes! :beer
106
- :john.likes! :milk
82
+ it "leaves unboud variables as they are" do
83
+ res = []
84
+ A.likes(B).if {res << A << B }
85
+ A.likes? :beer
86
+ res.should eql [A,:beer]
107
87
  end
108
88
 
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
89
+ it "substitutes deeper variables" do
90
+ res = []
91
+ A.likes(B).if {res << A << B; true}
92
+ (A.is(:john).and B.is(:swimming.in C).and \
93
+ C.is(:sea).and A.likes B).map{[A,B,C]}.should == [[:john,:swimming.in(:sea),:sea]]
94
+ res.should == [:john, :swimming.in(:sea)]
118
95
  end
119
96
 
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]
97
+ it "leaves deeper unboud variables as they are" do
98
+ res = []
99
+ A.likes(B).if {res << A << B; true}
100
+ (A.is(:john).and B.is(:swimming.in C).and A.likes B).map{[A,B,C]}.should eql [[:john,:swimming.in(C),C]]
101
+ res.should == [:john, :swimming.in(C)]
124
102
  end
125
103
 
126
- it "#map" do
127
- (:john.likes A).map{A.to_s}.should == ['beer', 'milk']
104
+ describe "support Enumerable" do
105
+ before do
106
+ :john.likes! :beer
107
+ :john.likes! :milk
108
+ end
109
+
110
+ it "#all?, #any? and #none?" do
111
+ (:john.likes A).all?{Symbol===A}.should be_true
112
+ (:john.likes A).all?{A == :beer}.should be_false
113
+ (:john.likes A).all?{A == :beer or A == :milk}.should be_true
114
+ (:john.likes A).any?{A == :beer}.should be_true
115
+ (:john.likes A).any?{A == :milk}.should be_true
116
+ (:john.likes A).any?{A == :water}.should be_false
117
+ (:john.likes A).none?{A == :water}.should be_true
118
+ (:john.likes A).none?{A == :beer}.should be_false
119
+ end
120
+
121
+ it "#to_a" do
122
+ (:john.likes A).to_a.should == [nil, nil]
123
+ (X.likes A).to_a.should == [nil, nil]
124
+ (ANYONE.likes A).to_a.should == [nil, nil]
125
+ end
126
+
127
+ it "#map" do
128
+ (:john.likes A).map{A.to_s}.should == ['beer', 'milk']
129
+ end
130
+
128
131
  end
129
132
 
130
133
  end
131
-
132
- end
134
+ end