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,9 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
module RubylogSpec
|
4
|
+
describe Symbol, :rubylog=>true do
|
5
|
+
it "can be asserted" do
|
6
|
+
predicate ":good"
|
7
|
+
:good.if { true }
|
8
|
+
true?(:good).should be_true
|
9
|
+
end
|
8
10
|
end
|
9
11
|
end
|
@@ -1,11 +1,13 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
require "rubylog/procedure"
|
3
3
|
|
4
|
-
|
5
|
-
describe
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
module RubylogSpec
|
5
|
+
describe Rubylog::Procedure, rubylog:true do
|
6
|
+
describe "#inspect" do
|
7
|
+
it "returns a human-readable output" do
|
8
|
+
predicate_for String, ".likes()"
|
9
|
+
A.likes(B).predicate.inspect.should == ".likes(): []"
|
10
|
+
end
|
9
11
|
end
|
10
12
|
end
|
11
|
-
end
|
13
|
+
end
|
data/spec/rubylog/rule_spec.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'rubylog/rule'
|
3
3
|
|
4
|
-
|
5
|
-
describe
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
module RubylogSpec
|
5
|
+
describe Rubylog::Rule, rubylog:true do
|
6
|
+
describe "#inspect" do
|
7
|
+
it "returns a human-readable output" do
|
8
|
+
predicate_for String, ".likes()"
|
9
|
+
A.likes(B).if B.is(:water)
|
9
10
|
|
10
|
-
|
11
|
+
A.likes(B).predicate[0].inspect.should == "A.likes(B).if(B.is(:water))"
|
12
|
+
end
|
11
13
|
end
|
12
|
-
end
|
13
|
-
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,83 +1,85 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
3
|
+
module RubylogSpec
|
4
|
+
describe Rubylog::Structure, :rubylog=>true do
|
4
5
|
|
5
|
-
|
6
|
+
predicate_for Symbol, ".is_happy .likes()"
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
it "can be created" do
|
9
|
+
(:john.is_happy).should be_kind_of Rubylog::Term
|
10
|
+
(:john.likes :beer).should be_kind_of Rubylog::Term
|
11
|
+
(A.likes :beer).should be_kind_of Rubylog::Term
|
12
|
+
(:john.likes Drink).should be_kind_of Rubylog::Term
|
13
|
+
(:john.likes :drinking.in :bar).should be_kind_of Rubylog::Term
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
it "forbids non-declared names" do
|
17
|
+
lambda { :john.something_else }.should raise_error(NoMethodError)
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
it "can be asked for their functor" do
|
21
|
+
(:john.is_happy).functor.should == :is_happy
|
22
|
+
(:john.likes :drinking.in :bar).functor.should == :likes
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
it "can be indexed" do
|
26
|
+
(:john.is_happy)[0].should == :john
|
27
|
+
(:john.likes :beer)[0].should == :john
|
28
|
+
(:john.likes :beer)[1].should == :beer
|
29
|
+
(:john.likes(:cold, :beer))[2].should == :beer
|
30
|
+
(:john.likes(:cold, :beer))[1..2].should == [:cold,:beer]
|
31
|
+
(:john.likes :drinking.in :bar)[1].should == (:drinking.in :bar)
|
32
|
+
end
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
34
|
+
it "can be asked for their args" do
|
35
|
+
(:john.is_happy).args.should == [:john]
|
36
|
+
(:john.likes :beer).args.should == [:john, :beer]
|
37
|
+
(:john.likes(:cold, :beer)).args.should == [:john, :cold, :beer]
|
38
|
+
(:john.likes :drinking.in :bar).args.should == [:john, :drinking.in(:bar)]
|
39
|
+
end
|
40
|
+
it "support ==" do
|
41
|
+
(:john.is_happy).should == (:john.is_happy)
|
42
|
+
(:john.is_happy).should_not be_equal(:john.is_happy)
|
43
|
+
(:john.is_happy).should_not == nil
|
44
|
+
(:john.is_happy).should_not == 9
|
45
|
+
(:john.is_happy).should_not == :john
|
46
|
+
(:john.is_happy).should_not == Rubylog
|
47
|
+
(:john.likes :drinking.in :bar).should == (:john.likes :drinking.in :bar)
|
48
|
+
end
|
49
|
+
it "support eql?" do
|
50
|
+
(:john.is_happy).should be_eql(:john.is_happy)
|
51
|
+
(:john.is_happy).should_not be_eql nil
|
52
|
+
(:john.is_happy).should_not be_eql 9
|
53
|
+
(:john.is_happy).should_not be_eql :john
|
54
|
+
(:john.is_happy).should_not be_eql Rubylog
|
55
|
+
(:john.likes :drinking.in :bar).should be_eql(:john.likes :drinking.in :bar)
|
56
|
+
end
|
57
|
+
it "support hash" do
|
58
|
+
(:john.is_happy).hash.should == (:john.is_happy).hash
|
59
|
+
(:john.likes :drinking.in :bar).hash.should ==
|
60
|
+
(:john.likes :drinking.in :bar).hash
|
61
|
+
end
|
62
|
+
it "support inspect" do
|
63
|
+
(:john.is_happy).inspect.should == ":john.is_happy"
|
64
|
+
(:john.likes :beer).inspect.should == ":john.likes(:beer)"
|
65
|
+
(:john.likes :drinking,:beer).inspect.should == ":john.likes(:drinking, :beer)"
|
66
|
+
(:john.likes :drinking.in :bar).inspect.should == ":john.likes(:drinking.in(:bar))"
|
67
|
+
end
|
68
|
+
it "can tell their arity" do
|
69
|
+
(:john.is_happy).arity.should == 1
|
70
|
+
(:john.likes :beer).arity.should == 2
|
71
|
+
(:john.likes :drinking,:beer).arity.should == 3
|
72
|
+
(:john.likes :drinking.in :bar).arity.should == 2
|
73
|
+
end
|
73
74
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
75
|
+
it "can tell their indicator" do
|
76
|
+
(:john.is_happy).indicator.should == [:is_happy,1]
|
77
|
+
(:john.likes :beer).indicator.should == [:likes,2]
|
78
|
+
(:john.likes :drinking,:beer).indicator.should == [:likes,3]
|
79
|
+
(:john.likes :drinking.in :bar).indicator.should == [:likes,2]
|
80
|
+
end
|
80
81
|
|
81
82
|
|
82
|
-
end
|
83
|
+
end
|
83
84
|
|
85
|
+
end
|
data/spec/rubylog/term_spec.rb
CHANGED
@@ -1,44 +1,46 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
after do
|
12
|
-
Rubylog.trace?.should == false
|
13
|
-
$stdout = @old_stdout
|
14
|
-
ARGV.replace @old_argv
|
15
|
-
end
|
16
|
-
|
17
|
-
it "can be called with true/false" do
|
18
|
-
Rubylog.trace true
|
19
|
-
1.is(A).solve
|
20
|
-
Rubylog.trace false
|
21
|
-
@output.string.should include "1.is(A).prove()"
|
22
|
-
end
|
3
|
+
module RubylogSpec
|
4
|
+
describe Rubylog::Tracing, :rubylog=>true do
|
5
|
+
before do
|
6
|
+
@old_argv = ARGV.dup
|
7
|
+
ARGV.replace ["spec/rubylog/tracing_spec.input"]
|
8
|
+
@old_stdout = $stdout
|
9
|
+
$stdout = @output = StringIO.new
|
10
|
+
end
|
23
11
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
12
|
+
after do
|
13
|
+
Rubylog.trace?.should == false
|
14
|
+
$stdout = @old_stdout
|
15
|
+
ARGV.replace @old_argv
|
16
|
+
end
|
30
17
|
|
31
|
-
|
32
|
-
|
18
|
+
it "can be called with true/false" do
|
19
|
+
Rubylog.trace true
|
33
20
|
1.is(A).solve
|
21
|
+
Rubylog.trace false
|
22
|
+
@output.string.should include "1.is(A).prove()"
|
34
23
|
end
|
35
|
-
@output.string.should include "1.is(A).prove()"
|
36
|
-
end
|
37
24
|
|
38
|
-
|
39
|
-
|
25
|
+
it "can be called without true" do
|
26
|
+
Rubylog.trace
|
40
27
|
1.is(A).solve
|
28
|
+
Rubylog.trace false
|
29
|
+
@output.string.should include "1.is(A).prove()"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "can be called with a block" do
|
33
|
+
Rubylog.trace do
|
34
|
+
1.is(A).solve
|
35
|
+
end
|
36
|
+
@output.string.should include "1.is(A).prove()"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "traces unifications" do
|
40
|
+
Rubylog.trace do
|
41
|
+
1.is(A).solve
|
42
|
+
end
|
43
|
+
@output.string.should include "A.bind_to(1)"
|
41
44
|
end
|
42
|
-
@output.string.should include "A.bind_to(1)"
|
43
45
|
end
|
44
46
|
end
|
@@ -1,310 +1,312 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
it "supports ==" do
|
9
|
-
A.should == A
|
10
|
-
end
|
3
|
+
module RubylogSpec
|
4
|
+
describe Rubylog::Variable, :rubylog=>true do
|
5
|
+
it "is created when an undefined constant name appears" do
|
6
|
+
[A, SomethingLong].each{|x|x.should be_kind_of Rubylog::Variable}
|
7
|
+
end
|
11
8
|
|
12
|
-
|
13
|
-
|
14
|
-
|
9
|
+
it "supports ==" do
|
10
|
+
A.should == A
|
11
|
+
end
|
15
12
|
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
it "supports eql?" do
|
14
|
+
A.should be_eql A
|
15
|
+
end
|
19
16
|
|
20
|
-
|
21
|
-
|
22
|
-
[ANY, Anything, AnYTIME].each{|x|x.should be_kind_of Rubylog::Variable; x.should be_dont_care}
|
23
|
-
[NOBODY, EVERYBODY, SOMEBODY].each{|x|x.should be_kind_of Rubylog::Variable; x.should_not be_dont_care}
|
17
|
+
it "returns different instances" do
|
18
|
+
A.should_not be_equal A
|
24
19
|
end
|
25
|
-
end
|
26
20
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
a.value.should == 5
|
21
|
+
describe "dont-care variables" do
|
22
|
+
specify "start with ANY or Any or AnY" do
|
23
|
+
[ANY, Anything, AnYTIME].each{|x|x.should be_kind_of Rubylog::Variable; x.should be_dont_care}
|
24
|
+
[NOBODY, EVERYBODY, SOMEBODY].each{|x|x.should be_kind_of Rubylog::Variable; x.should_not be_dont_care}
|
32
25
|
end
|
33
26
|
end
|
34
27
|
|
35
|
-
|
36
|
-
|
37
|
-
|
28
|
+
describe "#value" do
|
29
|
+
it "returns the value if bound" do
|
30
|
+
a = A
|
31
|
+
a.send :bind_to, 5 do
|
32
|
+
a.value.should == 5
|
33
|
+
end
|
38
34
|
end
|
39
|
-
a.value.should == nil
|
40
|
-
end
|
41
|
-
end
|
42
35
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
a.should
|
48
|
-
a.value.should eql 4
|
36
|
+
it "returns nil if unbound" do
|
37
|
+
a = A
|
38
|
+
a.send :bind_to, 5 do
|
39
|
+
end
|
40
|
+
a.value.should == nil
|
49
41
|
end
|
50
42
|
end
|
51
43
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
a.
|
56
|
-
|
44
|
+
describe "unification" do
|
45
|
+
it "unifies with non-var" do
|
46
|
+
a=A
|
47
|
+
a.rubylog_unify(4) do
|
48
|
+
a.should be_bound
|
49
|
+
a.value.should eql 4
|
50
|
+
end
|
57
51
|
end
|
58
|
-
end
|
59
52
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
b.should_not be_bound
|
53
|
+
it "unifies with non-var (reversed)" do
|
54
|
+
a=A
|
55
|
+
4.rubylog_unify(a) do
|
56
|
+
a.should be_bound
|
57
|
+
a.value.should eql 4
|
58
|
+
end
|
67
59
|
end
|
68
|
-
end
|
69
60
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
b.send(:bind_to, 4) do
|
61
|
+
it "unifies with another unbound variable with getting bound" do
|
62
|
+
a=A
|
63
|
+
b=B
|
74
64
|
a.rubylog_unify(b) do
|
75
|
-
a.
|
65
|
+
a.should be_bound
|
66
|
+
a.value.should equal b
|
67
|
+
b.should_not be_bound
|
76
68
|
end
|
77
69
|
end
|
78
|
-
end
|
79
70
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
71
|
+
it "unifies with a bound variable" do
|
72
|
+
a=A
|
73
|
+
b=B
|
74
|
+
b.send(:bind_to, 4) do
|
75
|
+
a.rubylog_unify(b) do
|
76
|
+
a.value.should == 4
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
it "when bound, unifies with an unbound variable" do
|
82
|
+
a=A
|
83
|
+
b=B
|
84
|
+
a.send(:bind_to, 4) do
|
85
|
+
a.rubylog_unify(b) do
|
86
|
+
b.value.should == 4
|
87
|
+
end
|
86
88
|
end
|
87
89
|
end
|
88
|
-
end
|
89
90
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
91
|
+
it "unifies with self" do
|
92
|
+
a=A
|
93
|
+
a.rubylog_unify(a) do
|
94
|
+
a.should_not be_bound
|
95
|
+
end
|
94
96
|
end
|
95
|
-
end
|
96
97
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
98
|
+
it "unifies with another bound to self" do
|
99
|
+
a=A
|
100
|
+
b=B
|
101
|
+
a.rubylog_unify(b) do
|
102
|
+
b.rubylog_unify(a) do
|
103
|
+
b.should_not be_bound
|
104
|
+
end
|
103
105
|
end
|
104
106
|
end
|
105
107
|
end
|
106
|
-
end
|
107
108
|
|
108
|
-
|
109
|
-
|
109
|
+
describe "dereferencing" do
|
110
|
+
predicate_for Integer, ".divides()"
|
110
111
|
|
111
|
-
|
112
|
-
|
112
|
+
check { A.is_a? Rubylog::Variable }
|
113
|
+
check { A.rubylog_deep_dereference == A }
|
113
114
|
|
114
|
-
|
115
|
-
|
115
|
+
a = A
|
116
|
+
check { a.rubylog_deep_dereference.equal? a }
|
116
117
|
|
117
|
-
|
118
|
+
check { not a.bound? }
|
118
119
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
120
|
+
specify do
|
121
|
+
a.rubylog_unify(4) do
|
122
|
+
check { a.bound? }
|
123
|
+
check { a.rubylog_deep_dereference == 4 }
|
124
|
+
check { [1,a].rubylog_deep_dereference == [1,4] }
|
125
|
+
check { a.divides(16).rubylog_deep_dereference == 4.divides(16) }
|
126
|
+
end
|
125
127
|
end
|
126
|
-
end
|
127
128
|
|
128
|
-
|
129
|
-
|
129
|
+
b = []
|
130
|
+
check { not b.rubylog_deep_dereference.equal? b }
|
130
131
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
describe "dont-care variables are case insensitive ANY* and _*" do
|
136
|
-
check 3.is(ANY).and 3.is(ANY)
|
137
|
-
check 3.is(ANY).and 4.is(ANY)
|
138
|
-
check 3.is(ANYTHING).and 3.is(ANYTHING)
|
139
|
-
check 3.is(ANYTHING).and 4.is(ANYTHING)
|
140
|
-
check 3.is(Anything).and 3.is(Anything)
|
141
|
-
check 3.is(Anything).and 4.is(Anything)
|
142
|
-
check 3.is(Rubylog::Variable.new(:_var1)).and(3.is(Rubylog::Variable.new(:_var1)))
|
143
|
-
check 3.is(Rubylog::Variable.new(:_var1)).and(4.is(Rubylog::Variable.new(:_var1)))
|
144
|
-
check 3.is(Rubylog::Variable.new(:var1 )).and(3.is(Rubylog::Variable.new(:var1 )))
|
145
|
-
check 3.is(Rubylog::Variable.new(:var1 )).and(4.is(Rubylog::Variable.new(:var1 ))).false
|
146
|
-
end
|
132
|
+
c = Object.new
|
133
|
+
check { c.rubylog_deep_dereference.equal? c }
|
134
|
+
end
|
147
135
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
136
|
+
describe "dont-care variables are case insensitive ANY* and _*" do
|
137
|
+
check 3.is(ANY).and 3.is(ANY)
|
138
|
+
check 3.is(ANY).and 4.is(ANY)
|
139
|
+
check 3.is(ANYTHING).and 3.is(ANYTHING)
|
140
|
+
check 3.is(ANYTHING).and 4.is(ANYTHING)
|
141
|
+
check 3.is(Anything).and 3.is(Anything)
|
142
|
+
check 3.is(Anything).and 4.is(Anything)
|
143
|
+
check 3.is(Rubylog::Variable.new(:_var1)).and(3.is(Rubylog::Variable.new(:_var1)))
|
144
|
+
check 3.is(Rubylog::Variable.new(:_var1)).and(4.is(Rubylog::Variable.new(:_var1)))
|
145
|
+
check 3.is(Rubylog::Variable.new(:var1 )).and(3.is(Rubylog::Variable.new(:var1 )))
|
146
|
+
check 3.is(Rubylog::Variable.new(:var1 )).and(4.is(Rubylog::Variable.new(:var1 ))).false
|
147
|
+
end
|
160
148
|
|
149
|
+
describe "variables support recursion" do
|
150
|
+
predicate_for Integer, ".factorial()"
|
151
|
+
0.factorial! 1
|
152
|
+
N[thats > 0].factorial(K).if N1.is {N-1} .and N1.factorial(K1).and K.is{ N*K1 }
|
153
|
+
|
154
|
+
check 0.factorial 1
|
155
|
+
check 1.factorial 1
|
156
|
+
check 2.factorial 2
|
157
|
+
check 3.factorial 6
|
158
|
+
check 4.factorial 24
|
159
|
+
check 7.factorial 5040
|
160
|
+
end
|
161
161
|
|
162
|
-
describe "dont-care variables support recursion" do
|
163
|
-
predicate_for Integer, ".factorial()"
|
164
|
-
0.factorial! 1
|
165
|
-
N.factorial(K).if proc{N > 0}.and N1.is {N-1} .and N1.factorial(K1).and K.is{ N*K1 }.and K.is(ANY1).and N.is(ANY2)
|
166
|
-
check 0.factorial 1
|
167
|
-
check 1.factorial 1
|
168
|
-
check 2.factorial 2
|
169
|
-
check 3.factorial 6
|
170
|
-
check 4.factorial 24
|
171
|
-
check 7.factorial 5040
|
172
|
-
end
|
173
162
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
163
|
+
describe "dont-care variables support recursion" do
|
164
|
+
predicate_for Integer, ".factorial()"
|
165
|
+
0.factorial! 1
|
166
|
+
N.factorial(K).if proc{N > 0}.and N1.is {N-1} .and N1.factorial(K1).and K.is{ N*K1 }.and K.is(ANY1).and N.is(ANY2)
|
167
|
+
check 0.factorial 1
|
168
|
+
check 1.factorial 1
|
169
|
+
check 2.factorial 2
|
170
|
+
check 3.factorial 6
|
171
|
+
check 4.factorial 24
|
172
|
+
check 7.factorial 5040
|
178
173
|
end
|
179
174
|
|
180
|
-
describe "
|
181
|
-
|
182
|
-
|
183
|
-
|
175
|
+
describe "calling" do
|
176
|
+
describe "precompiled" do
|
177
|
+
check B.is(4).and A.is(B.is(C).and C.is(4)).and A
|
178
|
+
check((B.is(4).and A.is(B.is(C).and C.is(3)).and A).false)
|
179
|
+
end
|
184
180
|
|
185
|
-
|
181
|
+
describe "compiled run-time" do
|
182
|
+
check B.is(4).and A.is{B.is(C).and C.is(4)}.and A
|
183
|
+
check((B.is(4).and A.is{B.is(C).and C.is(3)}.and A).false)
|
184
|
+
end
|
186
185
|
|
187
|
-
describe "guards", :rubylog=>true do
|
188
|
-
|
189
|
-
describe "class guard" do
|
190
|
-
predicate_for [Integer,Float], ".divides()"
|
191
|
-
A[Integer].divides(B[Integer]).if { B % A == 0 }
|
192
|
-
A[Float].divides!(B[Float])
|
193
|
-
check 2.divides(10)
|
194
|
-
check 2.divides(9).false
|
195
|
-
check 2.divides(1).false
|
196
|
-
check 2.divides(0)
|
197
|
-
check 2.12.divides(4.5)
|
198
|
-
check -0.31.divides(-1.5)
|
199
|
-
check 0.3.divides(3).false
|
200
|
-
check 2.0.divides(10).false
|
201
|
-
check 2.divides(10.0).false
|
202
|
-
check 2.divides(9.0).false
|
203
186
|
end
|
204
187
|
|
205
|
-
describe "
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
188
|
+
describe "guards", :rubylog=>true do
|
189
|
+
|
190
|
+
describe "class guard" do
|
191
|
+
predicate_for [Integer,Float], ".divides()"
|
192
|
+
A[Integer].divides(B[Integer]).if { B % A == 0 }
|
193
|
+
A[Float].divides!(B[Float])
|
194
|
+
check 2.divides(10)
|
195
|
+
check 2.divides(9).false
|
196
|
+
check 2.divides(1).false
|
197
|
+
check 2.divides(0)
|
198
|
+
check 2.12.divides(4.5)
|
199
|
+
check -0.31.divides(-1.5)
|
200
|
+
check 0.3.divides(3).false
|
201
|
+
check 2.0.divides(10).false
|
202
|
+
check 2.divides(10.0).false
|
203
|
+
check 2.divides(9.0).false
|
204
|
+
end
|
218
205
|
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
206
|
+
describe "union of guards at compile" do
|
207
|
+
predicate_for Numeric, ".small"
|
208
|
+
A[0...100].small.if ANY.is A[Integer]
|
209
|
+
check 0.small
|
210
|
+
check 10.small
|
211
|
+
check -1.small.false
|
212
|
+
check 0.0.small.false
|
213
|
+
check 99.small
|
214
|
+
check 99.0.small.false
|
215
|
+
check 99.9.small.false
|
216
|
+
check 100.small.false
|
217
|
+
check 100.0.small.false
|
218
|
+
end
|
232
219
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
220
|
+
describe "union of guards at compile (dont-care)" do
|
221
|
+
predicate_for Numeric, ".small"
|
222
|
+
A[0...100].small.if A.is ANY[Integer]
|
223
|
+
check 0.small
|
224
|
+
check 10.small
|
225
|
+
check -1.small.false
|
226
|
+
check 0.0.small.false
|
227
|
+
check 99.small
|
228
|
+
check 99.0.small.false
|
229
|
+
check 99.9.small.false
|
230
|
+
check 100.small.false
|
231
|
+
check 100.0.small.false
|
232
|
+
end
|
246
233
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
234
|
+
describe "union of guards at unification" do
|
235
|
+
predicate_for Numeric, ".small"
|
236
|
+
A[0...100].small.if A.is B[Integer]
|
237
|
+
check 0.small
|
238
|
+
check 10.small
|
239
|
+
check -1.small.false
|
240
|
+
check 0.0.small.false
|
241
|
+
check 99.small
|
242
|
+
check 99.0.small.false
|
243
|
+
check 99.9.small.false
|
244
|
+
check 100.small.false
|
245
|
+
check 100.0.small.false
|
246
|
+
end
|
260
247
|
|
248
|
+
describe "union of guards at unification (reversed)" do
|
249
|
+
predicate_for Numeric, ".small"
|
250
|
+
A[0...100].small.if B[Integer].is A
|
251
|
+
check 0.small
|
252
|
+
check 10.small
|
253
|
+
check -1.small.false
|
254
|
+
check 0.0.small.false
|
255
|
+
check 99.small
|
256
|
+
check 99.0.small.false
|
257
|
+
check 99.9.small.false
|
258
|
+
check 100.small.false
|
259
|
+
check 100.0.small.false
|
260
|
+
end
|
261
261
|
|
262
|
-
describe "proc guards" do
|
263
|
-
predicate_for Numeric, ".big"
|
264
|
-
A[proc{|a|a > 20}].big!
|
265
|
-
check -100.big.false
|
266
|
-
check 0.big.false
|
267
|
-
check 10.big.false
|
268
|
-
check 20.big.false
|
269
|
-
check 21.big
|
270
|
-
check 200.big
|
271
|
-
end
|
272
262
|
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
263
|
+
describe "proc guards" do
|
264
|
+
predicate_for Numeric, ".big"
|
265
|
+
A[proc{|a|a > 20}].big!
|
266
|
+
check -100.big.false
|
267
|
+
check 0.big.false
|
268
|
+
check 10.big.false
|
269
|
+
check 20.big.false
|
270
|
+
check 21.big
|
271
|
+
check 200.big
|
272
|
+
end
|
282
273
|
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
274
|
+
describe "hash guards" do
|
275
|
+
predicate_for String, ".char"
|
276
|
+
S[length: 1].char!
|
277
|
+
check "a".char
|
278
|
+
check " ".char
|
279
|
+
check "".char.false
|
280
|
+
check "af".char.false
|
281
|
+
check "Hello".char.false
|
282
|
+
end
|
283
|
+
|
284
|
+
describe "list hash guards" do
|
285
|
+
predicate_for String, ".capitalized"
|
286
|
+
S[[:[],0] => /[A-Z]/].capitalized!
|
287
|
+
check "a".capitalized.false
|
288
|
+
check " ".capitalized.false
|
289
|
+
check "".capitalized.false
|
290
|
+
check "af".capitalized.false
|
291
|
+
check "A".capitalized
|
292
|
+
check "Hello".capitalized
|
293
|
+
end
|
293
294
|
|
294
295
|
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
296
|
+
describe "chained hash guards" do
|
297
|
+
predicate_for String, ".funny"
|
298
|
+
S[upcase: {[:[],1..-2] => "ELL"}].funny!
|
299
|
+
check "hello".funny
|
300
|
+
check "Bell!".funny
|
301
|
+
check "BELL!".funny
|
302
|
+
check "DELL".funny.false
|
303
|
+
check "help!".funny.false
|
304
|
+
check "hello!".funny.false
|
305
|
+
end
|
305
306
|
|
306
307
|
|
307
308
|
|
309
|
+
end
|
308
310
|
end
|
309
|
-
end
|
310
311
|
|
312
|
+
end
|