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