rubylog 1.0.0 → 2.0pre1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|