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
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -3,12 +3,19 @@ GEM
|
|
3
3
|
specs:
|
4
4
|
diff-lcs (1.2.4)
|
5
5
|
git (1.2.5)
|
6
|
+
guard (1.4.0)
|
7
|
+
listen (>= 0.4.2)
|
8
|
+
thor (>= 0.14.6)
|
9
|
+
guard-rspec (2.0.0)
|
10
|
+
guard (>= 1.1)
|
11
|
+
rspec (~> 2.11)
|
6
12
|
jeweler (1.8.4)
|
7
13
|
bundler (~> 1.0)
|
8
14
|
git (>= 1.2.5)
|
9
15
|
rake
|
10
16
|
rdoc
|
11
17
|
json (1.7.7)
|
18
|
+
listen (0.5.2)
|
12
19
|
multi_json (1.7.2)
|
13
20
|
rake (10.0.4)
|
14
21
|
rdoc (4.0.1)
|
@@ -26,6 +33,7 @@ GEM
|
|
26
33
|
multi_json (~> 1.0)
|
27
34
|
simplecov-html (~> 0.7.1)
|
28
35
|
simplecov-html (0.7.1)
|
36
|
+
thor (0.18.1)
|
29
37
|
yard (0.8.6.1)
|
30
38
|
|
31
39
|
PLATFORMS
|
@@ -33,6 +41,8 @@ PLATFORMS
|
|
33
41
|
|
34
42
|
DEPENDENCIES
|
35
43
|
bundler (>= 1.0.0)
|
44
|
+
guard
|
45
|
+
guard-rspec
|
36
46
|
jeweler (>= 1.8.3)
|
37
47
|
rspec (>= 2.8.0, < 3)
|
38
48
|
ruby-prof
|
data/README.rdoc
CHANGED
data/RELEASE_NOTES.rdoc
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
-
==
|
1
|
+
== Planned features
|
2
|
+
* <tt>solve</tt> without a block returns an enumerator
|
3
|
+
* warning for singleton variables
|
4
|
+
* <tt>nonvar</tt> predicate
|
5
|
+
|
6
|
+
== Version 2.1
|
2
7
|
* New features
|
3
|
-
*
|
4
|
-
* warning for singleton variables
|
5
|
-
* predicate for checking bound/unbound variables
|
8
|
+
* Works with Ruby 1.9.3 and 2.0 (only <tt>module X; extend Rubylog::Context</tt> syntax)
|
6
9
|
|
7
10
|
== Version 2.0.1
|
8
11
|
* Bug fixes
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0
|
1
|
+
2.1.0
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require "rubylog"
|
3
|
+
|
4
|
+
module FamilyTree
|
5
|
+
extend Rubylog::Context
|
6
|
+
predicate_for $person_class, ".parent_of() .grandparent_of()"
|
7
|
+
|
8
|
+
def make_tree(parent, levels)
|
9
|
+
return if levels.zero?
|
10
|
+
|
11
|
+
children = (1..DEGREES).map{random_person}
|
12
|
+
|
13
|
+
children.each do |child|
|
14
|
+
# add relationship
|
15
|
+
parent.parent_of!(child)
|
16
|
+
end
|
17
|
+
|
18
|
+
children.each do |child|
|
19
|
+
# make sub-tree
|
20
|
+
make_tree(child, levels-1)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
make_tree(random_person, LEVELS)
|
25
|
+
|
26
|
+
A.grandparent_of(B).if A.parent_of(X).and X.parent_of(B)
|
27
|
+
|
28
|
+
end
|
data/bin/rubylog
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "rubylog"
|
3
|
+
require "rubylog/rubylog_files"
|
4
|
+
|
5
|
+
if ARGV.empty?
|
6
|
+
filename = '-'
|
7
|
+
source = $stdin.read
|
8
|
+
source = Rubylog::RubylogFiles.convert_source(source)
|
9
|
+
eval(source, TOPLEVEL_BINDING, filename, 1)
|
10
|
+
else
|
11
|
+
load_rubylog ARGV.shift
|
12
|
+
end
|
13
|
+
|
14
|
+
|
data/examples/a_plus_b.rb
CHANGED
data/examples/dcg.rb
CHANGED
@@ -1,36 +1,32 @@
|
|
1
|
-
|
2
|
-
# This is a quick and dirty solution to replace Prolog's DCG syntax.
|
1
|
+
# This is a simple solution to replace Prolog's DCG syntax.
|
3
2
|
# It is slow for long inputs. See examples/dcg2.rb for a more efficient algorithm (the same as Prolog's DCG).
|
4
3
|
|
5
|
-
|
6
|
-
predicate_for Array, ".sentence", ".subject", ".object", ".nominal_phrase", ".noun", ".verb", ".article"
|
4
|
+
predicate_for Array, ".sentence", ".subject", ".object", ".nominal_phrase", ".noun", ".verb", ".article"
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
[*S,*V,*O].sentence.if S.subject.and V.verb.and O.object
|
7
|
+
S.subject.if S.nominal_phrase
|
8
|
+
O.object .if O.nominal_phrase
|
9
|
+
[*A,*N].nominal_phrase.if A.article.and N.noun
|
12
10
|
|
13
|
-
|
14
|
-
|
11
|
+
%w(a).article!
|
12
|
+
%w(the).article!
|
15
13
|
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
%w(dog).noun!
|
15
|
+
%w(cat).noun!
|
16
|
+
%w(mouse).noun!
|
19
17
|
|
20
|
-
|
21
|
-
|
18
|
+
%w(chases).verb!
|
19
|
+
%w(eats).verb!
|
22
20
|
|
23
|
-
|
21
|
+
def check_passed goal; end
|
24
22
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
23
|
+
check %w(dog).noun
|
24
|
+
check %w(a dog).nominal_phrase
|
25
|
+
check %w(dog).nominal_phrase.false
|
26
|
+
check %w(the dog chases a cat).sentence
|
27
|
+
check %w(the dog chases a cat stuff).sentence.false
|
28
|
+
check %w(dog chases cat).sentence.false
|
29
|
+
check { %W(the #{S} chases the #{O}).sentence.map{[S,O]}.count == 9 }
|
32
30
|
|
33
|
-
|
31
|
+
puts *S.sentence.map{S.join(" ")}
|
34
32
|
|
35
|
-
|
36
|
-
end
|
data/examples/dcg2.rb
CHANGED
@@ -1,42 +1,37 @@
|
|
1
1
|
# This is an example of the same algorithm that Prolog's DCG syntax generates.
|
2
2
|
#
|
3
3
|
|
4
|
-
$:.unshift File.dirname(__FILE__)+"/../lib"
|
5
|
-
require 'rubylog'
|
6
4
|
|
7
|
-
|
8
|
-
predicate_for Array, ".sentence()", ".subject()", ".object()", ".nominal_phrase()", ".noun()", ".verb()", ".article()"
|
5
|
+
predicate_for Array, ".sentence()", ".subject()", ".object()", ".nominal_phrase()", ".noun()", ".verb()", ".article()"
|
9
6
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
7
|
+
# sentence --> subject, verb, object
|
8
|
+
Se.sentence(L3).if Se.subject(L1).and L1.verb(L2).and L2.object(L3)
|
9
|
+
# subject --> nominal_phrase
|
10
|
+
S.subject(L1).if S.nominal_phrase(L1)
|
11
|
+
# object --> nominal_phrase
|
12
|
+
O.object(L1) .if O.nominal_phrase(L1)
|
13
|
+
# nominal_phrase --> article, noun
|
14
|
+
N.nominal_phrase(L2).if N.article(L1).and L1.noun(L2)
|
18
15
|
|
19
|
-
|
20
|
-
|
16
|
+
["a",*L1].article! L1
|
17
|
+
["the",*L1].article! L1
|
21
18
|
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
["dog",*L1].noun! L1
|
20
|
+
["cat",*L1].noun! L1
|
21
|
+
["mouse",*L1].noun! L1
|
25
22
|
|
26
|
-
|
27
|
-
|
23
|
+
["chases",*L1].verb! L1
|
24
|
+
["eats",*L1].verb! L1
|
28
25
|
|
29
|
-
|
26
|
+
def check_passed goal; end
|
30
27
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
28
|
+
check %w(dog).noun([])
|
29
|
+
check %w(a dog).nominal_phrase([])
|
30
|
+
check %w(dog).nominal_phrase(ANY).false
|
31
|
+
check %w(the dog chases a cat).sentence([])
|
32
|
+
check %w(the dog chases a cat stuff).sentence(["stuff"])
|
33
|
+
check %w(dog chases cat).sentence(ANY).false
|
34
|
+
check { %W(the #{S} chases the #{O}).sentence([]).map{[S,O]}.count == 9 }
|
38
35
|
|
39
|
-
|
36
|
+
puts *S.sentence([]).map{S.join(" ")}
|
40
37
|
|
41
|
-
|
42
|
-
end
|
data/examples/divisors.rb
CHANGED
data/examples/factorial.rb
CHANGED
@@ -1,17 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
rubylog do
|
5
|
-
predicate_for Integer, ".factorial()"
|
6
|
-
|
7
|
-
0.factorial! 1
|
8
|
-
N[thats > 0].factorial(K).if \
|
9
|
-
N.sum_of(N1,1).
|
10
|
-
and N1.factorial(K1).
|
11
|
-
and K.product_of(K1,N)
|
12
|
-
|
13
|
-
7.factorial(N).solve {puts N}
|
14
|
-
end
|
15
|
-
|
1
|
+
# Factorial
|
2
|
+
predicate_for Integer, ".factorial()"
|
16
3
|
|
4
|
+
0.factorial! 1
|
5
|
+
N[thats > 0].factorial(K).if \
|
6
|
+
N.sum_of(N1,1).
|
7
|
+
and N1.factorial(K1).
|
8
|
+
and K.product_of(K1,N)
|
17
9
|
|
10
|
+
7.factorial(N).solve {puts N}
|
data/examples/file_search.rb
CHANGED
@@ -1,16 +1,17 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# Outputs which source files have and which source files do not have a test.
|
2
|
+
#
|
3
3
|
|
4
|
-
|
5
|
-
puts "Files which #{b ? 'have' : 'do not have'} spec:"
|
4
|
+
predicate_for String, ".libfile .specfile"
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
puts X
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
puts
|
14
|
-
|
15
|
-
end
|
6
|
+
L.libfile.if "lib/#{L}.rb".file_in("lib/**")
|
7
|
+
L.specfile.if "spec/#{L}_spec.rb".file_in("spec/**")
|
16
8
|
|
9
|
+
puts "Libs which have spec:"
|
10
|
+
L.libfile.and(L.specfile).each { puts L }
|
11
|
+
puts
|
12
|
+
puts "Libs which do not have spec:"
|
13
|
+
L.libfile.and(L.specfile.false).each { puts L }
|
14
|
+
puts
|
15
|
+
puts "Specs which do not have lib:"
|
16
|
+
L.specfile.and(L.libfile.false).each { puts L }
|
17
|
+
puts
|
data/examples/hanoi.rb
CHANGED
data/examples/hu/csaladfa.rb
CHANGED
data/examples/n_queens.rb
CHANGED
@@ -1,32 +1,27 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
predicate_for Integer, ".on(,)", ".attacks(,)", ".placed"
|
2
|
+
predicate ":arranged"
|
3
3
|
|
4
|
-
|
5
|
-
predicate_for Integer, ".on(,)", ".attacks(,)", ".placed"
|
6
|
-
predicate ":arranged"
|
4
|
+
N=7
|
7
5
|
|
8
|
-
|
6
|
+
A.attacks(R,ANY_C).if A.on(R,ANY_C)
|
7
|
+
A.attacks(ANY_R,C).if A.on(ANY_R,C)
|
8
|
+
A.attacks(R2,C2).if A.on(R1,C1).and {R1-C1==R2-C2}
|
9
|
+
A.attacks(R2,C2).if A.on(R1,C1).and {R1+C1==R2+C2}
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
A.attacks(R2,C2).if A.on(R1,C1).and {R1-C1==R2-C2}
|
13
|
-
A.attacks(R2,C2).if A.on(R1,C1).and {R1+C1==R2+C2}
|
11
|
+
A.placed.if \
|
12
|
+
C.in(1..N).and(B.on(ANY,ANY).none(B.attacks(A,C))).and A.on(A,C).assumed
|
14
13
|
|
15
|
-
|
16
|
-
C.in(1..N).and(B.on(ANY,ANY).none(B.attacks(A,C))).and A.on(A,C).assumed
|
14
|
+
:arranged.if every A.in(1..N), A.placed
|
17
15
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
print ANY.on?(L,M) ? "X" : "."
|
24
|
-
end
|
25
|
-
puts
|
16
|
+
:arranged.solve do
|
17
|
+
# draw board
|
18
|
+
L.in(1..N).each do
|
19
|
+
M.in(1..N).each do
|
20
|
+
print ANY.on?(L,M) ? "X" : "."
|
26
21
|
end
|
27
22
|
puts
|
28
23
|
end
|
29
|
-
|
30
|
-
|
24
|
+
puts
|
31
25
|
end
|
32
26
|
|
27
|
+
|
data/examples/parsing.rb
CHANGED
@@ -1,29 +1,25 @@
|
|
1
|
-
$:.unshift File.dirname(__FILE__)+"/../lib"
|
2
|
-
require "rubylog"
|
3
1
|
require "readline"
|
4
2
|
|
5
|
-
|
6
|
-
predicate_for String, ".term()", ".expr()", ".atom()"
|
3
|
+
predicate_for String, ".term()", ".expr()", ".atom()"
|
7
4
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
5
|
+
"#{A}+#{B}".expr(K).if A.expr(I).and B.term(J).and K.is{I+J}
|
6
|
+
"#{A}-#{B}".expr(K).if A.expr(I).and B.term(J).and K.is{I-J}
|
7
|
+
A.expr(K).if A.term(K)
|
8
|
+
"#{A}*#{B}".term(K).if A.atom(I).and B.term(J).and K.is{I*J}
|
9
|
+
"#{A}/#{B}".term(K).if A.atom(I).and B.term(J).and K.is{I/J}
|
10
|
+
A.term(K).if A.atom(K)
|
11
|
+
A[/\A[0-9]+\z/].atom(K).if K.is{A.to_i}
|
12
|
+
"(#{A})".atom(K).if A.expr(K)
|
16
13
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
puts
|
24
|
-
while k = Readline.readline("> ", true)
|
25
|
-
k.chomp!
|
26
|
-
puts k.expr(X).map{X}.first || "error"
|
27
|
-
end
|
14
|
+
check "5".expr(5)
|
15
|
+
check "5+3*2".expr(11)
|
16
|
+
check "1+2+3+4".expr(10)
|
17
|
+
check "(5+3)/2".expr(4)
|
18
|
+
check "(5+3(5)/2".expr(ANY).false
|
28
19
|
|
20
|
+
puts
|
21
|
+
while k = Readline.readline("> ", true)
|
22
|
+
k.chomp!
|
23
|
+
puts k.expr(X).map{X}.first || "error"
|
29
24
|
end
|
25
|
+
|