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