cauldron 0.1.1 → 0.1.2

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 (62) hide show
  1. data/Gemfile +2 -1
  2. data/VERSION +1 -1
  3. data/features/cauldron_generates_runtime_method.feature +2 -2
  4. data/lib/Chain.rb +22 -6
  5. data/lib/UnifiedChain.rb +17 -2
  6. data/lib/cauldron.rb +3 -0
  7. data/lib/cauldron/pot.rb +50 -40
  8. data/lib/cauldron/terminal.rb +2 -2
  9. data/lib/core/ClassMethodCallContainer.rb +0 -1
  10. data/lib/core/MethodUsage.rb +0 -1
  11. data/lib/core/TheoryGenerator.rb +0 -4
  12. data/lib/core/runtime_method/RuntimeMethod.rb +1 -1
  13. data/lib/core/statement/ActsAsStatement.rb +1 -1
  14. data/lib/core/statement/Statement.rb +65 -146
  15. data/lib/core/statement/TheoryStatement.rb +1 -0
  16. data/lib/core/variable/FixnumVariable.rb +4 -5
  17. data/lib/core/variable/Unknown.rb +1 -11
  18. data/lib/core/variable/Variable.rb +1 -1
  19. data/lib/required.rb +0 -1
  20. data/lib/ruby_code/String.rb +0 -6
  21. data/lib/theory/TheoryConnector.rb +54 -117
  22. data/lib/util/ClassEvaluation.rb +9 -28
  23. data/lib/util/CodeEvaluation.rb +22 -18
  24. data/lib/util/DeclarationStatementEvaluation.rb +4 -3
  25. data/lib/util/MethodEvaluation.rb +6 -6
  26. data/lib/util/StatementCheck.rb +5 -3
  27. data/lib/util/StringToTheory.rb +0 -1
  28. data/spec/cauldron/pot_spec.rb +40 -0
  29. data/test/fixtures/theories/0/dump +0 -0
  30. data/test/fixtures/theories/1/dump +0 -0
  31. data/test/fixtures/theories/10/dump +0 -0
  32. data/test/fixtures/theories/11/dump +0 -0
  33. data/test/fixtures/theories/12/dump +0 -0
  34. data/test/fixtures/theories/13/dump +0 -0
  35. data/test/fixtures/theories/14/dump +0 -0
  36. data/test/fixtures/theories/15/dump +0 -0
  37. data/test/fixtures/theories/16/dump +0 -0
  38. data/test/fixtures/theories/17/dump +0 -0
  39. data/test/fixtures/theories/18/dump +0 -0
  40. data/test/fixtures/theories/19/dump +0 -0
  41. data/test/fixtures/theories/2/dump +0 -0
  42. data/test/fixtures/theories/20/dump +0 -0
  43. data/test/fixtures/theories/3/dump +0 -0
  44. data/test/fixtures/theories/4/dump +0 -0
  45. data/test/fixtures/theories/5/dump +0 -0
  46. data/test/fixtures/theories/6/dump +0 -0
  47. data/test/fixtures/theories/7/dump +0 -0
  48. data/test/fixtures/theories/8/dump +0 -0
  49. data/test/fixtures/theories/9/declaration.txt +1 -1
  50. data/test/fixtures/theories/9/desc +1 -1
  51. data/test/fixtures/theories/9/dump +0 -0
  52. data/test/ts_complete.rb +0 -1
  53. data/test/unit/core/runtime_method/tc_runtime_method.rb +0 -25
  54. data/test/unit/core/statement/tc_statement.rb +0 -52
  55. data/test/unit/core/tc_theory_generator.rb +2 -2
  56. data/test/unit/tc_theory.rb +2 -10
  57. data/test/unit/theory/tc_theory_action.rb +2 -6
  58. data/test/unit/util/tc_string_to_theory.rb +2 -2
  59. data/tmp/runtime_method_evaluation.rb +10 -7
  60. metadata +28 -30
  61. data/lib/core/runtime_class/IfStatementClass.rb +0 -12
  62. data/test/tc_contextual_variables.rb +0 -48
@@ -21,6 +21,7 @@ class TheoryStatement < Statement
21
21
  end
22
22
  self[i].replace_theory_variables!(mapping) if self[i].respond_to?(:replace_theory_variables!)
23
23
  end
24
+ self
24
25
  end
25
26
 
26
27
  # TODO This method was just nicked from TheoryDependent
@@ -4,15 +4,14 @@ class FixnumVariable < TypeVariable
4
4
  super(val,id)
