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.
- data/Gemfile +2 -0
- data/Gemfile.lock +10 -0
- data/README.rdoc +1 -1
- data/RELEASE_NOTES.rdoc +7 -4
- data/VERSION +1 -1
- data/{examples → benchmark}/benchmark.rb +1 -0
- data/{examples → benchmark}/benchmark/compiled_not_indexed.rb +0 -0
- data/{examples → benchmark}/benchmark/compiled_sequence_indexed.rb +0 -0
- data/{examples → benchmark}/benchmark/indexed_procedure.rb +0 -0
- data/{examples → benchmark}/benchmark/prolog.rb +0 -0
- data/benchmark/benchmark/pure.rb +28 -0
- data/bin/rubylog +14 -0
- data/examples/a_plus_b.rb +2 -2
- data/examples/dcg.rb +22 -26
- data/examples/dcg2.rb +25 -30
- data/examples/divisors.rb +1 -3
- data/examples/factorial.rb +8 -15
- data/examples/file_search.rb +14 -13
- data/examples/hanoi.rb +1 -3
- data/examples/hu/csaladfa.rb +0 -4
- data/examples/n_queens.rb +17 -22
- data/examples/palindrome_detection.rb +1 -2
- data/examples/parsing.rb +19 -23
- data/examples/permutation.rb +1 -3
- data/examples/primality_by_division.rb +2 -2
- data/examples/sieve_of_eratosthenes.rb +2 -2
- data/examples/string_interpolation.rb +0 -3
- data/examples/tracing.rb +0 -4
- data/lib/rubylog/builtins/assumption.rb +2 -1
- data/lib/rubylog/builtins/file_system.rb +1 -1
- data/lib/rubylog/default_context.rb +3 -5
- data/lib/rubylog/mixins/kernel.rb +9 -1
- data/lib/rubylog/rubylog_files.rb +7 -0
- data/rubylog.gemspec +17 -22
- data/spec/inriasuite_spec.rb +851 -847
- data/spec/integration/dsl_spec.rb +32 -29
- data/spec/rspec/rubylog_spec.rb +46 -52
- data/spec/rubylog/assertable_spec.rb +92 -90
- data/spec/rubylog/builtins/arithmetics_spec.rb +92 -90
- data/spec/rubylog/builtins/assumption_spec.rb +59 -57
- data/spec/rubylog/builtins/ensure_spec.rb +6 -4
- data/spec/rubylog/builtins/file_system_spec.rb +41 -39
- data/spec/rubylog/builtins/logic_spec.rb +308 -306
- data/spec/rubylog/builtins/reflection_spec.rb +31 -29
- data/spec/rubylog/builtins/term_spec.rb +62 -60
- data/spec/rubylog/context_modules/demonstration_spec.rb +108 -106
- data/spec/rubylog/context_modules/predicates_spec.rb +29 -27
- data/spec/rubylog/context_modules/thats_spec.rb +77 -75
- data/spec/rubylog/dsl/array_splat_spec.rb +11 -9
- data/spec/rubylog/dsl/indicators_spec.rb +23 -21
- data/spec/rubylog/dsl/primitives_spec.rb +30 -28
- data/spec/rubylog/errors_spec.rb +13 -11
- data/spec/rubylog/interfaces/term_spec.rb +78 -76
- data/spec/rubylog/mixins/array_spec.rb +60 -58
- data/spec/rubylog/mixins/composite_term_spec.rb +55 -53
- data/spec/rubylog/mixins/proc_spec.rb +48 -46
- data/spec/rubylog/mixins/string_spec.rb +45 -43
- data/spec/rubylog/mixins/symbol_spec.rb +7 -5
- data/spec/rubylog/procedure_spec.rb +8 -6
- data/spec/rubylog/rule_spec.rb +10 -8
- data/spec/rubylog/structure_spec.rb +73 -71
- data/spec/rubylog/term_spec.rb +5 -3
- data/spec/rubylog/tracing_spec.rb +35 -33
- data/spec/rubylog/variable_spec.rb +249 -247
- data/spec/spec_helper.rb +4 -0
- metadata +54 -43
- data/examples/benchmark/pure.rb +0 -26
- data/examples/checkmate.rb +0 -88
- data/examples/combination.rb +0 -17
- data/examples/directory_structure_logic.rb +0 -17
- data/examples/dirlist.rb +0 -4
- data/examples/enumerators.rb +0 -30
- data/examples/hello.rb +0 -17
- data/examples/mice.rb +0 -92
- data/examples/mice2.rb +0 -37
- data/examples/object_oriented.rb +0 -14
- data/examples/prefix.rb +0 -13
- data/examples/primitives.rb +0 -26
- data/examples/sudoku.rb +0 -17
- data/spec/integration/theory_as_module_spec.rb +0 -20
- 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
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
module RubylogSpec
|
5
|
+
describe "reflection builtins", :rubylog => true do
|
6
|
+
before do
|
7
|
+
predicate_for String, ".likes() .drinks()"
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
-
|
4
|
-
|
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
|
-
|
11
|
-
:jane.likes! :milk
|
6
|
+
predicate_for Symbol, ".likes"
|
12
7
|
end
|
13
8
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
9
|
+
describe "in" do
|
10
|
+
before do
|
11
|
+
:john.likes! :beer
|
12
|
+
:jane.likes! :milk
|
13
|
+
end
|
20
14
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
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
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|
-
|
41
|
-
|
42
|
-
|
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
|
-
|
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
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
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
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
56
|
+
describe "is" do
|
57
|
+
before do
|
58
|
+
:john.likes! :beer
|
59
|
+
:jane.likes! :milk
|
60
|
+
end
|
65
61
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
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
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
-
|
42
|
-
|
43
|
-
|
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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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
|
-
|
51
|
-
|
52
|
-
|
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
|
-
|
55
|
-
|
56
|
-
|
57
|
-
end
|
42
|
+
it "yield all solutions" do
|
43
|
+
:john.likes! :beer
|
44
|
+
:john.likes! :milk
|
58
45
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
46
|
+
k=[]
|
47
|
+
(:john.likes X).each{k << X}
|
48
|
+
k.should == [:beer, :milk]
|
49
|
+
end
|
63
50
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
end
|
51
|
+
it "yield all solutions with solve" do
|
52
|
+
:john.likes! :beer
|
53
|
+
:john.likes! :milk
|
68
54
|
|
69
|
-
|
70
|
-
|
55
|
+
k=[]
|
56
|
+
(:john.likes X).solve{k << X}
|
57
|
+
k.should == [:beer, :milk]
|
58
|
+
end
|
71
59
|
|
72
|
-
|
73
|
-
|
74
|
-
|
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
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
65
|
+
k=[]
|
66
|
+
(X.likes Y).solve{k << [X,Y]}
|
67
|
+
k.should == [[:john, :beer], [:jane, :milk], [:jane, :water]]
|
68
|
+
end
|
80
69
|
|
81
|
-
|
82
|
-
|
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
|
-
|
89
|
-
|
90
|
-
|
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
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
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
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
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 "
|
110
|
-
|
111
|
-
|
112
|
-
(:john.
|
113
|
-
|
114
|
-
|
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 "
|
121
|
-
|
122
|
-
|
123
|
-
(
|
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
|
-
|
127
|
-
|
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
|