cauldron 0.1.2 → 0.1.3

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 (132) hide show
  1. data/Gemfile +6 -0
  2. data/Gemfile.lock +63 -0
  3. data/History.md +5 -0
  4. data/Rakefile +62 -16
  5. data/VERSION +1 -1
  6. data/cauldron.gemspec +463 -0
  7. data/cauldron/lib/cauldron.rb +1 -1
  8. data/features/cauldron_generates_runtime_method.feature +7 -4
  9. data/features/cauldron_generates_single_paramter_methods.feature +25 -0
  10. data/features/cauldron_interactive_start_terminal.feature +17 -0
  11. data/features/cauldron_quit_terminal.feature +9 -0
  12. data/features/cauldron_start_terminal.feature +0 -1
  13. data/features/step_definitions/cauldron_steps.rb +10 -5
  14. data/features/step_definitions/terminal_steps.rb +27 -0
  15. data/features/support/env.rb +2 -0
  16. data/features/support/hooks.rb +15 -0
  17. data/lib/Chain.rb +3 -3
  18. data/lib/Mapping.rb +1 -0
  19. data/lib/PartialChain.rb +253 -0
  20. data/lib/Theory.rb +28 -4
  21. data/lib/UnifiedChain.rb +94 -125
  22. data/lib/cauldron.rb +3 -0
  23. data/lib/cauldron/demos.rb +4 -4
  24. data/lib/cauldron/env.rb +1 -0
  25. data/lib/cauldron/pot.rb +42 -38
  26. data/lib/cauldron/terminal.rb +19 -3
  27. data/lib/cauldron/util/home.rb +21 -0
  28. data/lib/cauldron/util/saver.rb +45 -0
  29. data/lib/core/Container.rb +1 -1
  30. data/lib/core/runtime_method/ActsAsRuntimeMethod.rb +28 -28
  31. data/lib/core/runtime_method/RuntimeMethod.rb +6 -23
  32. data/lib/core/statement/ActsAsStatement.rb +0 -96
  33. data/lib/core/statement/BlockStatement.rb +1 -1
  34. data/lib/core/statement/OpenStatement.rb +1 -1
  35. data/lib/core/statement/Statement.rb +39 -94
  36. data/lib/core/statement/TheoryStatement.rb +1 -1
  37. data/lib/core/syntax/BlockContainer.rb +0 -28
  38. data/lib/core/variable/MethodParameter.rb +1 -1
  39. data/lib/required.rb +2 -14
  40. data/lib/theories.rb +0 -1
  41. data/lib/theory/ActionImplementation.rb +1 -1
  42. data/lib/theory/TheoryAction.rb +2 -2
  43. data/lib/theory/TheoryConnector.rb +11 -14
  44. data/lib/theory/TheoryImplementation.rb +10 -9
  45. data/lib/util/MethodWriter.rb +10 -10
  46. data/sandbox.rb +23 -0
  47. data/spec/cauldron/pot_spec.rb +62 -10
  48. data/spec/cauldron/runtime_method_spec.rb +31 -17
  49. data/spec/cauldron/saver_spec.rb +45 -0
  50. data/spec/cauldron/terminal_spec.rb +10 -1
  51. data/spec/cauldron/theory_spec.rb +4 -4
  52. data/spec/cauldron/unified_chain_spec.rb +38 -0
  53. data/spec/spec_helper.rb +3 -1
  54. data/tasks/development_tasks.rake +4 -0
  55. data/tasks/theory_tasks.rake +16 -20
  56. data/test/fixtures/theories/0/desc +6 -6
  57. data/test/fixtures/theories/0/dump +0 -0
  58. data/test/fixtures/theories/1/desc +7 -7
  59. data/test/fixtures/theories/1/dump +0 -0
  60. data/test/fixtures/theories/10/desc +13 -13
  61. data/test/fixtures/theories/10/dump +0 -0
  62. data/test/fixtures/theories/11/desc +10 -10
  63. data/test/fixtures/theories/11/dump +0 -0
  64. data/test/fixtures/theories/12/desc +9 -9
  65. data/test/fixtures/theories/12/dump +0 -0
  66. data/test/fixtures/theories/13/desc +16 -16
  67. data/test/fixtures/theories/13/dump +0 -0
  68. data/test/fixtures/theories/14/desc +16 -16
  69. data/test/fixtures/theories/14/dump +0 -0
  70. data/test/fixtures/theories/15/desc +10 -10
  71. data/test/fixtures/theories/15/dump +0 -0
  72. data/test/fixtures/theories/16/desc +10 -10
  73. data/test/fixtures/theories/16/dump +0 -0
  74. data/test/fixtures/theories/17/desc +7 -7
  75. data/test/fixtures/theories/17/dump +0 -0
  76. data/test/fixtures/theories/18/desc +7 -7
  77. data/test/fixtures/theories/18/dump +0 -0
  78. data/test/fixtures/theories/19/desc +7 -7
  79. data/test/fixtures/theories/19/dump +0 -0
  80. data/test/fixtures/theories/2/desc +6 -6
  81. data/test/fixtures/theories/2/dump +0 -0
  82. data/test/fixtures/theories/20/desc +13 -13
  83. data/test/fixtures/theories/20/dump +0 -0
  84. data/test/fixtures/theories/3/desc +7 -7
  85. data/test/fixtures/theories/3/dump +0 -0
  86. data/test/fixtures/theories/4/desc +7 -7
  87. data/test/fixtures/theories/4/dump +0 -0
  88. data/test/fixtures/theories/5/desc +6 -6
  89. data/test/fixtures/theories/5/dump +0 -0
  90. data/test/fixtures/theories/6/desc +7 -7
  91. data/test/fixtures/theories/6/dump +0 -0
  92. data/test/fixtures/theories/7/desc +7 -7
  93. data/test/fixtures/theories/7/dump +0 -0
  94. data/test/fixtures/theories/8/desc +7 -7
  95. data/test/fixtures/theories/8/dump +0 -0
  96. data/test/fixtures/theories/9/desc +16 -16
  97. data/test/fixtures/theories/9/dump +0 -0
  98. data/test/fixtures/theory_implementations/0/dump +0 -0
  99. data/test/fixtures/theory_implementations/2/dump +0 -0
  100. data/test/ts_complete.rb +1 -10
  101. data/test/unit/core/runtime_method/tc_realised_runtime_method.rb +1 -0
  102. data/test/unit/core/runtime_method/tc_runtime_method.rb +16 -39
  103. data/test/unit/core/statement/tc_block_statement.rb +3 -3
  104. data/test/unit/core/statement/tc_open_statement.rb +4 -4
  105. data/test/unit/core/statement/tc_statement.rb +2 -147
  106. data/test/unit/core/statement/tc_theory_statement.rb +1 -1
  107. data/test/unit/theory/tc_theory_dependent.rb +3 -3
  108. data/test/unit/theory/tc_theory_result.rb +5 -5
  109. data/test/unit/util/tc_method_validation.rb +45 -45
  110. data/test/unit/util/tc_parser.rb +1 -1
  111. data/test/unit/util/tc_string_to_theory.rb +2 -2
  112. metadata +74 -48
  113. data/lib/ScopeDependencies.rb +0 -8
  114. data/lib/core/statement/StatementDependencies.rb +0 -271
  115. data/lib/core/structure/DeclareNewInstanceStructure.rb +0 -49
  116. data/lib/core/structure/DeclareRuntimeMethodStructure.rb +0 -34
  117. data/lib/core/structure/DeclareVariableAsLiteralStructure.rb +0 -31
  118. data/lib/core/structure/DeclareVariableAsVariableStructure.rb +0 -52
  119. data/lib/core/structure/FixnumAdditionStructure.rb +0 -56
  120. data/lib/core/structure/InstanceCallContainerStructure.rb +0 -50
  121. data/lib/core/structure/InstanceCallStructure.rb +0 -53
  122. data/lib/core/structure/InstanceMethodCallStructure.rb +0 -21
  123. data/lib/core/structure/ReturnStructure.rb +0 -20
  124. data/lib/core/structure/StatementStructure.rb +0 -11
  125. data/test/unit/core/statement/tc_statement_dependencies.rb +0 -147
  126. data/test/unit/core/structure/tc_declare_new_instance_structure.rb +0 -41
  127. data/test/unit/core/structure/tc_declare_variable_as_literal_structure.rb +0 -41
  128. data/test/unit/core/structure/tc_declare_variable_as_variable_structure.rb +0 -66
  129. data/test/unit/core/structure/tc_instance_call_container_structure.rb +0 -41
  130. data/test/unit/core/structure/tc_return_structure.rb +0 -32
  131. data/test/unit/tc_instance_call_structure.rb +0 -35
  132. data/test/unit/tc_statement_structure_2.rb +0 -43
