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