5
5
  end
6
6
 
7
- # TODO Write test
8
7
  def to_declaration
9
8
  return VariableDeclaration.new('FixnumVariable',@value.to_declaration)
10
9
  end
11
10
 
12
- # TODO I wan't to get rid of this call entirly
13
- def copy_contextual_variable
14
- return copy
15
- end
11
+ # # TODO I wan't to get rid of this call entirly
12
+ # def copy_contextual_variable
13
+ # return copy
14
+ # end
16
15
 
17
16
  # Returns true if the variable type is Fixnum, this is used
18
17
  # to determine whether a BlockVariable or VariableContainer
@@ -1,4 +1,4 @@
1
- #require $LOC+File.join(['lib','core','variable','Variable'])
1
+
2
2
  # TODO This is not strickly a Variable - it is a data type of it's own
3
3
 
4
4
  class Unknown < BaseVariable
@@ -9,14 +9,6 @@ class Unknown < BaseVariable
9
9
  super(*requirements)
10
10
  end
11
11
 
12
- # Adds a new requirement to the unknown variable. Unlike
13
- # variables requirements can be added from outside the
14
- # instance.
15
- #
16
- def push requirement
17
- variable_push requirement
18
- end
19
-
20
12
  # Returns a typed version of the variable with the correct
21
13
  # variable id. This occurs when an Unknown variable is
22
14
  # used in a statement and its value can be determined.
@@ -36,7 +28,6 @@ class Unknown < BaseVariable
36
28
  end
37
29
  end
38
30
 
39
- # TODO Test this
40
31
  # TODO Should 'Unknown' have a variable id
41
32
  def copy
42
33
  result = self.class.new(*self) {{:variable_id => variable_id,:uniq_id=>@uniq_id,:uniq_id_history=>@uniq_id_history.copy}}
@@ -97,7 +88,6 @@ class Unknown < BaseVariable
97
88
 
98
89
  def to_var(id=nil,uniq_id=nil)
99
90
  StandardLogger.instance.warning('"Unknown" is NOT a variable - it is a data type')
100
- #super(id)
101
91
  return UnknownVariable.new(self) {{:variable_id => id,:uniq_id=>uniq_id}}
102
92
  end
103
93
 
@@ -27,7 +27,7 @@ module Variable
27
27
  def self.reset_global_id
28
28
  #http://www.zenspider.com/Languages/Ruby/QuickRef.html
29
29
  unless $".include?('test/unit.rb')
30
- StandardLogger.log 'WARNING: Resetting variable id, this should only be done for tests'
30
+ StandardLogger.instance.log 'WARNING: Resetting variable id, this should only be done for tests'
31
31
  end
32
32
  @@variable_id = 0
33
33
  @@uniq_id = 0
@@ -143,7 +143,6 @@ require $LOC+File.join(['core','runtime_class','RuntimeMethodClass'])
143
143
  require $LOC+File.join(['core','runtime_class','MethodUsageClass'])
144
144
  require $LOC+File.join(['core','runtime_class','UnknownClass'])
145
145
  require $LOC+File.join(['core','runtime_class','StatementClass'])
146
- require $LOC+File.join(['core','runtime_class','IfStatementClass'])
147
146
  require $LOC+File.join(['core','runtime_class','ReturnClass'])
148
147
  require $LOC+File.join(['core','runtime_class','RuntimeClassClass'])
149
148
  require $LOC+File.join(['core','runtime_class','DefCallClass'])
@@ -13,7 +13,6 @@ class String
13
13
  return '\''+x+'\''
14
14
  end
15
15
 
16
- # TODO Write tests
17
16
  def instance_call_structures