@@ -6,15 +6,14 @@ class Theory
6
6
 
7
7
  attr_accessor :theory_instance_id
8
8
 
9
- @@theory_id = 0
9
+ @@theory_id = nil
10
10
  #
11
11
  # @param example_runtime_method A runtime method instance with this theories action applied to it and
12
12
  # which meets the theories dependents with a certain set of test cases.
13
13
  #
14
14
  def initialize(dependents,action,results,example_runtime_method=nil)
15
15
  @dependents, @action, @results, @example_runtime_method = dependents, action, results, example_runtime_method
16
- @theory_id = @@theory_id
17
- @@theory_id += 1
16
+ @theory_id = Theory.next_theory_id
18
17
  end
19
18
 
20
19
  def copy
@@ -22,6 +21,31 @@ class Theory
22
21
  return Marshal.load(Marshal.dump(self))
23
22
  end
24
23
 
24
+ def self.next_theory_id
25
+ if @@theory_id.nil?
26
+ FileUtils.mkdir(theories_directory) unless File.exists?(theories_directory)
27
+ highest_integer = 0
28
+ Dir.glob(File.join(theories_directory,'*')).each do |filename|
29
+ if filename.match(/(\d+)/)
30
+ highest_integer = $1.to_i if $1.to_i > highest_integer
31
+ end
32
+ end
33
+ @@theory_id = highest_integer
34
+ end
35
+ @@theory_id += 1
36
+ return @@theory_id
37
+ end
38
+
39
+ def self.theories_directory
40
+ # the home directory code is duplicated
41
+ realHome = ["HOME", "HOMEPATH"].detect {|h| ENV[h] != nil}
42
+ if not realHome
43
+ StandardLogger.instance.warning "Couldn't detect a home directory"
44
+ end
45
+ # => TODO Should use proper version
46
+ return File.join(ENV[realHome],'cauldron','0-1-1','theories')
47
+ end
48
+
25
49
  def irrelevant?
