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,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
|
|