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,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