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.
- data/Gemfile +6 -0
- data/Gemfile.lock +63 -0
- data/History.md +5 -0
- data/Rakefile +62 -16
- data/VERSION +1 -1
- data/cauldron.gemspec +463 -0
- data/cauldron/lib/cauldron.rb +1 -1
- data/features/cauldron_generates_runtime_method.feature +7 -4
- data/features/cauldron_generates_single_paramter_methods.feature +25 -0
- data/features/cauldron_interactive_start_terminal.feature +17 -0
- data/features/cauldron_quit_terminal.feature +9 -0
- data/features/cauldron_start_terminal.feature +0 -1
- data/features/step_definitions/cauldron_steps.rb +10 -5
- data/features/step_definitions/terminal_steps.rb +27 -0
- data/features/support/env.rb +2 -0
- data/features/support/hooks.rb +15 -0
- data/lib/Chain.rb +3 -3
- data/lib/Mapping.rb +1 -0
- data/lib/PartialChain.rb +253 -0
- data/lib/Theory.rb +28 -4
- data/lib/UnifiedChain.rb +94 -125
- data/lib/cauldron.rb +3 -0
- data/lib/cauldron/demos.rb +4 -4
- data/lib/cauldron/env.rb +1 -0
- data/lib/cauldron/pot.rb +42 -38
- data/lib/cauldron/terminal.rb +19 -3
- data/lib/cauldron/util/home.rb +21 -0
- data/lib/cauldron/util/saver.rb +45 -0
- data/lib/core/Container.rb +1 -1
- data/lib/core/runtime_method/ActsAsRuntimeMethod.rb +28 -28
- data/lib/core/runtime_method/RuntimeMethod.rb +6 -23
- data/lib/core/statement/ActsAsStatement.rb +0 -96
- data/lib/core/statement/BlockStatement.rb +1 -1
- data/lib/core/statement/OpenStatement.rb +1 -1
- data/lib/core/statement/Statement.rb +39 -94
- data/lib/core/statement/TheoryStatement.rb +1 -1
- data/lib/core/syntax/BlockContainer.rb +0 -28
- data/lib/core/variable/MethodParameter.rb +1 -1
- data/lib/required.rb +2 -14
- data/lib/theories.rb +0 -1
- data/lib/theory/ActionImplementation.rb +1 -1
- data/lib/theory/TheoryAction.rb +2 -2
- data/lib/theory/TheoryConnector.rb +11 -14
- data/lib/theory/TheoryImplementation.rb +10 -9
- data/lib/util/MethodWriter.rb +10 -10
- data/sandbox.rb +23 -0
- data/spec/cauldron/pot_spec.rb +62 -10
- data/spec/cauldron/runtime_method_spec.rb +31 -17
- data/spec/cauldron/saver_spec.rb +45 -0
- data/spec/cauldron/terminal_spec.rb +10 -1
- data/spec/cauldron/theory_spec.rb +4 -4
- data/spec/cauldron/unified_chain_spec.rb +38 -0
- data/spec/spec_helper.rb +3 -1
- data/tasks/development_tasks.rake +4 -0
- data/tasks/theory_tasks.rake +16 -20
- data/test/fixtures/theories/0/desc +6 -6
- data/test/fixtures/theories/0/dump +0 -0
- data/test/fixtures/theories/1/desc +7 -7
- data/test/fixtures/theories/1/dump +0 -0
- data/test/fixtures/theories/10/desc +13 -13
- data/test/fixtures/theories/10/dump +0 -0
- data/test/fixtures/theories/11/desc +10 -10
- data/test/fixtures/theories/11/dump +0 -0
- data/test/fixtures/theories/12/desc +9 -9
- data/test/fixtures/theories/12/dump +0 -0
- data/test/fixtures/theories/13/desc +16 -16
- data/test/fixtures/theories/13/dump +0 -0
- data/test/fixtures/theories/14/desc +16 -16
- data/test/fixtures/theories/14/dump +0 -0
- data/test/fixtures/theories/15/desc +10 -10
- data/test/fixtures/theories/15/dump +0 -0
- data/test/fixtures/theories/16/desc +10 -10
- data/test/fixtures/theories/16/dump +0 -0
- data/test/fixtures/theories/17/desc +7 -7
- data/test/fixtures/theories/17/dump +0 -0
- data/test/fixtures/theories/18/desc +7 -7
- data/test/fixtures/theories/18/dump +0 -0
- data/test/fixtures/theories/19/desc +7 -7
- data/test/fixtures/theories/19/dump +0 -0
- data/test/fixtures/theories/2/desc +6 -6
- data/test/fixtures/theories/2/dump +0 -0
- data/test/fixtures/theories/20/desc +13 -13
- data/test/fixtures/theories/20/dump +0 -0
- data/test/fixtures/theories/3/desc +7 -7
- data/test/fixtures/theories/3/dump +0 -0
- data/test/fixtures/theories/4/desc +7 -7
- data/test/fixtures/theories/4/dump +0 -0
- data/test/fixtures/theories/5/desc +6 -6
- data/test/fixtures/theories/5/dump +0 -0
- data/test/fixtures/theories/6/desc +7 -7
- data/test/fixtures/theories/6/dump +0 -0
- data/test/fixtures/theories/7/desc +7 -7
- data/test/fixtures/theories/7/dump +0 -0
- data/test/fixtures/theories/8/desc +7 -7
- data/test/fixtures/theories/8/dump +0 -0
- data/test/fixtures/theories/9/desc +16 -16
- data/test/fixtures/theories/9/dump +0 -0
- data/test/fixtures/theory_implementations/0/dump +0 -0
- data/test/fixtures/theory_implementations/2/dump +0 -0
- data/test/ts_complete.rb +1 -10
- data/test/unit/core/runtime_method/tc_realised_runtime_method.rb +1 -0
- data/test/unit/core/runtime_method/tc_runtime_method.rb +16 -39
- data/test/unit/core/statement/tc_block_statement.rb +3 -3
- data/test/unit/core/statement/tc_open_statement.rb +4 -4
- data/test/unit/core/statement/tc_statement.rb +2 -147
- data/test/unit/core/statement/tc_theory_statement.rb +1 -1
- data/test/unit/theory/tc_theory_dependent.rb +3 -3
- data/test/unit/theory/tc_theory_result.rb +5 -5
- data/test/unit/util/tc_method_validation.rb +45 -45
- data/test/unit/util/tc_parser.rb +1 -1
- data/test/unit/util/tc_string_to_theory.rb +2 -2
- metadata +74 -48
- data/lib/ScopeDependencies.rb +0 -8
- data/lib/core/statement/StatementDependencies.rb +0 -271
- data/lib/core/structure/DeclareNewInstanceStructure.rb +0 -49
- data/lib/core/structure/DeclareRuntimeMethodStructure.rb +0 -34
- data/lib/core/structure/DeclareVariableAsLiteralStructure.rb +0 -31
- data/lib/core/structure/DeclareVariableAsVariableStructure.rb +0 -52
- data/lib/core/structure/FixnumAdditionStructure.rb +0 -56
- data/lib/core/structure/InstanceCallContainerStructure.rb +0 -50
- data/lib/core/structure/InstanceCallStructure.rb +0 -53
- data/lib/core/structure/InstanceMethodCallStructure.rb +0 -21
- data/lib/core/structure/ReturnStructure.rb +0 -20
- data/lib/core/structure/StatementStructure.rb +0 -11
- data/test/unit/core/statement/tc_statement_dependencies.rb +0 -147
- data/test/unit/core/structure/tc_declare_new_instance_structure.rb +0 -41
- data/test/unit/core/structure/tc_declare_variable_as_literal_structure.rb +0 -41
- data/test/unit/core/structure/tc_declare_variable_as_variable_structure.rb +0 -66
- data/test/unit/core/structure/tc_instance_call_container_structure.rb +0 -41
- data/test/unit/core/structure/tc_return_structure.rb +0 -32
- data/test/unit/tc_instance_call_structure.rb +0 -35
- data/test/unit/tc_statement_structure_2.rb +0 -43
data/lib/Theory.rb
CHANGED
@@ -6,15 +6,14 @@ class Theory
|
|
6
6
|
|
7
7
|
attr_accessor :theory_instance_id
|
8
8
|
|
9
|
-
@@theory_id =
|
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 =
|
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
|
-
|
266
|
+
|
243
267
|
# Describe the despendencies
|
244
268
|
description = 'if: '+"\n"
|
245
269
|
@dependents.inject(description) do |description, x|
|
data/lib/UnifiedChain.rb
CHANGED
@@ -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
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
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
|
-
|
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.
|
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
|
112
|
-
|
113
|
-
|
114
|
-
|
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
|
125
|
+
end
|
126
|
+
return valid_mappings
|
118
127
|
end
|
119
128
|
|
120
|
-
def
|
121
|
-
|
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 |
|
124
|
-
|
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
|
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
|
-
|
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
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
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(
|
283
|
-
links = @nodes[
|
284
|
-
|
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
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
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
|
-
#
|
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
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
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
|
data/lib/cauldron.rb
CHANGED
data/lib/cauldron/demos.rb
CHANGED
@@ -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
|
}
|
data/lib/cauldron/env.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
TAB = ' '
|
data/lib/cauldron/pot.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
module Cauldron
|
2
2
|
|
3
3
|
class Pot
|
4
|
-
|
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
|
-
|
16
|
-
if
|
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
|
-
|
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
|
-
|
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
|
57
|
-
|
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
|
74
|
-
|
75
|
-
end
|
83
|
+
return chains
|
84
|
+
end
|
76
85
|
|
77
86
|
def saved_theories
|
78
|
-
|
79
|
-
|
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
|
-
|
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
|
|