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,80 +1,82 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Array, :rubylog=>true do
4
-
5
- describe "unification" do
6
- def can_unify a, b
7
- result = false
8
- a.rubylog_unify(b) { result = true; yield if block_given? }
9
- result.should == true
10
- end
3
+ module RubylogSpec
4
+ describe Array, :rubylog=>true do
5
+
6
+ describe "unification" do
7
+ def can_unify a, b
8
+ result = false
9
+ a.rubylog_unify(b) { result = true; yield if block_given? }
10
+ result.should == true
11
+ end
11
12
 
12
- def cannot_unify a, b
13
- result = false
14
- a.rubylog_unify(b) { result = true }
15
- result.should == false
16
- end
13
+ def cannot_unify a, b
14
+ result = false
15
+ a.rubylog_unify(b) { result = true }
16
+ result.should == false
17
+ end
17
18
 
18
- it "does not unify with non-array" do
19
- cannot_unify [A,B], 12
20
- end
19
+ it "does not unify with non-array" do
20
+ cannot_unify [A,B], 12
21
+ end
21
22
 
22
- it "unifies empty arrays" do
23
- can_unify [], []
24
- end
23
+ it "unifies empty arrays" do
24
+ can_unify [], []
25
+ end
25
26
 
26
- it "unifies empty array with splat" do
27
- a = A
28
- can_unify [], [*a] do
29
- a.value.should == []
27
+ it "unifies empty array with splat" do
28
+ a = A
29
+ can_unify [], [*a] do
30
+ a.value.should == []
31
+ end
30
32
  end
31
- end
32
33
 
33
- it "unifies two splats" do
34
- a = A
35
- b = B
36
- can_unify [*a], [*b] do
37
- a.value.should equal b
34
+ it "unifies two splats" do
35
+ a = A
36
+ b = B
37
+ can_unify [*a], [*b] do
38
+ a.value.should equal b
39
+ end
38
40
  end
39
- end
40
41
 
41
- it "unifies two arrays with splats at the first element" do
42
- a = A
43
- b = B
44
- can_unify [*a], [*b,5] do
45
- a.value.should eql [*b,5]
42
+ it "unifies two arrays with splats at the first element" do
43
+ a = A
44
+ b = B
45
+ can_unify [*a], [*b,5] do
46
+ a.value.should eql [*b,5]
47
+ end
46
48
  end
47
- end
48
49
 
49
- it "unifies a splat with empty array" do
50
- a = A
51
- can_unify [*a], [] do
52
- a.value.should eql []
50
+ it "unifies a splat with empty array" do
51
+ a = A
52
+ can_unify [*a], [] do
53
+ a.value.should eql []
54
+ end
53
55
  end
54
- end
55
56
 
56
- it "unififes splats at first elements" do
57
- A.is([1,2,3]).and([*A,4].is([*B,*ANY])).map{B}.should ==
58
- [[],[1],[1,2],[1,2,3],[1,2,3,4]]
59
- end
57
+ it "unififes splats at first elements" do
58
+ A.is([1,2,3]).and([*A,4].is([*B,*ANY])).map{B}.should ==
59
+ [[],[1],[1,2],[1,2,3],[1,2,3,4]]
60
+ end
60
61
 
61
- it "unififes first splat with first non-splat" do
62
- A.is([1,2,3]).and([*A,4].is([X,*C])).map{[X,C]}.should ==
63
- [[1,[2,3,4]]]
64
- end
62
+ it "unififes first splat with first non-splat" do
63
+ A.is([1,2,3]).and([*A,4].is([X,*C])).map{[X,C]}.should ==
64
+ [[1,[2,3,4]]]
65
+ end
65
66
 
66
- it "unififes first empty splat with first non-splat" do
67
- A.is([]).and([*A,4].is([X,*C])).map{[X,C]}.should ==
68
- [[4,[]]]
69
- end
67
+ it "unififes first empty splat with first non-splat" do
68
+ A.is([]).and([*A,4].is([X,*C])).map{[X,C]}.should ==
69
+ [[4,[]]]
70
+ end
70
71
 
71
72
 
72
- end
73
+ end
73
74
 
74
- describe "#rubylog_deep_dereference" do
75
- it "does keeps unbound splats" do
76
- [*A].rubylog_deep_dereference.should eql [*A]
75
+ describe "#rubylog_deep_dereference" do
76
+ it "does keeps unbound splats" do
77
+ [*A].rubylog_deep_dereference.should eql [*A]
78
+ end
77
79
  end
78
- end
79
80
 
81
+ end
80
82
  end
@@ -1,66 +1,68 @@
1
1
  require "spec_helper"
2
2
 
3
- describe Rubylog::CompoundTerm, :rubylog=>true do
4
- predicate_for Symbol, ".likes()"
3
+ module RubylogSpec
4
+ describe Rubylog::CompoundTerm, :rubylog=>true do
5
+ predicate_for Symbol, ".likes()"
5
6
 
