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
@@ -1,3 +1,3 @@
1
1
  class Cauldron
2
- VERSION = '1.0.0'
2
+
3
3
  end
@@ -2,12 +2,15 @@ Feature: Cauldron generates a runtime method
2
2
  I want a runtime method
3
3
  That will solve a set of example cases
4
4
 
5
+ TODO The second solution isn't correct but for now it will do
6
+
5
7
  Scenario Outline: Generate a solution to a previously solved problem
6
8
  Given that the terminal has been created
7
- When I add these <cases>
9
+ When I add a case with a param <case_1_param> and an expected output of <case_1_output>
10
+ And I add a case with a param <case_2_param> and an expected output of <case_2_output>
8
11
  Then I should receive a runtime method like this <runtime_method>
9
12
 
10
13
  Scenarios: example with only one parameter
11
- | cases | runtime_method | demo_num |
12
- | "'sparky','sparky'*'kel','kel'" | "def method_0(var_0)\n\treturn var_0\nend\n" | 1 |
13
- | "'fish','animal'*'carrot','vegetable'" | "def method_0(var_0)\n\tif(var_0 == 'fish')\n\t\treturn 'animal'\n\tend\n\treturn 'vegetable'\nend\n" | 2 |
14
+ | case_1_param | case_1_output | case_2_param | case_2_output | runtime_method |
15
+ | "sparky" | "sparky" | "kel" | "kel" | "def method_0(var_0)\n return var_0\nend\n" |
16
+ | "fish" | "animal" | "carrot" | "vegetable" | "def method_0(var_0)\n if(var_0 == 'fish')\n return 'animal'\n end\n return 'vegetable'\n return var_0\nend\n" |
@@ -0,0 +1,25 @@
1
+ Feature: Cauldron generates single parameter methods
2
+
3
+ Cauldron can generate runtime methods that accepts one parameters
4
+
5
+ NOTE: it creates the file in tmp/aruba/launch.rb - so that loading path needs to be changed
6
+ - use @pause to see if it's working.
7
+
8
+ @announce @slow_process
9
+ Scenario: Method returns the passed in value
10
+ Given a file named "launch.rb" with:
11
+ """
12
+ $LOAD_PATH.unshift File.expand_path( File.join('lib') )
13
+ require 'cauldron'
14
+ cauldron = Cauldron::Terminal.new(STDOUT,false)
15
+ cauldron.start
16
+ """
17
+ And I run `ruby launch.rb` interactively
18
+ And I add the case "sparky","sparky"
19
+ And I type "RUN"
20
+ When I type "QUIT"
21
+ Then the output should contain:
22
+ """
23
+ return var_0
24
+ """
25
+
@@ -0,0 +1,17 @@
1
+ Feature: It should display a start up message
2
+
3
+ @announce @slow_process
4
+ Scenario: Interactive cauldron start up
5
+ Given a file named "launch.rb" with:
6
+ """
7
+ $LOAD_PATH.unshift File.expand_path( File.join('lib') )
8
+ require 'cauldron'
9
+ cauldron = Cauldron::Terminal.new(STDOUT,false)
10
+ cauldron.start
11
+ """
12
+ And I run `ruby launch.rb` interactively
13
+ When I type "QUIT"
14
+ Then the output should contain:
15
+ """
16
+ Starting...
17
+ """
@@ -0,0 +1,9 @@
1
+ Feature: Cauldron can be quit from the terminal
2
+ Typing "QUIT" in the terminal will cause the process to quit
3
+
4
+ see for examples https://github.com/cucumber/aruba/blob/master/features/interactive.feature
5
+
6
+ #Scenario: quit cauldron from the terminal
7
+ # Given I've started Cauldron
8
+ # Then the exit status should be 0
9
+
@@ -7,7 +7,6 @@ Feature: Cauldron starts on the command line
7
7
  And then I should see "To start enter your first test like this"
8
8
  And then I should see "input,input,output"
9
9
  And then I should see "For example "
10
- And then I should see "'fish','animal'"
11
10
  And then I should see "'cat','animal'"
12
11
  And then I should see "'carrot','vegtable'"
13
12
  And then I should see "and when you're done just type RUN"
@@ -1,9 +1,14 @@
1
1
 
2
- When /^I add these "([^"]*)"$/ do |test_cases_statement|
3
- test_cases = test_cases_statement.split('*')
4
- test_cases.each do |x|
5
- @terminal.submit x
6
- end
2
+ # When /^I add these "([^"]*)"$/ do |test_cases_statement|
3
+ # test_cases = test_cases_statement.split('*')
4
+ # test_cases.each do |x|
5
+ # @terminal.submit x
6
+ # end
7
+ # end
8
+
9
+ When /^I add a case with a param "([^"]*)" and an expected output of "([^"]*)"$/ do |param, output|
10
+ #@terminal.submit("'"+param+,"'+output+'"')
11
+ @terminal.submit("'#{param}','#{output}'")
7
12
  end
8
13
 
9
14
  Then /^I should receive a runtime method like this "([^"]*)"$/ do |runtime_method_statement|
