rubylog 0.0.1 → 1.0.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 +1 -1
- data/README.hu.rb +58 -0
- data/README.rdoc +248 -89
- data/Rakefile +6 -1
- data/VERSION +1 -1
- data/bin/rubylog +18 -0
- data/examples/dcg.rb +35 -0
- data/examples/dcg2.rb +42 -0
- data/examples/enumerators.rb +30 -0
- data/examples/factorial.rb +9 -8
- data/examples/hanoi.rb +24 -0
- data/examples/hello.rb +11 -5
- data/examples/parsing.rb +27 -0
- data/examples/primitives.rb +24 -0
- data/examples/theory.rb +22 -10
- data/lib/rubylog/builtins/default.rb +10 -0
- data/lib/rubylog/builtins/file_system.rb +15 -0
- data/lib/rubylog/builtins/logic.rb +109 -0
- data/lib/rubylog/builtins/reflection.rb +94 -0
- data/lib/rubylog/builtins/term.rb +47 -0
- data/lib/rubylog/dsl/array_splat.rb +25 -0
- data/lib/rubylog/dsl/primitives.rb +17 -0
- data/lib/rubylog/dsl/thats.rb +22 -0
- data/lib/rubylog/dsl/variables.rb +30 -0
- data/lib/rubylog/dsl.rb +35 -17
- data/lib/rubylog/errors.rb +19 -1
- data/lib/rubylog/interfaces/assertable.rb +16 -0
- data/lib/rubylog/interfaces/callable.rb +18 -0
- data/lib/rubylog/interfaces/composite_term.rb +47 -0
- data/lib/rubylog/interfaces/predicate.rb +8 -0
- data/lib/rubylog/interfaces/procedure.rb +60 -0
- data/lib/rubylog/interfaces/term.rb +41 -0
- data/lib/rubylog/mixins/array.rb +118 -0
- data/lib/{class.rb → rubylog/mixins/class.rb} +2 -2
- data/lib/rubylog/mixins/hash.rb +8 -0
- data/lib/rubylog/mixins/kernel.rb +5 -0
- data/lib/rubylog/mixins/method.rb +3 -0
- data/lib/rubylog/mixins/object.rb +8 -0
- data/lib/rubylog/mixins/proc.rb +37 -0
- data/lib/rubylog/mixins/string.rb +104 -0
- data/lib/rubylog/mixins/symbol.rb +44 -0
- data/lib/rubylog/simple_procedure.rb +8 -0
- data/lib/rubylog/{clause.rb → structure.rb} +32 -31
- data/lib/rubylog/theory.rb +368 -79
- data/lib/rubylog/variable.rb +102 -23
- data/lib/rubylog.rb +33 -25
- data/logic/builtins/file_system_logic.rb +23 -0
- data/logic/builtins/reflection_logic.rb +40 -0
- data/logic/dereference_logic.rb +23 -0
- data/logic/directory_structure_logic.rb +19 -0
- data/logic/dsl_logic.rb +29 -0
- data/logic/errors_logic.rb +9 -0
- data/logic/guard_logic.rb +115 -0
- data/logic/list_logic.rb +55 -0
- data/logic/map_logic.rb +15 -0
- data/logic/multitheory.rb +23 -0
- data/logic/recursion_logic.rb +12 -0
- data/logic/string_logic.rb +41 -0
- data/logic/thats_logic.rb +51 -0
- data/logic/variable_logic.rb +24 -0
- data/rubylog.gemspec +85 -46
- data/spec/bartak_guide_spec.rb +57 -62
- data/spec/builtins/all_spec.rb +99 -0
- data/spec/builtins/and_spec.rb +22 -0
- data/spec/builtins/array_spec.rb +16 -0
- data/spec/builtins/branch_or_spec.rb +27 -0
- data/spec/builtins/cut_spec.rb +44 -0
- data/spec/builtins/fail_spec.rb +5 -0
- data/spec/builtins/false_spec.rb +5 -0
- data/spec/builtins/in_spec.rb +38 -0
- data/spec/builtins/is_false_spec.rb +12 -0
- data/spec/builtins/is_spec.rb +26 -0
- data/spec/builtins/matches_spec.rb +23 -0
- data/spec/builtins/or_spec.rb +22 -0
- data/spec/{rubylog/builtins → builtins}/splits_to.rb +0 -0
- data/spec/builtins/then_spec.rb +27 -0
- data/spec/builtins/true_spec.rb +5 -0
- data/spec/clause_spec.rb +82 -0
- data/spec/compilation_spec.rb +61 -0
- data/spec/custom_classes_spec.rb +43 -0
- data/spec/dereference.rb +10 -0
- data/spec/{inriasuite.rb → inriasuite_spec.rb} +2 -9
- data/spec/queries_spec.rb +150 -0
- data/spec/recursion_spec.rb +4 -4
- data/spec/ruby_code_spec.rb +52 -0
- data/spec/rules_spec.rb +97 -0
- data/spec/spec_helper.rb +6 -2
- data/spec/theory_spec.rb +28 -0
- data/spec/unification_spec.rb +84 -0
- data/spec/variable_spec.rb +26 -0
- metadata +153 -180
- data/examples/4queens.rb +0 -10
- data/examples/calculation.rb +0 -12
- data/examples/concepts.rb +0 -46
- data/examples/fp.rb +0 -56
- data/examples/historia_de_espana.rb +0 -31
- data/examples/idea.rb +0 -143
- data/examples/lists.rb +0 -5
- data/examples/mechanika.rb +0 -409
- data/examples/parse.rb +0 -15
- data/lib/array.rb +0 -24
- data/lib/method.rb +0 -4
- data/lib/object.rb +0 -5
- data/lib/proc.rb +0 -4
- data/lib/rubylog/builtins.rb +0 -193
- data/lib/rubylog/callable.rb +0 -20
- data/lib/rubylog/composite_term.rb +0 -38
- data/lib/rubylog/dsl/constants.rb +0 -15
- data/lib/rubylog/dsl/first_order_functors.rb +0 -9
- data/lib/rubylog/dsl/global_functors.rb +0 -3
- data/lib/rubylog/dsl/second_order_functors.rb +0 -8
- data/lib/rubylog/internal_helpers.rb +0 -16
- data/lib/rubylog/predicate.rb +0 -34
- data/lib/rubylog/proc_method_additions.rb +0 -69
- data/lib/rubylog/term.rb +0 -20
- data/lib/rubylog/unifiable.rb +0 -19
- data/lib/symbol.rb +0 -35
- data/script/inriasuite2spec +0 -0
- data/script/inriasuite2spec.pl +0 -22
- data/spec/rubylog/clause_spec.rb +0 -81
- data/spec/rubylog/variable_spec.rb +0 -25
- data/spec/rubylog_spec.rb +0 -914
@@ -0,0 +1,60 @@
|
|
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
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Rubylog::Term
|
2
|
+
def rubylog_clone
|
3
|
+
yield self
|
4
|
+
end
|
5
|
+
|
6
|
+
def rubylog_variables
|
7
|
+
[]
|
8
|
+
end
|
9
|
+
|
10
|
+
def rubylog_resolve_function
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
def rubylog_variables_hash
|
15
|
+
vars = rubylog_variables
|
16
|
+
Hash[vars.zip(vars.map{|v|v.value})]
|
17
|
+
end
|
18
|
+
|
19
|
+
def rubylog_unify other
|
20
|
+
if other.kind_of? Rubylog::Variable
|
21
|
+
other.rubylog_unify(self) do yield end
|
22
|
+
else
|
23
|
+
yield if self == other
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def rubylog_dereference
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def rubylog_deep_dereference
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def rubylog_compile_variables
|
36
|
+
self
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module Rubylog
|
2
|
+
# for the future
|
3
|
+
def self.unify_arrays a, a_start, a_end, b, b_start, b_end
|
4
|
+
case
|
5
|
+
when (a_start > a_end and b_start > b_end)
|
6
|
+
yield
|
7
|
+
when (a_start > a_end or b_start > b_end)
|
8
|
+
return
|
9
|
+
when (a[a_start].is_a? Rubylog::DSL::ArraySplat and b[b_start].is_a? Rubylog::DSL::ArraySplat)
|
10
|
+
raise "not implemented"
|
11
|
+
when (a[a_start].is_a? Rubylog::DSL::ArraySplat)
|
12
|
+
# A=[]
|
13
|
+
a[a_start].var.rubylog_unify [] do
|
14
|
+
unify_arrays(a, a_start+1, a_end, b, b_start, b_end) { yield }
|
15
|
+
end
|
16
|
+
|
17
|
+
# A=[_X, *_Y]
|
18
|
+
new_arr = [Rubylog::Variable.new, Rubylog::DSL::ArraySplat.new(Rubylog::Variable.new)]
|
19
|
+
a[a_start].var.rubylog_unify new_arr do
|
20
|
+
unify_arrays(a[a_start].var, a_start+1, a_end, b, b_start, b_end) { yield }
|
21
|
+
end
|
22
|
+
when (b[b_start].is_a? Rubylog::DSL::ArraySplat)
|
23
|
+
raise "not implemented"
|
24
|
+
else
|
25
|
+
a[a_start].rubylog_unify b[b_start] do
|
26
|
+
unify_arrays(a, a_start+1, a_end, b, b_start+1, b_end) { yield }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Array
|
33
|
+
|
34
|
+
# Term methods
|
35
|
+
def rubylog_unify other
|
36
|
+
return super{yield} unless other.instance_of? self.class
|
37
|
+
#Rubylog.unify_arrays(self, 0, length-1, other, 0, other.length-1) { yield }
|
38
|
+
if empty?
|
39
|
+
if other.empty?
|
40
|
+
yield
|
41
|
+
elsif other[0].is_a? Rubylog::DSL::ArraySplat
|
42
|
+
other[0].var.rubylog_unify [] do
|
43
|
+
self.rubylog_unify other[1..-1] do
|
44
|
+
yield
|
45
|
+
end
|
46
|
+
end
|
47
|
+
else
|
48
|
+
# failed
|
49
|
+
end
|
50
|
+
else
|
51
|
+
if self[0].is_a? Rubylog::DSL::ArraySplat
|
52
|
+
# optimize [*A] = [*B]
|
53
|
+
if other[0].is_a? Rubylog::DSL::ArraySplat and self.length == 1 and other.length == 1
|
54
|
+
self[0].var.rubylog_unify other[0].var do
|
55
|
+
yield
|
56
|
+
end
|
57
|
+
return
|
58
|
+
end
|
59
|
+
|
60
|
+
self[0].var.rubylog_unify [] do
|
61
|
+
self[1..-1].rubylog_unify other do
|
62
|
+
yield
|
63
|
+
end
|
64
|
+
end
|
65
|
+
part = [Rubylog::Variable.new, Rubylog::DSL::ArraySplat.new]
|
66
|
+
self[0].var.rubylog_unify part do
|
67
|
+
(part + self[1..-1]).rubylog_unify other do
|
68
|
+
yield
|
69
|
+
end
|
70
|
+
end
|
71
|
+
else
|
72
|
+
if other[0].is_a? Rubylog::DSL::ArraySplat
|
73
|
+
other[0].var.rubylog_unify [] do
|
74
|
+
self.rubylog_unify other[1..-1] do
|
75
|
+
yield
|
76
|
+
end
|
77
|
+
end
|
78
|
+
part = [Rubylog::Variable.new, Rubylog::DSL::ArraySplat.new]
|
79
|
+
other[0].var.rubylog_unify part do
|
80
|
+
self.rubylog_unify(part + other[1..-1]) do
|
81
|
+
yield
|
82
|
+
end
|
83
|
+
end
|
84
|
+
else
|
85
|
+
return if other.empty?
|
86
|
+
self[0].rubylog_unify other[0] do
|
87
|
+
self[1..-1].rubylog_unify other[1..-1] do
|
88
|
+
yield
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# CompositeTerm methods
|
97
|
+
include Rubylog::CompositeTerm
|
98
|
+
def rubylog_clone &block
|
99
|
+
block[map{|t|t.rubylog_clone &block}]
|
100
|
+
end
|
101
|
+
|
102
|
+
def rubylog_deep_dereference
|
103
|
+
map do |t|
|
104
|
+
case t
|
105
|
+
when Rubylog::DSL::ArraySplat
|
106
|
+
v = t.var.rubylog_dereference
|
107
|
+
if v.is_a? Array
|
108
|
+
v.rubylog_deep_dereference
|
109
|
+
else
|
110
|
+
[t]
|
111
|
+
end
|
112
|
+
else
|
113
|
+
[t.rubylog_deep_dereference]
|
114
|
+
end
|
115
|
+
end.inject(:concat) || []
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class Proc
|
2
|
+
|
3
|
+
# Callable methods
|
4
|
+
include Rubylog::Callable
|
5
|
+
|
6
|
+
def prove
|
7
|
+
yield if call_with_rubylog_variables
|
8
|
+
end
|
9
|
+
|
10
|
+
# CompositeTerm methods
|
11
|
+
include Rubylog::CompositeTerm
|
12
|
+
def rubylog_clone
|
13
|
+
yield dup
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
# Term methods
|
19
|
+
def rubylog_resolve_function
|
20
|
+
call_with_rubylog_variables
|
21
|
+
end
|
22
|
+
|
23
|
+
def call_with_rubylog_variables vars = nil
|
24
|
+
vars ||= @rubylog_variables
|
25
|
+
raise Rubylog::InvalidStateError, "variables not available" if not vars
|
26
|
+
|
27
|
+
Rubylog::Theory.with_vars vars do
|
28
|
+
return call
|
29
|
+
end
|
30
|
+
# to pass arguments:
|
31
|
+
#if arity == -1
|
32
|
+
# call *@rubylog_variables.map{|v|v.value}
|
33
|
+
#else
|
34
|
+
# call *@rubylog_variables[0...arity].map{|v|v.value}
|
35
|
+
#end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
class String
|
2
|
+
RUBYLOG_VAR_START = "\u0091" # "\u00ab"
|
3
|
+
RUBYLOG_VAR_END = "\u0092" # "\u00bb"
|
4
|
+
RUBYLOG_VAR_REGEXP = /#{RUBYLOG_VAR_START}([^\[]+?)\[(\d*)\]#{RUBYLOG_VAR_END}/
|
5
|
+
|
6
|
+
RubylogStringVariableGuards = [[]]
|
7
|
+
|
8
|
+
def self.rubylog_unify_strings a, a_segments, a_vars, b
|
9
|
+
#p a, a_segments, a_vars, b
|
10
|
+
if a_segments.count == 1
|
11
|
+
segment = a_segments[0]
|
12
|
+
if b.end_with?(segment)
|
13
|
+
#p b[0...b.length-segment.length]
|
14
|
+
a_vars[0].rubylog_unify b[0...b.length-segment.length] do
|
15
|
+
yield
|
16
|
+
end
|
17
|
+
end
|
18
|
+
else
|
19
|
+
b.scan /#{Regexp.quote(a_segments[0])}/ do
|
20
|
+
a_vars[0].rubylog_unify(b[0...Regexp.last_match.begin(0)]) do
|
21
|
+
rubylog_unify_strings(a, a_segments[1..-1], a_vars[1..-1], b[Regexp.last_match.end(0)..-1]) do
|
22
|
+
yield
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Term methods
|
30
|
+
def rubylog_unify other
|
31
|
+
return super{yield} unless other.instance_of? self.class
|
32
|
+
|
33
|
+
self_has_vars = self =~ RUBYLOG_VAR_REGEXP
|
34
|
+
other_has_vars = other =~ RUBYLOG_VAR_REGEXP
|
35
|
+
|
36
|
+
return super{yield} unless self_has_vars or other_has_vars
|
37
|
+
raise Rubylog::InstantiationError, "Cannot unify two strings with variables inside" if self_has_vars and other_has_vars
|
38
|
+
|
39
|
+
a, b = self_has_vars ? [self, other] : [other, self]
|
40
|
+
a_segments, a_vars = a.rubylog_segments
|
41
|
+
|
42
|
+
return unless b.start_with? a_segments[0]
|
43
|
+
b = b[a_segments[0].length..-1]; a_segments.shift
|
44
|
+
|
45
|
+
String.rubylog_unify_strings(a, a_segments, a_vars, b) do
|
46
|
+
yield
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
# CompositeTerm methods
|
52
|
+
include Rubylog::CompositeTerm
|
53
|
+
def rubylog_clone &block
|
54
|
+
scan RUBYLOG_VAR_REGEXP do
|
55
|
+
guards = RubylogStringVariableGuards[$2.to_i]
|
56
|
+
Rubylog::Variable.new($1.to_sym)[*guards].rubylog_clone(&block)
|
57
|
+
end
|
58
|
+
block[self]
|
59
|
+
end
|
60
|
+
|
61
|
+
def rubylog_deep_dereference
|
62
|
+
gsub RUBYLOG_VAR_REGEXP do
|
63
|
+
rubylog_get_string_variable($1).rubylog_deep_dereference.to_s
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# returns a list of substrings which are before, between and after the rubylog
|
68
|
+
# string variables
|
69
|
+
def rubylog_segments
|
70
|
+
segments = [[0]]
|
71
|
+
vars = []
|
72
|
+
|
73
|
+
scan RUBYLOG_VAR_REGEXP do
|
74
|
+
match = Regexp.last_match
|
75
|
+
#p match
|
76
|
+
#p match.begin(0)
|
77
|
+
#p match.end(0)
|
78
|
+
#p match[0]
|
79
|
+
#p match[1]
|
80
|
+
segments.last << match.begin(0)
|
81
|
+
segments << [match.end(0)]
|
82
|
+
vars << rubylog_get_string_variable(match[1])
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
segments.last << length
|
87
|
+
#p segments, vars
|
88
|
+
segments = segments.map{|s|self[s[0]...s[1]]}
|
89
|
+
#p [self, segments, vars]
|
90
|
+
return segments, vars
|
91
|
+
end
|
92
|
+
|
93
|
+
protected
|
94
|
+
|
95
|
+
def rubylog_get_string_variable s
|
96
|
+
s = s.to_sym
|
97
|
+
if @rubylog_variables
|
98
|
+
@rubylog_variables.find{|v|v.name == s}
|
99
|
+
else
|
100
|
+
raise Rubylog::InvalidStateError, "Rubylog variables not available"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class Symbol
|
2
|
+
|
3
|
+
# a proxy for Structure
|
4
|
+
def functor
|
5
|
+
self
|
6
|
+
end
|
7
|
+
|
8
|
+
def arity
|
9
|
+
0
|
10
|
+
end
|
11
|
+
|
12
|
+
def indicator
|
13
|
+
[self, 0]
|
14
|
+
end
|
15
|
+
|
16
|
+
def args
|
17
|
+
[]
|
18
|
+
end
|
19
|
+
|
20
|
+
# Assertable methods
|
21
|
+
include Rubylog::Assertable
|
22
|
+
|
23
|
+
# Term methods
|
24
|
+
include Rubylog::Term
|
25
|
+
|
26
|
+
# Callable methods
|
27
|
+
include Rubylog::Callable
|
28
|
+
|
29
|
+
def prove
|
30
|
+
begin
|
31
|
+
Rubylog.current_theory.print_trace 1, self, rubylog_variables_hash
|
32
|
+
|
33
|
+
predicate = Rubylog.current_theory[[self,0]]
|
34
|
+
raise Rubylog::ExistenceError, indicator if not predicate
|
35
|
+
|
36
|
+
predicate.call(*args) { yield }
|
37
|
+
|
38
|
+
ensure
|
39
|
+
Rubylog.current_theory.print_trace -1
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
module Rubylog
|
2
|
-
class
|
2
|
+
class Structure
|
3
3
|
|
4
4
|
# data structure
|
5
5
|
attr_reader :functor, :args
|
6
6
|
def initialize functor, *args
|
7
|
+
#raise Rubylog::TypeError, "functor cannot be #{functor}" unless functor.is_a? Symbol
|
7
8
|
@functor = functor
|
8
9
|
@args = args.freeze
|
9
10
|
@arity = args.count
|
@@ -14,7 +15,7 @@ module Rubylog
|
|
14
15
|
end
|
15
16
|
|
16
17
|
def == other
|
17
|
-
other.instance_of?
|
18
|
+
other.instance_of? Structure and
|
18
19
|
@functor == other.functor and @args == other.args
|
19
20
|
end
|
20
21
|
alias eql? ==
|
@@ -37,38 +38,36 @@ module Rubylog
|
|
37
38
|
@arity
|
38
39
|
end
|
39
40
|
|
40
|
-
def
|
41
|
+
def indicator
|
41
42
|
[@functor, @arity]
|
42
43
|
end
|
43
44
|
|
44
|
-
#
|
45
|
-
|
46
|
-
Rubylog.theory.assert self, body || block
|
47
|
-
end
|
48
|
-
|
49
|
-
def unless body=nil, &block
|
50
|
-
Rubylog.theory.assert self, Clause.new(:is_false, body || block)
|
51
|
-
end
|
52
|
-
|
53
|
-
|
45
|
+
# Assertable methods
|
46
|
+
include Rubylog::Assertable
|
54
47
|
|
55
48
|
# Callable methods
|
56
49
|
include Rubylog::Callable
|
57
50
|
|
58
51
|
def prove
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
52
|
+
begin
|
53
|
+
Rubylog.current_theory.print_trace 1, self, rubylog_variables_hash
|
54
|
+
predicate = Rubylog.current_theory[indicator]
|
55
|
+
raise Rubylog::ExistenceError, indicator.inspect if not predicate
|
56
|
+
count = 0
|
57
|
+
predicate.call(*@args) { yield; count+=1 }
|
58
|
+
count
|
59
|
+
ensure
|
60
|
+
Rubylog.current_theory.print_trace -1
|
61
|
+
end
|
64
62
|
end
|
63
|
+
|
65
64
|
|
66
65
|
# enumerable methods
|
67
66
|
include Enumerable
|
68
67
|
alias each solve
|
69
68
|
|
70
|
-
#
|
71
|
-
include Rubylog::
|
69
|
+
# Term methods
|
70
|
+
include Rubylog::Term
|
72
71
|
def rubylog_unify other
|
73
72
|
return super{yield} unless other.instance_of? self.class
|
74
73
|
return unless other.functor == @functor
|
@@ -81,20 +80,22 @@ module Rubylog
|
|
81
80
|
# CompositeTerm methods
|
82
81
|
include Rubylog::CompositeTerm
|
83
82
|
def rubylog_clone &block
|
84
|
-
block.call
|
85
|
-
*@args.map{|a|a.rubylog_clone &block}
|
83
|
+
block.call Structure.new @functor,
|
84
|
+
*@args.map{|a| a.rubylog_clone &block}
|
85
|
+
end
|
86
|
+
def rubylog_deep_dereference
|
87
|
+
Structure.new @functor.rubylog_deep_dereference,
|
88
|
+
*@args.rubylog_deep_dereference
|
86
89
|
end
|
87
90
|
|
88
|
-
# Second-order functors (:is_false, :and, :or, :then)
|
89
|
-
include Rubylog::DSL::SecondOrderFunctors
|
90
91
|
|
91
92
|
# convenience methods
|
92
|
-
def
|
93
|
-
goal = rubylog_compile_variables
|
94
|
-
goal.variable_hashes_without_compile.
|
95
|
-
goal.rubylog_clone {|i| hash[i] || i }
|
96
|
-
end
|
97
|
-
end
|
93
|
+
#def each_solution
|
94
|
+
#goal = rubylog_compile_variables
|
95
|
+
#goal.variable_hashes_without_compile.each do |hash|
|
96
|
+
#yield goal.rubylog_clone {|i| hash[i] || i }
|
97
|
+
#end
|
98
|
+
#end
|
98
99
|
|
99
100
|
def variable_hashes
|
100
101
|
rubylog_compile_variables.variable_hashes_without_compile
|
@@ -109,5 +110,5 @@ module Rubylog
|
|
109
110
|
end
|
110
111
|
end
|
111
112
|
end
|
112
|
-
|
113
113
|
end
|
114
|
+
|