cauldron 0.1.3 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +51 -0
- data/Gemfile +6 -3
- data/Gemfile.lock +16 -3
- data/Rakefile +94 -92
- data/VERSION +1 -1
- data/bin/cauldron +2 -2
- data/cauldron.gemspec +15 -451
- data/features/cauldron_new_approach.feature +46 -0
- data/features/step_definitions/cauldron_steps.rb +11 -0
- data/features/step_definitions/terminal_steps.rb +0 -2
- data/features/support/env.rb +11 -1
- data/features/support/hooks.rb +5 -0
- data/lib/cauldron.rb +13 -7
- data/lib/cauldron/array_reverse_operator.rb +39 -0
- data/lib/cauldron/concat_operator.rb +34 -0
- data/lib/cauldron/if_relationship.rb +37 -0
- data/lib/cauldron/numeric_operator.rb +45 -0
- data/lib/cauldron/pot.rb +54 -162
- data/lib/cauldron/relationship.rb +5 -0
- data/lib/cauldron/terminal.rb +4 -60
- data/lib/cauldron/version.rb +3 -0
- data/lib/core/string.rb +21 -0
- data/sandbox.rb +27 -6
- data/spec/cauldron/array_reverse_operator_spec.rb +59 -0
- data/spec/cauldron/concat_operator_spec.rb +89 -0
- data/spec/cauldron/if_relationship_spec.rb +25 -0
- data/spec/cauldron/numeric_operator_spec.rb +70 -0
- data/spec/cauldron/pot_spec.rb +81 -151
- data/spec/cauldron/terminal_spec.rb +1 -39
- data/spec/examples/adding_if_statement.yml +13 -0
- data/spec/examples/simple_head_theory.txt +13 -0
- data/spec/spec_helper.rb +1 -14
- data/tasks/theory_tasks.rake +207 -207
- metadata +92 -532
- data/cauldron/.autotest +0 -23
- data/cauldron/History.txt +0 -6
- data/cauldron/Manifest.txt +0 -8
- data/cauldron/README.txt +0 -57
- data/cauldron/Rakefile +0 -27
- data/cauldron/bin/cauldron +0 -3
- data/cauldron/lib/cauldron.rb +0 -3
- data/cauldron/test/test_cauldron.rb +0 -8
- data/features/cauldron_example_cases.feature +0 -13
- data/features/cauldron_generates_runtime_method.feature +0 -16
- data/features/cauldron_generates_single_paramter_methods.feature +0 -25
- data/features/cauldron_interactive_start_terminal.feature +0 -17
- data/features/cauldron_quit_terminal.feature +0 -9
- data/features/cauldron_start_terminal.feature +0 -12
- data/features/support/method_1.example +0 -3
- data/features/support/method_2.example +0 -6
- data/lib/Chain.rb +0 -771
- data/lib/ChainMapping.rb +0 -172
- data/lib/CodeHandler.rb +0 -513
- data/lib/Mapping.rb +0 -27
- data/lib/MappingValues.rb +0 -24
- data/lib/PartialChain.rb +0 -253
- data/lib/Theory.rb +0 -295
- data/lib/UnifiedChain.rb +0 -351
- data/lib/cauldron/conversion.rb +0 -15
- data/lib/cauldron/demos.rb +0 -280
- data/lib/cauldron/env.rb +0 -1
- data/lib/cauldron/sexp2cauldron.rb +0 -139
- data/lib/cauldron/theory_factory.rb +0 -10
- data/lib/cauldron/util/home.rb +0 -21
- data/lib/cauldron/util/saver.rb +0 -45
- data/lib/core/ActsAsCode.rb +0 -25
- data/lib/core/BlockToken.rb +0 -33
- data/lib/core/CCall.rb +0 -7
- data/lib/core/CTestCase.rb +0 -27
- data/lib/core/ClassMethodCallContainer.rb +0 -58
- data/lib/core/Container.rb +0 -95
- data/lib/core/InstanceCallContainer.rb +0 -298
- data/lib/core/MethodUsage.rb +0 -65
- data/lib/core/PrintVariables.rb +0 -25
- data/lib/core/TheoryGenerator.rb +0 -753
- data/lib/core/Token.rb +0 -7
- data/lib/core/assignment/Assignment.rb +0 -18
- data/lib/core/assignment/Equal.rb +0 -39
- data/lib/core/assignment/Equivalent.rb +0 -20
- data/lib/core/assignment/NotEqual.rb +0 -14
- data/lib/core/call_container/CallContainer.rb +0 -72
- data/lib/core/class_method_call/New.rb +0 -15
- data/lib/core/class_method_call/RuntimeClassMethodCall.rb +0 -31
- data/lib/core/declaration/Declaration.rb +0 -16
- data/lib/core/declaration/LiteralDeclaration.rb +0 -47
- data/lib/core/declaration/VariableDeclaration.rb +0 -59
- data/lib/core/instance_call/ArrayEach.rb +0 -23
- data/lib/core/instance_call/ArrayLength.rb +0 -15
- data/lib/core/instance_call/Chop.rb +0 -19
- data/lib/core/instance_call/Copy.rb +0 -22
- data/lib/core/instance_call/DeclaredVariable.rb +0 -18
- data/lib/core/instance_call/InstanceCall.rb +0 -77
- data/lib/core/instance_call/Params.rb +0 -15
- data/lib/core/instance_call/Push.rb +0 -20
- data/lib/core/instance_call/StringLength.rb +0 -32
- data/lib/core/instance_call/Times.rb +0 -20
- data/lib/core/instance_call/instance_calls.rb +0 -176
- data/lib/core/instance_call/length_equal.rb +0 -15
- data/lib/core/kernal/EvalCall.rb +0 -15
- data/lib/core/kernal/LocalVariablesCall.rb +0 -15
- data/lib/core/literal/Literal.rb +0 -111
- data/lib/core/literal/Raw.rb +0 -23
- data/lib/core/literal/RuntimeMethodLiteral.rb +0 -21
- data/lib/core/literal/StatementLiteral.rb +0 -28
- data/lib/core/method_call/AvailableVariablesCall.rb +0 -25
- data/lib/core/method_call/ClassCall.rb +0 -33
- data/lib/core/method_call/DefCall.rb +0 -72
- data/lib/core/method_call/EvaluateClassCall.rb +0 -29
- data/lib/core/method_call/MethodNameCall.rb +0 -27
- data/lib/core/method_call/ToDeclarationCall.rb +0 -15
- data/lib/core/requirement/Requirement.rb +0 -292
- data/lib/core/runtime_class/ArrayClass.rb +0 -19
- data/lib/core/runtime_class/ClassCallClass.rb +0 -23
- data/lib/core/runtime_class/ClassEvaluationClass.rb +0 -19
- data/lib/core/runtime_class/ClassName.rb +0 -18
- data/lib/core/runtime_class/DefCallClass.rb +0 -21
- data/lib/core/runtime_class/EqualClass.rb +0 -19
- data/lib/core/runtime_class/FixnumClass.rb +0 -15
- data/lib/core/runtime_class/InstanceCallClass.rb +0 -19
- data/lib/core/runtime_class/InstanceCallContainerClass.rb +0 -16
- data/lib/core/runtime_class/InstanceClassCallClass.rb +0 -19
- data/lib/core/runtime_class/LiteralClass.rb +0 -19
- data/lib/core/runtime_class/MethodParameterClass.rb +0 -27
- data/lib/core/runtime_class/MethodUsageClass.rb +0 -27
- data/lib/core/runtime_class/RequirementClass.rb +0 -19
- data/lib/core/runtime_class/ReturnClass.rb +0 -21
- data/lib/core/runtime_class/RuntimeClass.rb +0 -30
- data/lib/core/runtime_class/RuntimeClassClass.rb +0 -19
- data/lib/core/runtime_class/RuntimeMethodClass.rb +0 -34
- data/lib/core/runtime_class/StatementClass.rb +0 -53
- data/lib/core/runtime_class/StringClass.rb +0 -23
- data/lib/core/runtime_class/StringLengthClass.rb +0 -19
- data/lib/core/runtime_class/StringVariableClass.rb +0 -19
- data/lib/core/runtime_class/ThisClass.rb +0 -15
- data/lib/core/runtime_class/UnknownClass.rb +0 -23
- data/lib/core/runtime_class/class_names.rb +0 -95
- data/lib/core/runtime_class/runtime_class.rb +0 -123
- data/lib/core/runtime_method/ActsAsRuntimeMethod.rb +0 -293
- data/lib/core/runtime_method/ParametersContainer.rb +0 -29
- data/lib/core/runtime_method/RealisedRuntimeMethod.rb +0 -94
- data/lib/core/runtime_method/RuntimeMethod.rb +0 -814
- data/lib/core/runtime_method/WriteParameters.rb +0 -35
- data/lib/core/statement/ActsAsStatement.rb +0 -20
- data/lib/core/statement/ArrayAccess.rb +0 -122
- data/lib/core/statement/BlockStatement.rb +0 -348
- data/lib/core/statement/DeclarationStatement.rb +0 -19
- data/lib/core/statement/HackStatement.rb +0 -25
- data/lib/core/statement/HashAccess.rb +0 -18
- data/lib/core/statement/OpenStatement.rb +0 -178
- data/lib/core/statement/RealisedStatement.rb +0 -5
- data/lib/core/statement/SingleLineBlockStatement.rb +0 -39
- data/lib/core/statement/Statement.rb +0 -1091
- data/lib/core/statement/StatementGroup.rb +0 -157
- data/lib/core/statement/StatementStructure2.rb +0 -224
- data/lib/core/statement/TheoryStatement.rb +0 -68
- data/lib/core/statement/TopologicalStatements.rb +0 -34
- data/lib/core/syntax/Addition.rb +0 -26
- data/lib/core/syntax/BlockContainer.rb +0 -102
- data/lib/core/syntax/Boolean.rb +0 -15
- data/lib/core/syntax/Code.rb +0 -11
- data/lib/core/syntax/Do.rb +0 -20
- data/lib/core/syntax/False.rb +0 -12
- data/lib/core/syntax/If.rb +0 -36
- data/lib/core/syntax/Nil.rb +0 -15
- data/lib/core/syntax/Return.rb +0 -33
- data/lib/core/syntax/Subtract.rb +0 -19
- data/lib/core/syntax/This.rb +0 -40
- data/lib/core/syntax/True.rb +0 -20
- data/lib/core/syntax/syntax.rb +0 -24
- data/lib/core/tracking/ActsAsTrackable.rb +0 -65
- data/lib/core/tracking/History.rb +0 -167
- data/lib/core/tracking/RuntimeTrackingMethod.rb +0 -32
- data/lib/core/tracking/Step.rb +0 -52
- data/lib/core/variable/ArrayVariable.rb +0 -76
- data/lib/core/variable/BaseVariable.rb +0 -152
- data/lib/core/variable/BlockVariable.rb +0 -92
- data/lib/core/variable/FixnumVariable.rb +0 -35
- data/lib/core/variable/HistoryVariable.rb +0 -8
- data/lib/core/variable/MethodParameter.rb +0 -179
- data/lib/core/variable/MethodUsageVariable.rb +0 -60
- data/lib/core/variable/NilVariable.rb +0 -29
- data/lib/core/variable/RuntimeMethodParameter.rb +0 -67
- data/lib/core/variable/StatementVariable.rb +0 -72
- data/lib/core/variable/StepVariable.rb +0 -7
- data/lib/core/variable/StringVariable.rb +0 -46
- data/lib/core/variable/TypeVariable.rb +0 -72
- data/lib/core/variable/Unknown.rb +0 -102
- data/lib/core/variable/UnknownVariable.rb +0 -29
- data/lib/core/variable/Variable.rb +0 -70
- data/lib/core/variable/VariableContainer.rb +0 -28
- data/lib/core/variable/VariableIncluded.rb +0 -27
- data/lib/core/variable/VariableReference.rb +0 -85
- data/lib/error/FailedToFindStatementContainerError.rb +0 -7
- data/lib/error/FailedToFindStatementError.rb +0 -7
- data/lib/error/FailedToFindVariableError.rb +0 -7
- data/lib/error/FailedToLiteraliseError.rb +0 -7
- data/lib/error/FailedVariableMatch.rb +0 -7
- data/lib/error/ImproperStatementUsageError.rb +0 -7
- data/lib/error/IncompatiableRequirementsError.rb +0 -7
- data/lib/error/InvalidStatementError.rb +0 -7
- data/lib/error/MethodSizeError.rb +0 -7
- data/lib/error/RuntimeSyntaxError.rb +0 -7
- data/lib/error/UnexpectedStatementTypeError.rb +0 -7
- data/lib/error/UnknownStatementType.rb +0 -7
- data/lib/error/UnliteralisableError.rb +0 -7
- data/lib/implemented_chain.rb +0 -35
- data/lib/intrinsic/IntrinsicLastRuntimeMethod.rb +0 -20
- data/lib/intrinsic/IntrinsicLiteral.rb +0 -26
- data/lib/intrinsic/IntrinsicObject.rb +0 -22
- data/lib/intrinsic/IntrinsicRuntimeMethod.rb +0 -27
- data/lib/intrinsic/IntrinsicTestCases.rb +0 -17
- data/lib/logger/StandardLogger.rb +0 -62
- data/lib/required.rb +0 -222
- data/lib/ruby_code/Array.rb +0 -95
- data/lib/ruby_code/Fixnum.rb +0 -39
- data/lib/ruby_code/Hash.rb +0 -25
- data/lib/ruby_code/NilClass.rb +0 -19
- data/lib/ruby_code/Object.rb +0 -24
- data/lib/ruby_code/String.rb +0 -63
- data/lib/ruby_code/Symbol.rb +0 -7
- data/lib/standard_library/Tasks.rb +0 -12
- data/lib/theories.rb +0 -166
- data/lib/theory/ActionImplementation.rb +0 -17
- data/lib/theory/TheoryAction.rb +0 -100
- data/lib/theory/TheoryChainValidator.rb +0 -103
- data/lib/theory/TheoryComponent.rb +0 -59
- data/lib/theory/TheoryConnector.rb +0 -756
- data/lib/theory/TheoryDependent.rb +0 -135
- data/lib/theory/TheoryImplementation.rb +0 -75
- data/lib/theory/TheoryResult.rb +0 -131
- data/lib/theory/TheoryVariable.rb +0 -63
- data/lib/theory/theory_collection.rb +0 -62
- data/lib/util/ClassEvaluation.rb +0 -44
- data/lib/util/CodeEvaluation.rb +0 -39
- data/lib/util/DeclarationStatementEvaluation.rb +0 -32
- data/lib/util/MethodEvaluation.rb +0 -49
- data/lib/util/MethodTester.rb +0 -71
- data/lib/util/MethodValidation.rb +0 -149
- data/lib/util/MethodWriter.rb +0 -66
- data/lib/util/Parser.rb +0 -305
- data/lib/util/StatementCheck.rb +0 -44
- data/lib/util/StringToTheory.rb +0 -142
- data/lib/util/System.rb +0 -8
- data/spec/cauldron/chain_spec.rb +0 -24
- data/spec/cauldron/demos_spec.rb +0 -30
- data/spec/cauldron/runtime_method_spec.rb +0 -92
- data/spec/cauldron/saver_spec.rb +0 -45
- data/spec/cauldron/sexp_2_cauldron_spec.rb +0 -118
- data/spec/cauldron/theory_action_spec.rb +0 -25
- data/spec/cauldron/theory_connector_spec.rb +0 -52
- data/spec/cauldron/theory_spec.rb +0 -59
- data/spec/cauldron/unified_chain_spec.rb +0 -140
- data/test/fixtures/chains/1/declaration.txt +0 -26
- data/test/fixtures/chains/1/dump +0 -0
- data/test/fixtures/chains/2/declaration.txt +0 -26
- data/test/fixtures/chains/2/dump +0 -0
- data/test/fixtures/chains/3/declaration.txt +0 -26
- data/test/fixtures/chains/3/dump +0 -0
- data/test/fixtures/implementation_results/0/declaration.txt +0 -3
- data/test/fixtures/implementation_results/0/dump +0 -0
- data/test/fixtures/theories/0/declaration.txt +0 -9
- data/test/fixtures/theories/0/desc +0 -10
- data/test/fixtures/theories/0/dump +0 -0
- data/test/fixtures/theories/1/declaration.txt +0 -15
- data/test/fixtures/theories/1/desc +0 -11
- data/test/fixtures/theories/1/dump +0 -0
- data/test/fixtures/theories/10/declaration.txt +0 -23
- data/test/fixtures/theories/10/desc +0 -17
- data/test/fixtures/theories/10/dump +0 -0
- data/test/fixtures/theories/11/declaration.txt +0 -20
- data/test/fixtures/theories/11/desc +0 -14
- data/test/fixtures/theories/11/dump +0 -0
- data/test/fixtures/theories/12/declaration.txt +0 -18
- data/test/fixtures/theories/12/desc +0 -12
- data/test/fixtures/theories/12/dump +0 -0
- data/test/fixtures/theories/13/declaration.txt +0 -24
- data/test/fixtures/theories/13/desc +0 -20
- data/test/fixtures/theories/13/dump +0 -0
- data/test/fixtures/theories/14/declaration.txt +0 -26
- data/test/fixtures/theories/14/desc +0 -20
- data/test/fixtures/theories/14/dump +0 -0
- data/test/fixtures/theories/15/declaration.txt +0 -20
- data/test/fixtures/theories/15/desc +0 -14
- data/test/fixtures/theories/15/dump +0 -0
- data/test/fixtures/theories/16/declaration.txt +0 -30
- data/test/fixtures/theories/16/desc +0 -14
- data/test/fixtures/theories/16/dump +0 -0
- data/test/fixtures/theories/17/declaration.txt +0 -25
- data/test/fixtures/theories/17/desc +0 -11
- data/test/fixtures/theories/17/dump +0 -0
- data/test/fixtures/theories/18/declaration.txt +0 -23
- data/test/fixtures/theories/18/desc +0 -11
- data/test/fixtures/theories/18/dump +0 -0
- data/test/fixtures/theories/19/declaration.txt +0 -23
- data/test/fixtures/theories/19/desc +0 -11
- data/test/fixtures/theories/19/dump +0 -0
- data/test/fixtures/theories/2/declaration.txt +0 -12
- data/test/fixtures/theories/2/desc +0 -10
- data/test/fixtures/theories/2/dump +0 -0
- data/test/fixtures/theories/20/declaration.txt +0 -23
- data/test/fixtures/theories/20/desc +0 -17
- data/test/fixtures/theories/20/dump +0 -0
- data/test/fixtures/theories/3/declaration.txt +0 -19
- data/test/fixtures/theories/3/desc +0 -11
- data/test/fixtures/theories/3/dump +0 -0
- data/test/fixtures/theories/4/declaration.txt +0 -11
- data/test/fixtures/theories/4/desc +0 -11
- data/test/fixtures/theories/4/dump +0 -0
- data/test/fixtures/theories/5/declaration.txt +0 -6
- data/test/fixtures/theories/5/desc +0 -9
- data/test/fixtures/theories/5/dump +0 -0
- data/test/fixtures/theories/6/declaration.txt +0 -13
- data/test/fixtures/theories/6/desc +0 -11
- data/test/fixtures/theories/6/dump +0 -0
- data/test/fixtures/theories/7/declaration.txt +0 -19
- data/test/fixtures/theories/7/desc +0 -11
- data/test/fixtures/theories/7/dump +0 -0
- data/test/fixtures/theories/8/declaration.txt +0 -21
- data/test/fixtures/theories/8/desc +0 -11
- data/test/fixtures/theories/8/dump +0 -0
- data/test/fixtures/theories/9/declaration.txt +0 -24
- data/test/fixtures/theories/9/desc +0 -20
- data/test/fixtures/theories/9/dump +0 -0
- data/test/fixtures/theory_implementations/0/declaration.txt +0 -11
- data/test/fixtures/theory_implementations/0/desc.txt +0 -9
- data/test/fixtures/theory_implementations/0/dump +0 -0
- data/test/fixtures/theory_implementations/0/theory_id +0 -1
- data/test/fixtures/theory_implementations/1/declaration.txt +0 -11
- data/test/fixtures/theory_implementations/1/desc.txt +0 -9
- data/test/fixtures/theory_implementations/1/dump +0 -1
- data/test/fixtures/theory_implementations/1/theory_id +0 -1
- data/test/fixtures/theory_implementations/2/declaration.txt +0 -11
- data/test/fixtures/theory_implementations/2/desc.txt +0 -9
- data/test/fixtures/theory_implementations/2/dump +0 -0
- data/test/fixtures/theory_implementations/2/theory_id +0 -1
- data/test/output/simple_method.txt +0 -5
- data/test/output/test_method/first_possible_method.txt +0 -6
- data/test/output/test_simple_cases/simple_case_01.txt +0 -8
- data/test/output/test_simple_cases/simple_case_02.txt +0 -7
- data/test/output/test_simple_cases/simple_case_03.txt +0 -8
- data/test/output/test_simple_cases/simple_case_04.txt +0 -8
- data/test/output/test_simple_cases/simple_case_05.txt +0 -8
- data/test/output/test_simple_cases/simple_case_06.txt +0 -9
- data/test/output/test_simple_cases/simple_case_07.txt +0 -9
- data/test/output/test_simple_cases/simple_case_08.txt +0 -9
- data/test/tc_describe.rb +0 -46
- data/test/tc_method.rb +0 -130
- data/test/tc_requirement.rb +0 -30
- data/test/tc_suite_complete.rb +0 -26
- data/test/tc_variable.rb +0 -52
- data/test/ts_complete.rb +0 -74
- data/test/ts_stable.rb +0 -81
- data/test/unit/core/declaration/tc_literal_declaration.rb +0 -34
- data/test/unit/core/method_call/tc_class_call.rb +0 -20
- data/test/unit/core/runtime_method/tc_realised_runtime_method.rb +0 -132
- data/test/unit/core/runtime_method/tc_runtime_method.rb +0 -546
- data/test/unit/core/statement/tc_array_access.rb +0 -63
- data/test/unit/core/statement/tc_block_statement.rb +0 -53
- data/test/unit/core/statement/tc_hack_statement.rb +0 -26
- data/test/unit/core/statement/tc_open_statement.rb +0 -79
- data/test/unit/core/statement/tc_statement.rb +0 -483
- data/test/unit/core/statement/tc_statement_group.rb +0 -35
- data/test/unit/core/statement/tc_statement_replace_variable.rb +0 -61
- data/test/unit/core/statement/tc_theory_statement.rb +0 -53
- data/test/unit/core/syntax/tc_block_container.rb +0 -32
- data/test/unit/core/syntax/tc_if_container.rb +0 -39
- data/test/unit/core/tc_class_method_call.rb +0 -34
- data/test/unit/core/tc_container.rb +0 -41
- data/test/unit/core/tc_ctest_case.rb +0 -25
- data/test/unit/core/tc_instance_call_container.rb +0 -93
- data/test/unit/core/tc_literal.rb +0 -30
- data/test/unit/core/tc_theory_generator.rb +0 -336
- data/test/unit/core/tc_theory_generator_heavy.rb +0 -42
- data/test/unit/core/tracking/tc_history.rb +0 -104
- data/test/unit/core/tracking/tc_step.rb +0 -65
- data/test/unit/core/variable/tc_array_variable.rb +0 -61
- data/test/unit/core/variable/tc_block_variable.rb +0 -17
- data/test/unit/core/variable/tc_fixnum_variable.rb +0 -54
- data/test/unit/core/variable/tc_method_parameter_variable.rb +0 -22
- data/test/unit/core/variable/tc_runtime_method_variable.rb +0 -32
- data/test/unit/core/variable/tc_string_variable.rb +0 -37
- data/test/unit/core/variable/tc_unknown.rb +0 -24
- data/test/unit/core/variable/tc_variable_reference.rb +0 -28
- data/test/unit/ruby_code/tc_array.rb +0 -64
- data/test/unit/ruby_code/tc_fixnum.rb +0 -18
- data/test/unit/ruby_code/tc_hash.rb +0 -41
- data/test/unit/ruby_code/tc_string.rb +0 -38
- data/test/unit/tc_chain.rb +0 -434
- data/test/unit/tc_chain_mapping.rb +0 -62
- data/test/unit/tc_chain_with_case_1.rb +0 -169
- data/test/unit/tc_instance_call.rb +0 -40
- data/test/unit/tc_method_usage.rb +0 -35
- data/test/unit/tc_pot.rb +0 -124
- data/test/unit/tc_runtime_tracking_method.rb +0 -40
- data/test/unit/tc_theory.rb +0 -531
- data/test/unit/tc_variable_declaration.rb +0 -32
- data/test/unit/theory/tc_theory_action.rb +0 -108
- data/test/unit/theory/tc_theory_action_implementation.rb +0 -23
- data/test/unit/theory/tc_theory_chain_validator.rb +0 -340
- data/test/unit/theory/tc_theory_connector.rb +0 -361
- data/test/unit/theory/tc_theory_dependent.rb +0 -153
- data/test/unit/theory/tc_theory_implementation.rb +0 -137
- data/test/unit/theory/tc_theory_result.rb +0 -112
- data/test/unit/theory/tc_theory_variable.rb +0 -45
- data/test/unit/util/tc_method_validation.rb +0 -101
- data/test/unit/util/tc_parser.rb +0 -110
- data/test/unit/util/tc_string_to_theory.rb +0 -300
- data/test/unit/variable/tc_method_usage_variable.rb +0 -25
- data/tmp/runtime_method_evaluation.rb +0 -16
@@ -1,17 +0,0 @@
|
|
1
|
-
class ActionImplementation < TheoryAction
|
2
|
-
|
3
|
-
attr_reader :target_id
|
4
|
-
|
5
|
-
def initialize(statement,target_id,theory_component_id=nil)
|
6
|
-
super(statement,target_id,theory_component_id)
|
7
|
-
end
|
8
|
-
|
9
|
-
def copy
|
10
|
-
return ActionImplementation.new(@action.copy,@target_id.copy,@theory_component_id)
|
11
|
-
end
|
12
|
-
|
13
|
-
def write(tab=0)
|
14
|
-
return (" "*tab)+"runtime_method.add_statement_at(#{@action.write},#{@target_id.write})"
|
15
|
-
end
|
16
|
-
|
17
|
-
end
|
data/lib/theory/TheoryAction.rb
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
# The theory action represents the what theory inserts into the
|
2
|
-
# main runtime method.
|
3
|
-
#
|
4
|
-
class TheoryAction
|
5
|
-
include TheoryComponent
|
6
|
-
|
7
|
-
attr_reader :target_id, :action
|
8
|
-
#
|
9
|
-
# @param action A statement to insert into the main runtime method.
|
10
|
-
# e.g. action.write => "return var8"
|
11
|
-
# @param target_id The id of the nested statement or method to add the generated statement to.
|
12
|
-
#
|
13
|
-
def initialize(action,target_id,theory_component_id=nil)
|
14
|
-
raise StandardError.new('Expecting theory statement but was '+action.class.to_s) unless action.kind_of?(TheoryStatement)
|
15
|
-
@action = action
|
16
|
-
@target_id = target_id
|
17
|
-
@theory_component_id = theory_component_id unless theory_component_id.nil?
|
18
|
-
generate_theory_component_id
|
19
|
-
end
|
20
|
-
|
21
|
-
# Provide a general description of the action, explaining the statement
|
22
|
-
# it will add to the runtime method and where. This is pseudo code
|
23
|
-
# and shouldn't be interpretted at runtime. Use "write" for runtime
|
24
|
-
# actions.
|
25
|
-
#
|
26
|
-
# @param tab
|
27
|
-
#
|
28
|
-
def describe(tab=0)
|
29
|
-
# TODO That is nicer way to do tabs - I should make the other methods consistent with it
|
30
|
-
return (" "*tab)+"<runtime_method>.add_statement_at(#{@action.describe},#{@target_id.describe})"
|
31
|
-
end
|
32
|
-
|
33
|
-
def write(tab=0)
|
34
|
-
return (' '*tab)+"<runtime_method>.add_statement_at(#{@action.write},#{@target_id.write})"
|
35
|
-
end
|
36
|
-
|
37
|
-
# Returns all the theory vairables in this theory action
|
38
|
-
#
|
39
|
-
def theory_variables
|
40
|
-
return @action.select_all {|x| x.kind_of?(TheoryVariable)}
|
41
|
-
end
|
42
|
-
|
43
|
-
# Returns a action implementation with the theory variable declarations replaced with
|
44
|
-
# the values in the mapping hash.
|
45
|
-
#
|
46
|
-
def map_to(mapping)
|
47
|
-
|
48
|
-
# Duplicate the current statement before it is rewritten
|
49
|
-
rewritten_statement = @action.copy
|
50
|
-
target_id = @target_id.copy
|
51
|
-
|
52
|
-
# Find all containers of VariableDeclarations that declare a TheoryVariable
|
53
|
-
containers = [rewritten_statement,target_id].select_all {|x| x.respond_to?(:has?)}
|
54
|
-
theory_variable_containers = containers.select {|x| x.has? {|y| y.kind_of?(TheoryVariable)}}
|
55
|
-
|
56
|
-
# Do any of the containers contain each other?
|
57
|
-
# => TODO Need to prevent this
|
58
|
-
all_theory_variables = Set.new
|
59
|
-
theory_variable_containers.each do |x|
|
60
|
-
results = x.select_all([]) {|y| y.kind_of?(TheoryVariable)}
|
61
|
-
all_theory_variables += results
|
62
|
-
end
|
63
|
-
|
64
|
-
map = {}
|
65
|
-
all_theory_variables.each do |x|
|
66
|
-
next if mapping[x.theory_variable_id].nil?
|
67
|
-
map[x] = mapping[x.theory_variable_id]
|
68
|
-
end
|
69
|
-
|
70
|
-
rewritten_statement.replace_variables_alt!(map)
|
71
|
-
target_id.replace_variables_alt!(map)
|
72
|
-
|
73
|
-
return ActionImplementation.new(rewritten_statement,target_id,@theory_component_id)
|
74
|
-
|
75
|
-
end
|
76
|
-
|
77
|
-
def copy
|
78
|
-
return TheoryAction.new(@action.copy,@target_id,@theory_component_id)
|
79
|
-
end
|
80
|
-
|
81
|
-
def statements_with_variable(variable_id)
|
82
|
-
|
83
|
-
# Duplicate the current statement before it is rewritten
|
84
|
-
rewritten_statement = @action.copy
|
85
|
-
target_id = @target_id.copy
|
86
|
-
|
87
|
-
# Find all containers of VariableDeclarations that declare a TheoryVariable
|
88
|
-
containers = [rewritten_statement,target_id].select_all {|x| x.respond_to?(:has?)}
|
89
|
-
theory_variable_containers = containers.select {|x| x.has? {|y| y.kind_of?(TheoryVariable)}}
|
90
|
-
|
91
|
-
results = theory_variable_containers.select do |x|
|
92
|
-
reg = eval '/var'+variable_id.to_s+'/'
|
93
|
-
x.write.match(reg)
|
94
|
-
end
|
95
|
-
return results
|
96
|
-
|
97
|
-
end
|
98
|
-
|
99
|
-
|
100
|
-
end
|
@@ -1,103 +0,0 @@
|
|
1
|
-
# Instances of this class receive a chain of order theories and proceed
|
2
|
-
# to apply each of them and confirm their expected output. The valid chain
|
3
|
-
# can then be used to generate an appropriate runtime method.
|
4
|
-
#
|
5
|
-
class TheoryChainValidator
|
6
|
-
|
7
|
-
# TODO Is 'potential_values' used?
|
8
|
-
# Returns the first runtime method that could be created with the implemented chains
|
9
|
-
# supplied. This actually generates the runtime method to check the links of the chain
|
10
|
-
# are accurate - unlike the complete? check in chain instances.
|
11
|
-
#
|
12
|
-
def build(runtime_method,test_cases,theory_implementation_chains,potential_values=[])
|
13
|
-
validated_chains = []
|
14
|
-
theory_implementation_chains.each do |chain|
|
15
|
-
validate_next_chain_link(validated_chains,chain,runtime_method.copy,test_cases.copy,0)
|
16
|
-
end
|
17
|
-
raise StandardError.new('Failed to generate a valid runtime method') if validated_chains.length == 0
|
18
|
-
|
19
|
-
# Select the first chain and return the runtime method it generates
|
20
|
-
results = build_method_from_chain(validated_chains.first,runtime_method.copy,test_cases.copy)
|
21
|
-
return results
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
# Validates that the next link in the chain is consistent with the
|
26
|
-
# theories expected result. If it is then the next link is checked
|
27
|
-
# and so on. if all the links are consistent then the chain is add
|
28
|
-
# to the validated chain array.
|
29
|
-
#
|
30
|
-
def validate_next_chain_link(validated_chains,chain,runtime_method,test_cases,position)
|
31
|
-
|
32
|
-
# Check that current link in the chain meets in dependencies
|
33
|
-
# if its dependents are met it isn't suppose to work
|
34
|
-
unless chain[position].meets_dependencies?(runtime_method.copy,test_cases.copy)
|
35
|
-
return nil
|
36
|
-
end
|
37
|
-
|
38
|
-
# Add the theories action to the chains runtime method and realise the runtime method
|
39
|
-
# TODO This creates a new runtime method each time (so ignores what the previous theory did - BAD)
|
40
|
-
result = runtime_method.copy
|
41
|
-
unless chain[position].action.nil?
|
42
|
-
begin
|
43
|
-
result = add_statement_to_method(test_cases,runtime_method.copy,chain[position].action)
|
44
|
-
rescue SyntaxError => e
|
45
|
-
StandardLogger.instance.warn e
|
46
|
-
return nil
|
47
|
-
rescue TypeError => e
|
48
|
-
StandardLogger.instance.warn e
|
49
|
-
return nil
|
50
|
-
end
|
51
|
-
|
52
|
-
end
|
53
|
-
|
54
|
-
# Now check that the runtime method with the theories action also responds
|
55
|
-
# as the theory said it would in the result.
|
56
|
-
if chain[position].results.all? {|x| x.validates?(result,test_cases)}
|
57
|
-
|
58
|
-
# Has the chain been completed?
|
59
|
-
if (position+1) == chain.length
|
60
|
-
validated_chains << chain
|
61
|
-
return
|
62
|
-
else
|
63
|
-
# Continue along the chain
|
64
|
-
validate_next_chain_link(validated_chains,chain,result,test_cases,(position+1))
|
65
|
-
end
|
66
|
-
else
|
67
|
-
# Theory was wrong
|
68
|
-
# chain[position].results.each do |x|
|
69
|
-
# unless x.validates?(result,test_cases)
|
70
|
-
# StandardLogger.instance.info('The following result failed to be met')
|
71
|
-
# StandardLogger.instance.info(x.write)
|
72
|
-
# end
|
73
|
-
# end
|
74
|
-
return nil
|
75
|
-
end
|
76
|
-
|
77
|
-
end
|
78
|
-
|
79
|
-
# Builds the method using the chain without checking that the depenedents
|
80
|
-
# and results are accurate.
|
81
|
-
#
|
82
|
-
def build_method_from_chain(chain,runtime_method,test_cases)
|
83
|
-
runtime_method = runtime_method.copy
|
84
|
-
chain.each do |link|
|
85
|
-
next if link.action.nil?
|
86
|
-
runtime_method = add_statement_to_method(test_cases,runtime_method,link.action)
|
87
|
-
end
|
88
|
-
return runtime_method
|
89
|
-
end
|
90
|
-
|
91
|
-
def add_statement_to_method(test_cases,runtime_method,action)
|
92
|
-
evaluation_code = ''
|
93
|
-
# TODO I don't think this line below is needed
|
94
|
-
evaluation_code += "test_cases = #{test_cases.write}"+"\n"
|
95
|
-
evaluation_code += "last_runtime_method = runtime_method.copy"+"\n"
|
96
|
-
evaluation_code += action.write+"\n"
|
97
|
-
evaluation_code += 'return runtime_method'+"\n"
|
98
|
-
eval evaluation_code
|
99
|
-
rescue NoMethodError => e
|
100
|
-
return nil
|
101
|
-
end
|
102
|
-
|
103
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
module TheoryComponent
|
2
|
-
include ActsAsCode
|
3
|
-
|
4
|
-
attr_reader :theory_component_id
|
5
|
-
|
6
|
-
# TODO Complete hack for issue where component ids aren't unique - using marshal load
|
7
|
-
@@theory_component_id = 0
|
8
|
-
|
9
|
-
def generate_theory_component_id
|
10
|
-
if @theory_component_id.nil?
|
11
|
-
@theory_component_id = @@theory_component_id
|
12
|
-
@@theory_component_id += 1
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
# Returns all the theory vairables in this theory
|
17
|
-
# dependent.
|
18
|
-
#
|
19
|
-
def theory_variables
|
20
|
-
return @statement.select_all {|x| x.kind_of?(TheoryVariable)}
|
21
|
-
end
|
22
|
-
|
23
|
-
def tokens
|
24
|
-
return @statement.tokens
|
25
|
-
end
|
26
|
-
|
27
|
-
def statements_with_variable(variable_id)
|
28
|
-
|
29
|
-
# Duplicate the current statement before it is rewritten
|
30
|
-
rewritten_statement = @statement.copy
|
31
|
-
|
32
|
-
# Find all containers of VariableDeclarations that declare a TheoryVariable
|
33
|
-
containers = [rewritten_statement].select_all {|x| x.respond_to?(:has?)}
|
34
|
-
theory_variable_containers = containers.select {|x| x.has? {|y| y.kind_of?(TheoryVariable)}}
|
35
|
-
|
36
|
-
results = theory_variable_containers.select do |x|
|
37
|
-
reg = eval '/var'+variable_id.to_s+'/'
|
38
|
-
x.write.match(reg)
|
39
|
-
end
|
40
|
-
return results
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
# Returns an array of any of the accessors in the statement. An accessor
|
45
|
-
# is the chain to access a property e.g. in the following statement =>
|
46
|
-
#
|
47
|
-
# var1[:params][var3].something(var6)
|
48
|
-
#
|
49
|
-
# it would return ["var1[:params][var3]","var6"]
|
50
|
-
#
|
51
|
-
# The needed when trying to determine intrinsic values. So in this case
|
52
|
-
# var1 couln't be a runtime_method instance becuase it doesn't use
|
53
|
-
# the has key
|
54
|
-
#
|
55
|
-
def accessors
|
56
|
-
|
57
|
-
end
|
58
|
-
|
59
|
-
end
|
@@ -1,756 +0,0 @@
|
|
1
|
-
|
2
|
-
# Instances are expected to connect any number of theories so
|
3
|
-
# that the chain finishes with a particular outcome.
|
4
|
-
#
|
5
|
-
# e.g. '<runtime_method>.all_pass?(<test_cases>) = true'
|
6
|
-
#
|
7
|
-
class TheoryConnector
|
8
|
-
|
9
|
-
def initialize(potential_values)
|
10
|
-
@potential_values = potential_values
|
11
|
-
end
|
12
|
-
|
13
|
-
# Attempts to chain the theories togeather so that the final theory
|
14
|
-
# results in the specified "finish".
|
15
|
-
#
|
16
|
-
# @param runtime_method This is an instance of the core runtime method
|
17
|
-
# instance that is populated with any number of statements.
|
18
|
-
# @param test_cases An array of test cases that contain the values for
|
19
|
-
# runtime method's paramters and the expected return value
|
20
|
-
# given those parameters.
|
21
|
-
# @param finish A description of the desired final outcome - this will
|
22
|
-
# probably be
|
23
|
-
# '<runtime_method>.all_pass?(<test_cases>) = true'
|
24
|
-
# @param theories A array of theories to be chained togeather to result
|
25
|
-
# in the finish outcome.
|
26
|
-
#
|
27
|
-
# TODO Last runtime method dependencies can't be shared down the the theory chain
|
28
|
-
#
|
29
|
-
def chain(runtime_method,test_cases,finish,theories)
|
30
|
-
|
31
|
-
return create_possible_chains(runtime_method,test_cases,finish,theories)
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
# NOTE: Will probably replace the create_possible_chains and chain call
|
36
|
-
# Returns an array of complete chains that conclude with a valid
|
37
|
-
# runtime method.
|
38
|
-
#
|
39
|
-
def generate_chains(runtime_method,test_cases,theories,exclude=[])
|
40
|
-
|
41
|
-
theories = remove_irrelevant_theories(theories)
|
42
|
-
|
43
|
-
# Create the inital chain (with the head and tail)
|
44
|
-
intial_chain = Chain.new
|
45
|
-
|
46
|
-
# Find a theory that can act as the head
|
47
|
-
possible_head_theories = theories.select {|x| x.dependents.length == 0}
|
48
|
-
|
49
|
-
# Create the initial chains
|
50
|
-
possible_chains = []
|
51
|
-
possible_head_theories.each do |x|
|
52
|
-
possible_chains += intial_chain.copy.extension_permutaions(x)
|
53
|
-
end
|
54
|
-
|
55
|
-
# Check the initial chains incase they're complete
|
56
|
-
complete_chains = []
|
57
|
-
if possible_chains.any? {|x| x.complete? }
|
58
|
-
complete_chains += possible_chains.select {|x| x.complete?}
|
59
|
-
possible_chains.delete_if {|x| x.complete?}
|
60
|
-
end
|
61
|
-
complete_chains = complete_chains.delete_if do |x|
|
62
|
-
exclude.any? {|y| y == x.theories_sequence}
|
63
|
-
end
|
64
|
-
unless complete_chains.empty?
|
65
|
-
return complete_chains
|
66
|
-
end
|
67
|
-
possible_chains.each do |chain|
|
68
|
-
|
69
|
-
# Remove the head theory to avoid it being re-used
|
70
|
-
head_free_theories = theories.copy
|
71
|
-
head_free_theories.delete_if {|theory| theory.theory_id == chain.first.theory_id}
|
72
|
-
complete_chains += complete_chain(chain,head_free_theories)
|
73
|
-
end
|
74
|
-
return complete_chains
|
75
|
-
|
76
|
-
end
|
77
|
-
|
78
|
-
def complete_chain(chain,theories)
|
79
|
-
res = catch(:complete) do
|
80
|
-
converge_chain(chain,theories)
|
81
|
-
#raise StandardError.new('Failed to generate a chain')
|
82
|
-
return []
|
83
|
-
end
|
84
|
-
return [res]
|
85
|
-
|
86
|
-
end
|
87
|
-
|
88
|
-
def remove_existing_theories(chain,theories)
|
89
|
-
theories.delete_if do |theory|
|
90
|
-
chain.theories_sequence.include?(theory.theory_id)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
def converge_chain(chain,theories,step=0)
|
95
|
-
|
96
|
-
theories = remove_existing_theories(chain.copy,theories.copy)
|
97
|
-
|
98
|
-
extended_chains = add_to_chain(chain.copy,theories.copy,step)
|
99
|
-
|
100
|
-
if extended_chains.any? {|x| x.complete? }
|
101
|
-
res2 = extended_chains.select {|x| x.complete?}
|
102
|
-
raise StandardError.new('More than one complete chain found') if res2.length > 1
|
103
|
-
throw :complete, res2.first.freeze
|
104
|
-
end
|
105
|
-
closer = closer_chains(chain.copy,extended_chains)
|
106
|
-
|
107
|
-
complete_chains = []
|
108
|
-
unless closer.empty?
|
109
|
-
closer.each do |x|
|
110
|
-
complete_chains += converge_chain(x,theories,step+1)
|
111
|
-
end
|
112
|
-
else
|
113
|
-
extended_chains.each do |x|
|
114
|
-
complete_chains += converge_chain(x,theories,(step+1))
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
return complete_chains
|
119
|
-
end
|
120
|
-
|
121
|
-
def closer_chains(chain,chains)
|
122
|
-
closer_chains = []
|
123
|
-
chains.each do |x|
|
124
|
-
if ((chain.unmet_dependents_ids-x.unmet_dependents_ids).length == chain.unmet_dependents_ids.length)
|
125
|
-
closer_chains << x
|
126
|
-
end
|
127
|
-
end
|
128
|
-
return closer_chains
|
129
|
-
end
|
130
|
-
|
131
|
-
def add_to_chain(chain,theories,step)
|
132
|
-
extended_chains = []
|
133
|
-
theories.each do |theory|
|
134
|
-
last_position = 1
|
135
|
-
chains = chain.add_link_to(theory,last_position,[])
|
136
|
-
|
137
|
-
#chains = chain.extension_permutaions(theory,[])
|
138
|
-
next if chains.empty?
|
139
|
-
extended_chains += chains
|
140
|
-
end
|
141
|
-
return extended_chains
|
142
|
-
end
|
143
|
-
|
144
|
-
def extend_chain(chain,theories)
|
145
|
-
|
146
|
-
complete_chains = []
|
147
|
-
theories.each do |x|
|
148
|
-
extended_chains = chain.copy.extension_permutaions(x)
|
149
|
-
next if extended_chains.empty?
|
150
|
-
|
151
|
-
# Don't allow the same theory to be added twice - for now
|
152
|
-
updated_theories = theories.copy
|
153
|
-
updated_theories.delete_if {|theory| theory.theory_id == x.theory_id}
|
154
|
-
|
155
|
-
complete_chains += extended_chains.select {|y| y.complete?}
|
156
|
-
extended_chains.delete_if {|y| y.complete?}
|
157
|
-
extended_chains.each do |y|
|
158
|
-
complete_chains += extend_chain(y,updated_theories)
|
159
|
-
end
|
160
|
-
end
|
161
|
-
return complete_chains
|
162
|
-
end
|
163
|
-
|
164
|
-
def remove_irrelevant_theories(theories)
|
165
|
-
theories.delete_if {|theory| theory.irrelevant? }
|
166
|
-
end
|
167
|
-
|
168
|
-
def create_possible_chains(runtime_method,test_cases,finish,theories)
|
169
|
-
|
170
|
-
# Generate the head theory - this is the starting point and doesn't have any dependents
|
171
|
-
accessors, mapping = TheoryGenerator.new.generate_accessors_and_mapping(test_cases,runtime_method,7,0)
|
172
|
-
|
173
|
-
# * Generate all the possible results of this runtime method
|
174
|
-
theory_results = TheoryGenerator.new.get_theory_results(accessors)
|
175
|
-
|
176
|
-
# * Create the actual head theory
|
177
|
-
head_theory = Theory.new([],nil,theory_results,runtime_method.copy)
|
178
|
-
|
179
|
-
# Create the initial chain that needs to be connected
|
180
|
-
intial_chain = Chain.new
|
181
|
-
intial_chain.form_chain(head_theory,finish,mapping)
|
182
|
-
|
183
|
-
return create_possible_chain_extensions(runtime_method,test_cases,finish,theories,intial_chain)
|
184
|
-
end
|
185
|
-
|
186
|
-
# This method has been created so the initial chain can be passed in to start the method
|
187
|
-
# creation. Generating the initial chain can take a couple of minutes.
|
188
|
-
#
|
189
|
-
def create_possible_chain_extensions(runtime_method,test_cases,finish,theories,intial_chain)
|
190
|
-
|
191
|
-
# Save any of the complete chains
|
192
|
-
possible_chains = []
|
193
|
-
|
194
|
-
# Search through the available theories and find one that results in the finish
|
195
|
-
potential_final_theories = theories.select {|x| x.has_result_structure?(finish)}
|
196
|
-
|
197
|
-
# Attempt to add the potential link to the end of the chain
|
198
|
-
partial_chains = []
|
199
|
-
potential_final_theories.each do |theory|
|
200
|
-
potential_chain = intial_chain.copy
|
201
|
-
# TODO Maybe should be call add_link_to_tail - then check if it completes
|
202
|
-
if(potential_chain.add_link(theory))
|
203
|
-
# A new link has been added - does this complete the chain (tail -> head)
|
204
|
-
res = potential_chain.complete?
|
205
|
-
#if potential_chain.complete?
|
206
|
-
if res
|
207
|
-
possible_chains << potential_chain
|
208
|
-
else
|
209
|
-
partial_chains << potential_chain
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
end
|
214
|
-
|
215
|
-
|
216
|
-
# If there are any partial chains try to extend them with additional theories
|
217
|
-
# - partial chains were connect to the finish but not the head.
|
218
|
-
partial_chains.each do |partial_chain|
|
219
|
-
|
220
|
-
# Select from the chain the dependents that haven't be met.
|
221
|
-
|
222
|
-
# TODO This looks very messy -
|
223
|
-
|
224
|
-
# Take the first dependent attempt to add a theory to resolve it
|
225
|
-
# - NOTE: This theory may resolve other of the dependents
|
226
|
-
#until partial_chain.unmet_dependents.empty?
|
227
|
-
limit = 1
|
228
|
-
until partial_chain.unmet_dependents.empty? or limit == 0
|
229
|
-
|
230
|
-
# Select the firs of the unment dependents
|
231
|
-
dependent = partial_chain.unmet_dependents.first
|
232
|
-
|
233
|
-
# Search through the available theories for ones that match the dependent structure
|
234
|
-
# TODO This should be empty for "ruby test/unit/theory/tc_theory_connector.rb --name test_chain_with_2_theories"
|
235
|
-
potential_theories = theories.select {|x| x.has_result_structure?(dependent) }
|
236
|
-
if potential_theories.length > 10
|
237
|
-
raise StandardError.new("Have not tested for #{potential_theories.length.to_s} potential theories" )
|
238
|
-
end
|
239
|
-
|
240
|
-
# Attempt to add the theory to the partial chain (prefers the theories that complete)
|
241
|
-
potential_theories.each do |t|
|
242
|
-
updated_chain = partial_chain.copy
|
243
|
-
# TODO Should create a quick way to switch input on and off while the script is running
|
244
|
-
if(updated_chain.add_link(t))
|
245
|
-
partial_chain = updated_chain
|
246
|
-
if updated_chain.complete?
|
247
|
-
possible_chains << updated_chain
|
248
|
-
break
|
249
|
-
else
|
250
|
-
end
|
251
|
-
else
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
limit -= 1
|
256
|
-
end
|
257
|
-
|
258
|
-
end
|
259
|
-
|
260
|
-
# Return the complete chains
|
261
|
-
return possible_chains
|
262
|
-
|
263
|
-
end
|
264
|
-
|
265
|
-
# Returns a new chain so that they all use consistent theory variables ids
|
266
|
-
#
|
267
|
-
def unify_chain(chain)
|
268
|
-
|
269
|
-
# TODO Break up this method and write tests for the individual parts
|
270
|
-
|
271
|
-
# Find all the ways the theory and results can connected
|
272
|
-
# - the same_structure? approach is quite loose
|
273
|
-
arrangements = chain_arrangements(chain.copy.reverse)
|
274
|
-
|
275
|
-
# For each theory in the chain give each each variable a unique id
|
276
|
-
starting_id = 1
|
277
|
-
uniq_chain = chain.inject([]) do |total,x|
|
278
|
-
r = x.uniq_theory_variables(starting_id)
|
279
|
-
starting_id = r.highest_theory_variable_id+1
|
280
|
-
total << r
|
281
|
-
total
|
282
|
-
end
|
283
|
-
|
284
|
-
# Identify the matching variables
|
285
|
-
mappings = matching_variables(arrangements,uniq_chain)
|
286
|
-
# TODO Why are so many of these identical
|
287
|
-
mappings.uniq!
|
288
|
-
|
289
|
-
# Identify opposed mapping (variables that don't match in the context of the theory aren't equal)
|
290
|
-
false_mappings = {}
|
291
|
-
uniq_chain.each do |x|
|
292
|
-
r = x.all_theory_variables.collect {|x| x.theory_variable_id}
|
293
|
-
r.each do |y|
|
294
|
-
false_mappings[y] = r.copy.delete_if {|z| z == y}
|
295
|
-
end
|
296
|
-
end
|
297
|
-
|
298
|
-
final_mapping = []
|
299
|
-
#mappings = [mappings.last]
|
300
|
-
|
301
|
-
count = 0
|
302
|
-
mappings.each do |m|
|
303
|
-
count += 1
|
304
|
-
# Create an array of all variables that are equalivalent
|
305
|
-
master = combine_matches(m.to_a)
|
306
|
-
|
307
|
-
# Check that the equivalent variables don't occur in the same theory
|
308
|
-
# TODO If this never occurs I need to re-think things
|
309
|
-
catch :bad_map do
|
310
|
-
false_mappings.each do |key,value|
|
311
|
-
|
312
|
-
master.each do |x|
|
313
|
-
if x.include?(key)
|
314
|
-
if (x | value).length != x.length+value.length
|
315
|
-
throw :bad_map
|
316
|
-
end
|
317
|
-
end
|
318
|
-
end
|
319
|
-
end
|
320
|
-
|
321
|
-
final_mapping << master.collect {|x| x.uniq}
|
322
|
-
end
|
323
|
-
end
|
324
|
-
|
325
|
-
# Generate new chains using the final mappings
|
326
|
-
return [] if final_mapping.empty?
|
327
|
-
|
328
|
-
#m = final_mapping.last
|
329
|
-
new_chains = []
|
330
|
-
final_mapping.each do |x|
|
331
|
-
|
332
|
-
# Get the id of all the theory variables
|
333
|
-
all_theory_variable_ids = uniq_chain.collect {|y| y.all_theory_variables.collect {|z| z.theory_variable_id} }.flatten
|
334
|
-
|
335
|
-
# Unique theory variables
|
336
|
-
uniq_variables = all_theory_variable_ids-x.flatten
|
337
|
-
unique_count = (all_theory_variable_ids-x.flatten).length + x.length
|
338
|
-
|
339
|
-
# Prepare the mapping to match each id to a new variable
|
340
|
-
# (at this stage each of the mappings should be unique)
|
341
|
-
map = Mapping.new
|
342
|
-
unique_count.times do |k|
|
343
|
-
unless uniq_variables.empty?
|
344
|
-
#map << {uniq_variables.shift=>TheoryVariable.new(k)}
|
345
|
-
map[uniq_variables.shift] = TheoryVariable.new(k)
|
346
|
-
next
|
347
|
-
end
|
348
|
-
#t = m.shift
|
349
|
-
var = TheoryVariable.new(k)
|
350
|
-
#map += x.shift.collect {|u| {u=>var} }
|
351
|
-
x.shift.each do |j|
|
352
|
-
map[j] = var
|
353
|
-
end
|
354
|
-
end
|
355
|
-
|
356
|
-
# Copy the the chain and update the mapping
|
357
|
-
new_chains << Chain.new(uniq_chain.collect {|y| y.copy.map_to(map)})
|
358
|
-
|
359
|
-
end
|
360
|
-
return new_chains
|
361
|
-
|
362
|
-
end
|
363
|
-
|
364
|
-
# Returns an array of arrays containing matching ids
|
365
|
-
#
|
366
|
-
# matches e.g. [[5,10],[11,17],[12,18],[1,6],[7,12],[13,5]]
|
367
|
-
#
|
368
|
-
def combine_matches(matches)
|
369
|
-
|
370
|
-
results = []
|
371
|
-
until matches.empty?
|
372
|
-
start = matches.shift
|
373
|
-
|
374
|
-
catch :no_change do
|
375
|
-
loop do
|
376
|
-
initial_length = start.length
|
377
|
-
#removed = temp2.delete_if {|x| (x | start).length != start.length+x.length }
|
378
|
-
|
379
|
-
# TODO A delete command to that returns what you were deleting would be nice
|
380
|
-
index = matches.index {|x| (x | start).length != start.length+x.length }
|
381
|
-
if index.nil?
|
382
|
-
results << start
|
383
|
-
throw :no_change
|
384
|
-
end
|
385
|
-
b = matches.slice!(index)
|
386
|
-
start += b
|
387
|
-
start.uniq!
|
388
|
-
end
|
389
|
-
|
390
|
-
end
|
391
|
-
end
|
392
|
-
return results
|
393
|
-
end
|
394
|
-
|
395
|
-
# Returns an array that matches one variable to another indicating that
|
396
|
-
# they should be considered equal.
|
397
|
-
#
|
398
|
-
def matching_variables(arrangements,uniq_chain)
|
399
|
-
mappings = []
|
400
|
-
arrangements.each do |arrangement|
|
401
|
-
map = {}
|
402
|
-
arrangement.each do |theory|
|
403
|
-
|
404
|
-
dependents = uniq_chain.inject([]) {|total,x| total += x.dependents}
|
405
|
-
results = uniq_chain.inject([]) {|total,x| total += x.results}
|
406
|
-
|
407
|
-
theory.each do |dependent_id,result_id|
|
408
|
-
|
409
|
-
# Find the dependent with the matching id
|
410
|
-
dependent = dependents.detect() {|x| x.theory_component_id == dependent_id}
|
411
|
-
result = results.detect() {|x| x.theory_component_id == result_id}
|
412
|
-
|
413
|
-
# Temporary check that everything is tickety boo
|
414
|
-
if result.theory_variables.length != dependent.theory_variables.length
|
415
|
-
raise StandardError.new('They should always have the same number of theory variables')
|
416
|
-
end
|
417
|
-
|
418
|
-
# Go through each of the variables and match up the values
|
419
|
-
result.theory_variables.zip(dependent.theory_variables) do |x,y|
|
420
|
-
|
421
|
-
if map.has_key?(x.theory_variable_id)
|
422
|
-
end
|
423
|
-
map[y.theory_variable_id] = x.theory_variable_id
|
424
|
-
|
425
|
-
end
|
426
|
-
|
427
|
-
end
|
428
|
-
|
429
|
-
end
|
430
|
-
mappings << map
|
431
|
-
end
|
432
|
-
return mappings
|
433
|
-
end
|
434
|
-
|
435
|
-
# Returns an array of all the ways the theory chain can be arranged
|
436
|
-
# So dependent A -> result B
|
437
|
-
#
|
438
|
-
# @param chain An array containing all the theories in order
|
439
|
-
#
|
440
|
-
def chain_arrangements(chain)
|
441
|
-
arrangements = []
|
442
|
-
next_link_arrangement(arrangements,[],chain)
|
443
|
-
return arrangements
|
444
|
-
end
|
445
|
-
|
446
|
-
def next_link_arrangement(arrangements,arrangement,chain)
|
447
|
-
# Take out link and find the results that match its dependents
|
448
|
-
link = chain.pop
|
449
|
-
|
450
|
-
# Stop if the all the links in the chain have been met (the last one has nothing left to be dependent on)
|
451
|
-
if chain.empty?
|
452
|
-
arrangements << arrangement
|
453
|
-
return
|
454
|
-
end
|
455
|
-
|
456
|
-
# TODO Down the line I should see if Cauldron can tidy this up
|
457
|
-
|
458
|
-
# Saves what dependent connects to what result
|
459
|
-
# e.g. connection = {16=>[26, 28], 17=>[26, 28]}
|
460
|
-
connection = {}
|
461
|
-
link.dependents.each do |dependent|
|
462
|
-
|
463
|
-
# Get all the results from the rest of the chain
|
464
|
-
results = chain.inject([]) {|total,x| total + x.results }
|
465
|
-
|
466
|
-
# Go through the rest of the chain and find the results with the same structure
|
467
|
-
connection[dependent.theory_component_id] = results.select do |x|
|
468
|
-
x.same_structure?(dependent)
|
469
|
-
end.collect {|x| x.theory_component_id}
|
470
|
-
|
471
|
-
end
|
472
|
-
|
473
|
-
# TODO I need to re-do allot of the connecton stuff - I was using theories with arround 650 dependents and
|
474
|
-
# it was generating an insane size of arrangements. I think it is plausable to handle that size a theory
|
475
|
-
# but I should re-do this bit.
|
476
|
-
#
|
477
|
-
# I may need to reduce the theories to only include the dependent/result arrangements that change after
|
478
|
-
# the action is added.
|
479
|
-
|
480
|
-
# Calculate the total number of arrangements
|
481
|
-
total_arrangements = connection.values.collect {|x| x.length}.inject(1) {|total,y| total *= y}
|
482
|
-
|
483
|
-
# TODO Need to include an escape here if there are too many total_arrangements
|
484
|
-
|
485
|
-
# TODO The theory_generator is generating too many results and dependents.
|
486
|
-
|
487
|
-
# Find the various arrangements for the results
|
488
|
-
# e.g. [[26,26],[26,28],[28,26],..]
|
489
|
-
# NOTE I get a RangeError: too big to product with larger theories
|
490
|
-
connection_arrangements = connection.values.first.product(*connection.values[1..connection.values.length])
|
491
|
-
|
492
|
-
# Alternative
|
493
|
-
# NOTE: I've rewritten this because the code above generates an error for larger theories
|
494
|
-
# new_connection_arrangements = []
|
495
|
-
# extend_arrangement(new_connection_arrangements,connection.values)
|
496
|
-
|
497
|
-
# Jump back to the clearer dependent -> result arrangement
|
498
|
-
# e.g. [{16=>26, 17=>26}, {16=>26, 17=>28}, {16=>28, 17=>26}, {16=>28, 17=>28}]
|
499
|
-
nice_connection_arrangements = connection_arrangements.collect do |x|
|
500
|
-
a = []
|
501
|
-
connection.keys.zip(x) do |dependent_id,result_id|
|
502
|
-
a << dependent_id
|
503
|
-
a << result_id
|
504
|
-
end
|
505
|
-
Hash[*a]
|
506
|
-
end
|
507
|
-
|
508
|
-
# For each arrangement continue to the next link
|
509
|
-
nice_connection_arrangements.each do |x|
|
510
|
-
# TODO Maybe use a hash with the theory id in instead
|
511
|
-
a = arrangement.copy + [x]
|
512
|
-
next_link_arrangement(arrangements,a,chain.copy)
|
513
|
-
end
|
514
|
-
|
515
|
-
end
|
516
|
-
|
517
|
-
def extend_arrangement(total,groups,group=[])
|
518
|
-
if groups.empty?
|
519
|
-
total << group
|
520
|
-
return
|
521
|
-
end
|
522
|
-
groups.shift.each do |x|
|
523
|
-
extend_arrangement(total,groups.copy,group.copy.push(x))
|
524
|
-
end
|
525
|
-
end
|
526
|
-
|
527
|
-
# Returns all the implementation permutations for the theory.
|
528
|
-
def implement_chain(chain,mapping=Mapping.new)
|
529
|
-
|
530
|
-
|
531
|
-
# Implement the theory in all the permutations
|
532
|
-
# NOTE: Need to get the mapping during the implementation
|
533
|
-
link = chain.shift
|
534
|
-
|
535
|
-
# TODO Rewriting permutations takes quite long, I think it could be greatly reduced by
|
536
|
-
# stricting the posibilities by reviewing the dependents. For example:
|
537
|
-
#
|
538
|
-
# if(var6.kind_of?(Fixnum))
|
539
|
-
# return true
|
540
|
-
# end
|
541
|
-
#
|
542
|
-
# TODO I shouldn't treat the realisable fixnum variables as fair game. They should only
|
543
|
-
# TestCaseIndexFixnum and only available to things of that type.
|
544
|
-
#
|
545
|
-
link_permutations = link.rewrite_permutations(@potential_values,mapping)
|
546
|
-
implemented_chains = []
|
547
|
-
link_permutations.each do |x|
|
548
|
-
implement_next_link(implemented_chains,chain.copy,[link],[x])
|
549
|
-
end
|
550
|
-
|
551
|
-
return implemented_chains
|
552
|
-
|
553
|
-
end
|
554
|
-
|
555
|
-
def implement_next_link(implemented_chains,chain,previous_chain,partial_implemented_chain)
|
556
|
-
if chain.empty?
|
557
|
-
implemented_chains << partial_implemented_chain
|
558
|
-
return
|
559
|
-
end
|
560
|
-
next_link = chain.shift
|
561
|
-
|
562
|
-
# Create an hash to show how the results-dependents are linked.
|
563
|
-
# TODO Because I am loading the theories from Marshal dumps I need to make sure they all have unique ids
|
564
|
-
results_to_dependents = {}
|
565
|
-
|
566
|
-
dependent_mapping = conversion_mapping(partial_implemented_chain,previous_chain,next_link)
|
567
|
-
|
568
|
-
# # Now implement the next theory using the mapping dependency already established.
|
569
|
-
dependent_mapping.each do |mapping|
|
570
|
-
|
571
|
-
# NOTE: The mapping is only restricted between the dependent and result connection
|
572
|
-
implemented_links = next_link.rewrite_permutations(@potential_values,mapping)
|
573
|
-
|
574
|
-
implemented_links.each do |x|
|
575
|
-
extended_implemented_chain = partial_implemented_chain.copy << x
|
576
|
-
previous_chain = previous_chain.copy << next_link
|
577
|
-
implement_next_link(implemented_chains,chain,previous_chain,extended_implemented_chain)
|
578
|
-
end
|
579
|
-
end
|
580
|
-
|
581
|
-
end
|
582
|
-
|
583
|
-
# Returns a mapping hash that will describe how to implement the next theory
|
584
|
-
# so that it is compatiable with current chain.
|
585
|
-
#
|
586
|
-
def conversion_mapping(implemented_chain,current_chain,next_theory)
|
587
|
-
|
588
|
-
# Find all the permutations of theory dependents meet by the current chain.
|
589
|
-
|
590
|
-
# For each dependent find all the current implementations that meet it
|
591
|
-
# e.g. {16=>[26, 28, 12], 17=>[26, 28, 12]}
|
592
|
-
# TODO Should only include the most recent chain if the result contains a
|
593
|
-
# last_runtime_method variable.
|
594
|
-
results = current_chain.inject([]) {|total,x| total + x.results }
|
595
|
-
arrangements = next_theory.dependents.inject({}) do |total,dependent|
|
596
|
-
total[dependent.theory_component_id] = results.select do |x|
|
597
|
-
x.same_structure?(dependent)
|
598
|
-
end.collect {|x| x.theory_component_id}
|
599
|
-
total
|
600
|
-
end
|
601
|
-
|
602
|
-
# # ------------- Development Code -------------
|
603
|
-
# arrangements.each do |key,value|
|
604
|
-
# value.each do |x|
|
605
|
-
# end
|
606
|
-
# end
|
607
|
-
|
608
|
-
# Get the various permutations of the dependent to result
|
609
|
-
result_values = arrangements.values
|
610
|
-
# http://www.ruby-doc.org/core/classes/Array.html#M000287
|
611
|
-
# TODO Need to check when there is only one dependent
|
612
|
-
# [1,2].product() #=> [[1],[2]]
|
613
|
-
# [1,2].product([]) #=> []
|
614
|
-
|
615
|
-
variations = result_values.first.product(*result_values[1..result_values.length])
|
616
|
-
# e.g. [[26, 26], [26, 28], [26, 12], [28, 26], [28, 28], [28, 12], [12, 26], [12, 28], [12, 12]]
|
617
|
-
# TODO Maybe an array with the dependent id in would be more useful
|
618
|
-
# e.g. [[16=>26,17=>26],[16=>26,17=>28],...
|
619
|
-
|
620
|
-
# Need to find all the mappings that will still be consistent
|
621
|
-
potential_mappings = []
|
622
|
-
variations.each do |x|
|
623
|
-
|
624
|
-
# Go through each dependent to result pair
|
625
|
-
catch :incompatiable do
|
626
|
-
index = 0
|
627
|
-
mapping = Mapping.new
|
628
|
-
|
629
|
-
arrangements.each_key do |dependent_id|
|
630
|
-
|
631
|
-
# ----------- Development ----------------
|
632
|
-
|
633
|
-
# Find the implementation with this result
|
634
|
-
theory_result = results.detect {|y| y.theory_component_id == x[index]}
|
635
|
-
|
636
|
-
# Find the dependent that will be mapped
|
637
|
-
theory_dependent = next_theory.dependents.detect {|y| y.theory_component_id == dependent_id}
|
638
|
-
|
639
|
-
# Find the implementation that contains the selected result
|
640
|
-
# TODO This approach implies that the same theory can be used twice in the chain.
|
641
|
-
# TODO I could probably avoid allot of this by having implementation ids and including the
|
642
|
-
# mapping with the implementation's results
|
643
|
-
theory_implementation = implemented_chain.detect do |y|
|
644
|
-
y.results.any? {|z| z.theory_component_id == x[index]}
|
645
|
-
end
|
646
|
-
|
647
|
-
# Map the id of dependent to the real value used by the result
|
648
|
-
theory_result.theory_variables.zip(theory_dependent.theory_variables) do |z,y|
|
649
|
-
|
650
|
-
if mapping.has_key?(y.theory_variable_id)
|
651
|
-
throw :incompatiable if mapping[y.theory_variable_id] != theory_implementation.mapping[z.theory_variable_id]
|
652
|
-
end
|
653
|
-
|
654
|
-
mapping[y.theory_variable_id] = theory_implementation.mapping[z.theory_variable_id]
|
655
|
-
end
|
656
|
-
index += 1
|
657
|
-
end
|
658
|
-
potential_mappings << mapping
|
659
|
-
end
|
660
|
-
end
|
661
|
-
|
662
|
-
return potential_mappings
|
663
|
-
|
664
|
-
end
|
665
|
-
|
666
|
-
def find_theories_with_these_results(theories,results)
|
667
|
-
return theories.select do |theory|
|
668
|
-
results.all? {|x| theory.has_result_structure?(x)}
|
669
|
-
end
|
670
|
-
end
|
671
|
-
|
672
|
-
# Find the theories that match any of the results.
|
673
|
-
#
|
674
|
-
def find_the_theories_with_these_results(theories,results)
|
675
|
-
end
|
676
|
-
|
677
|
-
#
|
678
|
-
def add_link(complete_chains,chain,theories)
|
679
|
-
|
680
|
-
last_theory = chain.last
|
681
|
-
|
682
|
-
|
683
|
-
# Find the theories that can meet last theories dependency
|
684
|
-
# TODO Should this be looking for just one theory? If more than one theory is
|
685
|
-
# added they might not be compatible.
|
686
|
-
results = find_theories_with_these_results(theories,last_theory.dependents)
|
687
|
-
if results.empty?
|
688
|
-
complete_chains << chain
|
689
|
-
return
|
690
|
-
end
|
691
|
-
|
692
|
-
# Try to find any additional links to the new chain
|
693
|
-
results.each do |x|
|
694
|
-
extended_chain = chain.copy.push(x)
|
695
|
-
add_link(complete_chains,extended_chain,theories)
|
696
|
-
end
|
697
|
-
|
698
|
-
end
|
699
|
-
|
700
|
-
# Returns a number of updated mappings based on what if possible
|
701
|
-
# for the first theory and the current mapping for the end.
|
702
|
-
#
|
703
|
-
def refine_initial_mapping(theory,mapping,runtime_method,test_cases)
|
704
|
-
|
705
|
-
# TEMP
|
706
|
-
# 1. What theory variables don't have real values?
|
707
|
-
# 2. What real values are available?
|
708
|
-
# 3. For each real variable identify the theory variables it could be.
|
709
|
-
# 4. Given the possibilities work out the permutations
|
710
|
-
|
711
|
-
# Find the theory variable ids that don't have real values
|
712
|
-
var_ids = theory.dependents.inject([]){|total,x| total << x.theory_variables.collect {|z| z.theory_variable_id}}.flatten.uniq
|
713
|
-
unasigned_var_ids = var_ids-mapping.keys
|
714
|
-
|
715
|
-
# Development
|
716
|
-
|
717
|
-
# Find the available real values
|
718
|
-
available_real_values = @potential_values-mapping.values
|
719
|
-
|
720
|
-
# Determine the mermutations of unassigned var ids to available real values.
|
721
|
-
# NOTE: I'm sure how efficient it is working out every permutation especially
|
722
|
-
# when a dependent link "varA.kind_of?(Fixnum)" could narrow the
|
723
|
-
# combinations considerably.
|
724
|
-
value_permutations = available_real_values.permutation(unasigned_var_ids.length).to_a
|
725
|
-
var_value_permutations = value_permutations.inject([]) do |total,x|
|
726
|
-
r = []
|
727
|
-
x.zip(unasigned_var_ids) do |y,z|
|
728
|
-
r << z
|
729
|
-
r << y
|
730
|
-
end
|
731
|
-
total << Mapping.new(Hash[*r])
|
732
|
-
end
|
733
|
-
|
734
|
-
# = Remove any mapping permutaions that don't work =
|
735
|
-
passible_mappings = []
|
736
|
-
var_value_permutations.each_with_index do |possible_mapping,i|
|
737
|
-
|
738
|
-
# Combine the possible mapping with current actual mapping
|
739
|
-
m = mapping.merge(possible_mapping)
|
740
|
-
|
741
|
-
# Using this mapping go through each dependent and check it works
|
742
|
-
# (if it doesn't work then it's a none starter)
|
743
|
-
# TODO I don't really need to implement the full theory - just the dependents
|
744
|
-
implementation = theory.map_to(m)
|
745
|
-
|
746
|
-
# Use each implementation and find the ones that work
|
747
|
-
next unless implementation.meets_dependencies?(runtime_method,test_cases)
|
748
|
-
passible_mappings << m
|
749
|
-
|
750
|
-
|
751
|
-
end
|
752
|
-
return passible_mappings
|
753
|
-
|
754
|
-
end
|
755
|
-
|
756
|
-
end
|