6
- describe "compilation" do
7
+ describe "compilation" do
7
8
 
8
- it "makes eql variables be equal" do
9
- a = A; b = A
10
- c = (a.likes b)
11
- c[0].should be_equal a; c[1].should be_equal b
12
- c[0].should_not be_equal c[1]
13
- c = c.rubylog_match_variables
14
- c[0].should be_equal c[1]
15
- end
9
+ it "makes eql variables be equal" do
10
+ a = A; b = A
11
+ c = (a.likes b)
12
+ c[0].should be_equal a; c[1].should be_equal b
13
+ c[0].should_not be_equal c[1]
14
+ c = c.rubylog_match_variables
15
+ c[0].should be_equal c[1]
16
+ end
16
17
 
17
- it "makes non-eql variables be non-equal" do
18
- a = A; b = B
19
- c = (a.likes b)
20
- c[0].should be_equal a; c[1].should be_equal b
21
- c[0].should_not be_equal c[1]
22
- c = c.rubylog_match_variables
23
- c[0].should_not be_equal c[1]
24
- end
18
+ it "makes non-eql variables be non-equal" do
19
+ a = A; b = B
20
+ c = (a.likes b)
21
+ c[0].should be_equal a; c[1].should be_equal b
22
+ c[0].should_not be_equal c[1]
23
+ c = c.rubylog_match_variables
24
+ c[0].should_not be_equal c[1]
25
+ end
25
26
 
26
- it "makes dont-care variables be non-equal" do
27
- a = ANY; b = ANY
28
- c = (a.likes b)
29
- c[0].should be_equal a; c[1].should be_equal b
30
- c[0].should_not be_equal c[1]
31
- c = c.rubylog_match_variables
32
- c[0].should_not be_equal c[1]
33
- end
27
+ it "makes dont-care variables be non-equal" do
28
+ a = ANY; b = ANY
29
+ c = (a.likes b)
30
+ c[0].should be_equal a; c[1].should be_equal b
31
+ c[0].should_not be_equal c[1]
32
+ c = c.rubylog_match_variables
33
+ c[0].should_not be_equal c[1]
34
+ end
34
35
 
35
- it "creates new variables" do
36
- a = A; b = B
37
- c = (a.likes b)
38
- c[0].should be_equal a; c[1].should be_equal b
39
- c = c.rubylog_match_variables
40
- c[0].should_not be_equal a
41
- c[1].should_not be_equal a
42
- c[0].should_not be_equal b
43
- c[1].should_not be_equal b
44
- end
36
+ it "creates new variables" do
37
+ a = A; b = B
38
+ c = (a.likes b)
39
+ c[0].should be_equal a; c[1].should be_equal b
40
+ c = c.rubylog_match_variables
41
+ c[0].should_not be_equal a
42
+ c[1].should_not be_equal a
43
+ c[0].should_not be_equal b
44
+ c[1].should_not be_equal b
45
+ end
45
46
 
46
- it "makes variables available" do
47
- a = A; a1 = A; a2 = A; b = B; b1 = B; c = C;
48
- (a.likes b).rubylog_match_variables.rubylog_variables.should == [a, b]
49
- (a.likes a1).rubylog_match_variables.rubylog_variables.should == [a]
50
- (a.likes a1.in b).rubylog_match_variables.rubylog_variables.should == [a, b]
51
- (a.likes a1,b,b1,a2,c).rubylog_match_variables.rubylog_variables.should == [a, b, c]
52
- end
47
+ it "makes variables available" do
48
+ a = A; a1 = A; a2 = A; b = B; b1 = B; c = C;
49
+ (a.likes b).rubylog_match_variables.rubylog_variables.should == [a, b]
50
+ (a.likes a1).rubylog_match_variables.rubylog_variables.should == [a]
51
+ (a.likes a1.in b).rubylog_match_variables.rubylog_variables.should == [a, b]
52
+ (a.likes a1,b,b1,a2,c).rubylog_match_variables.rubylog_variables.should == [a, b, c]
53
+ end
53
54
 
54
- it "does not make dont-care variables available" do
55
- a = ANY; a1 = ANYTHING; a2 = ANYTHING; b = B; b1 = B; c = C;
56
- (a.likes b).rubylog_match_variables.rubylog_variables.should == [b]
57
- (a.likes a1).rubylog_match_variables.rubylog_variables.should == []
58
- (a.likes a1.in b).rubylog_match_variables.
59
- rubylog_variables.should == [b]
60
- (a.likes a1,b,b1,a2,c).rubylog_match_variables.
61
- rubylog_variables.should == [b, c]
62
- end
55
+ it "does not make dont-care variables available" do
56
+ a = ANY; a1 = ANYTHING; a2 = ANYTHING; b = B; b1 = B; c = C;
57
+ (a.likes b).rubylog_match_variables.rubylog_variables.should == [b]
58
+ (a.likes a1).rubylog_match_variables.rubylog_variables.should == []
59
+ (a.likes a1.in b).rubylog_match_variables.
60
+ rubylog_variables.should == [b]
61
+ (a.likes a1,b,b1,a2,c).rubylog_match_variables.
62
+ rubylog_variables.should == [b, c]
63
+ end
63
64
 
