cauldron 0.1.0
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/.document +5 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +20 -0
- data/README +1 -0
- data/README.rdoc +19 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/bin/cauldron +10 -0
- data/cauldron/.autotest +23 -0
- data/cauldron/History.txt +6 -0
- data/cauldron/Manifest.txt +8 -0
- data/cauldron/README.txt +57 -0
- data/cauldron/Rakefile +27 -0
- data/cauldron/bin/cauldron +3 -0
- data/cauldron/lib/cauldron.rb +3 -0
- data/cauldron/test/test_cauldron.rb +8 -0
- data/features/cauldron_example_cases.feature +13 -0
- data/features/cauldron_generates_runtime_method.feature +12 -0
- data/features/cauldron_start_terminal.feature +13 -0
- data/features/step_definitions/cauldron_steps.rb +16 -0
- data/features/step_definitions/terminal_steps.rb +34 -0
- data/features/support/env.rb +19 -0
- data/lib/Chain.rb +879 -0
- data/lib/ChainMapping.rb +172 -0
- data/lib/CodeHandler.rb +517 -0
- data/lib/Mapping.rb +26 -0
- data/lib/MappingValues.rb +24 -0
- data/lib/ScopeDependencies.rb +7 -0
- data/lib/Theory.rb +274 -0
- data/lib/UnifiedChain.rb +110 -0
- data/lib/cauldron.rb +6 -0
- data/lib/cauldron/conversion.rb +15 -0
- data/lib/cauldron/pot.rb +134 -0
- data/lib/cauldron/sexp2cauldron.rb +156 -0
- data/lib/cauldron/terminal.rb +120 -0
- data/lib/cauldron/theory_factory.rb +10 -0
- data/lib/core/ActsAsCode.rb +25 -0
- data/lib/core/BlockToken.rb +33 -0
- data/lib/core/CCall.rb +7 -0
- data/lib/core/CTestCase.rb +27 -0
- data/lib/core/ClassMethodCallContainer.rb +45 -0
- data/lib/core/Container.rb +85 -0
- data/lib/core/InstanceCallContainer.rb +272 -0
- data/lib/core/MethodUsage.rb +66 -0
- data/lib/core/PrintVariables.rb +25 -0
- data/lib/core/TheoryGenerator.rb +764 -0
- data/lib/core/Token.rb +7 -0
- data/lib/core/assignment/Assignment.rb +18 -0
- data/lib/core/assignment/Equal.rb +39 -0
- data/lib/core/assignment/Equivalent.rb +20 -0
- data/lib/core/assignment/NotEqual.rb +14 -0
- data/lib/core/call_container/CallContainer.rb +66 -0
- data/lib/core/class_method_call/New.rb +15 -0
- data/lib/core/class_method_call/RuntimeClassMethodCall.rb +31 -0
- data/lib/core/declaration/Declaration.rb +16 -0
- data/lib/core/declaration/LiteralDeclaration.rb +47 -0
- data/lib/core/declaration/VariableDeclaration.rb +59 -0
- data/lib/core/instance_call/ArrayEach.rb +23 -0
- data/lib/core/instance_call/ArrayLength.rb +15 -0
- data/lib/core/instance_call/Chop.rb +28 -0
- data/lib/core/instance_call/Copy.rb +22 -0
- data/lib/core/instance_call/DeclaredVariable.rb +18 -0
- data/lib/core/instance_call/InstanceCall.rb +77 -0
- data/lib/core/instance_call/Params.rb +15 -0
- data/lib/core/instance_call/Push.rb +20 -0
- data/lib/core/instance_call/StringLength.rb +32 -0
- data/lib/core/instance_call/Times.rb +20 -0
- data/lib/core/instance_call/instance_calls.rb +168 -0
- data/lib/core/instance_call/length_equal.rb +15 -0
- data/lib/core/kernal/EvalCall.rb +15 -0
- data/lib/core/kernal/LocalVariablesCall.rb +15 -0
- data/lib/core/literal/Literal.rb +111 -0
- data/lib/core/literal/Raw.rb +23 -0
- data/lib/core/literal/RuntimeMethodLiteral.rb +21 -0
- data/lib/core/literal/StatementLiteral.rb +28 -0
- data/lib/core/method_call/AvailableVariablesCall.rb +25 -0
- data/lib/core/method_call/ClassCall.rb +33 -0
- data/lib/core/method_call/DefCall.rb +72 -0
- data/lib/core/method_call/EvaluateClassCall.rb +29 -0
- data/lib/core/method_call/MethodNameCall.rb +27 -0
- data/lib/core/method_call/ToDeclarationCall.rb +15 -0
- data/lib/core/requirement/Requirement.rb +291 -0
- data/lib/core/runtime_class/ArrayClass.rb +19 -0
- data/lib/core/runtime_class/ClassCallClass.rb +23 -0
- data/lib/core/runtime_class/ClassEvaluationClass.rb +19 -0
- data/lib/core/runtime_class/ClassName.rb +18 -0
- data/lib/core/runtime_class/DefCallClass.rb +21 -0
- data/lib/core/runtime_class/EqualClass.rb +19 -0
- data/lib/core/runtime_class/FixnumClass.rb +15 -0
- data/lib/core/runtime_class/IfStatementClass.rb +12 -0
- data/lib/core/runtime_class/InstanceCallClass.rb +19 -0
- data/lib/core/runtime_class/InstanceCallContainerClass.rb +16 -0
- data/lib/core/runtime_class/InstanceClassCallClass.rb +19 -0
- data/lib/core/runtime_class/LiteralClass.rb +19 -0
- data/lib/core/runtime_class/MethodParameterClass.rb +27 -0
- data/lib/core/runtime_class/MethodUsageClass.rb +27 -0
- data/lib/core/runtime_class/RequirementClass.rb +19 -0
- data/lib/core/runtime_class/ReturnClass.rb +21 -0
- data/lib/core/runtime_class/RuntimeClass.rb +30 -0
- data/lib/core/runtime_class/RuntimeClassClass.rb +19 -0
- data/lib/core/runtime_class/RuntimeMethodClass.rb +34 -0
- data/lib/core/runtime_class/StatementClass.rb +53 -0
- data/lib/core/runtime_class/StringClass.rb +23 -0
- data/lib/core/runtime_class/StringLengthClass.rb +19 -0
- data/lib/core/runtime_class/StringVariableClass.rb +19 -0
- data/lib/core/runtime_class/ThisClass.rb +15 -0
- data/lib/core/runtime_class/UnknownClass.rb +23 -0
- data/lib/core/runtime_class/class_names.rb +95 -0
- data/lib/core/runtime_class/runtime_class.rb +123 -0
- data/lib/core/runtime_method/ActsAsRuntimeMethod.rb +300 -0
- data/lib/core/runtime_method/ParametersContainer.rb +29 -0
- data/lib/core/runtime_method/RealisedRuntimeMethod.rb +94 -0
- data/lib/core/runtime_method/RuntimeMethod.rb +817 -0
- data/lib/core/runtime_method/WriteParameters.rb +35 -0
- data/lib/core/statement/ActsAsStatement.rb +116 -0
- data/lib/core/statement/ArrayAccess.rb +96 -0
- data/lib/core/statement/BlockStatement.rb +348 -0
- data/lib/core/statement/DeclarationStatement.rb +19 -0
- data/lib/core/statement/HackStatement.rb +25 -0
- data/lib/core/statement/HashAccess.rb +18 -0
- data/lib/core/statement/OpenStatement.rb +171 -0
- data/lib/core/statement/RealisedStatement.rb +5 -0
- data/lib/core/statement/SingleLineBlockStatement.rb +39 -0
- data/lib/core/statement/Statement.rb +1223 -0
- data/lib/core/statement/StatementDependencies.rb +271 -0
- data/lib/core/statement/StatementGroup.rb +157 -0
- data/lib/core/statement/StatementStructure2.rb +224 -0
- data/lib/core/statement/TheoryStatement.rb +60 -0
- data/lib/core/statement/TopologicalStatements.rb +34 -0
- data/lib/core/structure/DeclareNewInstanceStructure.rb +49 -0
- data/lib/core/structure/DeclareRuntimeMethodStructure.rb +34 -0
- data/lib/core/structure/DeclareVariableAsLiteralStructure.rb +31 -0
- data/lib/core/structure/DeclareVariableAsVariableStructure.rb +52 -0
- data/lib/core/structure/FixnumAdditionStructure.rb +56 -0
- data/lib/core/structure/InstanceCallContainerStructure.rb +50 -0
- data/lib/core/structure/InstanceCallStructure.rb +53 -0
- data/lib/core/structure/InstanceMethodCallStructure.rb +21 -0
- data/lib/core/structure/ReturnStructure.rb +20 -0
- data/lib/core/structure/StatementStructure.rb +11 -0
- data/lib/core/syntax/Addition.rb +25 -0
- data/lib/core/syntax/BlockContainer.rb +130 -0
- data/lib/core/syntax/Boolean.rb +15 -0
- data/lib/core/syntax/Code.rb +11 -0
- data/lib/core/syntax/Do.rb +20 -0
- data/lib/core/syntax/False.rb +12 -0
- data/lib/core/syntax/If.rb +28 -0
- data/lib/core/syntax/IfContainer.rb +100 -0
- data/lib/core/syntax/Nil.rb +15 -0
- data/lib/core/syntax/Return.rb +33 -0
- data/lib/core/syntax/Subtract.rb +19 -0
- data/lib/core/syntax/This.rb +40 -0
- data/lib/core/syntax/True.rb +20 -0
- data/lib/core/syntax/syntax.rb +24 -0
- data/lib/core/tracking/ActsAsTrackable.rb +65 -0
- data/lib/core/tracking/History.rb +167 -0
- data/lib/core/tracking/RuntimeTrackingMethod.rb +32 -0
- data/lib/core/tracking/Step.rb +52 -0
- data/lib/core/variable/ArrayVariable.rb +76 -0
- data/lib/core/variable/BaseVariable.rb +154 -0
- data/lib/core/variable/BlockVariable.rb +92 -0
- data/lib/core/variable/FixnumVariable.rb +36 -0
- data/lib/core/variable/HistoryVariable.rb +8 -0
- data/lib/core/variable/MethodParameter.rb +206 -0
- data/lib/core/variable/MethodUsageVariable.rb +60 -0
- data/lib/core/variable/NilVariable.rb +29 -0
- data/lib/core/variable/RuntimeMethodParameter.rb +67 -0
- data/lib/core/variable/StatementVariable.rb +72 -0
- data/lib/core/variable/StepVariable.rb +7 -0
- data/lib/core/variable/StringVariable.rb +46 -0
- data/lib/core/variable/TypeVariable.rb +72 -0
- data/lib/core/variable/Unknown.rb +116 -0
- data/lib/core/variable/UnknownVariable.rb +29 -0
- data/lib/core/variable/Variable.rb +70 -0
- data/lib/core/variable/VariableContainer.rb +28 -0
- data/lib/core/variable/VariableIncluded.rb +27 -0
- data/lib/core/variable/VariableReference.rb +85 -0
- data/lib/error/FailedToFindStatementContainerError.rb +7 -0
- data/lib/error/FailedToFindStatementError.rb +7 -0
- data/lib/error/FailedToFindVariableError.rb +7 -0
- data/lib/error/FailedToLiteraliseError.rb +7 -0
- data/lib/error/FailedVariableMatch.rb +7 -0
- data/lib/error/ImproperStatementUsageError.rb +7 -0
- data/lib/error/IncompatiableRequirementsError.rb +7 -0
- data/lib/error/InvalidStatementError.rb +7 -0
- data/lib/error/MethodSizeError.rb +7 -0
- data/lib/error/RuntimeSyntaxError.rb +7 -0
- data/lib/error/UnexpectedStatementTypeError.rb +7 -0
- data/lib/error/UnknownStatementType.rb +7 -0
- data/lib/error/UnliteralisableError.rb +7 -0
- data/lib/implemented_chain.rb +34 -0
- data/lib/intrinsic/IntrinsicLastRuntimeMethod.rb +20 -0
- data/lib/intrinsic/IntrinsicLiteral.rb +26 -0
- data/lib/intrinsic/IntrinsicObject.rb +22 -0
- data/lib/intrinsic/IntrinsicRuntimeMethod.rb +27 -0
- data/lib/intrinsic/IntrinsicTestCases.rb +17 -0
- data/lib/logger/StandardLogger.rb +62 -0
- data/lib/required.rb +236 -0
- data/lib/ruby_code/Array.rb +95 -0
- data/lib/ruby_code/Fixnum.rb +39 -0
- data/lib/ruby_code/Hash.rb +25 -0
- data/lib/ruby_code/NilClass.rb +19 -0
- data/lib/ruby_code/Object.rb +24 -0
- data/lib/ruby_code/String.rb +86 -0
- data/lib/ruby_code/Symbol.rb +7 -0
- data/lib/standard_library/Tasks.rb +12 -0
- data/lib/theories.rb +143 -0
- data/lib/theory/ActionImplementation.rb +17 -0
- data/lib/theory/TheoryAction.rb +70 -0
- data/lib/theory/TheoryChainValidator.rb +101 -0
- data/lib/theory/TheoryComponent.rb +42 -0
- data/lib/theory/TheoryConnector.rb +755 -0
- data/lib/theory/TheoryDependent.rb +135 -0
- data/lib/theory/TheoryImplementation.rb +74 -0
- data/lib/theory/TheoryResult.rb +131 -0
- data/lib/theory/TheoryVariable.rb +63 -0
- data/lib/theory/theory_collection.rb +62 -0
- data/lib/util/ClassEvaluation.rb +68 -0
- data/lib/util/CodeEvaluation.rb +35 -0
- data/lib/util/DeclarationStatementEvaluation.rb +31 -0
- data/lib/util/MethodEvaluation.rb +49 -0
- data/lib/util/MethodTester.rb +71 -0
- data/lib/util/MethodValidation.rb +145 -0
- data/lib/util/MethodWriter.rb +66 -0
- data/lib/util/Parser.rb +299 -0
- data/lib/util/StatementCheck.rb +42 -0
- data/lib/util/StringToTheory.rb +119 -0
- data/lib/util/System.rb +8 -0
- data/spec/cauldron/pot_spec.rb +6 -0
- data/spec/cauldron/runtime_method_spec.rb +36 -0
- data/spec/cauldron/sexp_2_cauldron_spec.rb +26 -0
- data/spec/cauldron/terminal_spec.rb +38 -0
- data/spec/cauldron/theory_action_spec.rb +5 -0
- data/spec/spec_helper.rb +4 -0
- data/test/fixtures/chains/1/declaration.txt +26 -0
- data/test/fixtures/chains/1/dump +0 -0
- data/test/fixtures/chains/2/declaration.txt +26 -0
- data/test/fixtures/chains/2/dump +0 -0
- data/test/fixtures/chains/3/declaration.txt +26 -0
- data/test/fixtures/chains/3/dump +0 -0
- data/test/fixtures/implementation_results/0/declaration.txt +3 -0
- data/test/fixtures/implementation_results/0/dump +0 -0
- data/test/fixtures/theories/0/declaration.txt +9 -0
- data/test/fixtures/theories/0/desc +10 -0
- data/test/fixtures/theories/0/dump +0 -0
- data/test/fixtures/theories/1/declaration.txt +15 -0
- data/test/fixtures/theories/1/desc +11 -0
- data/test/fixtures/theories/1/dump +0 -0
- data/test/fixtures/theories/10/declaration.txt +23 -0
- data/test/fixtures/theories/10/desc +17 -0
- data/test/fixtures/theories/10/dump +0 -0
- data/test/fixtures/theories/11/declaration.txt +20 -0
- data/test/fixtures/theories/11/desc +14 -0
- data/test/fixtures/theories/11/dump +0 -0
- data/test/fixtures/theories/12/declaration.txt +18 -0
- data/test/fixtures/theories/12/desc +12 -0
- data/test/fixtures/theories/12/dump +0 -0
- data/test/fixtures/theories/13/declaration.txt +24 -0
- data/test/fixtures/theories/13/desc +20 -0
- data/test/fixtures/theories/13/dump +0 -0
- data/test/fixtures/theories/14/declaration.txt +26 -0
- data/test/fixtures/theories/14/desc +20 -0
- data/test/fixtures/theories/14/dump +0 -0
- data/test/fixtures/theories/15/declaration.txt +20 -0
- data/test/fixtures/theories/15/desc +14 -0
- data/test/fixtures/theories/15/dump +0 -0
- data/test/fixtures/theories/16/declaration.txt +30 -0
- data/test/fixtures/theories/16/desc +14 -0
- data/test/fixtures/theories/16/dump +0 -0
- data/test/fixtures/theories/17/declaration.txt +25 -0
- data/test/fixtures/theories/17/desc +11 -0
- data/test/fixtures/theories/17/dump +0 -0
- data/test/fixtures/theories/18/declaration.txt +23 -0
- data/test/fixtures/theories/18/desc +11 -0
- data/test/fixtures/theories/18/dump +0 -0
- data/test/fixtures/theories/19/declaration.txt +23 -0
- data/test/fixtures/theories/19/desc +11 -0
- data/test/fixtures/theories/19/dump +0 -0
- data/test/fixtures/theories/2/declaration.txt +12 -0
- data/test/fixtures/theories/2/desc +10 -0
- data/test/fixtures/theories/2/dump +0 -0
- data/test/fixtures/theories/20/declaration.txt +23 -0
- data/test/fixtures/theories/20/desc +17 -0
- data/test/fixtures/theories/20/dump +0 -0
- data/test/fixtures/theories/3/declaration.txt +19 -0
- data/test/fixtures/theories/3/desc +11 -0
- data/test/fixtures/theories/3/dump +0 -0
- data/test/fixtures/theories/4/declaration.txt +11 -0
- data/test/fixtures/theories/4/desc +11 -0
- data/test/fixtures/theories/4/dump +0 -0
- data/test/fixtures/theories/5/declaration.txt +6 -0
- data/test/fixtures/theories/5/desc +9 -0
- data/test/fixtures/theories/5/dump +0 -0
- data/test/fixtures/theories/6/declaration.txt +13 -0
- data/test/fixtures/theories/6/desc +11 -0
- data/test/fixtures/theories/6/dump +0 -0
- data/test/fixtures/theories/7/declaration.txt +19 -0
- data/test/fixtures/theories/7/desc +11 -0
- data/test/fixtures/theories/7/dump +0 -0
- data/test/fixtures/theories/8/declaration.txt +21 -0
- data/test/fixtures/theories/8/desc +11 -0
- data/test/fixtures/theories/8/dump +0 -0
- data/test/fixtures/theories/9/declaration.txt +24 -0
- data/test/fixtures/theories/9/desc +20 -0
- data/test/fixtures/theories/9/dump +0 -0
- data/test/fixtures/theory_implementations/0/declaration.txt +11 -0
- data/test/fixtures/theory_implementations/0/desc.txt +9 -0
- data/test/fixtures/theory_implementations/0/dump +0 -0
- data/test/fixtures/theory_implementations/0/theory_id +1 -0
- data/test/fixtures/theory_implementations/1/desc.txt +9 -0
- data/test/fixtures/theory_implementations/1/dump +0 -0
- data/test/fixtures/theory_implementations/1/theory_id +1 -0
- data/test/fixtures/theory_implementations/2/desc.txt +9 -0
- data/test/fixtures/theory_implementations/2/dump +0 -0
- data/test/fixtures/theory_implementations/2/theory_id +1 -0
- data/test/output/simple_method.txt +6 -0
- data/test/output/test_method/first_possible_method.txt +6 -0
- data/test/output/test_simple_cases/simple_case_01.txt +8 -0
- data/test/output/test_simple_cases/simple_case_02.txt +7 -0
- data/test/output/test_simple_cases/simple_case_03.txt +8 -0
- data/test/output/test_simple_cases/simple_case_04.txt +8 -0
- data/test/output/test_simple_cases/simple_case_05.txt +8 -0
- data/test/output/test_simple_cases/simple_case_06.txt +9 -0
- data/test/output/test_simple_cases/simple_case_07.txt +9 -0
- data/test/output/test_simple_cases/simple_case_08.txt +9 -0
- data/test/tc_contextual_variables.rb +87 -0
- data/test/tc_describe.rb +47 -0
- data/test/tc_method.rb +133 -0
- data/test/tc_requirement.rb +30 -0
- data/test/tc_suite_complete.rb +26 -0
- data/test/tc_variable.rb +52 -0
- data/test/ts_complete.rb +84 -0
- data/test/ts_stable.rb +81 -0
- data/test/unit/core/declaration/tc_literal_declaration.rb +34 -0
- data/test/unit/core/method_call/tc_class_call.rb +20 -0
- data/test/unit/core/runtime_method/tc_realised_runtime_method.rb +129 -0
- data/test/unit/core/runtime_method/tc_runtime_method.rb +616 -0
- data/test/unit/core/statement/tc_array_access.rb +63 -0
- data/test/unit/core/statement/tc_block_statement.rb +51 -0
- data/test/unit/core/statement/tc_hack_statement.rb +26 -0
- data/test/unit/core/statement/tc_open_statement.rb +70 -0
- data/test/unit/core/statement/tc_statement.rb +681 -0
- data/test/unit/core/statement/tc_statement_dependencies.rb +146 -0
- data/test/unit/core/statement/tc_statement_group.rb +35 -0
- data/test/unit/core/statement/tc_statement_replace_variable.rb +61 -0
- data/test/unit/core/statement/tc_theory_statement.rb +51 -0
- data/test/unit/core/structure/tc_declare_new_instance_structure.rb +41 -0
- data/test/unit/core/structure/tc_declare_variable_as_literal_structure.rb +41 -0
- data/test/unit/core/structure/tc_declare_variable_as_variable_structure.rb +66 -0
- data/test/unit/core/structure/tc_instance_call_container_structure.rb +41 -0
- data/test/unit/core/structure/tc_return_structure.rb +32 -0
- data/test/unit/core/syntax/tc_block_container.rb +32 -0
- data/test/unit/core/syntax/tc_if_container.rb +39 -0
- data/test/unit/core/tc_class_method_call.rb +34 -0
- data/test/unit/core/tc_container.rb +41 -0
- data/test/unit/core/tc_ctest_case.rb +25 -0
- data/test/unit/core/tc_instance_call_container.rb +93 -0
- data/test/unit/core/tc_literal.rb +30 -0
- data/test/unit/core/tc_theory_generator.rb +336 -0
- data/test/unit/core/tc_theory_generator_heavy.rb +42 -0
- data/test/unit/core/tracking/tc_history.rb +102 -0
- data/test/unit/core/tracking/tc_step.rb +65 -0
- data/test/unit/core/variable/tc_array_variable.rb +61 -0
- data/test/unit/core/variable/tc_block_variable.rb +17 -0
- data/test/unit/core/variable/tc_fixnum_variable.rb +54 -0
- data/test/unit/core/variable/tc_method_parameter_variable.rb +22 -0
- data/test/unit/core/variable/tc_runtime_method_variable.rb +32 -0
- data/test/unit/core/variable/tc_string_variable.rb +37 -0
- data/test/unit/core/variable/tc_unknown.rb +24 -0
- data/test/unit/core/variable/tc_variable_reference.rb +28 -0
- data/test/unit/ruby_code/tc_array.rb +64 -0
- data/test/unit/ruby_code/tc_fixnum.rb +18 -0
- data/test/unit/ruby_code/tc_hash.rb +41 -0
- data/test/unit/ruby_code/tc_string.rb +38 -0
- data/test/unit/tc_chain.rb +434 -0
- data/test/unit/tc_chain_mapping.rb +62 -0
- data/test/unit/tc_chain_with_case_1.rb +169 -0
- data/test/unit/tc_instance_call.rb +40 -0
- data/test/unit/tc_instance_call_structure.rb +35 -0
- data/test/unit/tc_method_usage.rb +35 -0
- data/test/unit/tc_pot.rb +124 -0
- data/test/unit/tc_runtime_tracking_method.rb +40 -0
- data/test/unit/tc_statement_structure_2.rb +43 -0
- data/test/unit/tc_theory.rb +533 -0
- data/test/unit/tc_variable_declaration.rb +32 -0
- data/test/unit/theory/tc_theory_action.rb +80 -0
- data/test/unit/theory/tc_theory_action_implementation.rb +23 -0
- data/test/unit/theory/tc_theory_chain_validator.rb +340 -0
- data/test/unit/theory/tc_theory_connector.rb +396 -0
- data/test/unit/theory/tc_theory_dependent.rb +151 -0
- data/test/unit/theory/tc_theory_implementation.rb +133 -0
- data/test/unit/theory/tc_theory_result.rb +111 -0
- data/test/unit/theory/tc_theory_variable.rb +45 -0
- data/test/unit/util/tc_method_validation.rb +98 -0
- data/test/unit/util/tc_parser.rb +108 -0
- data/test/unit/util/tc_string_to_theory.rb +299 -0
- data/test/unit/variable/tc_method_usage_variable.rb +25 -0
- data/tmp/runtime_method_evaluation.rb +10 -0
- metadata +522 -0
@@ -0,0 +1,66 @@
|
|
1
|
+
# Instances of this class describe the parameters that a method uses
|
2
|
+
# and is required to have
|
3
|
+
#
|
4
|
+
class MethodUsage < Array
|
5
|
+
|
6
|
+
def initialize(*parameters)
|
7
|
+
super()
|
8
|
+
|
9
|
+
# Check the data type of the provided variables
|
10
|
+
parameters.each do |x|
|
11
|
+
unless x.kind_of? MethodParameter then raise StandardError.new('Unexpected data type: '+x.class.to_s+' expecting MethodParameter') end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Add the method variables to your self
|
15
|
+
parameters.collect {|param| self.push param}
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
# Check whether the rule matches the usage of the method. Essentially
|
20
|
+
# checking that the number of parameters is correct and the data types
|
21
|
+
# are acceptable.
|
22
|
+
#
|
23
|
+
def valid_rule? rule
|
24
|
+
|
25
|
+
# Check that correct number of parameters are provided
|
26
|
+
unless rule.paramater_count == self.length then raise ParameterCountError.new('Expected '+self.length.to_s+' parameters') end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
def write
|
31
|
+
line = 'MethodUsage.new('
|
32
|
+
self.each do |x|
|
33
|
+
line += x.to_declaration.write
|
34
|
+
unless x.object_id == self.last.object_id then line += ', ' end
|
35
|
+
end
|
36
|
+
line += ')'
|
37
|
+
return line
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns this method usage case as MethodUsageVariable instance.
|
41
|
+
#
|
42
|
+
# TODO I'm not sure I should be allow this to set it's id
|
43
|
+
#
|
44
|
+
def to_var(id=nil,uniq_id=nil)
|
45
|
+
if id.nil? then return MethodUsageVariable.new(*self.collect {|x| x.copy}) end
|
46
|
+
return MethodUsageVariable.new(*self.collect {|x| x.copy}) {{:variable_id => id,:uniq_id=>uniq_id}}
|
47
|
+
end
|
48
|
+
|
49
|
+
# TODO Test this
|
50
|
+
def copy
|
51
|
+
return MethodUsage.new(*self.collect {|x| x.copy})
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_declaration
|
55
|
+
return VariableDeclaration.new('MethodUsage',*self.collect {|x| x.to_declaration})
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
class ParameterCountError < StandardError
|
61
|
+
|
62
|
+
def initialize(msg)
|
63
|
+
super(msg)
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module PrintVariables
|
2
|
+
|
3
|
+
#
|
4
|
+
def display_name_for(var)
|
5
|
+
|
6
|
+
# Has a name been given to this variable
|
7
|
+
unless @variable_names[var.variable_id].nil? then return @variable_names[var.variable_id] end
|
8
|
+
|
9
|
+
# Save the name of the new variable
|
10
|
+
var_name = 'var_'+@variable_counter.to_s
|
11
|
+
if var.kind_of? MethodParameter
|
12
|
+
var_name = 'param_var_'+@variable_counter.to_s
|
13
|
+
end
|
14
|
+
if var.kind_of? ResponseVariable
|
15
|
+
var_name = 'return_var_'+@variable_counter.to_s
|
16
|
+
end
|
17
|
+
@variable_counter += 1
|
18
|
+
|
19
|
+
# Save the existing name
|
20
|
+
@variable_names[var.variable_id] = var_name
|
21
|
+
return @variable_names[var.variable_id]
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,764 @@
|
|
1
|
+
class TheoryGenerator
|
2
|
+
|
3
|
+
def initialize(filters=[])
|
4
|
+
@filters = filters
|
5
|
+
end
|
6
|
+
|
7
|
+
# Returns an array of master theories(huge theories) generated using the runtime
|
8
|
+
# method at each stage of the chain.
|
9
|
+
#
|
10
|
+
def master_theories(chain,initial_runtime_method,test_cases)
|
11
|
+
raise StandardError.new('Currently only able to generate master theories for complete chains') unless chain.complete?
|
12
|
+
|
13
|
+
# Retrieve the full variable history for the chain - need to avoid duplicate variable creation especially if a variable
|
14
|
+
# only exists in the action.
|
15
|
+
creation_history = chain.variables_creation(initial_runtime_method,test_cases)
|
16
|
+
|
17
|
+
# * Create the values array [{:value=>x,:statement=>:step=>}]
|
18
|
+
master_theories = []
|
19
|
+
chain.each_theory_progression(initial_runtime_method,test_cases) do |implemented_theory,theory|
|
20
|
+
|
21
|
+
# TODO Include this as a test to confirm an exception is raised
|
22
|
+
# QUICK: Adding a new value in the test cases :after so it changes the output
|
23
|
+
# and the variable mapping - the error should be picked up.
|
24
|
+
# if implemented_theory.accessor_values[:after][1]
|
25
|
+
# implemented_theory.accessor_values[:after][1].push({:params=>["pip"],:output=>"pip"})
|
26
|
+
# end
|
27
|
+
|
28
|
+
dependent_accessors = retrieve_accessors(implemented_theory.accessor_values[:before],creation_history)
|
29
|
+
result_accessors = retrieve_accessors(implemented_theory.accessor_values[:after],creation_history)
|
30
|
+
|
31
|
+
# Generate the dependents and results
|
32
|
+
theory_dependents = get_theory_dependents(dependent_accessors.copy)[0..8]
|
33
|
+
theory_results = get_theory_dependents(result_accessors.copy)[0..2]
|
34
|
+
|
35
|
+
# Create the complete theory
|
36
|
+
master_theories << Theory.new(
|
37
|
+
theory_dependents.copy,
|
38
|
+
theory.action.copy,
|
39
|
+
theory_results
|
40
|
+
)
|
41
|
+
|
42
|
+
end
|
43
|
+
return master_theories
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns a master and simplistic theory in conext of the supplied runtime
|
48
|
+
# method after each of the actions is added. So for each action there is
|
49
|
+
# new theory generated.
|
50
|
+
#
|
51
|
+
# NOTE: This is the first time I've started to introduce this master/simply
|
52
|
+
# theory paradigm. The general rule I'm using is that the simple theory
|
53
|
+
# only needs to be complex enough so it can indicate the order the actions
|
54
|
+
# should be performed.
|
55
|
+
#
|
56
|
+
# NOTE: The variables that each of theories use always refer to the same value. So
|
57
|
+
# if var1 is the rutime method then var1 is the runtime method for all the theories.
|
58
|
+
#
|
59
|
+
def generate_theories_for_actions(runtime_method,test_cases,actions)
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns true if adding the supplied actions to the runtime method results
|
64
|
+
# in all the tests cases being met. This is useful to use before attempting
|
65
|
+
# to generate the theories to solve the test cases.
|
66
|
+
#
|
67
|
+
# TODO I would rather the mapping was ChainMapping or ideally the mapping wasn't passed
|
68
|
+
# all, just have it as internal to the chain.
|
69
|
+
#
|
70
|
+
def actions_validate_runtime_method?(runtime_method,test_cases,actions,mapping)
|
71
|
+
|
72
|
+
# Declare the default finish for any problem
|
73
|
+
head = Theory.new([],nil,[])
|
74
|
+
tail = Parser.run("if(runtime_method.all_pass?(test_cases))\nreturn true\nend")
|
75
|
+
|
76
|
+
# Create the chain
|
77
|
+
chain = Chain.new
|
78
|
+
chain.form_chain(head,tail,mapping)
|
79
|
+
|
80
|
+
# Add each of the actions to the chain
|
81
|
+
actions.each do |action|
|
82
|
+
chain.add_link(Theory.new([],action,[]))
|
83
|
+
end
|
84
|
+
|
85
|
+
# Implement the chain so that all variables are unified
|
86
|
+
implementd_chain = chain.implement
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
# This generates an inital set of theories using the initial values. It
|
91
|
+
# then continues to generate additional theories after applying the action
|
92
|
+
# of the previously generated theories.
|
93
|
+
#
|
94
|
+
def multiple_generate(runtime_method,test_cases,limit=1)
|
95
|
+
theories = generate(test_cases,runtime_method,0)
|
96
|
+
|
97
|
+
additional_theories = []
|
98
|
+
theories.each_with_index do |x,i|
|
99
|
+
additional_theories += recursive_generate(test_cases,x,1,(limit-1))
|
100
|
+
end
|
101
|
+
return theories+additional_theories
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
def recursive_generate(test_cases,theory,stage,limit=1,results=[])
|
106
|
+
|
107
|
+
results << theory
|
108
|
+
return results if limit == 0
|
109
|
+
|
110
|
+
# TODO It seems a bit wasteful to generate a whole new set of accessors for each
|
111
|
+
# new theory. It should maybe just up accessors that include the runtime method.
|
112
|
+
new_theories = generate(test_cases.copy,theory.example_runtime_method.copy,stage)
|
113
|
+
|
114
|
+
new_theories.each do |x|
|
115
|
+
recursive_generate(test_cases.copy,x,(stage+1),(limit-1),results)
|
116
|
+
end
|
117
|
+
return results
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
# Returns an array of theories that add a variety of statements to the runtime
|
122
|
+
# method. The theories will be quite bloated since they'll contain all the possible
|
123
|
+
# dependents and results.
|
124
|
+
#
|
125
|
+
# @param values An array of literal values
|
126
|
+
#
|
127
|
+
def generate(test_cases,runtime_method,stage=0)
|
128
|
+
|
129
|
+
#
|
130
|
+
# TODO Not keen on this parallel assignment (should really just
|
131
|
+
# have a single instance containing the accessors and
|
132
|
+
# mapping or have the mappig generated)
|
133
|
+
accessors, mapping = generate_accessors_and_mapping(test_cases,runtime_method,4,stage)
|
134
|
+
|
135
|
+
# Now generate some possible theories using these values
|
136
|
+
return generate_theories(test_cases,runtime_method,accessors,mapping)
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
# Returns an array of statements that use the values supplied but will return a
|
141
|
+
# value(including boolean).
|
142
|
+
#
|
143
|
+
def generate_accessors_and_mapping(test_cases,runtime_method,itterations=1,stage=0)
|
144
|
+
|
145
|
+
# TODO I'd like to drop this and just query the mapping instance
|
146
|
+
theory_variable_ids = [0,1,2]
|
147
|
+
|
148
|
+
# Create a theory variable for each of the values
|
149
|
+
# runtime_method => 1
|
150
|
+
# test_cases => 2
|
151
|
+
mapping = Mapping.new({
|
152
|
+
1 => runtime_method.copy,
|
153
|
+
2 => test_cases.copy
|
154
|
+
})
|
155
|
+
results = [
|
156
|
+
{:value=>runtime_method.copy,:statement=>TheoryStatement.new(TheoryVariable.new(1)),:step=>0},
|
157
|
+
{:value=>test_cases.copy,:statement=>TheoryStatement.new(TheoryVariable.new(2)),:step=>0}
|
158
|
+
]
|
159
|
+
|
160
|
+
# Generate a number of values that can be obtained from the current runtime method and test cases
|
161
|
+
itterations.times do |step|
|
162
|
+
results = extend_accessors(results,mapping,theory_variable_ids,(step+1))
|
163
|
+
end
|
164
|
+
return results, mapping
|
165
|
+
|
166
|
+
end
|
167
|
+
|
168
|
+
def generate_theories(test_cases,runtime_method,accessors,mapping)
|
169
|
+
|
170
|
+
# Retreive theory dependets relating to the current method
|
171
|
+
theory_dependents = get_theory_dependents(accessors.copy)
|
172
|
+
|
173
|
+
# Retrieve possible statements to include in the theory
|
174
|
+
theory_actions = get_theory_action(test_cases.copy,runtime_method.copy,accessors,mapping)
|
175
|
+
|
176
|
+
# For each action retrieve the results of adding the statement
|
177
|
+
theories = []
|
178
|
+
theory_actions.each_with_index do |selected_action,i|
|
179
|
+
|
180
|
+
# Add the statement to the runtime method and construct result theories based on it
|
181
|
+
new_values = accessors.copy
|
182
|
+
|
183
|
+
# Convert the mapping values into intrinsic values
|
184
|
+
intrinsic_mapping = covert_to_intrinsic_mapping(mapping)
|
185
|
+
|
186
|
+
# Re-create the action with intrinsic variables
|
187
|
+
implementated_action = selected_action.map_to(intrinsic_mapping)
|
188
|
+
|
189
|
+
# Generate the runtime method that would be created by using that action
|
190
|
+
modified_runtime_method = TheoryChainValidator.new.add_statement_to_method(
|
191
|
+
test_cases.copy,
|
192
|
+
runtime_method.copy,
|
193
|
+
implementated_action
|
194
|
+
)
|
195
|
+
|
196
|
+
# TODO I should maybe keep both runtime methods so the I can compare the runtime method's
|
197
|
+
# before and after.
|
198
|
+
|
199
|
+
# Create a new mapping using the update runtime method
|
200
|
+
new_mapping = mapping.copy
|
201
|
+
new_mapping[1] = modified_runtime_method
|
202
|
+
|
203
|
+
# Re-build the results but using the new value for the runtime method
|
204
|
+
# re_evaluate_results
|
205
|
+
# TODO Using the same result statements is limiting - there might be more calls available.
|
206
|
+
new_results = re_evaluate_results(accessors,new_mapping)
|
207
|
+
|
208
|
+
# Get the theory results for this modified runtime method
|
209
|
+
theory_results = get_theory_results(new_results)
|
210
|
+
|
211
|
+
# Create the complete theory
|
212
|
+
theories << Theory.new(
|
213
|
+
theory_dependents.copy,
|
214
|
+
selected_action,
|
215
|
+
theory_results,
|
216
|
+
modified_runtime_method
|
217
|
+
)
|
218
|
+
|
219
|
+
end
|
220
|
+
|
221
|
+
return theories
|
222
|
+
|
223
|
+
end
|
224
|
+
|
225
|
+
def get_theory_action(test_cases,runtime_method,results,mapping)
|
226
|
+
|
227
|
+
# Get possible statements ids
|
228
|
+
statement_ids = results.select {|x| x[:value].kind_of?(Fixnum)}
|
229
|
+
|
230
|
+
actions = []
|
231
|
+
|
232
|
+
# Add 'return <val>' statement
|
233
|
+
results.each do |x|
|
234
|
+
statement_ids.each do |y|
|
235
|
+
# TODO Shouldn't allow runtime methods to be included here
|
236
|
+
actions << TheoryAction.new(
|
237
|
+
TheoryStatement.new(StringToTheory.run("Statement.new(Return.new,#{x[:statement].write})")),
|
238
|
+
StringToTheory.run(y[:statement].write)
|
239
|
+
)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
# Add the 'if(var1 == var2)' statement
|
243
|
+
# TODO Might only allow values in the action at this point
|
244
|
+
# 'IfStatement.new(var2[var3][:params][var6],Equivalent.new,var2[var3][:output])'
|
245
|
+
# TODO Should the values be equal at this point??
|
246
|
+
|
247
|
+
# Exclude the runtime method from being included as a value (.write method becomes messy)
|
248
|
+
# also excludes the orginal test_cases.
|
249
|
+
valid_results = results.select do |x|
|
250
|
+
|
251
|
+
# TODO For some reason "x[:value].all? {|y| y.kind_of?(CTestCase)}" returns true for method Parameter (which is why this is here)
|
252
|
+
next true if x[:value].kind_of?(MethodParameter)
|
253
|
+
|
254
|
+
next false if x[:value].kind_of?(RuntimeMethod)
|
255
|
+
|
256
|
+
# NOTE: This is only temporary - I don't really see anything wrong with nil
|
257
|
+
next false if x[:value].kind_of?(NilClass)
|
258
|
+
|
259
|
+
next false if x[:value].kind_of?(Array) && x[:value].all? {|y| y.kind_of?(CTestCase)}
|
260
|
+
next true
|
261
|
+
end
|
262
|
+
|
263
|
+
(results-valid_results).each do |x|
|
264
|
+
next if x[:value].nil?
|
265
|
+
end
|
266
|
+
|
267
|
+
# Generate "if(varA == varB) statements"
|
268
|
+
value_pairs = valid_results.permutation(2)
|
269
|
+
value_pairs.each do |x,y|
|
270
|
+
statement_ids.each do |z|
|
271
|
+
|
272
|
+
# if(x == y)
|
273
|
+
# COMPROMISE - Only include statements with the same data type
|
274
|
+
# TODO They should be same type not identical so as long as the extend Array
|
275
|
+
# TODO I need to get the value of the runtime method parameter e.g. 'var2.params[var5]'
|
276
|
+
if x[:value].class != MethodParameter and y[:value].class != MethodParameter
|
277
|
+
next unless x[:value].class == y[:value].class
|
278
|
+
end
|
279
|
+
actions << TheoryAction.new(
|
280
|
+
TheoryStatement.new(
|
281
|
+
StringToTheory.run(
|
282
|
+
"OpenStatement.new(IfContainer.new(#{x[:statement].write},Equivalent.new,#{y[:statement].write}))"
|
283
|
+
)
|
284
|
+
),
|
285
|
+
StringToTheory.run(z[:statement].write)
|
286
|
+
)
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
# TODO I haven't allowed last_runtime_method to be used yet
|
291
|
+
|
292
|
+
# ========================================================
|
293
|
+
# Remove the actions that don't work
|
294
|
+
# ========================================================
|
295
|
+
# TODO This duplicates the the "covert_to_intrinsic_mapping" method
|
296
|
+
# Convert the mapping values into intrinsic values
|
297
|
+
intrinsic_mapping = Mapping.new
|
298
|
+
test_cases_key = nil
|
299
|
+
runtime_method_key = nil
|
300
|
+
mapping.each do |key,value|
|
301
|
+
|
302
|
+
# Convert fixnum into intrinisic fixnums
|
303
|
+
if value.kind_of?(Fixnum)
|
304
|
+
intrinsic_mapping[key] = IntrinsicLiteral.new(value)
|
305
|
+
next
|
306
|
+
end
|
307
|
+
|
308
|
+
end
|
309
|
+
intrinsic_mapping[1] = Parser.run('runtime_method')
|
310
|
+
intrinsic_mapping[2] = Parser.run('test_cases')
|
311
|
+
|
312
|
+
# Attempt to add the statement to the actual runtime method
|
313
|
+
valid_actions = []
|
314
|
+
actions.each do |x|
|
315
|
+
implementation = x.map_to(intrinsic_mapping)
|
316
|
+
if action_works_with_runtime_method?(test_cases.copy,runtime_method.copy,implementation)
|
317
|
+
valid_actions << x
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
return valid_actions
|
322
|
+
|
323
|
+
end
|
324
|
+
|
325
|
+
def covert_to_intrinsic_mapping(mapping)
|
326
|
+
|
327
|
+
# Convert the mapping values into intrinsic values
|
328
|
+
intrinsic_mapping = Mapping.new
|
329
|
+
test_cases_key = nil
|
330
|
+
runtime_method_key = nil
|
331
|
+
mapping.each do |key,value|
|
332
|
+
|
333
|
+
# Convert fixnum into intrinisic fixnums
|
334
|
+
if value.kind_of?(Fixnum)
|
335
|
+
intrinsic_mapping[key] = IntrinsicLiteral.new(value)
|
336
|
+
next
|
337
|
+
end
|
338
|
+
|
339
|
+
if value.kind_of?(RuntimeMethod)
|
340
|
+
intrinsic_mapping[key] = Parser.run('runtime_method')
|
341
|
+
runtime_method_key = key
|
342
|
+
next
|
343
|
+
end
|
344
|
+
|
345
|
+
if value.kind_of?(Array) && value.first.has_key?(:params)
|
346
|
+
intrinsic_mapping[key] = Parser.run('test_cases')
|
347
|
+
test_cases_key = key
|
348
|
+
next
|
349
|
+
end
|
350
|
+
raise StandardError.new('Unknown value '+value.class.to_s)
|
351
|
+
end
|
352
|
+
return intrinsic_mapping
|
353
|
+
end
|
354
|
+
|
355
|
+
# Attempt to use the generated action with the runtime method to determine if
|
356
|
+
# it's valid syntax.
|
357
|
+
#
|
358
|
+
def action_works_with_runtime_method?(test_cases,runtime_method,action)
|
359
|
+
return TheoryChainValidator.new.add_statement_to_method(test_cases,runtime_method,action) ? true : false
|
360
|
+
rescue StandardError => e
|
361
|
+
return false
|
362
|
+
end
|
363
|
+
|
364
|
+
# Returns an array of theory dependents
|
365
|
+
#
|
366
|
+
def get_theory_dependents(results)
|
367
|
+
|
368
|
+
# Create the theory dependents for all the values
|
369
|
+
value_pairs = results.permutation(2)
|
370
|
+
theory_dependents = []
|
371
|
+
value_pairs.each do |x,y|
|
372
|
+
if x[:value] == y[:value]
|
373
|
+
theory_dependents << TheoryDependent.new(
|
374
|
+
StringToTheory.run("if(#{x[:statement].write} == #{y[:statement].write})\nreturn true\nend")
|
375
|
+
)
|
376
|
+
else
|
377
|
+
theory_dependents << TheoryDependent.new(
|
378
|
+
StringToTheory.run("if((#{x[:statement].write} == #{y[:statement].write})==false)\nreturn true\nend")
|
379
|
+
)
|
380
|
+
end
|
381
|
+
end
|
382
|
+
return theory_dependents
|
383
|
+
end
|
384
|
+
|
385
|
+
def get_theory_results(results)
|
386
|
+
theory_results = []
|
387
|
+
|
388
|
+
# Create the single statement theory results
|
389
|
+
results.each do |x|
|
390
|
+
if x[:value]
|
391
|
+
theory_results << TheoryResult.new(
|
392
|
+
StringToTheory.run("if(#{x[:statement].write})\nreturn true\nend")
|
393
|
+
)
|
394
|
+
elsif x[:value] == false
|
395
|
+
theory_results << TheoryResult.new(
|
396
|
+
StringToTheory.run("if((#{x[:statement].write})==false)\nreturn true\nend")
|
397
|
+
)
|
398
|
+
else
|
399
|
+
StandardLogger.instance.error(x[:statement].write+' is '+x[:value].to_s)
|
400
|
+
end
|
401
|
+
# TODO Should probably have else x[:value].nil? and StringToTheory.run("if((#{x[:statement].write}).nil?)\nreturn true\nend")
|
402
|
+
end
|
403
|
+
|
404
|
+
# Create the theory dependents for all the values
|
405
|
+
value_pairs = results.permutation(2)
|
406
|
+
value_pairs.each do |x,y|
|
407
|
+
if x[:value] == y[:value]
|
408
|
+
theory_results << TheoryResult.new(
|
409
|
+
StringToTheory.run("if(#{x[:statement].write} == #{y[:statement].write})\nreturn true\nend")
|
410
|
+
)
|
411
|
+
else
|
412
|
+
theory_results << TheoryResult.new(
|
413
|
+
StringToTheory.run("if((#{x[:statement].write} == #{y[:statement].write})==false)\nreturn true\nend")
|
414
|
+
)
|
415
|
+
end
|
416
|
+
end
|
417
|
+
return theory_results
|
418
|
+
|
419
|
+
end
|
420
|
+
|
421
|
+
# Re-evaluate the values of each of the results using an updated
|
422
|
+
# runtime method instance.
|
423
|
+
#
|
424
|
+
def re_evaluate_results(results,mapping)
|
425
|
+
new_results = []
|
426
|
+
results.each do |x|
|
427
|
+
v = obtain_value(x[:statement],mapping)
|
428
|
+
new_results << {:value=>v,:statement=>x[:statement],:step=>x[:step]}
|
429
|
+
end
|
430
|
+
return new_results
|
431
|
+
end
|
432
|
+
|
433
|
+
# Extends the provided accessors by another method call. For example
|
434
|
+
# if it is passed "test", it would return 'test'.length and
|
435
|
+
# 'test'.lowercase etc.
|
436
|
+
#
|
437
|
+
# @param initial_accessors An array of initial accessors containing the statement used
|
438
|
+
# to generate the value and the value itself.
|
439
|
+
# {:value=>#<Some Literal Value>,:statement=><#Statement: A statement instance>}
|
440
|
+
# @param mapping The current mapping being used. This is extended when a new
|
441
|
+
# index is used. So if test_case[0] is used, then 0 needs to have
|
442
|
+
# variable created for it and that added to the mapping.
|
443
|
+
# @param variable_history This keeps track of each time a new variable is created via additional
|
444
|
+
# array access calls. This allows the structure of the theories to remain
|
445
|
+
# unified across the dependents and results.
|
446
|
+
#
|
447
|
+
def extend_accessors(values,mapping,theory_variable_id,step,variable_history=[])
|
448
|
+
|
449
|
+
# Go through each of the values and get each of the cauldron method calls
|
450
|
+
total_results = []
|
451
|
+
values.each do |x|
|
452
|
+
|
453
|
+
# Get the possible cauldron method calls
|
454
|
+
results = []
|
455
|
+
x[:value].cauldron_method_calls.each do |y|
|
456
|
+
|
457
|
+
# Only get array access for values obtained in the last itteration
|
458
|
+
if (step-1) == x[:step]
|
459
|
+
results += params_output(x,y,mapping,theory_variable_id,step,values)
|
460
|
+
results += array_access(x,y,mapping,theory_variable_id,step,values,variable_history)
|
461
|
+
end
|
462
|
+
|
463
|
+
# If the variable is new it should have all the paramters
|
464
|
+
# If it isn't new it only needs the recent params
|
465
|
+
|
466
|
+
# Only include parameters for recently created values
|
467
|
+
if (step-1) == x[:step]
|
468
|
+
results += use_method_call(x,y,mapping,theory_variable_id,step,values)
|
469
|
+
else
|
470
|
+
last_results = values.select {|z| z[:step] == (step-1)}
|
471
|
+
results += use_method_call(x,y,mapping,theory_variable_id,step,last_results,true)
|
472
|
+
end
|
473
|
+
|
474
|
+
end
|
475
|
+
total_results += results
|
476
|
+
end
|
477
|
+
return total_results+values
|
478
|
+
end
|
479
|
+
|
480
|
+
#
|
481
|
+
#
|
482
|
+
#
|
483
|
+
def use_method_call(result,cauldron_method_call,mapping,theory_variable_id,step,available_params,params_only=false)
|
484
|
+
|
485
|
+
# Does it start with a '.'
|
486
|
+
results = []
|
487
|
+
if cauldron_method_call =~ /^\./
|
488
|
+
|
489
|
+
# Does it require any parameters
|
490
|
+
if ['.any?','.all_pass?','.pass?','.history2','.realise2','.kind_of?'].include?(cauldron_method_call)
|
491
|
+
|
492
|
+
case cauldron_method_call
|
493
|
+
when '.pass?'
|
494
|
+
# Uses one parameter - a test case
|
495
|
+
cauldron_test_cases = available_params.select {|x| x[:value].kind_of?(CTestCase)}
|
496
|
+
cauldron_test_cases.each do |x|
|
497
|
+
s = TheoryStatement.new(
|
498
|
+
StringToTheory.run(result[:statement].write+cauldron_method_call+'('+x[:statement].write+')')
|
499
|
+
)
|
500
|
+
v = obtain_value(s,mapping)
|
501
|
+
results << {:value=>v,:statement=>s,:step=>step}
|
502
|
+
end
|
503
|
+
when '.kind_of?'
|
504
|
+
|
505
|
+
# TODO Should probably include value class check here
|
506
|
+
s = TheoryStatement.new(
|
507
|
+
StringToTheory.run(result[:statement].write+cauldron_method_call+'(CTestCase)')
|
508
|
+
)
|
509
|
+
v = obtain_value(s,mapping)
|
510
|
+
results << {:value=>v,:statement=>s,:step=>step}
|
511
|
+
|
512
|
+
s2 = TheoryStatement.new(
|
513
|
+
StringToTheory.run(result[:statement].write+cauldron_method_call+'(Fixnum)')
|
514
|
+
)
|
515
|
+
v2 = obtain_value(s,mapping)
|
516
|
+
results << {:value=>v2,:statement=>s2,:step=>step}
|
517
|
+
when '.all_pass?'
|
518
|
+
|
519
|
+
available_params.each do |x|
|
520
|
+
if x[:value].kind_of?(Array) and x[:value].any? {|y| y.kind_of?(CTestCase)}
|
521
|
+
s = TheoryStatement.new(
|
522
|
+
StringToTheory.run(
|
523
|
+
result[:statement].write+cauldron_method_call+'('+x[:statement].write+')'
|
524
|
+
)
|
525
|
+
)
|
526
|
+
v = obtain_value(s,mapping)
|
527
|
+
results << {:value=>v,:statement=>s,:step=>step}
|
528
|
+
end
|
529
|
+
end
|
530
|
+
|
531
|
+
when '.history2'
|
532
|
+
return []
|
533
|
+
cauldron_arrays = available_params.select {|x| x[:value].kind_of?(Array)}
|
534
|
+
cauldron_test_case_params = cauldron_arrays.select {|x| x[:statement].write.include?(':params')}
|
535
|
+
cauldron_test_case_params.each do |x|
|
536
|
+
s = TheoryStatement.new(
|
537
|
+
StringToTheory.run(result[:statement].write+cauldron_method_call+'('+x[:statement].write+')')
|
538
|
+
)
|
539
|
+
v = obtain_value(s,mapping)
|
540
|
+
results << {:value=>v,:statement=>s,:step=>step}
|
541
|
+
end
|
542
|
+
when '.realise2'
|
543
|
+
cauldron_arrays = available_params.select {|x| x[:value].kind_of?(Array)}
|
544
|
+
cauldron_test_case_params = cauldron_arrays.select {|x| x[:statement].write =~ /:params\]$/}
|
545
|
+
cauldron_test_case_params.each do |x|
|
546
|
+
s = TheoryStatement.new(
|
547
|
+
StringToTheory.run(result[:statement].write+cauldron_method_call+'('+x[:statement].write+')')
|
548
|
+
)
|
549
|
+
v = obtain_value(s,mapping)
|
550
|
+
results << {:value=>v,:statement=>s,:step=>step}
|
551
|
+
end
|
552
|
+
when '.any?'
|
553
|
+
return []
|
554
|
+
# if(var5.history2(var2[var3][:params]).any?{ |x| x['statement_id'] == var1.last.statement_id} )
|
555
|
+
if result[:value].kind_of?(Array)
|
556
|
+
available_params.each do |x|
|
557
|
+
# TODO Should probably only match values of the same type - I don't want
|
558
|
+
# var1.any?{|x| x == var2.pass?(var1[var4])}
|
559
|
+
|
560
|
+
# Only allow one block statement -
|
561
|
+
next if x[:statement].write.include?('{')
|
562
|
+
|
563
|
+
# TODO I should reduce the number of possible comparisons
|
564
|
+
# (there is no point in comparing things will never be the same)
|
565
|
+
s = TheoryStatement.new(
|
566
|
+
StringToTheory.run(
|
567
|
+
result[:statement].write+cauldron_method_call+'{|x| x == '+x[:statement].write+'}'
|
568
|
+
)
|
569
|
+
)
|
570
|
+
v = obtain_value(s,mapping)
|
571
|
+
results << {:value=>v,:statement=>s,:step=>step}
|
572
|
+
end
|
573
|
+
|
574
|
+
# TODO This is is a quick hack to get x[:statement] included - down the line it might
|
575
|
+
# require a separate extend_accessors call.
|
576
|
+
if(result[:value].first.class==Step)
|
577
|
+
result[:value].first.cauldron_method_calls.each do |x|
|
578
|
+
|
579
|
+
available_params.each do |y|
|
580
|
+
|
581
|
+
# Only allow one block statement -
|
582
|
+
next if y[:statement].write.include?('{')
|
583
|
+
|
584
|
+
s = TheoryStatement.new(
|
585
|
+
StringToTheory.run(
|
586
|
+
result[:statement].write+cauldron_method_call+'{|x| x'+x+' == '+y[:statement].write+'}'
|
587
|
+
)
|
588
|
+
)
|
589
|
+
v = obtain_value(s,mapping)
|
590
|
+
|
591
|
+
results << {:value=>v,:statement=>s,:step=>step}
|
592
|
+
|
593
|
+
end
|
594
|
+
end
|
595
|
+
end
|
596
|
+
|
597
|
+
else
|
598
|
+
raise StandardError.new("Not setup for call '#{cauldron_method_call}'")
|
599
|
+
end
|
600
|
+
else
|
601
|
+
raise StandardError.new("Not setup for call '#{cauldron_method_call}'")
|
602
|
+
end
|
603
|
+
|
604
|
+
# NOTE: These don't take parameters
|
605
|
+
elsif ['.length','.last','.statement_id','.params','.value'].include?(cauldron_method_call)
|
606
|
+
|
607
|
+
# Don't include this call if only parameter calls are being considered
|
608
|
+
return [] if params_only
|
609
|
+
|
610
|
+
s = TheoryStatement.new(StringToTheory.run(result[:statement].write+cauldron_method_call))
|
611
|
+
v = obtain_value(s,mapping)
|
612
|
+
results << {
|
613
|
+
:value=>v,
|
614
|
+
:statement=>s,
|
615
|
+
:step=>step,
|
616
|
+
:intrinsic_statement=>self.convert_to_intrinsic_statement(s,mapping)
|
617
|
+
}
|
618
|
+
else
|
619
|
+
raise StandardError.new('Unknown method '+cauldron_method_call)
|
620
|
+
end
|
621
|
+
end
|
622
|
+
return results
|
623
|
+
end
|
624
|
+
|
625
|
+
def params_output(result,cauldron_method_call,mapping,theory_variable_id,step,results=[])
|
626
|
+
results = []
|
627
|
+
if cauldron_method_call.include?('[:params]') or cauldron_method_call.include?('[:output]')
|
628
|
+
s = TheoryStatement.new(StringToTheory.run(result[:statement].write+cauldron_method_call))
|
629
|
+
v = obtain_value(s,mapping)
|
630
|
+
results << {:value=>v,:statement=>s,:step=>step}
|
631
|
+
end
|
632
|
+
return results
|
633
|
+
end
|
634
|
+
|
635
|
+
# TODO Why is results passed through if it is just overwritten?
|
636
|
+
def array_access(result,cauldron_method_call,mapping,theory_variable_ids,step,results=[],variable_history=[])
|
637
|
+
|
638
|
+
results = []
|
639
|
+
if cauldron_method_call == '[]'
|
640
|
+
if result[:value].length > 4 then raise StandardError.new('Cauldron has not been tested with arrays larger that 4') end
|
641
|
+
|
642
|
+
# Generate theory variables for each of the new accessors
|
643
|
+
array_indexs = []
|
644
|
+
result[:value].length.times do |z|
|
645
|
+
|
646
|
+
theory_id = theory_variable_ids.length
|
647
|
+
|
648
|
+
# TODO Taking this complexity out for now.
|
649
|
+
# # Find pre-exisitng variables of the same value
|
650
|
+
# # TODO I should make sure I don't include unessary values here - I should check
|
651
|
+
# # that the same array access has not already been included indirectly in
|
652
|
+
# # via the action. var2, var3 both refer to same fixnum for case 1
|
653
|
+
# existing_variables = mapping.select{|key,value| value == z}
|
654
|
+
# array_indexs += existing_variables.collect {|key,value| TheoryVariable.new(key)}
|
655
|
+
|
656
|
+
# Before adding a new variable - check that an existing one doesn't already exist
|
657
|
+
|
658
|
+
# * Generate the intrinsic statement for it
|
659
|
+
new_written_intrinsic_statement = result[:intrinsic_statement].write+'['+z.to_s+']'
|
660
|
+
# TODO I might be able to use the results instead for the variable history now that I'm
|
661
|
+
# saving the intrinsic_statement
|
662
|
+
if variable_history.any? { |x| new_written_intrinsic_statement == x[:intrinsic_statement].write }
|
663
|
+
StandardLogger.instance.warning('Identical array access already exists '+new_written_intrinsic_statement)
|
664
|
+
saved_variable = variable_history.find {|x| x[:intrinsic_statement].write == new_written_intrinsic_statement}
|
665
|
+
|
666
|
+
#mapping[saved_variable[:global_variable_id]] = saved_variable[:variable_value].value
|
667
|
+
mapping[saved_variable[:global_variable_id]] = z
|
668
|
+
array_indexs << TheoryVariable.new(saved_variable[:global_variable_id])
|
669
|
+
else
|
670
|
+
|
671
|
+
mapping[theory_id] = z
|
672
|
+
array_indexs << TheoryVariable.new(theory_id)
|
673
|
+
theory_variable_ids << theory_variable_ids.length
|
674
|
+
end
|
675
|
+
end
|
676
|
+
|
677
|
+
# Generate a statement for each of the calls
|
678
|
+
array_indexs.each do |z|
|
679
|
+
s = TheoryStatement.new(StringToTheory.run(result[:statement].write+'['+z.write+']'))
|
680
|
+
v = obtain_value(s,mapping)
|
681
|
+
var_ids = s.variables.collect {|a| a.theory_variable_id}
|
682
|
+
var_values = var_ids.collect {|a| mapping[a]}
|
683
|
+
results << {
|
684
|
+
:value=>v,
|
685
|
+
:statement=>s,
|
686
|
+
:step=>step,
|
687
|
+
:variable_values=>var_values,
|
688
|
+
:intrinsic_statement=>convert_to_intrinsic_statement(s,mapping)
|
689
|
+
}
|
690
|
+
|
691
|
+
# Save the array history as well
|
692
|
+
unless variable_history.any? {|x| x[:global_variable_id] == z.theory_variable_id}
|
693
|
+
|
694
|
+
variable_history << {
|
695
|
+
:intrinsic_statement=>convert_to_intrinsic_statement(s,mapping),
|
696
|
+
:written_statement=>s.write,
|
697
|
+
:variable_value=>var_values.last.to_intrinsic,
|
698
|
+
:global_variable_id=>z.theory_variable_id
|
699
|
+
}
|
700
|
+
#raise StandardError.new('This array index has not been saved in the history '+z.theory_variable_id.to_s)
|
701
|
+
|
702
|
+
end
|
703
|
+
|
704
|
+
end
|
705
|
+
end
|
706
|
+
return results
|
707
|
+
|
708
|
+
end
|
709
|
+
|
710
|
+
def obtain_value(statement,mapping)
|
711
|
+
|
712
|
+
# Declare each of the theory variables with the correct value
|
713
|
+
declaration = ''
|
714
|
+
mapping.each do |key,value|
|
715
|
+
declaration += 'var'+key.to_s+' = mapping['+key.to_s+']'+"\n"
|
716
|
+
end
|
717
|
+
eval(declaration)
|
718
|
+
return eval(statement.write)
|
719
|
+
|
720
|
+
end
|
721
|
+
|
722
|
+
protected
|
723
|
+
|
724
|
+
def retrieve_accessors(literal_values,variable_creation_history)
|
725
|
+
value_accessors = []
|
726
|
+
a = literal_values.copy
|
727
|
+
literal_values.each do |key,val|
|
728
|
+
s = TheoryStatement.new(StringToTheory.run('var'+key.to_s))
|
729
|
+
value_accessors << {
|
730
|
+
:value=>val.copy,
|
731
|
+
:statement=>s,
|
732
|
+
:variable_values=>[val.copy],
|
733
|
+
:step=>0,
|
734
|
+
:intrinsic_statement=>convert_to_intrinsic_statement(s.copy,a.copy)
|
735
|
+
}
|
736
|
+
end
|
737
|
+
step = 0
|
738
|
+
|
739
|
+
array_of_variable_ids = literal_values.keys.copy
|
740
|
+
# TODO Hate the fact that mapping is modified via 'extend_accessors'
|
741
|
+
mapping = literal_values.copy
|
742
|
+
|
743
|
+
2.times do
|
744
|
+
value_accessors = self.extend_accessors( value_accessors,
|
745
|
+
mapping,
|
746
|
+
array_of_variable_ids,
|
747
|
+
(step+1),
|
748
|
+
variable_creation_history
|
749
|
+
)
|
750
|
+
step += 1
|
751
|
+
end
|
752
|
+
|
753
|
+
return value_accessors
|
754
|
+
end
|
755
|
+
|
756
|
+
# Converts the theory statement to an intrinsic statement.
|
757
|
+
#
|
758
|
+
def convert_to_intrinsic_statement(theory_statement,literal_values)
|
759
|
+
intrinsic_values = literal_values.inject({}) {|total,(key,value)| total[key] = value.to_intrinsic; total}
|
760
|
+
intrinsic_statement = theory_statement.map_to(intrinsic_values)
|
761
|
+
return intrinsic_statement
|
762
|
+
end
|
763
|
+
|
764
|
+
end
|