@@ -6,12 +6,39 @@ Given /^that the terminal has been created$/ do
6
6
  @terminal.start
7
7
  end
8
8
 
9
+ Given /^I've started Cauldron$/ do
10
+ When "I start cauldron"
11
+ end
9
12
 
10
13
  When /^I start cauldron$/ do
11
14
  @terminal = Cauldron::Terminal.new(output)
12
15
  @terminal.start
13
16
  end
14
17
 
18
+ # When /^I type "([^"]*)"$/ do |command|
19
+ # @terminal.submit command
20
+ # end
21
+
22
+ # When /^I type "([^"]*)","([^"]*)"$/ do |param, output|
23
+ # #type "'"+param+"','"+output+"'"
24
+ # type 'test'
25
+ # end
26
+
27
+ When /^I add the case "([^"]*)","([^"]*)"$/ do |param, output|
28
+ #pending # express the regexp above with the code you wish you had
29
+ type "'"+param+"','"+output+"'"
30
+ end
31
+
32
+
33
+ # Then /^cauldron should say 'bye'$/ do
34
+ # output.messages.should include('bye')
35
+ # end
36
+ #
37
+ # Then /^the exit status should be (\d+)$/ do |exit_status|
38
+ # @terminal.submit 'QUIT'
39
+ # @last_exit_status.should == exit_status.to_i
40
+ # end
41
+
15
42
  Then /^I should see "([^"]*)"$/ do |message|
16
43
  output.messages.should include(message)
17
44
  end
@@ -2,6 +2,8 @@ $LOAD_PATH << File.expand_path('../../../lib',__FILE__)
2
2
 
3
3
  require 'cauldron'
4
4
 
5
+ require 'aruba/cucumber'
6
+
5
7
  class Output
6
8
 
7
9
  def messages
@@ -0,0 +1,15 @@
1
+
2
+ # => http://itshouldbeuseful.wordpress.com/2011/06/23/step-through-your-cucumber-features-interactively/
3
+ AfterStep('@pause') do
4
+ print "Press Return to continue..."
5
+ STDIN.getc
6
+ end
7
+
8
+ Before('@slow_process') do
9
+ @aruba_io_wait_seconds = 3
10
+ @aruba_timeout_seconds = 3
11
+ end
12
+
13
+ Before do
14
+ @dirs = ["."]
15
+ end
@@ -11,7 +11,7 @@ class Chain
11
11
  @values, @nodes = {}, []
12
12
 
13
13
  # Create an array of possible ids for any theories added
14
- @uniq_theory_instance_ids = ('A'...'Z').to_a
14
+ @uniq_theory_instance_ids = ('AA'...'ZZ').to_a
15
15
 
16
16
  # Create a result version of 'finish'
17
17
 
@@ -141,7 +141,8 @@ class Chain
141
141
  mapped_theory = theory.map_to(mapping)
142
142
  total.push(mapped_theory)
143
143
  end
144
- return UnifiedChain.new(unified_theories)
144
+ # => TODO This contians information about the chain before it has been unified - this should not be included
145
+ return UnifiedChain.new(unified_theories,@chain_mapping.copy).freeze
145
146
  end
146
147
 
147
148
  # DEVELOPMENT
@@ -591,7 +592,6 @@ protected
591
592
 
592
593
  if potentential_values.length > 1
593
594
  unless potentential_values.collect {|y| y.write}.uniq.length == 1
594
- pp potentential_values
595
595
  raise StandardError.new('There is more than one possible value for this('+global_id.to_s+') - it is ok if there the same')
596
596
  end
597
597
  end
@@ -5,6 +5,7 @@ class Mapping
5
5
 
6
6
  def initialize(hash={})
7
7
  super()
8
+ raise StandardError.new('This should be a hash not a '+hash.class.to_s) unless hash.kind_of?(Hash)
8
9
  @hash = hash
9
10
  end
10
11
 