26
50
  dependents.empty? and results.empty? and action.nil?
27
51
  end
@@ -239,7 +263,7 @@ class Theory
239
263
  end
240
264
 
241
265
  def highlight(component_ids=[])
242
- # @log.error("\033[0;31m\ "+msg+"\033[00m\ ")
266
+
243
267
  # Describe the despendencies
244
268
  description = 'if: '+"\n"
245
269
  @dependents.inject(description) do |description, x|
@@ -2,11 +2,19 @@
2
2
  # chain there is no mapping, all the theories should have the correct ids if they are
3
3
  # linked. A unified chain is always complete.
4
4
  #
5
- class UnifiedChain < Chain
6
- # TODO I don't like that extending to Chain exposes the @nodes to public access
7
-
8
- def initialize(nodes)
5
+ class UnifiedChain
6
+
7
+ attr_reader :connections
8
+
9
+ def initialize(nodes,connections)
9
10
  @nodes = nodes
11
+ #pp connections
12
+
13
+ @connections = connections
14
+ @variable_keys = connections.mapping.keys
15
+ #pp @variable_keys
16
+
17
+ raise StandardError.new('chain is not complete ') unless self.complete?
10
18
  end
11
19
 
12
20
  def write(tab=0)
@@ -17,6 +25,11 @@ class UnifiedChain < Chain
17
25
  return @nodes.inject('') {|total,x| total += x.describe}
18
26
  end
19
27
 
