cauldron 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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