@@ -0,0 +1,253 @@
1
+ # => TODO This is a duplicate of of UnifiedChain - it needs stripped down allot - probably shouldn't exist
2
+
3
+ class PartialChain
4
+
5
+ def initialize(nodes)
6
+ @nodes = nodes
7
+ end
8
+
9
+ def write(tab=0)
10
+ return @nodes.inject('') {|total,x| total += x.write}
11
+ end
12
+
13
+ def describe(tab=0)
14
+ return @nodes.inject('') {|total,x| total += x.describe}
15
+ end
16
+
17
+ def copy
18
+ #return Chain.new(@nodes.copy)
19
+ return Marshal.load(Marshal.dump(self))
20
+ end
21
+
22
+ # Returns an array of all the theory variables in the chain. All the
23
+ # theory variables should be global across the chain.
24
+ #
25
+ def theory_variables
26
+ results = @nodes.inject([]) do |total,theory|
27
+ total += theory.all_theory_variables.collect {|x| x}
28
+ total
29
+ end
30
+ return results.uniq
31
+ end
32
+
33
+ def length
34
+ return @nodes.length
35
+ end
36
+
37
+ # Return an implemented version of the chain where all the theory variables have
38
+ # been replaced with read values.
39
+ #
40
+ def implement(mapping)
41
+ implemented_nodes = @nodes.inject([]) do |total,theory|
42
+ total << theory.map_to(mapping)
43
+ end
44
+ return ImplementedChain.new(implemented_nodes,mapping)
45
+ end
46
+
47
+ def implementation_permuatations2(runtime_method,test_cases,mapping)
48
+
49
+ more_mapping = valid_mapping_permutations(runtime_method.copy,test_cases.copy)
50
+
51
+ return more_mapping.inject([]) { |total,mapping| total << self.copy.implement(mapping) }
52
+
53
+ end
54
+
55
+ def has_all_variables_been_found?(component,mappings)
56
+ component.theory_variables.each do |var|
57
+ mappings.each do |mapping|
58
+ return false unless mapping.has_key? var.theory_variable_id
59
+ end
60
+ end
61
+ return true
62
+ end
63
+
64
+ def identify_uniq_mappings(mappings)
65
+ uniq_mappings = []
66
+ count = mappings.length
67
+ until mappings.empty?
68
+ mapping = mappings.shift
69
+ already_exists = mappings.any? do |x|
70
+ next false unless x.length == mapping.length
71
+ next false unless x.keys.sort == mapping.keys.sort
72
+ all_values_the_same = true
73
+ x.each do |key,value|
74
+ if mapping[key].class != value.class
75
+ all_values_the_same = false
76
+ end
77
+ if mapping[key].class == value.class
78
+ if mapping[key].kind_of?(IntrinsicLiteral)
79
+ if mapping[key].write != value.write
80
+ all_values_the_same = false
81
+ end
82
+ end
83
+ end
84
+ end
85
+ next false unless all_values_the_same
86
+ next true
87
+ end
88
+ unless already_exists
89
+ uniq_mappings << mapping
90
+ end
91
+ end
92
+ if uniq_mappings.length == 0 && count != 0
93
+ raise StandardError.new('uniq_mappings should not be 0')
94
+ end
95
+ return uniq_mappings
96
+ end
97
+
98
+ def intrinsic_values_for_variable(id,component,mapping,runtime_method,test_cases,intrinsic_values)
99
+
100
+ values = []
101
+ component.statements_with_variable(id).each do |statement|
102
+ reg = eval('/^var'+id.to_s+'\./')
103
+ if statement.write.match(reg)
104
+
105
+ intrinsic_values.each do |value|
106
+ temp_mapping = mapping.copy
107
+ temp_mapping[id] = value
108
+ # => TODO Not validating the component - e.g. if(var1.kind_of?(RuntimeMethod))
109
+ if valid_mapping?(runtime_method.copy,test_cases.copy,statement,temp_mapping)
110
+ values << value
111
+ end
112
+ end
113
+ next
114
+ end
115
+
116
+ # values for index
117
+ index_values = []
118
+ intrinsic_statement = statement.map_to(mapping)
119
+ if intrinsic_statement.select_all {|z| z.kind_of?(TheoryVariable)}.length > 0
120
+ if m = intrinsic_statement.write.match(/([\w\.]+)\[var(\d)+\]/)
121
+ method_call = $1
122
+ if m2 = method_call.match(/var(\d+)/)
123
+ next
124
+ end
125
+ literal = evaluate_statement(method_call,runtime_method.copy,test_cases.copy)
126
+ literal.length.times do |n|
127
+ index_values << IntrinsicLiteral.new(n)
128
+ end
129
+ end
130
+ end
131
+ values += index_values
132
+
133
+ #variable_values = []
134
+ #result.statements_with_variable(var.theory_variable_id).each do |statement|
135
+ #variable_values += values_for_variable_as_argument(var,statement,mapping,intrinsic_values,implemented_runtime_method.copy,test_cases.copy)
136
+ #end
137
+ #values += variable_values
138
+
139
+ #intrinsic_statement = statement.map_to(mapping)
140
+ variable_values = []
141
+ intrinsic_values.each do |value|
142
+ literal = intrinsic_statement.write.gsub(/var(\d)+/,value.write)
143
+ begin
144
+ eval literal
145
+ variable_values << value
146
+ rescue
147
+ next
148
+ end
149
+ end
150
+ #return results
151
+ values += variable_values
152
+
153
+
154
+ end
155
+ return values
156
+ end
157
+
158
+ def mapping_permutations(keys,values)
159
+ values.permutation(keys.length).to_a.inject([]) do |total,value_permutation|
160
+ total << Hash[*keys.zip(value_permutation).flatten]
161
+ end
162
+ end
163
+
164
+ def valid_mapping?(runtime_method,test_cases,statement,mapping)
165
+ intrinsic_statement = statement.map_to(mapping)
166
+ return false unless intrinsic_statement.select_all {|z| z.kind_of?(TheoryVariable)}.length == 0
167
+ valid_statement?(intrinsic_statement,runtime_method.copy,test_cases.copy)
168
+ end
169
+
170
+ def evaluate_statement(statement,runtime_method,test_cases)
171
+ eval statement
172
+ end
173
+
174
+ def valid_statement?(statement,runtime_method,test_cases)
175
+ eval statement.write
176
+ return true
177
+ rescue NoMethodError
178
+ return false
179
+ end
180
+
181
+ # Returns an array of implemented chains using the various value
182
+ # permutations. Essential what it is looking for is mapping to convert
183
+ # all the theory variables to intrinsic variables.
184
+ #
185
+ # @param runtime_method The runtime method instance that will be populated to
186
+ # create the solution.<#RuntimeMethod >
187
+ # @param test_cases The test cases instance containing real values.
188
+ #
189
+ def implementation_permuatations(runtime_method,test_cases,mapping)
190
+
191
+ return implementation_permuatations2(runtime_method,test_cases,mapping)
192
+
193
+ # Determine the number of variables without intrinsic values
194
+ theory_variable_ids = theory_variables.collect {|x| x.theory_variable_id}
195
+
196
+ # Collect the theory variables without intrinsic values
197
+ missing_intrinsic_values = theory_variable_ids-mapping.keys
198
+
199
+ # Take the first theory and identify all the accessors
200
+ # (need to work out what is the runtime method and what the test cases)
201
+
202
+ # TEMP: Why are these implemented theories
203
+ # @nodes.first.all_theory_variables
204
+
205
+ # Create the theory generator
206
+ generator = TheoryGenerator.new()
207
+
208
+ #accessors, temp_mapping = generator.generate_accessors_and_mapping(test_cases,runtime_method,1)
209
+ accessors, temp_mapping = generator.generate_accessors_and_mapping(test_cases,runtime_method,3)
210
+
211
+ if temp_mapping.length > missing_intrinsic_values.length
212
+
213
+ # Now to assign real values to the chain
214
+
215
+ # Apply the values in the various permutaions
216
+ # (this is very crude and means that odd calls )
217
+ #theory_variable_ids = @nodes.first.all_theory_variables.collect {|x| x.theory_variable_id }
218
+
219
+ theory_variable_ids = self.theory_variables.collect {|x| x.theory_variable_id }
220
+
221
+ # Get the posible sets for values in an array so that non of the arrays contain all the same values
222
+ res = temp_mapping.values.collect {|x| x}
223
+
224
+ # TODO This is a complete hack but I think I should be using intrinsic values rather than real
225
+ intrinsic_res = res.collect {|x| x.to_intrinsic}
226
+ value_permutaions = intrinsic_res.permutation(theory_variable_ids.length).to_a
227
+ uniq_value_permutations = value_permutaions.collect {|x| x.to_set}.uniq
228
+ possible_mappings = []
229
+
230
+ theory_variable_id_permutations = theory_variable_ids.permutation(theory_variable_ids.length).to_a
231
+
232
+ possible_mappings = []
233
+ theory_variable_id_permutations.each do |theory_variable_id_permutation|
234
+ uniq_value_permutations.each do |value_permutation|
235
+ m = Mapping.new
236
+ theory_variable_id_permutation.zip(value_permutation.to_a) do |key,value|
237
+ m[key] = value
238
+ end
239
+ possible_mappings << m
240
+ end
241
+
242
+ end
243
+
244
+ # Implemented changes
245
+ return possible_mappings.inject([]) { |total,mapping| total << self.copy.implement(mapping) }
246
+
247
+ else
248
+ raise StandardError.new('Could not generate enough real vlaues to test theory - try increasing the itterations')
249
+ end
250
+
251
+ end
252
+
253
+ end