28
+ def copy
29
+ #return Chain.new(@nodes.copy)
30
+ return Marshal.load(Marshal.dump(self))
31
+ end
32
+
20
33
  # Returns an array of all the theory variables in the chain. All the
21
34
  # theory variables should be global across the chain.
22
35
  #
@@ -48,38 +61,37 @@ class UnifiedChain < Chain
48
61
 
49
62
  def valid_mapping_permutations(runtime_method,test_cases)
50
63
 
64
+ # puts '-------------------------------'
65
+ # puts Cauldron::Util::Saver.save(runtime_method)
66
+ # puts Cauldron::Util::Saver.save(test_cases)
67
+ # puts '-------------------------------'
51
68
  # Get the initially available intrinsic values
52
69
  intrinsic_values = [IntrinsicRuntimeMethod.new,IntrinsicTestCases.new]
53
70
 
54
71
  total_variables = self.theory_variables.length
55
72
 
56
73
  available_values = [IntrinsicRuntimeMethod.new,IntrinsicTestCases.new]
74
+
75
+ valid_mappings = [{}]
57
76
 
58
- valid_mappings = [Mapping.new]
59
-
60
- #itteration_limit = 6
61
77
  itteration_limit = 9
62
78
 
63
79
  @nodes.each_with_index do |node,index|
64
-
65
- node.dependents.each do |dependent|
66
- if index == 0
67
- chain = partial_chain(0)
68
- else
69
- chain = partial_chain(index-1)
70
- end
71
- limit = 0
72
- until has_all_variables_been_found?(dependent,valid_mappings) or limit > itteration_limit
73
- valid_mappings = extend_mapping(valid_mappings,dependent,runtime_method.copy,test_cases.copy,chain,available_values)
74
- limit += 1
75
- end
76
- end
80
+
81
+ valid_mappings = extend_value_mapping_wtih_dependents(
82
+ valid_mappings,
83
+ index,
84
+ node,
85
+ available_values,
86
+ test_cases.copy,
87
+ runtime_method.copy
88
+ )
77
89
 
78
90
  unless node.action.nil?
79
91
  if index == 0
80
- chain = partial_chain(0)
92
+ chain = partial_chain(1..0)
81
93
  else
82
- chain = partial_chain(index-1)
94
+ chain = partial_chain(1..(index-1))
83
95
  end
84
96
  limit = 0
85
97
  until has_all_variables_been_found?(node.action,valid_mappings) or limit > itteration_limit
@@ -87,20 +99,13 @@ class UnifiedChain < Chain
87
99
  limit += 1
88
100
  end
89
101
  if limit > itteration_limit
90
- pp missing_variables(node.action,valid_mappings)
102
+ puts 'Chain saved '+Cauldron::Util::Saver.save(self)
103
+ puts 'Is chain complete: '+complete?.to_s
91
104
  raise StandardError.new('Unable to resolve action: '+"\n"+node.action.write)
92
105
  end
93
106
  end
94
107
 
95
- node.results.each do |result|
96
- chain = partial_chain(index)
97
- limit = 0
98
- until has_all_variables_been_found?(result,valid_mappings) or limit > itteration_limit
99
- valid_mappings = extend_mapping(valid_mappings,result,runtime_method.copy,test_cases.copy,chain,available_values)
100
- limit += 1
101
- end
102
-
103
- end
108
+ valid_mappings = extend_value_mapping_with_result(valid_mappings,index,node,available_values,test_cases.copy,runtime_method.copy)
104
109
 
105
110
  end
106
111
 
@@ -108,37 +113,52 @@ class UnifiedChain < Chain
108
113
 
109
114
  end
110
115
 
111
- def has_all_variables_been_found?(component,mappings)
112
- component.theory_variables.each do |var|
113
- mappings.each do |mapping|
114
- return false unless mapping.has_key? var.theory_variable_id
116
+ def extend_value_mapping_with_result(valid_mappings,index,node,available_values,test_cases,runtime_method)
117
+ itteration_limit = 3
118
+ node.results.each do |result|
119
+ chain = partial_chain(0..index)
120
+ limit = 0
121
+ until has_all_variables_been_found?(result,valid_mappings) or limit > itteration_limit
122
+ valid_mappings = extend_mapping(valid_mappings,result,runtime_method.copy,test_cases.copy,chain,available_values)
123
+ limit += 1
115
124
  end