18
17
  return [
19
18
  InstanceCallContainerStructure.new(StringVariable,Chop.new),
@@ -28,11 +27,6 @@ class String
28
27
  return StringVariable.new(self,var_id){{:variable_id => var_id,:uniq_id=>unique_id}}
29
28
  end
30
29
 
31
- # TODO This might have been superceeded by "to_declaration"
32
- def creation
33
- return self.write
34
- end
35
-
36
30
  def to_declaration
37
31
  return LiteralDeclaration.new(self.clone)
38
32
  end
@@ -36,7 +36,7 @@ class TheoryConnector
36
36
  # Returns an array of complete chains that conclude with a valid
37
37
  # runtime method.
38
38
  #
39
- def generate_chains(runtime_method,test_cases,theories)
39
+ def generate_chains(runtime_method,test_cases,theories,exclude=[])
40
40
 
41
41
  theories = remove_irrelevant_theories(theories)
42
42
 
@@ -58,10 +58,15 @@ class TheoryConnector
58
58
  complete_chains += possible_chains.select {|x| x.complete?}
59
59
  possible_chains.delete_if {|x| x.complete?}
60
60
  end
61
- return complete_chains unless complete_chains.empty?
61
+ complete_chains = complete_chains.delete_if do |x|
62
+ exclude.any? {|y| y == x.theories_sequence}
63
+ end
64
+ unless complete_chains.empty?
65
+ return complete_chains
66
+ end
62
67
 
63
68
  possible_chains.each do |chain|
64
-
69
+
65
70
  # Remove the head theory to avoid it being re-used
66
71
  head_free_theories = theories.copy
67
72
  head_free_theories.delete_if {|theory| theory.theory_id == chain.first.theory_id}
@@ -73,56 +78,69 @@ class TheoryConnector
73
78
  end
74
79
 
75
80
  def complete_chain(chain,theories)
76
- chains = converge_chain(chain,theories)
77
- return chains
81
+ res = catch(:complete) do
82
+ converge_chain(chain,theories)
83
+ end
84
+
85
+ #return chains
86
+ return [res]
78
87
 
79
88
  end
80
89
 
81
- def converge_chain(chain,theories,step=0)
82
-
83
- complete_chains = []
84
- extended_chains = []
85
- theories.each do |theory|
86
- last_position = 1
87
- chains = chain.add_link_to(theory,last_position,[])
88
- next if chains.empty?
89
- extended_chains += chains
90
+ def remove_existing_theories(chain,theories)
91
+ theories.delete_if do |theory|
92
+ chain.theories_sequence.include?(theory.theory_id)
90
93
  end
94
+ end
95
+
96
+ def converge_chain(chain,theories,step=0)
97
+ theories = remove_existing_theories(chain.copy,theories)
91
98
 
92
- # Are any of the chains complete
93
- if extended_chains.any? {|x| x.complete? }
94
- return extended_chains.select {|x| x.complete?}
95
- end
99
+ extended_chains = add_to_chain(chain.copy,theories,step)
96
100
 
97
- closer_chains = []
98
- extended_chains.each do |x|
99
- if ((chain.unmet_dependents_ids-x.unmet_dependents_ids).length == chain.unmet_dependents_ids.length)
100
- closer_chains << x
101
- end
101
+ if extended_chains.any? {|x| x.complete? }
102
+ res2 = extended_chains.select {|x| x.complete?}
103
+ throw :complete, res2.first
102
104
  end
103
-
105
+ closer_chains = closer_chains(chain.copy,extended_chains)
106
+
107
+ complete_chains = []
104
108
  unless closer_chains.empty?
105
109
  closer_chains.each do |x|
106
110
  complete_chains += converge_chain(x,theories,step+1)
107
111
  end
108
- else
112
+ else
109
113
  extended_chains.each do |x|
110
- theories.each do |theory|
111
- copied_chain = x.copy
112
- last_position = 1
113
- chains = copied_chain.add_link_to(theory,last_position,[])
114
- chains.each do |z|
115
- if ((chain.unmet_dependents_ids-z.unmet_dependents_ids).length == chain.unmet_dependents_ids.length)
116
- complete_chains += converge_chain(z.copy,theories,step+1)
117
- end
118
- end
119
- end
114
+ complete_chains += converge_chain(x,theories,(step+1))
120
115
  end
121
116
  end
122
117
 
123
118
  return complete_chains
124
119
  end
125
120
 
121
+ def closer_chains(chain,chains)
122
+ closer_chains = []
123
+ chains.each do |x|
124
+ if ((chain.unmet_dependents_ids-x.unmet_dependents_ids).length == chain.unmet_dependents_ids.length)
125
+ closer_chains << x
126
+ end
127
+ end
128
+ return closer_chains
129
+ end
130
+
131
+ def add_to_chain(chain,theories,step)
132
+ extended_chains = []
133
+ theories.each do |theory|
134
+ last_position = 1
135
+ chains = chain.add_link_to(theory,last_position,[])
136
+
137
+ #chains = chain.extension_permutaions(theory,[])
138
+ next if chains.empty?
139
+ extended_chains += chains
140
+ end
141
+ return extended_chains
142
+ end
143
+
126
144
  def extend_chain(chain,theories)
127
145
 
128
146
  complete_chains = []
@@ -244,88 +262,6 @@ class TheoryConnector
244
262
 
245
263
  end
246
264
 
247
- # Returns a new chain so that they all use consistent theory variables ids
248
- #
249
- # @param chain An array of theories e.g.
250
- # [<#Theory>,<#Theory>,<#Theory>,<#Theory>]
251
- #
252
- # The last chain contains the finished theory.
253
- #
254
- # It is difficult to generate all the arrangements for the chain as soon as
255
- # there start to be a large number of dependents and results. There is just too
256
- # many permutations. Once any connection is decided upon e.g. this dependent to
257
- # that result then the number of permutations is reduced. As such they need to
258
- # be updated in parallet.
259
- #
260
- #
261
- #
262
- def unify_chain2(chain)
263
-
264
- unified_chains = []
265
-
266
- # Reverse the chain so that the finish is the first theory
267
- reversed_chain = chain.reverse
268
-
269
- # This method needs to map the theory variables used in one theory to the
270
- # rest. This basically means there is a global theory that has a respective
271
- # id in each of the other theories in the chain. e.g.
272
- #
273
- # +----------+--------+--------+--------+--------+
274
- # |Global #ID| link#1 | link#2 | link#3 | link#4 |
275
- # +----------+--------+--------+--------+--------+
276
- # | 0 | 1 | 1 | 2 | 89 |
277
- # +----------+--------+--------+--------+--------+
278
- # | 1 | 2 | 4 | 6 | 1 |
279
- # +----------+--------+--------+--------+--------+
280
- #
281
-
282
- # {global#ID=> #{link#1=>1,#link#2=>5}
283
-
284
- # Take the first theory and set the global theory variables to the first link
285
- global_theory_variables = {}
286
-
287
- # * Pop the first link in the chain and set ids of the theory variables
288
- link = chain.pop
289
- link.all_theory_variables.each do |theory_variable|
290
-
291
- # For the first link I'm just going to use the same id as the first link
292
- global_theory_variables[theory_variable.theory_variable_id] = {link.theory_id=>theory_variable.theory_variable_id}
293
-
294
- end
295
-
296
- # 1. Find all the dependent-> result permutations for the last chain
297
- # 2. Exclude any that are mutually exclusive
298
-
299
- #possible_global_theory_variables = extend_global_mapping(global_theory_variables,link,chain)
300
-
301
- # NOTE: Previously I had normalised the theories by working out all the possible permutations
302
- # of dependent to result. Then work out the variable substitution. This did work but
303
- # the number of permutations for larger theories meant it was completely impractical. Instead
304
- # now it needs to form one connection "dependent to result" and then update the consequence of
305
- # that. Some of the decisions will be mutually exclusive.
306
-
307
- return unified_chains
308
-
309
- end
310
-
311
- def extend_global_mapping(global_theory_variables,link,chain,results=[])
312
-
313
- next_link = chain.pop
314
-
315
- # Find all the variables in the next link thats global ids have not been determined
316
- unidentified_theory_variables = next_link.all_theory_variables.inject([]) do |total,x|
317
- total << x if global_theory_variables.any? {|key,value| !value[next_link.theory_id].nil? }
318
- end
319
-
320
- # Link the previous dependents to the this link
321
- link.dependents.each do |dependent|
322
-
323
- # Find the similar
324
-
325
- end
326
-
327
- end
328
-
329
265
  # Returns a new chain so that they all use consistent theory variables ids
330
266
  #
331
267
  def unify_chain(chain)
@@ -337,6 +273,7 @@ class TheoryConnector
337
273
  # Find all the ways the theory and results can connected
338
274
  # - the same_structure? approach is quite loose
339
275
  arrangements = chain_arrangements(chain.copy.reverse)
276
+
340
277
  # For each theory in the chain give each each variable a unique id
341
278
  starting_id = 1
342
279
  uniq_chain = chain.inject([]) do |total,x|
@@ -1,39 +1,17 @@
1
+
1
2
  # Used to make calls to a dynamically written class.
2
3
  #
3
4
  class ClassEvaluation
4
- #include WriteParameters
5
5
  @@count = 0
6
6
 
7
- def evaluate_class(runtime_class,runtime_call)
8
-
9
- # Create file to include the test method
10
- #filepath = $LOC+File.join(['tmp','runtime_class_evaluation.rb'])
11
- filepath = $LOC+File.join(['tmp',runtime_class.class_name+'.rb'])
12
- file = File.open(filepath,'w+')
13
- @@count += 1
14
-
15
- # Include the sytax for the statement in the file
16
- file << runtime_class.write
17
- file.close
18
-
19
- # Load the newly created class and check the statement
20
- load filepath
21
- begin
22
- return eval("#{runtime_class.class_name}.new.#{runtime_call}")
23
- rescue NameError => e
24
- StandardLogger.instance.info(runtime_class.write)
25
- raise e
26
- end
27
-
7
+ def evaluate_class(runtime_class,runtime_call)
8
+ return evaluate_class_2(runtime_class,runtime_call)
28
9
  end
29
10
 
30
- # TODO This duplicates allot of the code above
31
11
  def evaluate_class_2(runtime_class,runtime_call,*params)
32
12
 
33
13
  # Create file to include the test method
34
- #filepath = $LOC+File.join(['tmp','runtime_class_evaluation.rb'])
35
- filepath = $LOC+File.join(['tmp',runtime_class.class_name+'.rb'])
36
- file = File.open(filepath,'w+')
14
+ file = Tempfile.new(runtime_class.class_name+'.rb')
37
15
  @@count += 1
38
16
 
39
17
  # Include the sytax for the statement in the file
@@ -41,7 +19,7 @@ class ClassEvaluation
41
19
  file.close
42
20
 
43
21
  # Load the newly created class and check the statement
44
- load filepath
22
+ load file.path
45
23
  begin
46
24
  # TODO Make this more generic
47
25
  case params.length
@@ -55,7 +33,10 @@ class ClassEvaluation
55
33
  rescue NameError => e
56
34
  StandardLogger.instance.info(runtime_class.write)
57
35
  raise e
58
- end
36
+ ensure
37
+ file.close
38
+ file.unlink
39
+ end
59
40
 
60
41
  end
61
42
 
@@ -11,25 +11,29 @@ class CodeEvaluation
11
11
  def evaluate_code(code)
12
12
  @@COUNT += 1
13
13
 
14
- # Create file to include the test method
15
- filepath = $LOC+File.join(['tmp',"runtime_code_evaluation_#{@@COUNT}.rb"])
16
- file = File.open(filepath,'w+')
17
-
18
- # Include the sytax for the statement in the file
19
- file << "class RuntimeCodeEvaluation#{@@COUNT}"+"\n"
20
- file << "\t"+'def check'+"\n"
21
- code.each_line do |l|
22
- file << "\t\t"+l+"\n"
14
+ begin
15
+
16
+ # Create file to include the test method
17
+ file = Tempfile.new("runtime_code_evaluation_#{@@COUNT}.rb")
18
+
19
+ # Include the sytax for the statement in the file
20
+ file << "class RuntimeCodeEvaluation#{@@COUNT}"+"\n"
21
+ file << "\t"+'def check'+"\n"
22
+ code.each_line do |l|
23
+ file << "\t\t"+l+"\n"
24
+ end
25
+ file << "\t"+'end'+"\n"
26
+ file << 'end'
27
+ file.close
28
+
29
+ # Load the newly created class and check the statement
30
+ load file.path
31
+
32
+ return eval("RuntimeCodeEvaluation#{@@COUNT}.new.check")
33
+ ensure
34
+ file.close
35
+ file.unlink
23
36
  end
24
- file << "\t"+'end'+"\n"
25
- file << 'end'
26
- file.close
27
-
28
- # Load the newly created class and check the statement
29
- load filepath
30
-
31
- return eval("RuntimeCodeEvaluation#{@@COUNT}.new.check")
32
-
33
37
  end
34
38
 
35
39
  end
@@ -4,8 +4,7 @@ class DeclarationStatementEvaluation
4
4
  def evaluate(written_statement,runtime_methods=[])
5
5
 
6
6
  # Create file to include the test method
7
- filepath = $LOC+File.join(['tmp','runtime_declaration_statement_evaluation.rb'])
8
- file = File.open(filepath,'w+')
7
+ file = Tempfile.new("runtime_declaration_statement_evaluation.rb")
9
8
 
10
9
  # Include the sytax for the statement in the file
11
10
  file << 'class RuntimeDeclarationStatementEvaluation'+"\n"
@@ -25,7 +24,9 @@ class DeclarationStatementEvaluation
25
24
  load filepath
26
25
  return RuntimeDeclarationStatementEvaluation.new.check
27
26
 
28
-
27
+ ensure
28
+ file.close
29
+ file.unlink
29
30
  end
30
31
 
31
32
  end