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
@@ -0,0 +1,60 @@
|
|
1
|
+
module Cauldron
|
2
|
+
|
3
|
+
class Builder
|
4
|
+
|
5
|
+
attr_reader :composite
|
6
|
+
|
7
|
+
def initialize(composite)
|
8
|
+
@composite = composite
|
9
|
+
end
|
10
|
+
|
11
|
+
def tree
|
12
|
+
root_node = Tree::TreeNode.new("ROOT", "Root Content")
|
13
|
+
line_count = 0
|
14
|
+
composite.operators.each do |x|
|
15
|
+
child_node = Tree::TreeNode.new('CHILD-'+line_count.to_s)
|
16
|
+
root_node << child_node
|
17
|
+
line_count += 1
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# NOTE: returns an array of new actualized composites extending the current composite
|
22
|
+
def insertable_operators(examples)
|
23
|
+
actualized_composite = ActualizedComposite.new(composite.clone_solution, examples)
|
24
|
+
h = actualized_composite.histories
|
25
|
+
results = self.class.available_statement_types.inject([]) do |total,x|
|
26
|
+
total += x.instances(h, composite, examples, h.insert_points)
|
27
|
+
total
|
28
|
+
end
|
29
|
+
#binding.pry
|
30
|
+
results
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.available_statement_types
|
34
|
+
|
35
|
+
# CURRENT
|
36
|
+
# StatementGenerator.new.build(
|
37
|
+
# ['A','B', 'AC'],
|
38
|
+
# [:collect]
|
39
|
+
# )+Cauldron::StatementGenerator.new.build('string',[:chop])
|
40
|
+
|
41
|
+
# TRYING
|
42
|
+
# StatementGenerator.new.build(
|
43
|
+
# ['A','B', 'AC'],
|
44
|
+
# [:collect]
|
45
|
+
# )+Cauldron::StatementGenerator.new.build('string',[:chop])+[Cauldron::ArrayCollectTemplate::Template]
|
46
|
+
[StatementGenerator.new.build_template(
|
47
|
+
['A','B', 'AC'],
|
48
|
+
:collect
|
49
|
+
).statement_classes.first]+[Cauldron::StatementGenerator.new.build_template('string',:chop).statement_classes.first]+[Cauldron::ArrayCollectTemplate::Template]+[Cauldron::NumberAdditionTemplate::Template]
|
50
|
+
|
51
|
+
# TODO Not very effient to regenerate the opperators
|
52
|
+
# StatementGenerator.new.build(
|
53
|
+
# ['A','B', 'AC'],
|
54
|
+
# [:collect]
|
55
|
+
# )+Cauldron::StatementGenerator.new.build('string',[:chop])+[ArrayReverseOperator]+[StatementGenerator.new.build(3,[:+])]
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Cauldron
|
2
|
+
|
3
|
+
class Caret
|
4
|
+
|
5
|
+
#attr_reader :line, :depth, :total_line
|
6
|
+
attr_reader :total_lines, :current_depth
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@total_lines, @current_depth = 0, 0 #,@line = 0, 0, 0
|
10
|
+
@lines = { 0 => 0}
|
11
|
+
end
|
12
|
+
|
13
|
+
# TODO This approach will need re-worked to support nesting - in and out
|
14
|
+
def add_line(depth)
|
15
|
+
unless @lines.has_key?(depth)
|
16
|
+
@lines[depth] = 0
|
17
|
+
end
|
18
|
+
|
19
|
+
@total_lines += 1
|
20
|
+
if @current_depth != depth
|
21
|
+
@current_depth = depth
|
22
|
+
else
|
23
|
+
@lines[depth] += 1
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
def point
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
def line
|
33
|
+
@lines[@current_depth]
|
34
|
+
end
|
35
|
+
|
36
|
+
def step_in
|
37
|
+
@current_depth += 1
|
38
|
+
unless @lines.has_key?(@current_depth)
|
39
|
+
@lines[@current_depth] = 0
|
40
|
+
end
|
41
|
+
#@line = 0
|
42
|
+
end
|
43
|
+
|
44
|
+
def return_depth(depth)
|
45
|
+
@current_depth = depth
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Cauldron
|
2
|
+
|
3
|
+
class DynamicOperator
|
4
|
+
|
5
|
+
include Cauldron::Operator
|
6
|
+
|
7
|
+
attr_reader :indexes
|
8
|
+
attr_accessor :failed_uses
|
9
|
+
|
10
|
+
def initialize(information, sexp_methods)
|
11
|
+
@information, @sexp_methods = information, sexp_methods
|
12
|
+
@failed_uses = []
|
13
|
+
@closed = false
|
14
|
+
end
|
15
|
+
|
16
|
+
def uses_constants?
|
17
|
+
@information[:constants]
|
18
|
+
end
|
19
|
+
|
20
|
+
def indexes=(value)
|
21
|
+
raise StandardError.new('') if @closed
|
22
|
+
@indexes = value
|
23
|
+
end
|
24
|
+
|
25
|
+
def close
|
26
|
+
@closed = true
|
27
|
+
end
|
28
|
+
|
29
|
+
def extend_actualized_composite(x, container, examples, point)
|
30
|
+
cloned_container = container.clone_solution
|
31
|
+
cloned_container.add_statement_at(x, point)
|
32
|
+
cloned_container
|
33
|
+
Cauldron::ActualizedComposite.new(cloned_container, examples)
|
34
|
+
end
|
35
|
+
|
36
|
+
def context_realizable?(context)
|
37
|
+
|
38
|
+
vars = context.keys.select {|x| x.match(/var\d/) }
|
39
|
+
var_names = vars.collect(&:to_s)
|
40
|
+
|
41
|
+
a = %Q{
|
42
|
+
def function(var0)
|
43
|
+
#{Sorcerer.source(to_sexp(Cauldron::Scope.new(var_names), []), indent: true)}
|
44
|
+
end
|
45
|
+
}
|
46
|
+
|
47
|
+
o = Object.new
|
48
|
+
o.instance_eval(a)
|
49
|
+
|
50
|
+
begin
|
51
|
+
o.function(vars.collect {|x| context[x] })
|
52
|
+
rescue NoMethodError => e
|
53
|
+
return false
|
54
|
+
rescue StandardError => e
|
55
|
+
puts e
|
56
|
+
end
|
57
|
+
return true
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
def write_to_file(filename)
|
62
|
+
FileUtils.mkdir_p File.join('tmp')
|
63
|
+
File.open( File.join('tmp',filename), 'w+') do |file|
|
64
|
+
file << "class DynamicOperator"+"\n"
|
65
|
+
file << Sorcerer.source(@sexp_methods, indent: true)
|
66
|
+
file << "\n"
|
67
|
+
file << "end"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def rip2
|
72
|
+
%Q{
|
73
|
+
def function(var0)
|
74
|
+
#{Sorcerer.source(to_sexp(Cauldron::Scope.new(['var0'])), indent: true)}
|
75
|
+
end
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
def rip(composite,examples)
|
80
|
+
Ripper::SexpBuilder.new(
|
81
|
+
%Q{
|
82
|
+
def function(var0)
|
83
|
+
#{composite.to_ruby(examples.scope)}
|
84
|
+
end
|
85
|
+
}).parse
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
module Cauldron
|
2
|
+
|
3
|
+
module DynamicOperatorModule
|
4
|
+
|
5
|
+
def uses_constants?
|
6
|
+
@information[:constants]
|
7
|
+
end
|
8
|
+
|
9
|
+
def indexes=(value)
|
10
|
+
raise StandardError.new('') if @closed
|
11
|
+
@indexes = value
|
12
|
+
end
|
13
|
+
|
14
|
+
def close
|
15
|
+
@closed = true
|
16
|
+
end
|
17
|
+
|
18
|
+
def clone_statement
|
19
|
+
# TODO Need to clone the sexp methods
|
20
|
+
# o = DynamicOperator.new(@information, @sexp_methods)
|
21
|
+
# o.instance_eval(Sorcerer.source(@sexp_methods, indent: true))
|
22
|
+
# o
|
23
|
+
self.class.new(@indexes.clone)
|
24
|
+
end
|
25
|
+
|
26
|
+
# def context_instances(contexts)
|
27
|
+
# results = []
|
28
|
+
# contexts.each do |context|
|
29
|
+
# results << context.keys.collect(&:to_s).select {|x| x.match(/var\d/) }
|
30
|
+
# end
|
31
|
+
# results = results.flatten.uniq
|
32
|
+
# variable_numbers = results.collect { |x| x.match(/var(\d+)/)[1] }
|
33
|
+
# variable_numbers.collect { |x| init([x.to_i])}
|
34
|
+
# end
|
35
|
+
|
36
|
+
# def extend_actualized_composite(x, container, examples, point)
|
37
|
+
# cloned_container = container.clone_solution
|
38
|
+
# cloned_container.add_statement_at(x, point)
|
39
|
+
# cloned_container
|
40
|
+
# Cauldron::ActualizedComposite.new(cloned_container, examples)
|
41
|
+
# end
|
42
|
+
|
43
|
+
def context_realizable?(context)
|
44
|
+
|
45
|
+
vars = context.keys.select {|x| x.match(/var\d/) }
|
46
|
+
var_names = vars.collect(&:to_s)
|
47
|
+
|
48
|
+
first_variable = 'var'+@indexes[0].to_s
|
49
|
+
|
50
|
+
# a = %Q{
|
51
|
+
# def function(var0)
|
52
|
+
# #{Sorcerer.source(to_sexp(var_names), indent: true)}
|
53
|
+
# end
|
54
|
+
# }
|
55
|
+
# a = %Q{
|
56
|
+
# def function(var0)
|
57
|
+
# #{Sorcerer.source(to_sexp(Cauldron::Scope.new(var_names), []), indent: true)}
|
58
|
+
# end
|
59
|
+
# }
|
60
|
+
a = %Q{
|
61
|
+
def function(#{first_variable})
|
62
|
+
#{Sorcerer.source(to_sexp(Cauldron::Scope.new(var_names), []), indent: true)}
|
63
|
+
end
|
64
|
+
}
|
65
|
+
|
66
|
+
o = Object.new
|
67
|
+
o.instance_eval(a)
|
68
|
+
|
69
|
+
begin
|
70
|
+
#o.function(*vars.collect {|x| context[x] })
|
71
|
+
o.function context[first_variable.to_sym]
|
72
|
+
rescue NoMethodError => e
|
73
|
+
return false
|
74
|
+
rescue StandardError => e
|
75
|
+
puts e
|
76
|
+
return false
|
77
|
+
end
|
78
|
+
return true
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
#o.function(*params.values)
|
83
|
+
|
84
|
+
# a = %Q{
|
85
|
+
# def function(var0)
|
86
|
+
# #{Sorcerer.source(to_sexp(Cauldron::Scope.new(['var0'])), indent: true)}
|
87
|
+
# end
|
88
|
+
# }
|
89
|
+
end
|
90
|
+
|
91
|
+
def write_to_file(filename)
|
92
|
+
File.open( File.join('tmp',filename), 'w+') do |file|
|
93
|
+
file << "class DynamicOperator"+"\n"
|
94
|
+
file << Sorcerer.source(@sexp_methods, indent: true)
|
95
|
+
file << "\n"
|
96
|
+
file << "end"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def rip(composite,examples)
|
101
|
+
Ripper::SexpBuilder.new(
|
102
|
+
%Q{
|
103
|
+
def function(var0)
|
104
|
+
#{composite.to_ruby(examples.scope)}
|
105
|
+
end
|
106
|
+
}).parse
|
107
|
+
end
|
108
|
+
|
109
|
+
# def to_tracking_sexp(operators, scope, caret)
|
110
|
+
# raise StandardError.new('statement has been instance closed') unless @closed
|
111
|
+
# to_sexp(scope)
|
112
|
+
# end
|
113
|
+
|
114
|
+
def realizable?(histories, point)
|
115
|
+
parameters = histories.variable_permutations(@indexes.length)
|
116
|
+
parameters.each do |params|
|
117
|
+
begin
|
118
|
+
realize(params)
|
119
|
+
rescue => e
|
120
|
+
puts e
|
121
|
+
failed_uses.push(histories)
|
122
|
+
return false
|
123
|
+
end
|
124
|
+
end
|
125
|
+
true
|
126
|
+
rescue => e
|
127
|
+
puts e
|
128
|
+
puts e.backtrace
|
129
|
+
# TODO GENERATE RSPEC TEST with arguments
|
130
|
+
end
|
131
|
+
|
132
|
+
def realize(params)
|
133
|
+
o = Object.new
|
134
|
+
o.instance_eval(rip2)
|
135
|
+
o.function(*params.values)
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Cauldron
|
2
|
+
|
3
|
+
class Example
|
4
|
+
|
5
|
+
attr_reader :arguments, :response
|
6
|
+
|
7
|
+
def initialize(hash)
|
8
|
+
@arguments, @response = hash[:arguments], hash[:response]
|
9
|
+
@arguments.freeze
|
10
|
+
end
|
11
|
+
|
12
|
+
def params
|
13
|
+
(0...@arguments.length).collect {|x| 'var'+x.to_s}
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Cauldron
|
2
|
+
|
3
|
+
class ExampleSet
|
4
|
+
|
5
|
+
attr_reader :examples
|
6
|
+
|
7
|
+
def initialize(examples)
|
8
|
+
@examples = examples
|
9
|
+
end
|
10
|
+
|
11
|
+
def variables
|
12
|
+
args = examples.first.arguments
|
13
|
+
(0...args.length).collect {|x| 'var'+x.to_s}
|
14
|
+
end
|
15
|
+
|
16
|
+
def all?(&block)
|
17
|
+
examples.all?(&block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def collect(&block)
|
21
|
+
examples.collect(&block)
|
22
|
+
end
|
23
|
+
|
24
|
+
# TODO Might drop - limit access
|
25
|
+
def each_with_index(&block)
|
26
|
+
examples.each_with_index(&block)
|
27
|
+
end
|
28
|
+
|
29
|
+
def scope
|
30
|
+
sexp = Ripper::SexpBuilder.new(examples.first.params.to_s).parse
|
31
|
+
Cauldron::Scope.new(eval(Sorcerer.source(sexp)))
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Cauldron
|
2
|
+
|
3
|
+
class Histories
|
4
|
+
|
5
|
+
def initialize(results)
|
6
|
+
@results = results
|
7
|
+
end
|
8
|
+
|
9
|
+
def variable_permutations(count)
|
10
|
+
variables = @results.first.logs.first.keys.select { |x| x.match /var/ }
|
11
|
+
v = Hash[*variables.collect {|x| [x,nil]}.flatten]
|
12
|
+
|
13
|
+
@results.collect do |history|
|
14
|
+
history.logs.collect do |a|
|
15
|
+
Hash[*v.keys.collect do |x|
|
16
|
+
[x, a[x] ]
|
17
|
+
end.flatten(1)]
|
18
|
+
end
|
19
|
+
end.flatten
|
20
|
+
end
|
21
|
+
|
22
|
+
def each(&block)
|
23
|
+
@results.each(&block)
|
24
|
+
end
|
25
|
+
|
26
|
+
def first
|
27
|
+
@results.first
|
28
|
+
end
|
29
|
+
|
30
|
+
def length
|
31
|
+
@results.length
|
32
|
+
end
|
33
|
+
|
34
|
+
def insert_points
|
35
|
+
@results.inject([]) { |total, x| total += x.insert_points; total }.uniq
|
36
|
+
end
|
37
|
+
|
38
|
+
def contexts_at(point)
|
39
|
+
a = []
|
40
|
+
@results.each do |history|
|
41
|
+
a += history.logs.inject([]) do |total,log|
|
42
|
+
if log[:point] == point
|
43
|
+
total << log
|
44
|
+
end
|
45
|
+
total
|
46
|
+
end
|
47
|
+
end
|
48
|
+
a
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|