116
- end
117
- return true
125
+ end
126
+ return valid_mappings
118
127
  end
119
128
 
120
- def missing_variables(component,mappings)
121
- results = []
129
+ def extend_value_mapping_wtih_dependents(valid_mappings,index,node,available_values,test_cases,runtime_method)
130
+ itteration_limit = 6
131
+ node.dependents.each do |dependent|
132
+ if index == 0
133
+ chain = partial_chain(0..0)
134
+ else
135
+ chain = partial_chain(1..(index-1))
136
+ end
137
+ limit = 0
138
+ until has_all_variables_been_found?(dependent,valid_mappings) or limit > itteration_limit
139
+ valid_mappings = extend_mapping(valid_mappings,dependent,runtime_method.copy,test_cases.copy,chain,available_values)
140
+ limit += 1
141
+ end
142
+ end
143
+ return valid_mappings
144
+ end
145
+
146
+ def has_all_variables_been_found?(component,mappings)
122
147
  component.theory_variables.each do |var|
123
- mappings.each do |mapping|
124
- #return false unless mapping.has_key? var.theory_variable_id
125
- results << var unless mapping.has_key? var.theory_variable_id
148
+ mappings.each do |m|
149
+ return false unless m.has_key?(var.theory_variable_id)
126
150
  end
127
151
  end
128
- return results
152
+ return true
129
153
  end
130
154
 
131
155
  def extend_mapping(valid_mappings,component,runtime_method,test_cases,chain,available_values)
132
156
 
133
157
  new_mappings = []
134
158
  component.theory_variables.each do |var|
135
- next if valid_mappings.first.has_key?(var.theory_variable_id)
136
- #next if valid_mappings.any? {|x| x.has_key?(var.theory_variable_id)}
159
+
137
160
  valid_mappings.each do |mapping|
138
-
139
- #next if mapping.has_key?(var.theory_variable_id)
140
161
 
141
- #next if mapping.has_key?(var.theory_variable_id)
142
162
  implemented_chain = chain.implement(Mapping.new(mapping))
