cauldron 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +4 -1
- data/.rspec +1 -0
- data/Gemfile +16 -9
- data/Gemfile.lock +134 -64
- data/README.md +26 -0
- data/Rakefile +24 -99
- data/build_sandbox.rb +41 -0
- data/cucumber.yml +8 -0
- data/features/chop.feature +23 -0
- data/features/create_dynamic_statements.feature +14 -0
- data/features/generate_known_solution.feature +42 -0
- data/features/generate_new_statement.feature +20 -0
- data/features/step_definitions/cauldron_steps.rb +47 -0
- data/features/support/env.rb +1 -1
- data/features/use_existing_statements.feature +23 -0
- data/lib/cauldron.rb +41 -5
- data/lib/cauldron/actualized_composite.rb +35 -0
- data/lib/cauldron/array_collect_template/default.rb +95 -0
- data/lib/cauldron/array_collect_template/template.rb +57 -0
- data/lib/cauldron/builder.rb +60 -0
- data/lib/cauldron/caret.rb +50 -0
- data/lib/cauldron/dynamic_operator.rb +90 -0
- data/lib/cauldron/dynamic_operator_module.rb +140 -0
- data/lib/cauldron/example.rb +18 -0
- data/lib/cauldron/example_set.rb +36 -0
- data/lib/cauldron/histories.rb +53 -0
- data/lib/cauldron/history.rb +34 -0
- data/lib/cauldron/if_relationship.rb +4 -6
- data/lib/cauldron/number_addition_template/add_five.rb +71 -0
- data/lib/cauldron/number_addition_template/template.rb +56 -0
- data/lib/cauldron/operator.rb +62 -0
- data/lib/cauldron/operator/array_reverse_operator.rb +160 -0
- data/lib/cauldron/operator/concat_operator.rb +72 -0
- data/lib/cauldron/operator/hash_key_value_operator.rb +74 -0
- data/lib/cauldron/operator/numeric_operator.rb +115 -0
- data/lib/cauldron/operator/string_asterisk_operator.rb +131 -0
- data/lib/cauldron/operator/to_s_operator.rb +18 -0
- data/lib/cauldron/operator/var_collect_operator.rb +29 -0
- data/lib/cauldron/pot.rb +136 -26
- data/lib/cauldron/scope.rb +24 -0
- data/lib/cauldron/solution/composite.rb +236 -0
- data/lib/cauldron/solution/one.rb +49 -0
- data/lib/cauldron/statement_generator.rb +298 -0
- data/lib/cauldron/template_base.rb +14 -0
- data/lib/cauldron/tracer.rb +55 -0
- data/lib/cauldron/version.rb +1 -1
- data/lib/pry_tester.rb +76 -0
- data/ruby_to_sexp.rb +74 -0
- data/sandbox.rb +7 -0
- data/sexp_to_ruby.rb +150 -0
- data/spec/cauldron/actualized_composite_spec.rb +140 -0
- data/spec/cauldron/array_collect_template/default_spec.rb +41 -0
- data/spec/cauldron/builder_spec.rb +186 -0
- data/spec/cauldron/dynamic/add_number_template_spec.rb +30 -0
- data/spec/cauldron/dynamic_operator_spec.rb +416 -0
- data/spec/cauldron/example_set_spec.rb +49 -0
- data/spec/cauldron/example_spec.rb +33 -0
- data/spec/cauldron/histories_spec.rb +135 -0
- data/spec/cauldron/history_spec.rb +118 -0
- data/spec/cauldron/if_relationship_spec.rb +1 -1
- data/spec/cauldron/operator/array_reverse_operator_spec.rb +73 -0
- data/spec/cauldron/{concat_operator_spec.rb → operator/concat_operator_spec.rb} +30 -12
- data/spec/cauldron/operator/hash_key_value_operator_spec.rb +98 -0
- data/spec/cauldron/operator/numeric_operator_spec.rb +110 -0
- data/spec/cauldron/operator/string_asterisk_operator_spec.rb +196 -0
- data/spec/cauldron/operator/var_collect_operator_spec.rb +38 -0
- data/spec/cauldron/pot_spec.rb +176 -14
- data/spec/cauldron/solution/composite_spec.rb +421 -0
- data/spec/cauldron/solution/one_spec.rb +24 -0
- data/spec/cauldron/statement_generator_spec.rb +211 -0
- data/spec/cauldron/terminal_spec.rb +2 -2
- data/spec/spec_helper.rb +5 -1
- data/spec/support/code_matcher.rb +55 -0
- data/spec/support/include_instance_of_matcher.rb +9 -0
- data/spec/support/shared_examples_for_leaf_operators.rb +22 -0
- data/spec/support/shared_examples_for_operators.rb +23 -0
- data/syntax_spec.txt +2 -0
- metadata +104 -41
- data/README +0 -1
- data/README.rdoc +0 -19
- data/VERSION +0 -1
- data/features/cauldron_new_approach.feature +0 -46
- data/lib/cauldron/array_reverse_operator.rb +0 -39
- data/lib/cauldron/concat_operator.rb +0 -34
- data/lib/cauldron/numeric_operator.rb +0 -45
- data/lib/cauldron/relationship.rb +0 -5
- data/spec/cauldron/array_reverse_operator_spec.rb +0 -59
- data/spec/cauldron/numeric_operator_spec.rb +0 -70
data/cucumber.yml
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Feature: Using String#chop
|
2
|
+
|
3
|
+
Scenario: Using chop example
|
4
|
+
Given I'm using the chop example
|
5
|
+
When I generate a solution
|
6
|
+
Then the solution should include:
|
7
|
+
"""
|
8
|
+
def function(var0)
|
9
|
+
var1 = var0.collect do |var2|
|
10
|
+
var2.chop
|
11
|
+
end
|
12
|
+
end
|
13
|
+
"""
|
14
|
+
|
15
|
+
Scenario: Using simple chop example
|
16
|
+
Given I'm using the simple chop example
|
17
|
+
When I generate a solution
|
18
|
+
Then the solution should include:
|
19
|
+
"""
|
20
|
+
def function(var0)
|
21
|
+
var0.chop
|
22
|
+
end
|
23
|
+
"""
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Feature: Using dynamic method
|
2
|
+
|
3
|
+
@wip
|
4
|
+
Scenario: Using the collect and + 7 example
|
5
|
+
Given I'm using the collect and plus 7 example
|
6
|
+
When I generate a solution
|
7
|
+
Then the solution should include:
|
8
|
+
"""
|
9
|
+
def function(var0)
|
10
|
+
var1 = var0.collect do |var2|
|
11
|
+
var2 + 7
|
12
|
+
end
|
13
|
+
end
|
14
|
+
"""
|
@@ -0,0 +1,42 @@
|
|
1
|
+
Feature: Cauldron generates single parameter methods
|
2
|
+
|
3
|
+
Cauldron can generate runtime methods that accepts one parameters
|
4
|
+
|
5
|
+
@announce @slow_process
|
6
|
+
Scenario: Chop the last character off a string
|
7
|
+
Given a file named "launch.rb" with:
|
8
|
+
"""
|
9
|
+
$LOAD_PATH.unshift File.expand_path( File.join(['..','..','lib']) )
|
10
|
+
require 'cauldron'
|
11
|
+
cauldron = Cauldron::Pot.new
|
12
|
+
puts cauldron.solve [{arguments: ['Sparky'], response: 'Spark'}, {arguments: ['Kel'], response: 'Ke'}]
|
13
|
+
"""
|
14
|
+
When I run `ruby launch.rb` interactively
|
15
|
+
Then the output should contain:
|
16
|
+
"""
|
17
|
+
def function(var0)
|
18
|
+
var0.chop
|
19
|
+
end
|
20
|
+
"""
|
21
|
+
|
22
|
+
@announce @slow_process @wip
|
23
|
+
Scenario: Chop the last character off a string
|
24
|
+
Given a file named "launch.rb" with:
|
25
|
+
"""
|
26
|
+
$LOAD_PATH.unshift File.expand_path( File.join('lib') )
|
27
|
+
require 'cauldron'
|
28
|
+
cauldron = Cauldron::Pot.new
|
29
|
+
puts cauldron.solve [
|
30
|
+
{arguments: [['Sparky', 'Kels']], response: ['Spark', 'Kel']},
|
31
|
+
{arguments: [['Pip','Rowe']], response: ['Pi','Row']}
|
32
|
+
]
|
33
|
+
"""
|
34
|
+
When I run `ruby launch.rb` interactively
|
35
|
+
Then the output should contain:
|
36
|
+
"""
|
37
|
+
def function(var0)
|
38
|
+
var2 = var0.collect do |var1|
|
39
|
+
var1.chop
|
40
|
+
end
|
41
|
+
end
|
42
|
+
"""
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: Cauldron generates single parameter methods
|
2
|
+
|
3
|
+
Cauldron can generate runtime methods that accepts one parameters
|
4
|
+
|
5
|
+
@announce @slow_process @wip
|
6
|
+
Scenario: Using statements that require a constant
|
7
|
+
Given a file named "launch.rb" with:
|
8
|
+
"""
|
9
|
+
$LOAD_PATH.unshift File.expand_path( File.join('lib') )
|
10
|
+
require 'cauldron'
|
11
|
+
cauldron = Cauldron::Pot.new
|
12
|
+
puts cauldron.solve [{arguments: [8], response: 4}, {arguments: [12], response: 8}]
|
13
|
+
"""
|
14
|
+
When I run `ruby launch.rb` interactively
|
15
|
+
Then the output should contain:
|
16
|
+
"""
|
17
|
+
def function(var0)
|
18
|
+
var0 - 4
|
19
|
+
end
|
20
|
+
"""
|
@@ -28,4 +28,51 @@ Then /^I should receive a runtime method like this "([^"]*)"$/ do |runtime_metho
|
|
28
28
|
output.messages.should include(runtime_method_statement)
|
29
29
|
end
|
30
30
|
|
31
|
+
Given(/^I'm using the chop example$/) do
|
32
|
+
#pending # Write code here that turns the phrase above into concrete actions
|
33
|
+
@pot = Cauldron::Pot.new
|
34
|
+
@examples = [
|
35
|
+
{arguments: [['Sparky', 'Kels']], response: ['Spark', 'Kel']},
|
36
|
+
{arguments: [['Pip','Rowe']], response: ['Pi','Row']}
|
37
|
+
]
|
38
|
+
end
|
39
|
+
|
40
|
+
Given(/^I'm using the simple chop example$/) do
|
41
|
+
@pot = Cauldron::Pot.new
|
42
|
+
@examples = [
|
43
|
+
{arguments: ['Andy'], response: 'And'},
|
44
|
+
{arguments: ['Kels'], response: 'Kel'}
|
45
|
+
]
|
46
|
+
end
|
47
|
+
|
48
|
+
Given(/^I'm using the reverse example$/) do
|
49
|
+
@pot = Cauldron::Pot.new
|
50
|
+
@examples = [
|
51
|
+
{arguments: [['Sparky', 'Kels']], response: ['Kels', 'Sparky']}
|
52
|
+
]
|
53
|
+
end
|
54
|
+
|
55
|
+
Given(/^I'm using the collect and \+ (\d+) example$/) do |arg1|
|
56
|
+
@pot = Cauldron::Pot.new
|
57
|
+
@examples = [
|
58
|
+
{arguments: [[5,7]], response: [10, 12]},
|
59
|
+
{arguments: [[9,15]], response: [14, 20]}
|
60
|
+
]
|
61
|
+
end
|
62
|
+
|
63
|
+
Given(/^I'm using the collect and plus (\d+) example$/) do |arg1|
|
64
|
+
@pot = Cauldron::Pot.new
|
65
|
+
@examples = [
|
66
|
+
{arguments: [[5,7]], response: [12, 14]},
|
67
|
+
{arguments: [[9,15]], response: [16, 22]}
|
68
|
+
]
|
69
|
+
end
|
70
|
+
|
71
|
+
When(/^I generate a solution$/) do
|
72
|
+
@solution = @pot.solve @examples
|
73
|
+
end
|
74
|
+
|
75
|
+
Then(/^the solution should include:$/) do |string|
|
76
|
+
@solution.should include(string)
|
77
|
+
end
|
31
78
|
|
data/features/support/env.rb
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
Feature: Using Array#reverse
|
2
|
+
|
3
|
+
Scenario: Using chop example
|
4
|
+
Given I'm using the reverse example
|
5
|
+
When I generate a solution
|
6
|
+
Then the solution should include:
|
7
|
+
"""
|
8
|
+
def function(var0)
|
9
|
+
var0.reverse
|
10
|
+
end
|
11
|
+
"""
|
12
|
+
|
13
|
+
Scenario: Using the collect and + 5 example
|
14
|
+
Given I'm using the collect and + 5 example
|
15
|
+
When I generate a solution
|
16
|
+
Then the solution should include:
|
17
|
+
"""
|
18
|
+
def function(var0)
|
19
|
+
var1 = var0.collect do |var2|
|
20
|
+
var2 + 5
|
21
|
+
end
|
22
|
+
end
|
23
|
+
"""
|
data/lib/cauldron.rb
CHANGED
@@ -5,14 +5,50 @@ require 'logger'
|
|
5
5
|
require 'yaml'
|
6
6
|
require 'ruby2ruby'
|
7
7
|
require 'ruby_parser'
|
8
|
-
|
8
|
+
require 'sorcerer'
|
9
|
+
|
10
|
+
require 'pry_tester'
|
11
|
+
require 'pry'
|
12
|
+
|
13
|
+
# http://stackoverflow.com/questions/18732338/trying-to-require-active-support-in-gem
|
14
|
+
require "active_support/all"
|
15
|
+
|
16
|
+
require 'tree'
|
9
17
|
|
10
18
|
require 'core/string'
|
11
19
|
|
12
20
|
require 'cauldron/pot'
|
21
|
+
require 'cauldron/caret'
|
22
|
+
require 'cauldron/example'
|
23
|
+
require 'cauldron/example_set'
|
13
24
|
require 'cauldron/terminal'
|
14
|
-
require 'cauldron/
|
25
|
+
require 'cauldron/scope'
|
26
|
+
require 'cauldron/histories'
|
27
|
+
require 'cauldron/history'
|
28
|
+
require 'cauldron/tracer'
|
29
|
+
require 'cauldron/operator'
|
30
|
+
require 'cauldron/statement_generator'
|
31
|
+
require 'cauldron/dynamic_operator'
|
32
|
+
require 'cauldron/operator/numeric_operator'
|
33
|
+
require 'cauldron/operator/concat_operator'
|
34
|
+
require 'cauldron/operator/array_reverse_operator'
|
35
|
+
require 'cauldron/operator/hash_key_value_operator'
|
36
|
+
require 'cauldron/operator/string_asterisk_operator'
|
37
|
+
require 'cauldron/operator/to_s_operator'
|
38
|
+
require 'cauldron/operator/var_collect_operator'
|
15
39
|
require 'cauldron/if_relationship'
|
16
|
-
|
17
|
-
require 'cauldron/
|
18
|
-
|
40
|
+
|
41
|
+
require 'cauldron/template_base'
|
42
|
+
|
43
|
+
require 'cauldron/array_collect_template/default'
|
44
|
+
require 'cauldron/array_collect_template/template'
|
45
|
+
|
46
|
+
require 'cauldron/number_addition_template/template'
|
47
|
+
require 'cauldron/number_addition_template/add_five'
|
48
|
+
|
49
|
+
require 'cauldron/dynamic_operator_module'
|
50
|
+
|
51
|
+
require 'cauldron/solution/one'
|
52
|
+
require 'cauldron/actualized_composite'
|
53
|
+
require 'cauldron/solution/composite'
|
54
|
+
require 'cauldron/builder'
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Cauldron
|
2
|
+
|
3
|
+
class ActualizedComposite
|
4
|
+
|
5
|
+
attr_reader :examples, :composite
|
6
|
+
|
7
|
+
# Might include the insert point here too
|
8
|
+
def initialize(composite,examples)
|
9
|
+
@composite, @examples = composite, examples
|
10
|
+
end
|
11
|
+
|
12
|
+
def histories
|
13
|
+
results = @examples.collect do |example|
|
14
|
+
@composite.record(example)
|
15
|
+
end
|
16
|
+
Cauldron::Histories.new(results)
|
17
|
+
end
|
18
|
+
|
19
|
+
def extend_solution
|
20
|
+
builder = Builder.new(composite)
|
21
|
+
builder.insertable_operators(examples)
|
22
|
+
end
|
23
|
+
|
24
|
+
def solution?(problems)
|
25
|
+
# TODO Should not need to
|
26
|
+
composite.solution?(examples)
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_ruby
|
30
|
+
composite.to_ruby(examples.scope)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Cauldron
|
2
|
+
|
3
|
+
module ArrayCollectTemplate
|
4
|
+
|
5
|
+
class Default
|
6
|
+
|
7
|
+
attr_reader :indexes
|
8
|
+
|
9
|
+
def initialize(indexes)
|
10
|
+
@indexes = indexes
|
11
|
+
end
|
12
|
+
|
13
|
+
def context_realizable?(context)
|
14
|
+
|
15
|
+
vars = context.keys.select {|x| x.match(/var\d/) }
|
16
|
+
var_names = vars.collect(&:to_s)
|
17
|
+
|
18
|
+
first_variable = 'var'+@indexes[0].to_s
|
19
|
+
|
20
|
+
a = %Q{
|
21
|
+
def function(#{first_variable})
|
22
|
+
#{Sorcerer.source(to_sexp(Cauldron::Scope.new(var_names), []), indent: true)}
|
23
|
+
end
|
24
|
+
}
|
25
|
+
|
26
|
+
o = Object.new
|
27
|
+
o.instance_eval(a)
|
28
|
+
|
29
|
+
begin
|
30
|
+
#o.function(*vars.collect {|x| context[x] })
|
31
|
+
o.function context[first_variable.to_sym]
|
32
|
+
rescue NoMethodError => e
|
33
|
+
return false
|
34
|
+
rescue StandardError => e
|
35
|
+
puts e
|
36
|
+
return false
|
37
|
+
end
|
38
|
+
return true
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_sexp(scope, children)
|
43
|
+
scope_var = scope.new_variable!
|
44
|
+
first_variable = 'var'+@indexes[0].to_s
|
45
|
+
[:method_add_block,
|
46
|
+
[:call,
|
47
|
+
[:vcall,
|
48
|
+
# [:@ident, scope[@indexes[0]] ]],
|
49
|
+
[:@ident, first_variable ]],
|
50
|
+
:".",
|
51
|
+
[:@ident, "collect"]
|
52
|
+
],
|
53
|
+
unless children.empty?
|
54
|
+
[:brace_block,
|
55
|
+
[:block_var,
|
56
|
+
[:params, [[:@ident, scope_var]]]],
|
57
|
+
[
|
58
|
+
:stmts_add,
|
59
|
+
[:stmts_new],
|
60
|
+
# TODO Shouild probably be passing the children through here
|
61
|
+
children.first.content.to_sexp(scope, [])
|
62
|
+
]
|
63
|
+
]
|
64
|
+
else
|
65
|
+
[:brace_block,
|
66
|
+
[:block_var,
|
67
|
+
[:params, [[:@ident, scope_var]]],
|
68
|
+
[:stmts_add, [:stmts_new]]
|
69
|
+
]
|
70
|
+
]
|
71
|
+
end
|
72
|
+
]
|
73
|
+
end
|
74
|
+
|
75
|
+
def to_ruby(scope, operators)
|
76
|
+
Sorcerer.source to_sexp(scope, operators)
|
77
|
+
end
|
78
|
+
|
79
|
+
def clone_statement
|
80
|
+
# TODO Need to clone the sexp methods
|
81
|
+
# o = DynamicOperator.new(@information, @sexp_methods)
|
82
|
+
# o.instance_eval(Sorcerer.source(@sexp_methods, indent: true))
|
83
|
+
# o
|
84
|
+
self.class.new(@indexes.clone)
|
85
|
+
end
|
86
|
+
|
87
|
+
def branch?
|
88
|
+
true
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Cauldron
|
2
|
+
|
3
|
+
module ArrayCollectTemplate
|
4
|
+
|
5
|
+
class Template < Cauldron::TemplateBase
|
6
|
+
|
7
|
+
def self.instances(histories, composite, examples, insert_points)
|
8
|
+
|
9
|
+
# TEMP
|
10
|
+
unless examples.class == ExampleSet
|
11
|
+
raise StandardError.new('Examples should be an example')
|
12
|
+
end
|
13
|
+
|
14
|
+
# Print out each insertable statements
|
15
|
+
scope = examples.scope
|
16
|
+
|
17
|
+
# self.init([0]).to_ruby(scope)
|
18
|
+
# - this will print out "var0.chop"
|
19
|
+
|
20
|
+
# Get the variables available at each point
|
21
|
+
results = []
|
22
|
+
|
23
|
+
insert_points.each do |point|
|
24
|
+
|
25
|
+
# Find the variables at a particular point
|
26
|
+
# TODO Change to test
|
27
|
+
contexts = histories.contexts_at(point)
|
28
|
+
composites = context_instances(contexts)
|
29
|
+
|
30
|
+
composites.each do |x|
|
31
|
+
if contexts.all? { |context| x.context_realizable?(context) }
|
32
|
+
#binding.pry
|
33
|
+
results << extend_actualized_composite(x, composite, examples, point)
|
34
|
+
end
|
35
|
+
#results << extend_actualized_composite(x, composite, examples, point)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
results
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.context_instances(contexts)
|
43
|
+
temp = []
|
44
|
+
contexts.each do |context|
|
45
|
+
temp << context.keys.collect(&:to_s).select {|x| x.match(/var\d/) }
|
46
|
+
end
|
47
|
+
results = temp.flatten.uniq
|
48
|
+
|
49
|
+
variable_numbers = results.collect { |x| x.match(/var(\d+)/)[1] }
|
50
|
+
variable_numbers.collect { |x| Cauldron::ArrayCollectTemplate::Default.new([x.to_i])}
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|