64
65
 
66
+ end
65
67
  end
66
68
  end
@@ -1,59 +1,61 @@
1
1
  require "spec_helper"
2
2
 
3
- describe Proc, :rubylog=>true do
4
- before do
5
- predicate_for Symbol, ".is_happy .likes()"
6
- end
7
-
8
- describe "using ruby code in clauses" do
9
- it "works" do
10
- (:true.and? {false}).should be_false
11
- (:true.and? {true}).should be_true
12
- (:fail.and? {false}).should be_false
13
- (:fail.and? {true}).should be_false
14
- (:true.or? {false}).should be_true
15
- (:true.or? {true}).should be_true
16
- (:fail.or? {false}).should be_false
17
- (:fail.or? {true}).should be_true
18
-
19
- (:fail.or? {false}).should be_false
20
- (:fail.or? {true}).should be_true
21
- end
22
- it "runs the query once at every evaluation" do
23
- count = 0
24
- :john.is_happy.if :true.and { count += 1 }
25
- count.should == 0
26
- :john.is_happy?
27
- count.should == 1
28
- :john.is_happy?
29
- count.should == 2
30
- (:fail.or? {count+=1}).should be_true
31
- count.should == 3
3
+ module RubylogSpec
4
+ describe Proc, :rubylog=>true do
5
+ before do
6
+ predicate_for Symbol, ".is_happy .likes()"
32
7
  end
33
8
 
34
- describe "bindings" do
35
- it "works for rule bodies" do
36
- result = nil;
37
- (A.likes(B).if {result = [A,B]})
38
- (:john.likes(:beer)).solve{}
39
- result.should == [:john,:beer]
9
+ describe "using ruby code in clauses" do
10
+ it "works" do
11
+ (:true.and? {false}).should be_false
12
+ (:true.and? {true}).should be_true
13
+ (:fail.and? {false}).should be_false
14
+ (:fail.and? {true}).should be_false
15
+ (:true.or? {false}).should be_true
16
+ (:true.or? {true}).should be_true
17
+ (:fail.or? {false}).should be_false
18
+ (:fail.or? {true}).should be_true
19
+
20
+ (:fail.or? {false}).should be_false
21
+ (:fail.or? {true}).should be_true
40
22
  end
41
-
42
- it "works for rules" do
43
- result = nil
44
- (A.likes(B).if B.is(4).and A.is(2).and C.is(5).and {result = [A,B,C]})
45
- (A.likes(B)).solve{}
46
- result.should == [2,4,5]
23
+ it "runs the query once at every evaluation" do
24
+ count = 0
25
+ :john.is_happy.if :true.and { count += 1 }
26
+ count.should == 0
27
+ :john.is_happy?
28
+ count.should == 1
29
+ :john.is_happy?
30
+ count.should == 2
31
+ (:fail.or? {count+=1}).should be_true
32
+ count.should == 3
47
33
  end
48
34
 
49
- it "works for inline terms" do
50
- result = nil
51
- (A.is(1).and B.is(2).and {result = [A,B]}).solve{}
52
- result.should == [1,2]
53
- end
35
+ describe "bindings" do
36
+ it "works for rule bodies" do
37
+ result = nil;
38
+ (A.likes(B).if {result = [A,B]})
39
+ (:john.likes(:beer)).solve{}
40
+ result.should == [:john,:beer]
41
+ end
42
+
43
+ it "works for rules" do
44
+ result = nil
45
+ (A.likes(B).if B.is(4).and A.is(2).and C.is(5).and {result = [A,B,C]})
46
+ (A.likes(B)).solve{}
47
+ result.should == [2,4,5]
48
+ end
54
49
 
50
+ it "works for inline terms" do
51
+ result = nil
52
+ (A.is(1).and B.is(2).and {result = [A,B]}).solve{}
53
+ result.should == [1,2]
54
+ end
55
55
 
56
56
 
57
+
58
+ end
57
59
  end
58
60
  end
59
61
  end
@@ -1,48 +1,50 @@
1
1
  require "spec_helper"
2
2
 