143
163
  implemented_runtime_method = TheoryChainValidator.new.build_method_from_chain(
144
164
  implemented_chain,runtime_method.copy,test_cases.copy
@@ -146,14 +166,14 @@ class UnifiedChain < Chain
146
166
 
147
167
  possible_values = available_values-mapping.values
148
168
  begin
149
- values = intrinsic_values_for_variable(
150
- var.theory_variable_id,
151
- component,
152
- mapping,
153
- implemented_runtime_method,
154
- test_cases.copy,
155
- possible_values
156
- )
169
+ values = intrinsic_values_for_variable(
170
+ var.theory_variable_id,
171
+ component,
172
+ mapping,
173
+ implemented_runtime_method,
174
+ test_cases.copy,
175
+ possible_values
176
+ )
157
177
  rescue NoMethodError => e
158
178
  valid_mappings = valid_mappings-[mapping]
159
179
  next
@@ -254,13 +274,6 @@ class UnifiedChain < Chain
254
274
  end
255
275
  values += index_values
256
276
 
257
- #variable_values = []
258
- #result.statements_with_variable(var.theory_variable_id).each do |statement|
259
- #variable_values += values_for_variable_as_argument(var,statement,mapping,intrinsic_values,implemented_runtime_method.copy,test_cases.copy)
260
- #end
261
- #values += variable_values
262
-
263
- #intrinsic_statement = statement.map_to(mapping)
264
277
  variable_values = []
265
278
  intrinsic_values.each do |value|
266
279
  literal = intrinsic_statement.write.gsub(/var(\d)+/,value.write)
@@ -271,19 +284,18 @@ class UnifiedChain < Chain
271
284
  next
272
285
  end
273
286
  end
274
- #return results
275
287
  values += variable_values
276
288
 
277
-
278
289
  end
279
290
  return values
280
291
  end
281
292
 
282
- def partial_chain(limit)
283
- links = @nodes[1..limit].collect {|x| x.copy }
284
- UnifiedChain.new(links)
293
+ def partial_chain(range)
294
+ links = @nodes[range].collect {|x| x.copy }
295
+ PartialChain.new(links)
285
296
  end
286
297
 
298
+ # => TODO This might not be need - use cucumber to check
287
299
  def mapping_permutations(keys,values)
288
300
  values.permutation(keys.length).to_a.inject([]) do |total,value_permutation|
289
301
  total << Hash[*keys.zip(value_permutation).flatten]
@@ -316,67 +328,24 @@ class UnifiedChain < Chain
316
328
  # @param test_cases The test cases instance containing real values.
317
329
  #
318
330
  def implementation_permuatations(runtime_method,test_cases,mapping)
319
-
320
331
  return implementation_permuatations2(runtime_method,test_cases,mapping)
321
-
322
- # Determine the number of variables without intrinsic values
323
- theory_variable_ids = theory_variables.collect {|x| x.theory_variable_id}
324
-
325
- # Collect the theory variables without intrinsic values
326
- missing_intrinsic_values = theory_variable_ids-mapping.keys
327
-
328
- # Take the first theory and identify all the accessors
329
- # (need to work out what is the runtime method and what the test cases)
330
-
331
- # TEMP: Why are these implemented theories
332
- # @nodes.first.all_theory_variables
333
-
334
- # Create the theory generator
335
- generator = TheoryGenerator.new()
336
-
337
- #accessors, temp_mapping = generator.generate_accessors_and_mapping(test_cases,runtime_method,1)
338
- accessors, temp_mapping = generator.generate_accessors_and_mapping(test_cases,runtime_method,3)
339
-
340
- if temp_mapping.length > missing_intrinsic_values.length
332
+ end
333
+
334
+ # TODO This is a temporary method while I work out how incomplete? chains are being created
335
+ def complete?
336
+ @nodes.each do |node|
341
337
 
342
- # Now to assign real values to the chain
343
-
344
- # Apply the values in the various permutaions
345
- # (this is very crude and means that odd calls )
346
- #theory_variable_ids = @nodes.first.all_theory_variables.collect {|x| x.theory_variable_id }
338
+ # Exclude the current node being considered
339
+ filtered_nodes = TheoryCollection.new(@nodes.copy - [node])
347
340
 
348
- theory_variable_ids = self.theory_variables.collect {|x| x.theory_variable_id }
349
-
350
- # Get the posible sets for values in an array so that non of the arrays contain all the same values
351
- res = temp_mapping.values.collect {|x| x}
352
-
353
- # TODO This is a complete hack but I think I should be using intrinsic values rather than real
354
- intrinsic_res = res.collect {|x| x.to_intrinsic}
355
- value_permutaions = intrinsic_res.permutation(theory_variable_ids.length).to_a
356
- uniq_value_permutations = value_permutaions.collect {|x| x.to_set}.uniq
357
- possible_mappings = []
358
-
359
- theory_variable_id_permutations = theory_variable_ids.permutation(theory_variable_ids.length).to_a
360
-
361
- possible_mappings = []
362
- theory_variable_id_permutations.each do |theory_variable_id_permutation|
363
- uniq_value_permutations.each do |value_permutation|
364
- m = Mapping.new
365
- theory_variable_id_permutation.zip(value_permutation.to_a) do |key,value|
366
- m[key] = value
367
- end
368
- possible_mappings << m
369
- end
370
-
341
+ node.dependents.each do |dependent|
342
+ unless filtered_nodes.results.any? {|result| result.write == dependent.write}
343
+ return false
344
+ end
371
345
  end
372
346
 
373
- # Implemented changes
374
- return possible_mappings.inject([]) { |total,mapping| total << self.copy.implement(mapping) }
375
-
376
- else
377
- raise StandardError.new('Could not generate enough real vlaues to test theory - try increasing the itterations')
378
347
  end
379
-
380
- end
348
+ return true
349
+ end
381
350
 
382
351
  end
@@ -1,6 +1,9 @@
1
1
  require 'rubygems'
2
2
  require 'tempfile'
3
3
 
4
+ require 'cauldron/util/home'
5
+ require 'cauldron/util/saver'
6
+
4
7
  require 'required'
5
8
 
6
9
  require 'cauldron/sexp2cauldron'
@@ -31,7 +31,7 @@ module Cauldron
31
31
 
32
32
  # Create demo #1 chain
33
33
  # Create the head for the chain
34
- head = Theory.new([],nil,[])
34
+ head = Theory.new([],nil,[])
35
35
 
36
36
  link_one_action = TheoryAction.new(
37
37
  TheoryStatement.new(StringToTheory.run('Statement.new(Return.new,var1.params[var3])')),
@@ -58,7 +58,7 @@ module Cauldron
58
58
  # TODO It should generate the values too.(TheoryGenerator)
59
59
  return {
60
60
  :initial_method=>RuntimeMethod.new(MethodUsage.new(MethodParameter.new)),
61
- :test_cases=>@demo_1_test_cases,
61
+ :test_cases=>@demo_1_test_cases.copy,
62
62
  :chain=>chain,
63
63
  :values=>{}
64
64
  }
@@ -73,7 +73,7 @@ module Cauldron
73
73
  [['carrot'],'vegtable'],
74
74
  ]
75
75
  )
