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.
Files changed (163) hide show
  1. data/Gemfile +3 -12
  2. data/Gemfile.lock +22 -48
  3. data/README.rdoc +38 -38
  4. data/README.rdoc.orig +284 -0
  5. data/RELEASE_NOTES.rdoc +51 -0
  6. data/Rakefile +14 -18
  7. data/TODO.txt +0 -0
  8. data/VERSION +1 -1
  9. data/examples/a_plus_b.rb +6 -0
  10. data/examples/checkmate.rb +88 -0
  11. data/examples/combination.rb +17 -0
  12. data/examples/dcg.rb +3 -2
  13. data/examples/dcg2.rb +2 -2
  14. data/{logic → examples}/directory_structure_logic.rb +3 -5
  15. data/examples/dirlist.rb +4 -0
  16. data/examples/divisors.rb +6 -0
  17. data/examples/enumerators.rb +3 -3
  18. data/examples/factorial.rb +2 -3
  19. data/examples/file_search.rb +14 -0
  20. data/examples/hanoi.rb +4 -5
  21. data/examples/hello.rb +6 -4
  22. data/examples/mice.rb +92 -0
  23. data/examples/mice2.rb +19 -0
  24. data/examples/n_queens.rb +32 -0
  25. data/examples/object_oriented.rb +14 -0
  26. data/examples/palindrome_detection.rb +18 -0
  27. data/examples/parsing.rb +6 -4
  28. data/examples/permutation.rb +12 -0
  29. data/examples/prefix.rb +13 -0
  30. data/examples/primality_by_division.rb +22 -0
  31. data/examples/primitives.rb +10 -8
  32. data/examples/sieve_of_eratosthenes.rb +14 -0
  33. data/examples/string_interpolation.rb +4 -0
  34. data/examples/sudoku.rb +52 -0
  35. data/examples/tracing.rb +19 -0
  36. data/lib/rspec/rubylog.rb +29 -0
  37. data/lib/rubylog/assertable.rb +24 -0
  38. data/lib/rubylog/builtins/arithmetics.rb +63 -0
  39. data/lib/rubylog/builtins/assumption.rb +71 -0
  40. data/lib/rubylog/builtins/ensure.rb +13 -0
  41. data/lib/rubylog/builtins/file_system.rb +30 -8
  42. data/lib/rubylog/builtins/logic.rb +69 -38
  43. data/lib/rubylog/builtins/reflection.rb +35 -50
  44. data/lib/rubylog/builtins/term.rb +15 -17
  45. data/lib/rubylog/builtins.rb +11 -0
  46. data/lib/rubylog/clause.rb +19 -0
  47. data/lib/rubylog/{interfaces/composite_term.rb → compound_term.rb} +3 -3
  48. data/lib/rubylog/context.rb +24 -0
  49. data/lib/rubylog/context_creation.rb +71 -0
  50. data/lib/rubylog/context_modules/checks.rb +35 -0
  51. data/lib/rubylog/context_modules/demonstration.rb +16 -0
  52. data/lib/rubylog/context_modules/predicates.rb +86 -0
  53. data/lib/rubylog/context_modules/primitives.rb +18 -0
  54. data/lib/rubylog/context_modules/thats.rb +13 -0
  55. data/lib/rubylog/default_context.rb +9 -0
  56. data/lib/rubylog/dsl/array_splat.rb +11 -3
  57. data/lib/rubylog/dsl/primitives.rb +24 -12
  58. data/lib/rubylog/dsl/thats.rb +6 -0
  59. data/lib/rubylog/dsl/variables.rb +56 -21
  60. data/lib/rubylog/errors.rb +26 -15
  61. data/lib/rubylog/mixins/array.rb +95 -62
  62. data/lib/rubylog/mixins/kernel.rb +3 -2
  63. data/lib/rubylog/mixins/method.rb +0 -1
  64. data/lib/rubylog/mixins/object.rb +2 -1
  65. data/lib/rubylog/mixins/proc.rb +9 -12
  66. data/lib/rubylog/mixins/string.rb +15 -23
  67. data/lib/rubylog/mixins/symbol.rb +7 -24
  68. data/lib/rubylog/nullary_predicates.rb +3 -0
  69. data/lib/rubylog/predicate.rb +53 -0
  70. data/lib/rubylog/primitive.rb +15 -0
  71. data/lib/rubylog/procedure.rb +42 -0
  72. data/lib/rubylog/rule.rb +24 -0
  73. data/lib/rubylog/structure.rb +19 -38
  74. data/lib/rubylog/{interfaces/term.rb → term.rb} +2 -7
  75. data/lib/rubylog/tracing.rb +75 -0
  76. data/lib/rubylog/variable.rb +31 -12
  77. data/lib/rubylog.rb +36 -32
  78. data/rubylog.gemspec +92 -84
  79. data/spec/inriasuite_spec.rb +906 -9
  80. data/spec/integration/custom_classes_spec.rb +61 -0
  81. data/spec/integration/dsl_spec.rb +38 -0
  82. data/spec/integration/recursion_spec.rb +14 -0
  83. data/spec/integration/theory_as_module_spec.rb +20 -0
  84. data/spec/integration/theory_as_module_with_include_spec.rb +14 -0
  85. data/spec/rspec/rubylog_spec.rb +75 -0
  86. data/spec/rubylog/assertable_spec.rb +111 -0
  87. data/spec/rubylog/builtins/arithmetics_spec.rb +94 -0
  88. data/spec/rubylog/builtins/assumption_spec.rb +70 -0
  89. data/spec/rubylog/builtins/ensure_spec.rb +8 -0
  90. data/spec/rubylog/builtins/file_system_spec.rb +40 -0
  91. data/spec/rubylog/builtins/logic_spec.rb +340 -0
  92. data/spec/rubylog/builtins/reflection_spec.rb +43 -0
  93. data/spec/rubylog/builtins/term_spec.rb +85 -0
  94. data/spec/rubylog/context_modules/demonstration_spec.rb +132 -0
  95. data/spec/rubylog/context_modules/predicates_spec.rb +57 -0
  96. data/spec/rubylog/context_modules/thats_spec.rb +94 -0
  97. data/spec/rubylog/dsl/array_splat_spec.rb +15 -0
  98. data/spec/rubylog/dsl/primitives_spec.rb +43 -0
  99. data/spec/rubylog/errors_spec.rb +18 -0
  100. data/spec/{unification_spec.rb → rubylog/interfaces/term_spec.rb} +8 -9
  101. data/spec/rubylog/mixins/array_spec.rb +80 -0
  102. data/spec/rubylog/mixins/composite_term_spec.rb +66 -0
  103. data/spec/rubylog/mixins/proc_spec.rb +59 -0
  104. data/spec/rubylog/mixins/string_spec.rb +48 -0
  105. data/spec/rubylog/mixins/symbol_spec.rb +9 -0
  106. data/spec/{clause_spec.rb → rubylog/structure_spec.rb} +16 -15
  107. data/spec/rubylog/term_spec.rb +7 -0
  108. data/spec/rubylog/tracing_spec.input +27 -0
  109. data/spec/rubylog/tracing_spec.rb +44 -0
  110. data/spec/rubylog/variable_spec.rb +279 -0
  111. data/spec/spec_helper.rb +1 -0
  112. data/vimrc +11 -0
  113. metadata +103 -123
  114. data/README.hu.rb +0 -58
  115. data/bin/rubylog +0 -18
  116. data/examples/theory.rb +0 -32
  117. data/lib/rubylog/builtins/default.rb +0 -10
  118. data/lib/rubylog/dsl.rb +0 -70
  119. data/lib/rubylog/interfaces/assertable.rb +0 -16
  120. data/lib/rubylog/interfaces/callable.rb +0 -18
  121. data/lib/rubylog/interfaces/predicate.rb +0 -8
  122. data/lib/rubylog/interfaces/procedure.rb +0 -60
  123. data/lib/rubylog/mixins/class.rb +0 -11
  124. data/lib/rubylog/simple_procedure.rb +0 -8
  125. data/lib/rubylog/theory.rb +0 -422
  126. data/logic/builtins/file_system_logic.rb +0 -23
  127. data/logic/builtins/reflection_logic.rb +0 -40
  128. data/logic/dereference_logic.rb +0 -23
  129. data/logic/dsl_logic.rb +0 -29
  130. data/logic/errors_logic.rb +0 -9
  131. data/logic/guard_logic.rb +0 -115
  132. data/logic/list_logic.rb +0 -55
  133. data/logic/map_logic.rb +0 -15
  134. data/logic/multitheory.rb +0 -23
  135. data/logic/recursion_logic.rb +0 -12
  136. data/logic/string_logic.rb +0 -41
  137. data/logic/thats_logic.rb +0 -51
  138. data/logic/variable_logic.rb +0 -24
  139. data/spec/bartak_guide_spec.rb +0 -86
  140. data/spec/builtins/all_spec.rb +0 -99
  141. data/spec/builtins/and_spec.rb +0 -22
  142. data/spec/builtins/array_spec.rb +0 -16
  143. data/spec/builtins/branch_or_spec.rb +0 -27
  144. data/spec/builtins/cut_spec.rb +0 -44
  145. data/spec/builtins/fail_spec.rb +0 -5
  146. data/spec/builtins/false_spec.rb +0 -5
  147. data/spec/builtins/in_spec.rb +0 -38
  148. data/spec/builtins/is_false_spec.rb +0 -12
  149. data/spec/builtins/is_spec.rb +0 -26
  150. data/spec/builtins/matches_spec.rb +0 -23
  151. data/spec/builtins/or_spec.rb +0 -22
  152. data/spec/builtins/splits_to.rb +0 -18
  153. data/spec/builtins/then_spec.rb +0 -27
  154. data/spec/builtins/true_spec.rb +0 -5
  155. data/spec/compilation_spec.rb +0 -61
  156. data/spec/custom_classes_spec.rb +0 -43
  157. data/spec/dereference.rb +0 -10
  158. data/spec/queries_spec.rb +0 -150
  159. data/spec/recursion_spec.rb +0 -18
  160. data/spec/ruby_code_spec.rb +0 -52
  161. data/spec/rules_spec.rb +0 -97
  162. data/spec/theory_spec.rb +0 -29
  163. data/spec/variable_spec.rb +0 -26
