rubylog 2.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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