3
- describe String, :rubylog=>true do
4
- describe "unification" do
5
- check "asdf".is "asdf"
6
- check { "abc#{S}def" =~ /abc.S\[\].def/ }
7
- check { "abc#{S[length: 1]}def" =~ /abc.S\[\d+\].def/ }
8
- check { "h#{S}o".is("hello").map{S} == ["ell"] }
9
- check { "#{Base}.#{Ext}".is("hello.rb").map{Base} == ["hello"] }
10
- check { "#{Base}.#{Ext}".is("hello.rb").map{Ext} == ["rb"] }
11
- check { "h#{S}o".is("auto").map{S} == [] }
12
- end
13
-
14
- describe "backtracked matches" do
15
- check { "abc".is("#{A}#{B}").map{"#{A}:#{B}"} == [":abc","a:bc","ab:c","abc:"] }
16
- check { "www.google.com".is("#{A}.#{B}").map{[A,B]} == [["www", "google.com"],["www.google", "com"]] }
17
- check { "a".is("#{A}#{B}#{C}").map{"#{A}:#{B}:#{C}"} == ["::a",":a:","a::"] }
18
- check { "ab".is("#{A}#{B}#{C}").map{"#{A}:#{B}:#{C}"} == %w(::ab :a:b :ab: a::b a:b: ab::) }
19
- end
3
+ module RubylogSpec
4
+ describe String, :rubylog=>true do
5
+ describe "unification" do
6
+ check "asdf".is "asdf"
7
+ check { "abc#{S}def" =~ /abc.S\[\].def/ }
8
+ check { "abc#{S[length: 1]}def" =~ /abc.S\[\d+\].def/ }
9
+ check { "h#{S}o".is("hello").map{S} == ["ell"] }
10
+ check { "#{Base}.#{Ext}".is("hello.rb").map{Base} == ["hello"] }
11
+ check { "#{Base}.#{Ext}".is("hello.rb").map{Ext} == ["rb"] }
12
+ check { "h#{S}o".is("auto").map{S} == [] }
13
+ end
14
+
15
+ describe "backtracked matches" do
16
+ check { "abc".is("#{A}#{B}").map{"#{A}:#{B}"} == [":abc","a:bc","ab:c","abc:"] }
17
+ check { "www.google.com".is("#{A}.#{B}").map{[A,B]} == [["www", "google.com"],["www.google", "com"]] }
18
+ check { "a".is("#{A}#{B}#{C}").map{"#{A}:#{B}:#{C}"} == ["::a",":a:","a::"] }
19
+ check { "ab".is("#{A}#{B}#{C}").map{"#{A}:#{B}:#{C}"} == %w(::ab :a:b :ab: a::b a:b: ab::) }
20
+ end
21
+
22
+ describe "guards" do
23
+ check { "abc".is("#{A[/\A.\z/]}#{B}").map{"#{A}:#{B}"} == ["a:bc"] }
24
+ check { "abc".is("#{A[length: 1]}#{B}").map{"#{A}:#{B}"} == ["a:bc"] }
25
+ end
26
+
27
+
28
+ describe "palindromes" do
29
+ predicate_for String, ".palindrome"
30
+
31
+ S[empty?: true].palindrome!
32
+ S[length: 1].palindrome!
33
+ S[lambda{|s|s.length > 1}].palindrome.if S.is("#{A[length: 1]}#{B}#{A}").and B.palindrome
34
+
35
+ check "".palindrome
36
+ check "dd".palindrome
37
+ check "aba".palindrome
38
+ check "faaf".palindrome
39
+ check "ffaaff".palindrome
40
+ check "rererer".palindrome
41
+ check "lol".palindrome
42
+ check "ji".palindrome.false
43
+ check "doo".palindrome.false
44
+ check "taaaz".palindrome.false
45
+ check "faad".palindrome.false
46
+ check "rerere".palindrome.false
47
+ end
20
48
 
21
- describe "guards" do
22
- check { "abc".is("#{A[/\A.\z/]}#{B}").map{"#{A}:#{B}"} == ["a:bc"] }
23
- check { "abc".is("#{A[length: 1]}#{B}").map{"#{A}:#{B}"} == ["a:bc"] }
24
49
  end
25
-
26
-
27
- describe "palindromes" do
28
- predicate_for String, ".palindrome"
29
-
30
- S[empty?: true].palindrome!
31
- S[length: 1].palindrome!
32
- S[lambda{|s|s.length > 1}].palindrome.if S.is("#{A[length: 1]}#{B}#{A}").and B.palindrome
33
-
34
- check "".palindrome
35
- check "dd".palindrome
36
- check "aba".palindrome
37
- check "faaf".palindrome
38
- check "ffaaff".palindrome
39
- check "rererer".palindrome
40
- check "lol".palindrome
41
- check "ji".palindrome.false
42
- check "doo".palindrome.false
43
- check "taaaz".palindrome.false
44
- check "faad".palindrome.false
45
- check "rerere".palindrome.false
46
- end
47
-
48
50
  end