rubylog 1.0.0 → 2.0pre1
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 +3 -12
- data/Gemfile.lock +22 -48
- data/README.rdoc +38 -38
- data/README.rdoc.orig +284 -0
- data/RELEASE_NOTES.rdoc +51 -0
- data/Rakefile +14 -18
- data/TODO.txt +0 -0
- data/VERSION +1 -1
- data/examples/a_plus_b.rb +6 -0
- data/examples/checkmate.rb +88 -0
- data/examples/combination.rb +17 -0
- data/examples/dcg.rb +3 -2
- data/examples/dcg2.rb +2 -2
- data/{logic → examples}/directory_structure_logic.rb +3 -5
- data/examples/dirlist.rb +4 -0
- data/examples/divisors.rb +6 -0
- data/examples/enumerators.rb +3 -3
- data/examples/factorial.rb +2 -3
- data/examples/file_search.rb +14 -0
- data/examples/hanoi.rb +4 -5
- data/examples/hello.rb +6 -4
- data/examples/mice.rb +92 -0
- data/examples/mice2.rb +19 -0
- data/examples/n_queens.rb +32 -0
- data/examples/object_oriented.rb +14 -0
- data/examples/palindrome_detection.rb +18 -0
- data/examples/parsing.rb +6 -4
- data/examples/permutation.rb +12 -0
- data/examples/prefix.rb +13 -0
- data/examples/primality_by_division.rb +22 -0
- data/examples/primitives.rb +10 -8
- data/examples/sieve_of_eratosthenes.rb +14 -0
- data/examples/string_interpolation.rb +4 -0
- data/examples/sudoku.rb +52 -0
- data/examples/tracing.rb +19 -0
- data/lib/rspec/rubylog.rb +29 -0
- data/lib/rubylog/assertable.rb +24 -0
- data/lib/rubylog/builtins/arithmetics.rb +63 -0
- data/lib/rubylog/builtins/assumption.rb +71 -0
- data/lib/rubylog/builtins/ensure.rb +13 -0
- data/lib/rubylog/builtins/file_system.rb +30 -8
- data/lib/rubylog/builtins/logic.rb +69 -38
- data/lib/rubylog/builtins/reflection.rb +35 -50
- data/lib/rubylog/builtins/term.rb +15 -17
- data/lib/rubylog/builtins.rb +11 -0
- data/lib/rubylog/clause.rb +19 -0
- data/lib/rubylog/{interfaces/composite_term.rb → compound_term.rb} +3 -3
- data/lib/rubylog/context.rb +24 -0
- data/lib/rubylog/context_creation.rb +71 -0
- data/lib/rubylog/context_modules/checks.rb +35 -0
- data/lib/rubylog/context_modules/demonstration.rb +16 -0
- data/lib/rubylog/context_modules/predicates.rb +86 -0
- data/lib/rubylog/context_modules/primitives.rb +18 -0
- data/lib/rubylog/context_modules/thats.rb +13 -0
- data/lib/rubylog/default_context.rb +9 -0
- data/lib/rubylog/dsl/array_splat.rb +11 -3
- data/lib/rubylog/dsl/primitives.rb +24 -12
- data/lib/rubylog/dsl/thats.rb +6 -0
- data/lib/rubylog/dsl/variables.rb +56 -21
- data/lib/rubylog/errors.rb +26 -15
- data/lib/rubylog/mixins/array.rb +95 -62
- data/lib/rubylog/mixins/kernel.rb +3 -2
- data/lib/rubylog/mixins/method.rb +0 -1
- data/lib/rubylog/mixins/object.rb +2 -1
- data/lib/rubylog/mixins/proc.rb +9 -12
- data/lib/rubylog/mixins/string.rb +15 -23
- data/lib/rubylog/mixins/symbol.rb +7 -24
- data/lib/rubylog/nullary_predicates.rb +3 -0
- data/lib/rubylog/predicate.rb +53 -0
- data/lib/rubylog/primitive.rb +15 -0
- data/lib/rubylog/procedure.rb +42 -0
- data/lib/rubylog/rule.rb +24 -0
- data/lib/rubylog/structure.rb +19 -38
- data/lib/rubylog/{interfaces/term.rb → term.rb} +2 -7
- data/lib/rubylog/tracing.rb +75 -0
- data/lib/rubylog/variable.rb +31 -12
- data/lib/rubylog.rb +36 -32
- data/rubylog.gemspec +92 -84
- data/spec/inriasuite_spec.rb +906 -9
- data/spec/integration/custom_classes_spec.rb +61 -0
- data/spec/integration/dsl_spec.rb +38 -0
- data/spec/integration/recursion_spec.rb +14 -0
- data/spec/integration/theory_as_module_spec.rb +20 -0
- data/spec/integration/theory_as_module_with_include_spec.rb +14 -0
- data/spec/rspec/rubylog_spec.rb +75 -0
- data/spec/rubylog/assertable_spec.rb +111 -0
- data/spec/rubylog/builtins/arithmetics_spec.rb +94 -0
- data/spec/rubylog/builtins/assumption_spec.rb +70 -0
- data/spec/rubylog/builtins/ensure_spec.rb +8 -0
- data/spec/rubylog/builtins/file_system_spec.rb +40 -0
- data/spec/rubylog/builtins/logic_spec.rb +340 -0
- data/spec/rubylog/builtins/reflection_spec.rb +43 -0
- data/spec/rubylog/builtins/term_spec.rb +85 -0
- data/spec/rubylog/context_modules/demonstration_spec.rb +132 -0
- data/spec/rubylog/context_modules/predicates_spec.rb +57 -0
- data/spec/rubylog/context_modules/thats_spec.rb +94 -0
- data/spec/rubylog/dsl/array_splat_spec.rb +15 -0
- data/spec/rubylog/dsl/primitives_spec.rb +43 -0
- data/spec/rubylog/errors_spec.rb +18 -0
- data/spec/{unification_spec.rb → rubylog/interfaces/term_spec.rb} +8 -9
- data/spec/rubylog/mixins/array_spec.rb +80 -0
- data/spec/rubylog/mixins/composite_term_spec.rb +66 -0
- data/spec/rubylog/mixins/proc_spec.rb +59 -0
- data/spec/rubylog/mixins/string_spec.rb +48 -0
- data/spec/rubylog/mixins/symbol_spec.rb +9 -0
- data/spec/{clause_spec.rb → rubylog/structure_spec.rb} +16 -15
- data/spec/rubylog/term_spec.rb +7 -0
- data/spec/rubylog/tracing_spec.input +27 -0
- data/spec/rubylog/tracing_spec.rb +44 -0
- data/spec/rubylog/variable_spec.rb +279 -0
- data/spec/spec_helper.rb +1 -0
- data/vimrc +11 -0
- metadata +103 -123
- data/README.hu.rb +0 -58
- data/bin/rubylog +0 -18
- data/examples/theory.rb +0 -32
- data/lib/rubylog/builtins/default.rb +0 -10
- data/lib/rubylog/dsl.rb +0 -70
- data/lib/rubylog/interfaces/assertable.rb +0 -16
- data/lib/rubylog/interfaces/callable.rb +0 -18
- data/lib/rubylog/interfaces/predicate.rb +0 -8
- data/lib/rubylog/interfaces/procedure.rb +0 -60
- data/lib/rubylog/mixins/class.rb +0 -11
- data/lib/rubylog/simple_procedure.rb +0 -8
- data/lib/rubylog/theory.rb +0 -422
- data/logic/builtins/file_system_logic.rb +0 -23
- data/logic/builtins/reflection_logic.rb +0 -40
- data/logic/dereference_logic.rb +0 -23
- data/logic/dsl_logic.rb +0 -29
- data/logic/errors_logic.rb +0 -9
- data/logic/guard_logic.rb +0 -115
- data/logic/list_logic.rb +0 -55
- data/logic/map_logic.rb +0 -15
- data/logic/multitheory.rb +0 -23
- data/logic/recursion_logic.rb +0 -12
- data/logic/string_logic.rb +0 -41
- data/logic/thats_logic.rb +0 -51
- data/logic/variable_logic.rb +0 -24
- data/spec/bartak_guide_spec.rb +0 -86
- data/spec/builtins/all_spec.rb +0 -99
- data/spec/builtins/and_spec.rb +0 -22
- data/spec/builtins/array_spec.rb +0 -16
- data/spec/builtins/branch_or_spec.rb +0 -27
- data/spec/builtins/cut_spec.rb +0 -44
- data/spec/builtins/fail_spec.rb +0 -5
- data/spec/builtins/false_spec.rb +0 -5
- data/spec/builtins/in_spec.rb +0 -38
- data/spec/builtins/is_false_spec.rb +0 -12
- data/spec/builtins/is_spec.rb +0 -26
- data/spec/builtins/matches_spec.rb +0 -23
- data/spec/builtins/or_spec.rb +0 -22
- data/spec/builtins/splits_to.rb +0 -18
- data/spec/builtins/then_spec.rb +0 -27
- data/spec/builtins/true_spec.rb +0 -5
- data/spec/compilation_spec.rb +0 -61
- data/spec/custom_classes_spec.rb +0 -43
- data/spec/dereference.rb +0 -10
- data/spec/queries_spec.rb +0 -150
- data/spec/recursion_spec.rb +0 -18
- data/spec/ruby_code_spec.rb +0 -52
- data/spec/rules_spec.rb +0 -97
- data/spec/theory_spec.rb +0 -29
- data/spec/variable_spec.rb +0 -26
data/bin/rubylog
DELETED
data/examples/theory.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
$:.unshift File.dirname(__FILE__)+"/../lib"
|
2
|
-
require 'rubylog'
|
3
|
-
|
4
|
-
class User
|
5
|
-
attr_accessor :favorite, :possessions
|
6
|
-
|
7
|
-
def initialize favorite, possessions
|
8
|
-
@favorite, @possessions = favorite, possessions
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
Rubylog.theory "LikingTheory" do
|
13
|
-
functor :likes
|
14
|
-
U.likes(D).if {U.favorite == D}
|
15
|
-
end
|
16
|
-
|
17
|
-
Rubylog.theory "HavingTheory" do
|
18
|
-
functor :has
|
19
|
-
U.has(D).if {U.possessions.include? D}
|
20
|
-
end
|
21
|
-
|
22
|
-
Rubylog.theory "DrinkingTheory" do
|
23
|
-
functor :drinks
|
24
|
-
include LikingTheory, HavingTheory
|
25
|
-
subject User
|
26
|
-
|
27
|
-
U.drinks(D).if U.likes(D).and U.has(D)
|
28
|
-
end
|
29
|
-
|
30
|
-
joe = User.new :beer, [:water, :beer]
|
31
|
-
p DrinkingTheory.true? joe.drinks :water # false
|
32
|
-
p DrinkingTheory.true? joe.drinks :beer # true
|
data/lib/rubylog/dsl.rb
DELETED
@@ -1,70 +0,0 @@
|
|
1
|
-
module Rubylog::DSL
|
2
|
-
def self.add_functors_to class_or_module, *functors
|
3
|
-
functors.each do |f|
|
4
|
-
m = functor_module(f)
|
5
|
-
class_or_module.send :include, m
|
6
|
-
Rubylog::Variable.send :include, m
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
|
11
|
-
@functor_modules ||= {}
|
12
|
-
|
13
|
-
def self.normalize_functor fct
|
14
|
-
case s = fct.to_s
|
15
|
-
when /[?!]\z/ then :"#{s[0...-1]}"
|
16
|
-
when /=\z/ then nil
|
17
|
-
else fct
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.functor_module f
|
22
|
-
@functor_modules[f] ||= Module.new do
|
23
|
-
define_method f do |*args, &block|
|
24
|
-
args << block if block
|
25
|
-
Rubylog::Structure.new f, self, *args
|
26
|
-
end
|
27
|
-
|
28
|
-
f_bang = :"#{f}!"
|
29
|
-
define_method f_bang do |*args, &block|
|
30
|
-
args << block if block
|
31
|
-
Rubylog.current_theory.assert Rubylog::Structure.new(f, self, *args), :true
|
32
|
-
self
|
33
|
-
end
|
34
|
-
|
35
|
-
f_qmark = :"#{f}?"
|
36
|
-
define_method f_qmark do |*args, &block|
|
37
|
-
args << block if block
|
38
|
-
Rubylog.current_theory.true? Rubylog::Structure.new(f, self, *args)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def self.add_prefix_functors_to class_or_module, *functors
|
44
|
-
functors.each do |f|
|
45
|
-
class_or_module.class_eval do
|
46
|
-
define_method f do |*args, &block|
|
47
|
-
args << block if block
|
48
|
-
Rubylog::Structure.new f, *args
|
49
|
-
end
|
50
|
-
|
51
|
-
f_bang = :"#{f}!"
|
52
|
-
define_method f_bang do |*args, &block|
|
53
|
-
args << block if block
|
54
|
-
# TODO consider self.assert
|
55
|
-
Rubylog.current_theory.assert Rubylog::Structure.new(f, *args), :true
|
56
|
-
self
|
57
|
-
end
|
58
|
-
|
59
|
-
f_qmark = :"#{f}?"
|
60
|
-
define_method f_qmark do |*args, &block|
|
61
|
-
args << block if block
|
62
|
-
#TODO consider self.true?
|
63
|
-
Rubylog.current_theory.true? Rubylog::Structure.new(f, *args)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
70
|
-
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module Rubylog::Assertable
|
2
|
-
def if body=nil, &block
|
3
|
-
raise Rubylog::SyntaxError, "No body given", caller unless body || block
|
4
|
-
Rubylog.current_theory.assert self, body || block
|
5
|
-
end
|
6
|
-
|
7
|
-
def if! body=nil, &block
|
8
|
-
raise Rubylog::SyntaxError, "No body given", caller unless body || block
|
9
|
-
Rubylog.current_theory.assert self, Rubylog::Structure.new(:and, :cut!, body || block)
|
10
|
-
end
|
11
|
-
|
12
|
-
def unless body=nil, &block
|
13
|
-
raise Rubylog::SyntaxError, "No body given", caller unless body || block
|
14
|
-
Rubylog.current_theory.assert self, Rubylog::Structure.new(:false, body || block)
|
15
|
-
end
|
16
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
module Rubylog::Callable
|
2
|
-
# should yield for each possible solution of the term
|
3
|
-
#def prove
|
4
|
-
# raise "abstract method called"
|
5
|
-
#end
|
6
|
-
|
7
|
-
def true?
|
8
|
-
Rubylog.current_theory.true? self
|
9
|
-
end
|
10
|
-
|
11
|
-
def solve
|
12
|
-
if block_given?
|
13
|
-
Rubylog.current_theory.solve(self) {|*a| yield *a}
|
14
|
-
else
|
15
|
-
Rubylog.current_theory.solve(self) {|*a|}
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
module Rubylog::Procedure
|
2
|
-
include Rubylog::Predicate
|
3
|
-
|
4
|
-
# accepts the *args of the called structure
|
5
|
-
def call *args
|
6
|
-
catch :cut do
|
7
|
-
each do |rule|
|
8
|
-
begin
|
9
|
-
rule = rule.rubylog_compile_variables
|
10
|
-
head, body = rule[0], rule[1]
|
11
|
-
Rubylog.current_theory.print_trace 1, head.args, "=", args
|
12
|
-
head.args.rubylog_unify(args) {
|
13
|
-
begin
|
14
|
-
Rubylog.current_theory.print_trace 1, head, head.rubylog_variables_hash
|
15
|
-
body.prove {
|
16
|
-
yield
|
17
|
-
}
|
18
|
-
ensure
|
19
|
-
Rubylog.current_theory.print_trace -1
|
20
|
-
end
|
21
|
-
}
|
22
|
-
ensure
|
23
|
-
Rubylog.current_theory.print_trace -1
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def discontiguous!
|
30
|
-
@discontiguous = true
|
31
|
-
end
|
32
|
-
|
33
|
-
def discontiguous?
|
34
|
-
@discontiguous
|
35
|
-
end
|
36
|
-
|
37
|
-
def multitheory!
|
38
|
-
@multitheory = true
|
39
|
-
end
|
40
|
-
|
41
|
-
def multitheory?
|
42
|
-
@multitheory
|
43
|
-
end
|
44
|
-
|
45
|
-
# In case of a procedure, `each` can be implemented, which should yield all
|
46
|
-
# clauses. This makes reflection possible.
|
47
|
-
#
|
48
|
-
# def each
|
49
|
-
# yield ...
|
50
|
-
# end
|
51
|
-
#
|
52
|
-
# this should be implemented to enable assertions
|
53
|
-
# def assertz clause
|
54
|
-
# ...
|
55
|
-
# end
|
56
|
-
#
|
57
|
-
# def assertz clause
|
58
|
-
# ...
|
59
|
-
# end
|
60
|
-
end
|
data/lib/rubylog/mixins/class.rb
DELETED
data/lib/rubylog/theory.rb
DELETED
@@ -1,422 +0,0 @@
|
|
1
|
-
module Rubylog
|
2
|
-
|
3
|
-
# @return [Rubylog::Theory] the current theory
|
4
|
-
def self.current_theory
|
5
|
-
Thread.current[:rubylog_current_theory]
|
6
|
-
end
|
7
|
-
|
8
|
-
# Create a new Rubylog theory or modify an existing one.
|
9
|
-
#
|
10
|
-
# You can create theories with the theory method, which is available from
|
11
|
-
# anywhere:
|
12
|
-
# theory "MyTheory" do
|
13
|
-
# # ...
|
14
|
-
# end
|
15
|
-
def self.theory full_name=nil, *args, &block
|
16
|
-
case full_name
|
17
|
-
when nil
|
18
|
-
theory = Rubylog::Theory.new
|
19
|
-
when Rubylog::Theory
|
20
|
-
theory=full_name
|
21
|
-
else
|
22
|
-
names = full_name.to_s.split("::")
|
23
|
-
parent_names, name = names[0...-1], names[-1]
|
24
|
-
parent = parent_names.inject(block.binding.eval("Module.nesting[0]") || Object) {|a,b| a.const_get b}
|
25
|
-
|
26
|
-
if not parent.const_defined?(name)
|
27
|
-
theory = Rubylog::Theory.new *args
|
28
|
-
parent.const_set name, theory
|
29
|
-
else
|
30
|
-
theory = parent.const_get name
|
31
|
-
raise TypeError, "#{name} is not a theory" unless theory.is_a? Rubylog::Theory
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
theory.amend &block
|
36
|
-
theory
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
# The Theory class represents a collection of rules.
|
42
|
-
class Rubylog::Theory
|
43
|
-
|
44
|
-
|
45
|
-
include Rubylog::DSL::Variables
|
46
|
-
|
47
|
-
# Call the given block with variables automatically resolved
|
48
|
-
def self.with_vars vars
|
49
|
-
begin
|
50
|
-
old_vars = Thread.current[:rubylog_current_variables]
|
51
|
-
Thread.current[:rubylog_current_variables] = vars
|
52
|
-
yield
|
53
|
-
ensure
|
54
|
-
Thread.current[:rubylog_current_variables] = old_vars
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
attr_reader :public_interface, :included_theories, :prefix_functor_modules
|
59
|
-
|
60
|
-
def initialize base=Rubylog::DefaultBuiltins, &block
|
61
|
-
clear
|
62
|
-
include base if base
|
63
|
-
|
64
|
-
if block
|
65
|
-
with_context &block
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def [] indicator
|
70
|
-
@database[indicator]
|
71
|
-
end
|
72
|
-
|
73
|
-
def []= indicator, predicate
|
74
|
-
@database[indicator] = predicate
|
75
|
-
end
|
76
|
-
|
77
|
-
def keys
|
78
|
-
@database.keys
|
79
|
-
end
|
80
|
-
|
81
|
-
def each_pair
|
82
|
-
if block_given?
|
83
|
-
@database.each_pair {|*a| yield *a }
|
84
|
-
else
|
85
|
-
@database.each_pair
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
# Clear all data in the theory and bring it to its initial state.
|
90
|
-
def clear
|
91
|
-
@database = {}
|
92
|
-
@primitives = Rubylog::DSL::Primitives.new self
|
93
|
-
@variable_bindings = []
|
94
|
-
@public_interface = Module.new
|
95
|
-
@subjects = []
|
96
|
-
@trace = false
|
97
|
-
@implicit = false
|
98
|
-
@check_discontiguous = true
|
99
|
-
@included_theories = []
|
100
|
-
@check_number = 0
|
101
|
-
@prefix_functor_modules = []
|
102
|
-
end
|
103
|
-
|
104
|
-
def primitives
|
105
|
-
@primitives
|
106
|
-
end
|
107
|
-
private :primitives
|
108
|
-
|
109
|
-
def with_context &block
|
110
|
-
begin
|
111
|
-
# save current theory
|
112
|
-
old_theory = Thread.current[:rubylog_current_theory]
|
113
|
-
Thread.current[:rubylog_current_theory] = self
|
114
|
-
|
115
|
-
# start implicit mode
|
116
|
-
if @implicit
|
117
|
-
start_implicit
|
118
|
-
end
|
119
|
-
|
120
|
-
# call the block
|
121
|
-
return instance_exec &block
|
122
|
-
ensure
|
123
|
-
# restore current theory
|
124
|
-
Thread.current[:rubylog_current_theory] = old_theory
|
125
|
-
|
126
|
-
# stop implicit mode
|
127
|
-
if @implicit_started
|
128
|
-
stop_implicit
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
alias amend with_context
|
134
|
-
alias eval with_context
|
135
|
-
|
136
|
-
|
137
|
-
# directives
|
138
|
-
#
|
139
|
-
def predicate *indicators
|
140
|
-
indicators.each do |indicator|
|
141
|
-
check_indicator indicator
|
142
|
-
create_procedure indicator
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
def discontiguous *indicators
|
147
|
-
indicators.each do |indicator|
|
148
|
-
check_indicator indicator
|
149
|
-
create_procedure(indicator).discontiguous!
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
def check_discontiguous value = true
|
154
|
-
@check_discontiguous = value
|
155
|
-
end
|
156
|
-
|
157
|
-
def check_discontiguous?
|
158
|
-
@check_discontiguous
|
159
|
-
end
|
160
|
-
|
161
|
-
def multitheory *indicators
|
162
|
-
indicators.each do |indicator|
|
163
|
-
check_indicator indicator
|
164
|
-
create_procedure(indicator).multitheory!
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
def functor *functors
|
169
|
-
functors.each do |fct|
|
170
|
-
Rubylog::DSL.add_functors_to @public_interface, fct
|
171
|
-
@subjects.each do |s|
|
172
|
-
Rubylog::DSL.add_functors_to s, fct
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
def prefix_functor *functors
|
178
|
-
functors.each do |fct|
|
179
|
-
m = Module.new
|
180
|
-
Rubylog::DSL.add_prefix_functors_to m, fct
|
181
|
-
@prefix_functor_modules << m
|
182
|
-
extend m
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
def functor_for target, *functors
|
187
|
-
functors.each do |fct|
|
188
|
-
Rubylog::DSL.add_functors_to target, fct
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
def private *indicators
|
193
|
-
end
|
194
|
-
|
195
|
-
def subject *subjects
|
196
|
-
subjects.each do |s|
|
197
|
-
s.send :include, @public_interface
|
198
|
-
@subjects << s
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
def include *theories
|
203
|
-
theories.each do |theory|
|
204
|
-
|
205
|
-
@included_theories << theory
|
206
|
-
|
207
|
-
# include all public_interface predicates
|
208
|
-
@public_interface.send :include, theory.public_interface
|
209
|
-
theory.each_pair do |indicator, predicate|
|
210
|
-
if keys.include? indicator and self[indicator].respond_to? :multitheory? and self[indicator].multitheory?
|
211
|
-
raise TypeError, "You can only use a procedure as a multitheory predicate (#{indicator})" unless predicate.respond_to? :each
|
212
|
-
predicate.each do |rule|
|
213
|
-
@database[indicator].assertz rule
|
214
|
-
end
|
215
|
-
else
|
216
|
-
@database[indicator] = predicate
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
# include prefix_functors
|
221
|
-
theory.prefix_functor_modules.each do |m|
|
222
|
-
@prefix_functor_modules << m
|
223
|
-
extend m
|
224
|
-
end
|
225
|
-
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
|
230
|
-
def explain c
|
231
|
-
require "rubylog/because"
|
232
|
-
include Rubylog::Because unless included_theories.include? Rubylog::Because
|
233
|
-
expl = Rubylog::Variable.new :_expl
|
234
|
-
c.because(expl).solve do
|
235
|
-
return c.because(expl.value)
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
def check_passed goal
|
240
|
-
print "#{n = check_number} :)\t"
|
241
|
-
end
|
242
|
-
|
243
|
-
def check_failed goal
|
244
|
-
puts "#{check_number} :/\t"
|
245
|
-
puts "Check failed: #{goal.inspect}"
|
246
|
-
puts caller[1]
|
247
|
-
#raise Rubylog::CheckFailed, goal.inspect, caller[1..-1]
|
248
|
-
end
|
249
|
-
|
250
|
-
def check_raised_exception goal, exception
|
251
|
-
puts "#{check_number} :(\t"
|
252
|
-
puts "Check raised exception: #{exception}"
|
253
|
-
puts exception.backtrace
|
254
|
-
end
|
255
|
-
|
256
|
-
# returns the line number of the most recen +check+ call
|
257
|
-
def check_number
|
258
|
-
i = caller.index{|l| l.end_with? "in `check'" }
|
259
|
-
caller[i+1] =~ /:(\d+):/
|
260
|
-
$1
|
261
|
-
end
|
262
|
-
private :check_number
|
263
|
-
|
264
|
-
# Tries to prove goal (or block if goal is not given). If it proves, calles
|
265
|
-
# +check_passed+. If it fails, calls +check_failed+. If it raises an exception, calls +check_raised_exception+.
|
266
|
-
def check goal=nil, &block
|
267
|
-
goal ||= block
|
268
|
-
result = nil
|
269
|
-
begin
|
270
|
-
result = true?(goal)
|
271
|
-
rescue
|
272
|
-
check_raised_exception goal, $!
|
273
|
-
else
|
274
|
-
if result
|
275
|
-
check_passed goal, &block
|
276
|
-
else
|
277
|
-
check_failed goal, &block
|
278
|
-
end
|
279
|
-
end
|
280
|
-
result
|
281
|
-
end
|
282
|
-
|
283
|
-
# Starts (if +val+ is not given or true) or stops (if +val+ is false) implicit mode.
|
284
|
-
#
|
285
|
-
# In implicit mode you can start using infix functors without declaring them.
|
286
|
-
def implicit val=true
|
287
|
-
@implicit = val
|
288
|
-
|
289
|
-
if val
|
290
|
-
if Thread.current[:rubylog_current_theory] == self
|
291
|
-
start_implicit
|
292
|
-
end
|
293
|
-
else
|
294
|
-
if @implicit_started
|
295
|
-
stop_implicit
|
296
|
-
end
|
297
|
-
end
|
298
|
-
end
|
299
|
-
|
300
|
-
def thats
|
301
|
-
Rubylog::DSL::Thats.new
|
302
|
-
end
|
303
|
-
|
304
|
-
|
305
|
-
# predicates
|
306
|
-
|
307
|
-
def assert head, body=:true
|
308
|
-
indicator = head.indicator
|
309
|
-
predicate = @database[indicator]
|
310
|
-
if predicate
|
311
|
-
check_assertable predicate, head, body
|
312
|
-
else
|
313
|
-
predicate = create_procedure indicator
|
314
|
-
end
|
315
|
-
predicate.assertz Rubylog::Structure.new(:-, head, body)
|
316
|
-
@last_predicate = predicate
|
317
|
-
end
|
318
|
-
|
319
|
-
|
320
|
-
def solve goal, &block
|
321
|
-
with_context do
|
322
|
-
goal = goal.rubylog_compile_variables
|
323
|
-
goal.prove { block.call_with_rubylog_variables(goal.rubylog_variables) }
|
324
|
-
end
|
325
|
-
end
|
326
|
-
|
327
|
-
def true? goal=nil, &block
|
328
|
-
if goal.nil?
|
329
|
-
raise ArgumentError, "No goal given" if block.nil?
|
330
|
-
goal = with_context &block
|
331
|
-
end
|
332
|
-
with_context do
|
333
|
-
goal = goal.rubylog_compile_variables
|
334
|
-
goal.prove { return true }
|
335
|
-
end
|
336
|
-
false
|
337
|
-
end
|
338
|
-
|
339
|
-
alias prove true?
|
340
|
-
|
341
|
-
# debugging
|
342
|
-
#
|
343
|
-
#
|
344
|
-
def trace val=true, &block
|
345
|
-
@trace=block || val
|
346
|
-
@trace_levels = 0
|
347
|
-
end
|
348
|
-
|
349
|
-
def print_trace level, *args
|
350
|
-
return unless @trace
|
351
|
-
if @trace.respond_to? :call
|
352
|
-
@trace.call @trace_levels, *args if not args.empty?
|
353
|
-
else
|
354
|
-
puts " "*@trace_levels + args.map{|a|a.rubylog_deep_dereference.to_s}.join(" ") if not args.empty?
|
355
|
-
end
|
356
|
-
@trace_levels += level
|
357
|
-
end
|
358
|
-
|
359
|
-
protected
|
360
|
-
|
361
|
-
|
362
|
-
def check_assertable predicate, head, body
|
363
|
-
raise Rubylog::NonAssertableError, head.indicator.inspect, caller[2..-1] unless predicate.respond_to? :assertz
|
364
|
-
raise Rubylog::DiscontiguousPredicateError, head.indicator.inspect, caller[2..-1] if check_discontiguous? and not predicate.empty? and predicate != @last_predicate and not predicate.discontiguous?
|
365
|
-
end
|
366
|
-
|
367
|
-
def create_procedure indicator
|
368
|
-
functor indicator[0]
|
369
|
-
@database[indicator] = Rubylog::SimpleProcedure.new
|
370
|
-
end
|
371
|
-
|
372
|
-
def start_implicit
|
373
|
-
[@public_interface, Rubylog::Variable].each do |m|
|
374
|
-
m.send :define_method, :method_missing do |m, *args|
|
375
|
-
fct = Rubylog::DSL.normalize_functor(m)
|
376
|
-
return super if fct.nil?
|
377
|
-
raise NameError, "'#{fct}' method already exists" if respond_to? fct
|
378
|
-
Rubylog.current_theory.functor fct
|
379
|
-
self.class.send :include, Rubylog::DSL.functor_module(fct)
|
380
|
-
send m, *args
|
381
|
-
end
|
382
|
-
end
|
383
|
-
@implicit_started = true
|
384
|
-
end
|
385
|
-
|
386
|
-
def stop_implicit
|
387
|
-
[@public_interface, Rubylog::Variable].each do |m|
|
388
|
-
m.send :remove_method, :method_missing
|
389
|
-
end
|
390
|
-
@implicit_started = false
|
391
|
-
end
|
392
|
-
|
393
|
-
|
394
|
-
#def private *args
|
395
|
-
#if args.empty?
|
396
|
-
#@scope = :private
|
397
|
-
#else
|
398
|
-
#end
|
399
|
-
#end
|
400
|
-
#def protected *args
|
401
|
-
#if args.empty?
|
402
|
-
#@scope = :protected
|
403
|
-
#else
|
404
|
-
#end
|
405
|
-
#end
|
406
|
-
|
407
|
-
private
|
408
|
-
|
409
|
-
def check_indicator indicator
|
410
|
-
raise ArgumentError, "#{indicator.inspect} should be a predicate indicator", caller[2..-1] unless indicator.is_a? Array and
|
411
|
-
indicator.length == 2 and
|
412
|
-
indicator[0].is_a? Symbol and
|
413
|
-
indicator[1].is_a? Integer
|
414
|
-
end
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
end
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require "./lib/rubylog/builtins/file_system"
|
2
|
-
|
3
|
-
theory do
|
4
|
-
check "lib".dirname_in(".")
|
5
|
-
check "lib".filename_in(".").false
|
6
|
-
check "README.rdoc".filename_in(".")
|
7
|
-
check "README.rdoc".dirname_in(".").false
|
8
|
-
check (Dir.pwd+"/lib").dir_in(".")
|
9
|
-
check (Dir.pwd+"/lib").file_in(".").false
|
10
|
-
check (Dir.pwd+"/README.rdoc").file_in(".")
|
11
|
-
check (Dir.pwd+"/README.rdoc").dir_in(".").false
|
12
|
-
check (Dir.pwd+"/lib/rubylog.rb").file_in("lib")
|
13
|
-
check (Dir.pwd+"/lib/rubylog").dir_in("lib")
|
14
|
-
check "rubylog.rb".filename_in("lib")
|
15
|
-
check "rubylog".dirname_in("lib")
|
16
|
-
|
17
|
-
|
18
|
-
# this is removed in favor of string unification
|
19
|
-
#check "rubylog.rb".filename("rubylog", "rb")
|
20
|
-
#check A.filename("rubylog", "rb").and A.is "rubylog.rb"
|
21
|
-
#check "rubylog.rb".filename(F, "rb").and F.is "rubylog"
|
22
|
-
#check "rubylog.rb".filename("rubylog", E).and E.is "rb"
|
23
|
-
end
|