cauldron 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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/cauldron/lib/cauldron.rb
CHANGED
@@ -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
|
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
|
-
|
12
|
-
|
13
|
-
|
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
|
data/features/support/env.rb
CHANGED
@@ -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
|
data/lib/Chain.rb
CHANGED
@@ -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 = ('
|
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
|
-
|
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
|
data/lib/Mapping.rb
CHANGED
data/lib/PartialChain.rb
ADDED
@@ -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
|