cauldron 0.1.5 → 0.1.6
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.
- 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
|