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
@@ -0,0 +1,74 @@
|
|
1
|
+
#http://www.ruby-doc.org/core-2.1.1/Hash.html
|
2
|
+
#hsh[key] → value
|
3
|
+
class HashKeyValueOperator
|
4
|
+
|
5
|
+
# var0[:foo]
|
6
|
+
|
7
|
+
def initialize(indexes)
|
8
|
+
@indexes = indexes
|
9
|
+
@constant = :foo
|
10
|
+
#@constant, @indexes = constant, indexes
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.viable?(arguments, response)
|
14
|
+
return false unless arguments.all? { |x| x.kind_of?(Hash) }
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.uses_constants?
|
19
|
+
true
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.find_constants(problems)
|
23
|
+
problems.collect {|x| x.arguments.first.keys }.flatten
|
24
|
+
end
|
25
|
+
|
26
|
+
def successful?(problem)
|
27
|
+
if problem.arguments.first[@constant] == problem.response
|
28
|
+
return true
|
29
|
+
end
|
30
|
+
return false
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_ruby(scope, operators)
|
34
|
+
Sorcerer.source self.to_sexp(scope, operators)
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_sexp(scope, operators)
|
38
|
+
[:aref,
|
39
|
+
[:vcall,
|
40
|
+
[:@ident, scope[0]]
|
41
|
+
],
|
42
|
+
[:args_add_block,
|
43
|
+
[
|
44
|
+
:args_add,
|
45
|
+
[:args_new],
|
46
|
+
sexp_index
|
47
|
+
]
|
48
|
+
]
|
49
|
+
]
|
50
|
+
end
|
51
|
+
|
52
|
+
def sexp_index
|
53
|
+
if @constant.kind_of?(Symbol)
|
54
|
+
a = [
|
55
|
+
:symbol_literal,
|
56
|
+
[:symbol, [:@ident, @constant]],
|
57
|
+
[:string_add, [:@ident, @constant]]
|
58
|
+
]
|
59
|
+
return a
|
60
|
+
elsif @constant.kind_of?(String)
|
61
|
+
return [
|
62
|
+
:string_literal,
|
63
|
+
[
|
64
|
+
:string_add,
|
65
|
+
[:string_content],
|
66
|
+
[:@tstring_content, @constant ]
|
67
|
+
]
|
68
|
+
]
|
69
|
+
else
|
70
|
+
raise StandardError.new('Unknown index')
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
class NumericOperator
|
2
|
+
|
3
|
+
include Cauldron::Operator
|
4
|
+
|
5
|
+
# Maybe NumericOperation
|
6
|
+
ADDITION = 4
|
7
|
+
|
8
|
+
def initialize(indexes)
|
9
|
+
@indexes = indexes
|
10
|
+
end
|
11
|
+
|
12
|
+
# Is the problem suitable for a numeric operatio?
|
13
|
+
# e.g. can the .find_contants call be called without error
|
14
|
+
def self.viable?(arguments,output)
|
15
|
+
|
16
|
+
# 1. Only has one argument value
|
17
|
+
# 2. Argument is a numeric value
|
18
|
+
# 3. Response is numeric
|
19
|
+
|
20
|
+
# TODO Need to save these viablility tests in shared (easily comparable) state.
|
21
|
+
# e.g. so all viable operations can be found in one go.
|
22
|
+
|
23
|
+
return false unless arguments.all? { |x| x.kind_of?(Numeric) }
|
24
|
+
return false unless output.kind_of?(Numeric)
|
25
|
+
true
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
def realizable?(histories)
|
30
|
+
parameters = histories.variable_permutations(@indexes.length)
|
31
|
+
parameters.each do |params|
|
32
|
+
begin
|
33
|
+
realize(params)
|
34
|
+
rescue TypeError
|
35
|
+
return false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
true
|
39
|
+
end
|
40
|
+
|
41
|
+
def realize(params)
|
42
|
+
o = Object.new
|
43
|
+
a = %Q{
|
44
|
+
def function(var0)
|
45
|
+
#{Sorcerer.source(to_sexp(Cauldron::Scope.new(['var0']),[]), indent: true)}
|
46
|
+
end
|
47
|
+
}
|
48
|
+
o.instance_eval(a)
|
49
|
+
o.function(*params.values)
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_sexp(scope, operators)
|
53
|
+
[:binary, [:@ident, scope[@indexes[0]] ] , :+, [:@int, ADDITION.to_s]]
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_ruby(scope, operators)
|
57
|
+
Sorcerer.source self.to_sexp(scope, operators)
|
58
|
+
end
|
59
|
+
|
60
|
+
def build(operators, scope)
|
61
|
+
to_sexp(scope)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Operator for "x + n" e.g. x + 1
|
65
|
+
# Does the input match the answer
|
66
|
+
def successful?(problem)
|
67
|
+
if (problem[:arguments].first + ADDITION) == problem[:response]
|
68
|
+
return true
|
69
|
+
end
|
70
|
+
return false
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.find_constants(problems)
|
74
|
+
problems.collect {|x| x.response - x.arguments.first }.uniq
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.uses_constants?
|
78
|
+
true
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.uses_block?
|
82
|
+
false
|
83
|
+
end
|
84
|
+
|
85
|
+
def branch?
|
86
|
+
false
|
87
|
+
end
|
88
|
+
|
89
|
+
def context_realizable?(context)
|
90
|
+
vars = context.keys.select {|x| x.match(/var\d/) }
|
91
|
+
var_names = vars.collect(&:to_s)
|
92
|
+
|
93
|
+
first_variable = 'var'+@indexes[0].to_s
|
94
|
+
|
95
|
+
a = %Q{
|
96
|
+
def function(#{first_variable})
|
97
|
+
#{Sorcerer.source(to_sexp(Cauldron::Scope.new(var_names), []), indent: true)}
|
98
|
+
end
|
99
|
+
}
|
100
|
+
|
101
|
+
o = Object.new
|
102
|
+
o.instance_eval(a)
|
103
|
+
|
104
|
+
begin
|
105
|
+
#o.function(*vars.collect {|x| context[x] })
|
106
|
+
o.function context[first_variable.to_sym]
|
107
|
+
rescue NoMethodError => e
|
108
|
+
return false
|
109
|
+
rescue StandardError => e
|
110
|
+
puts e
|
111
|
+
end
|
112
|
+
return true
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
class StringAsteriskOperator
|
2
|
+
|
3
|
+
# var0 * 3
|
4
|
+
|
5
|
+
# TODO Possibly include the scope of the index
|
6
|
+
# a = 5
|
7
|
+
# ['sdsd'].each do |b|
|
8
|
+
# c = 5
|
9
|
+
# end
|
10
|
+
# (1...6).each do |d|
|
11
|
+
# g = d
|
12
|
+
# end
|
13
|
+
|
14
|
+
# [0] = ['a']
|
15
|
+
# [1] = ['b', 'c']
|
16
|
+
# [2] = ['g', 'd']
|
17
|
+
|
18
|
+
# Although it should probably be
|
19
|
+
# [0] = [ ['a'] ]
|
20
|
+
# [1] = [ ['b', 'c'], ['g', 'd'] ]
|
21
|
+
#
|
22
|
+
# Or the order it was added might be more useful - e.g. last variable, second last variable or first variable
|
23
|
+
# - variable at depth(1)[1] - stepUp(1).first
|
24
|
+
|
25
|
+
def initialize(indexes)
|
26
|
+
@indexes = indexes
|
27
|
+
@constant = 2
|
28
|
+
#@constant, @indexes = constant, indexes
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.instances(histories, composite, examples, insert_points)
|
32
|
+
|
33
|
+
# TEMP
|
34
|
+
unless examples.class == ExampleSet
|
35
|
+
raise StandardError.new('Examples should be an example')
|
36
|
+
end
|
37
|
+
|
38
|
+
# Print out each insertable statements
|
39
|
+
scope = examples.scope
|
40
|
+
|
41
|
+
# self.init([0]).to_ruby(scope)
|
42
|
+
# - this will print out "var0.chop"
|
43
|
+
|
44
|
+
# Get the variables available at each point
|
45
|
+
results = []
|
46
|
+
|
47
|
+
insert_points.each do |point|
|
48
|
+
|
49
|
+
# Find the variables at a particular point
|
50
|
+
# TODO Change to test
|
51
|
+
contexts = histories.contexts_at(point)
|
52
|
+
composites = context_instances(contexts)
|
53
|
+
|
54
|
+
composites.each do |x|
|
55
|
+
if contexts.all? do |context|
|
56
|
+
x.context_realizable?(context)
|
57
|
+
end
|
58
|
+
results << extend_actualized_composite(x, composite, examples, point)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
results
|
65
|
+
end
|
66
|
+
|
67
|
+
# def self.instances(context_history, target)
|
68
|
+
# res = history_goals(context_history, target)
|
69
|
+
|
70
|
+
# possible_constant = res.collect do |x|
|
71
|
+
# x[1].scan( x[0][:x] ).count
|
72
|
+
# end.uniq
|
73
|
+
|
74
|
+
# if possible_constant.length == 1
|
75
|
+
# #return [StringAsteriskOperator.new([1],possible_constant.first)]
|
76
|
+
# return [StringAsteriskOperator.new([1])]
|
77
|
+
# end
|
78
|
+
|
79
|
+
# end
|
80
|
+
|
81
|
+
def self.history_goals(context_history,target)
|
82
|
+
variables = context_history.first.keys
|
83
|
+
context_history.each {|x| x[variables.first] }.zip(target)
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.find_constants(problems)
|
87
|
+
return [] unless problems.all? { |x| x.response.kind_of?(String) }
|
88
|
+
problems.collect {|x| x.response.scan(x.arguments.first).count }.reject {|x| x == 0}
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.viable?(arguments,output)
|
92
|
+
return false unless output.kind_of?(String)
|
93
|
+
return false unless arguments.first.kind_of?(String)
|
94
|
+
true
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.uses_constants?
|
98
|
+
true
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.uses_block?
|
102
|
+
false
|
103
|
+
end
|
104
|
+
|
105
|
+
def branch?
|
106
|
+
false
|
107
|
+
end
|
108
|
+
|
109
|
+
def successful?(problem)
|
110
|
+
return true if problem[:arguments].first*@constant == problem[:response]
|
111
|
+
false
|
112
|
+
end
|
113
|
+
|
114
|
+
def to_ruby(scope, operators)
|
115
|
+
Sorcerer.source self.to_sexp([], scope)
|
116
|
+
end
|
117
|
+
|
118
|
+
# def to_sexp(operators, scope)
|
119
|
+
# [:binary, [:vcall, [:@ident, scope[@indexes[0]] ]], :*, [:@int, @constant]]
|
120
|
+
# end
|
121
|
+
def to_sexp(scope, children)
|
122
|
+
first_variable = 'var'+@indexes[0].to_s
|
123
|
+
Ripper::SexpBuilder.new(%Q{#{first_variable} * #{@constant}}).parse
|
124
|
+
end
|
125
|
+
|
126
|
+
# TODO Get rid of the defined names
|
127
|
+
def build(operators, scope)
|
128
|
+
to_sexp(operators, scope)
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Cauldron
|
2
|
+
|
3
|
+
class VarCollectOperator
|
4
|
+
|
5
|
+
def initialize(indexes)
|
6
|
+
@indexes = indexes
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_ruby(contents, variables)
|
10
|
+
Sorcerer.source self.to_sexp( contents ,variables)
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_sexp(scope, operators)
|
14
|
+
scope_var = scope.new_variable!
|
15
|
+
second_scope_var = scope.new_variable!
|
16
|
+
if operators.empty?
|
17
|
+
return [:stmts_add, [:stmts_new], [:assign, [:var_field, [:@ident, scope_var ]], [:method_add_block, [:call, [:vcall, [:@ident, scope[@indexes[0]]]], :".", [:@ident, "collect"]], [:do_block, [:block_var, [:params, [[:@ident, second_scope_var]], nil, nil, nil, nil, nil, nil], false], [:stmts_add, [:stmts_new], [:var_ref, [:@ident, second_scope_var]]]]]]]
|
18
|
+
else
|
19
|
+
return [:stmts_add, [:stmts_new], [:assign, [:var_field, [:@ident, scope_var ]], [:method_add_block, [:call, [:vcall, [:@ident, scope[@indexes[0]]]], :".", [:@ident, "collect"]], [:do_block, [:block_var, [:params, [[:@ident, second_scope_var]], nil, nil, nil, nil, nil, nil], false], [:stmts_add, [:stmts_new], operators.first.content.build([], scope) ]]]]]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def build(children, scope)
|
24
|
+
to_sexp(scope, children)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
data/lib/cauldron/pot.rb
CHANGED
@@ -4,20 +4,59 @@ module Cauldron
|
|
4
4
|
|
5
5
|
def solve(problems)
|
6
6
|
|
7
|
+
example_set = Cauldron::ExampleSet.new(problems.collect {|x| Cauldron::Example.new(x) })
|
8
|
+
|
7
9
|
# Identify the relationship
|
8
|
-
|
10
|
+
|
11
|
+
# Pry::Code
|
12
|
+
# TODO Change term to solution
|
13
|
+
if find_saved_solution(example_set)
|
14
|
+
variables = example_set.variables
|
15
|
+
solution = find_saved_solution(example_set)
|
16
|
+
sexp = Ripper::SexpBuilder.new('def function('+variables.join(',')+');'+solution.to_ruby(variables)+"; end").parse
|
17
|
+
return Sorcerer.source(sexp, indent: true)
|
18
|
+
end
|
19
|
+
relationship = find_relationship(example_set)
|
9
20
|
|
10
21
|
# Generate if statements
|
11
22
|
result = ''
|
12
23
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
24
|
+
variables = example_set.variables
|
25
|
+
#sexp = Ripper::SexpBuilder.new('def function('+variables.join(',')+');'+relationship.to_ruby(variables)+"; end").parse
|
26
|
+
sexp = Ripper::SexpBuilder.new('def function('+variables.join(',')+');'+relationship.to_ruby(example_set.scope)+"; end").parse
|
27
|
+
|
28
|
+
Sorcerer.source(sexp, indent: true)
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
def chain_operators(problems,operators)
|
33
|
+
# TODO Presumes only two operators
|
34
|
+
|
35
|
+
operators[0].to_ruby( [
|
36
|
+
Tree::TreeNode.new("CHILD1", operators[1])
|
37
|
+
], Cauldron::Scope.new(['var0']) )
|
38
|
+
end
|
39
|
+
|
40
|
+
def single_viable_operators(problems)
|
41
|
+
|
42
|
+
operations = [
|
43
|
+
NumericOperator, ArrayReverseOperator,
|
44
|
+
HashKeyValueOperator, StringAsteriskOperator,
|
45
|
+
ConcatOperator
|
46
|
+
]
|
47
|
+
|
48
|
+
# Try each possible operation
|
49
|
+
viable_option_classes = []
|
50
|
+
operations.each do |operation_class|
|
51
|
+
|
52
|
+
# Are all the problems viable for this operation
|
53
|
+
if problems.all? {|x| operation_class.viable?(x.arguments,x.response) }
|
54
|
+
viable_option_classes << operation_class
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
19
58
|
|
20
|
-
|
59
|
+
viable_option_classes
|
21
60
|
|
22
61
|
end
|
23
62
|
|
@@ -30,33 +69,104 @@ module Cauldron
|
|
30
69
|
value.to_s
|
31
70
|
end
|
32
71
|
|
33
|
-
def
|
72
|
+
def build_operators(operation_class,problems)
|
73
|
+
results = []
|
74
|
+
if operation_class.uses_constants?
|
75
|
+
|
76
|
+
possible_constants = operation_class.find_constants(problems)
|
34
77
|
|
35
|
-
|
78
|
+
possible_constants.each do |constant|
|
79
|
+
#operator = operation_class.new([0],constant)
|
80
|
+
operator = operation_class.new([0])
|
81
|
+
results << operator
|
82
|
+
end
|
83
|
+
else
|
36
84
|
|
37
|
-
|
38
|
-
|
85
|
+
# Does the operator always result in the correct solution
|
86
|
+
operator = operation_class.new([0])
|
87
|
+
results << operator
|
39
88
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
89
|
+
end
|
90
|
+
results
|
91
|
+
end
|
92
|
+
|
93
|
+
# BRUTE FORCE - Loop through all the solutions
|
94
|
+
def find_saved_solution examples
|
95
|
+
solutions = [
|
96
|
+
Cauldron::Solution::One.new
|
97
|
+
]
|
98
|
+
successful_solutions = solutions.select do |solution|
|
99
|
+
examples.all? { |problem| solution.successful?(problem) }
|
100
|
+
end
|
101
|
+
return successful_solutions[0] unless successful_solutions.empty?
|
102
|
+
nil
|
103
|
+
end
|
104
|
+
|
105
|
+
def find_relationship(examples)
|
106
|
+
|
107
|
+
# ==== NEW APPROACH ====
|
108
|
+
|
109
|
+
new_composites = [
|
110
|
+
Cauldron::ActualizedComposite.new(
|
111
|
+
Cauldron::Solution::Composite.new([]),
|
112
|
+
examples
|
113
|
+
)
|
114
|
+
]
|
115
|
+
itterations = 0
|
116
|
+
until itterations == 2
|
117
|
+
|
118
|
+
new_composites = extended_composites(new_composites)
|
119
|
+
|
120
|
+
if new_composites.any? {|x| x.solution?(examples) }
|
121
|
+
return new_composites.select {|x| x.solution?(examples) }.first.composite
|
122
|
+
end
|
123
|
+
itterations += 1
|
124
|
+
end
|
125
|
+
|
126
|
+
# 1. TRY TO FIND SOLUTION via the history
|
127
|
+
# 2. Desired history
|
128
|
+
# 3. Chaing matching history
|
129
|
+
|
130
|
+
# ================== END HERE ===============
|
131
|
+
|
132
|
+
solutions = []
|
133
|
+
single_viable_operators(examples).each do |operation_class|
|
134
|
+
|
135
|
+
operators = build_operators(operation_class,examples)
|
136
|
+
operators.each do |operator|
|
137
|
+
root = Tree::TreeNode.new("ROOT", "Root Content")
|
138
|
+
root << Tree::TreeNode.new("CHILD1", operator)
|
139
|
+
solutions << Cauldron::Solution::Composite.new(root.children)
|
51
140
|
end
|
141
|
+
end
|
52
142
|
|
143
|
+
solutions.each do |solution|
|
144
|
+
if solution.solution?(examples)
|
145
|
+
return solution
|
146
|
+
end
|
53
147
|
end
|
54
148
|
|
55
|
-
|
56
|
-
|
149
|
+
# operator_chains = viable_double_operators(problems)
|
150
|
+
|
151
|
+
# operator_chains.each do |operators|
|
152
|
+
|
153
|
+
# code = build_chain_operator(operators,problems)
|
154
|
+
# if problems.all? {|x| code.successful?(x) }
|
155
|
+
# return code
|
156
|
+
# end
|
157
|
+
# end
|
158
|
+
|
159
|
+
if IfRelationship.match? examples
|
160
|
+
return IfRelationship.new(examples)
|
57
161
|
end
|
58
|
-
IfRelationShip.new(
|
162
|
+
IfRelationShip.new(examples)
|
59
163
|
end
|
164
|
+
|
165
|
+
def extended_composites(actualized_composites)
|
166
|
+
actualized_composites.inject([]) do |total, x|
|
167
|
+
total += x.extend_solution; total
|
168
|
+
end
|
169
|
+
end
|
60
170
|
|
61
171
|
end
|
62
172
|
|