data/bin/rubylog DELETED
@@ -1,18 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require "./lib/rubylog"
3
-
4
- files = ARGV.empty? ? Dir['./logic/**/*_logic.rb'] : Dir[*ARGV].map{|f| File.expand_path f }
5
- ARGV.clear
6
-
7
-
8
- files.each do |x|
9
- puts x
10
-
11
- require x
12
-
13
- puts
14
- end
15
-
16
-
17
-
18
-
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
@@ -1,10 +0,0 @@
1
- # Includes every builtin library required. +logic+ and +term+ builtins are
2
- # included by default.
3
- Rubylog.theory "Rubylog::DefaultBuiltins", nil do
4
- end
5
-
6
- require File.dirname(__FILE__)+"/logic"
7
- require File.dirname(__FILE__)+"/term"
8
-
9
-
10
-
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,8 +0,0 @@
1
- module Rubylog::Predicate
2
- # should yield iff the predicate is solvable eg.
3
- # def call
4
- # ...
5
- # yield if ...
6
- # ...
7
- # end
8
- 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
@@ -1,11 +0,0 @@
1
- class Class
2
- def use_theory *theories
3
- raise ArgumentError, "no theory given" if theories.empty?
4
- theories.each {|t| t.subject self }
5
- end
6
-
7
- def rubylog_functor *functors
8
- Rubylog::DSL.add_functors_to self, *functors
9
- end
10
-
11
- end
@@ -1,8 +0,0 @@
1
- class Rubylog::SimpleProcedure < Array
2
- include Rubylog::Procedure
3
-
4
- alias assertz <<
5
- alias asserta unshift
6
- end
7
-
8
-
@@ -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