76
- head = Theory.new([],nil,[])
76
+ # => head = Theory.new([],nil,[])
77
77
 
78
78
  # Statementents
79
79
  # => TODO Need a clear way to format theories
@@ -268,7 +268,7 @@ module Cauldron
268
268
 
269
269
  return {
270
270
  :initial_method=>RuntimeMethod.new(MethodUsage.new(MethodParameter.new)),
271
- :test_cases=>@demo_2_test_cases,
271
+ :test_cases=>@demo_2_test_cases.copy,
272
272
  :chain=>chain,
273
273
  :values=>{}
274
274
  }
@@ -0,0 +1 @@
1
+ TAB = ' '
@@ -1,7 +1,10 @@
1
1
  module Cauldron
2
2
 
3
3
  class Pot
4
- include ContainsTheories
4
+
5
+ include Cauldron::Util::Home
6
+ include ContainsTheories
7
+
5
8
 
6
9
  VERSION = '0-1-1'
7
10
 
@@ -9,35 +12,48 @@ module Cauldron
9
12
  StandardLogger.instance.level = Logger::FATAL
10
13
  end
11
14
 
15
+ # Returns a runtime method that meets the requirements of the test cases.
12
16
  def brew(test_cases)
13
17
 
14
18
  exclude = []
15
- chain = next_chain(test_cases,exclude)
16
- if chain.nil?
17
- raise StandardError.new('Failed to generate a chain for this problem')
19
+ chains = next_chains(test_cases,exclude)
20
+ if chains.empty?
21
+ raise StandardError.new('Failed to generate a chain for this problem A')
18
22
  end
19
23
 
20
24
  runtime_method = RuntimeMethod.new(MethodUsage.new(MethodParameter.new))
21
- if chain_valid?(chain,test_cases.copy)
22
- validator = TheoryChainValidator.new
23
- unified_chain = chain.unify_chain
24
- implementation_permutations = unified_chain.implementation_permuatations(runtime_method.copy,test_cases.copy,Mapping.new)
25
- return validator.build(runtime_method.copy,test_cases.copy,implementation_permutations)
26
- else
27
- exclude << chain.theories_sequence
28
- chain = next_chain(test_cases,exclude)
25
+ chains.each do |chain|
29
26
  if chain_valid?(chain,test_cases.copy)
30
27
  validator = TheoryChainValidator.new
31
28
  unified_chain = chain.unify_chain
32
29
  implementation_permutations = unified_chain.implementation_permuatations(runtime_method.copy,test_cases.copy,Mapping.new)
33
30
  return validator.build(runtime_method.copy,test_cases.copy,implementation_permutations)
34
- end
31
+ end
32
+ end
33
+ chains.each do |chain|
34
+ exclude << chain.theories_sequence
35
35
  end
36
- return nil
36
+
37
+ chains = next_chains(test_cases,exclude)
38
+ if chains.empty?
39
+ raise StandardError.new('Failed to generate a chain for this problem')
40
+ end
41
+ chains.each do |chain|
42
+ if chain_valid?(chain,test_cases.copy)
43
+ validator = TheoryChainValidator.new
44
+ unified_chain = chain.unify_chain
45
+ implementation_permutations = unified_chain.implementation_permuatations(runtime_method.copy,test_cases.copy,Mapping.new)
46
+ return validator.build(runtime_method.copy,test_cases.copy,implementation_permutations)
47
+ end
48
+ end
49
+ raise StandardError.new('Failed to generate a valid runtime method C '+chains.length.to_s)
37
50
 
38
51
  end
39
52
 
40
53
  def chain_valid?(chain,test_cases)
54
+ if chain.kind_of?(Array)
55
+ raise StandardError.new('should be a chain '+chain.first.class.to_s)
56
+ end
41
57
  runtime_method = RuntimeMethod.new(MethodUsage.new(MethodParameter.new))
42
58
  unified_chain = chain.unify_chain
43
59
  implementation_permutations = unified_chain.implementation_permuatations(runtime_method.copy,test_cases.copy,Mapping.new)
@@ -53,16 +69,10 @@ module Cauldron
53
69
  return true
54
70
  end
55
71
 
56
- def complete_chains(test_cases)
57
- return [next_chain(test_cases)]
58
- end
59
-
60
- def next_chain(test_cases,exclude=[])
61
-
62
- theories = saved_theories
72
+ def next_chains(test_cases,exclude=[])
73
+ theories = saved_theories
63
74
 
64
75
  res = theories.collect {|x| x.theory_id }
65
-
66
76
  runtime_method = RuntimeMethod.new(MethodUsage.new(MethodParameter.new))
67
77
 
68
78
  potential_values = MappingValues.new([])
@@ -70,13 +80,16 @@ module Cauldron
70
80
 
71
81
  # Attempt to generate a complete chain for the solution
72
82
  chains = connector.generate_chains(runtime_method,test_cases,theories,exclude)
73
- return chains.first
74
-
75
- end
83
+ return chains
84
+ end
76
85
 
77
86
  def saved_theories
78
- saved_theory_file_paths = Dir.glob(File.join(theory_repository_path,'*','dump'))
79
- saved_theory_file_paths.collect {|x| Marshal.load(File.open(x,'r'))}
87
+ # => TODO This needs to cached to prevent error
88
+ if @cached_saved_theories.nil?
89
+ saved_theory_file_paths = Dir.glob(File.join(theory_repository_path,'*','dump'))
90
+ @cached_saved_theories = saved_theory_file_paths.collect {|x| Marshal.load(File.open(x,'r'))}
91
+ end
92
+ @cached_saved_theories
80
93
  end
81
94
 
82
95
  def simmer(demo)
@@ -122,15 +135,6 @@ module Cauldron
122
135
  end
123
136
 
124
137
  private
125
-
126
- # Check that the home directory exists
127
- def home
128
- realHome = ["HOME", "HOMEPATH"].detect {|h| ENV[h] != nil}
129
- if not realHome
130
- StandardLogger.instance.warning "Couldn't detect a home directory"
131
- end
132
- return ENV[realHome]
133
- end
134
138
 
135
139
  # Saves the generic theory to file. This theory will have minimal
136
140
  # dependents and results.
@@ -140,8 +144,8 @@ module Cauldron
140
144
  # Define the theory's directory
141
145
  theory_path = File.join(repository,theory.theory_id.to_s)
142
146
  if File.exists?(theory_path)
143
- puts theory_path+' already exists'
144
- #raise StandardError.new('Directory already exists - how as this happened?') if File.exists?(theory_path)
147
+ StandardLogger.instance.warning theory_path+' already exists'
148
+ #raise StandardError.new('Directory already exists - how as this happened? '+theory.theory_id.to_s) if File.exists?(theory_path)
145
149
  return
146
150
  end
147
151