From ac9fe51c59201f18de1705a1df3a6a557d8aa857 Mon Sep 17 00:00:00 2001 From: Sarah Keating Date: Thu, 19 Dec 2024 16:14:45 +0000 Subject: [PATCH] committing and hopefully I have turned off all build --- .github/workflows/brief.yml | 2 +- .github/workflows/matlab.yml | 2 +- .github/workflows/octave.yml | 2 +- src/sbml/conversion/ExpressionAnalyser.cpp | 3 +- .../test/TestExpressionAnalyser.cpp | 125 +++++++++++++- src/sbml/conversion/test/test-data/test | 3 + src/sbml/math/ASTNode.cpp | 40 ++++- src/sbml/math/ASTNode.h | 15 +- src/sbml/math/test/TestLevelNodeFunction.cpp | 159 ++++++++++++++++++ src/sbml/math/test/TestRunner.c | 41 ++--- 10 files changed, 364 insertions(+), 28 deletions(-) create mode 100644 src/sbml/math/test/TestLevelNodeFunction.cpp diff --git a/.github/workflows/brief.yml b/.github/workflows/brief.yml index 578986a030..c5f6b9da6f 100644 --- a/.github/workflows/brief.yml +++ b/.github/workflows/brief.yml @@ -1,6 +1,6 @@ name: CMake (rapid build on push) -on: [push] +on: env: BUILD_TYPE: Release diff --git a/.github/workflows/matlab.yml b/.github/workflows/matlab.yml index a2d90d57c7..1c62904e05 100644 --- a/.github/workflows/matlab.yml +++ b/.github/workflows/matlab.yml @@ -1,6 +1,6 @@ name: Matlab (ubuntu) build and test -on: [push] +on: [] env: MATLAB_VERSION: R2021a diff --git a/.github/workflows/octave.yml b/.github/workflows/octave.yml index b0c345c8ab..6fa52f739e 100644 --- a/.github/workflows/octave.yml +++ b/.github/workflows/octave.yml @@ -1,6 +1,6 @@ name: Octave -on: [push] +on: env: # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) diff --git a/src/sbml/conversion/ExpressionAnalyser.cpp b/src/sbml/conversion/ExpressionAnalyser.cpp index f4992d1f36..104952900f 100644 --- a/src/sbml/conversion/ExpressionAnalyser.cpp +++ b/src/sbml/conversion/ExpressionAnalyser.cpp @@ -558,7 +558,7 @@ ExpressionAnalyser::shouldAddExpression(SubstitutionValues_t* value) bool ExpressionAnalyser::analyseNode(ASTNode* node, SubstitutionValues_t *value) { - cout << "current node: " << SBML_formulaToL3String(node) << endl; +// cout << "current node: " << SBML_formulaToL3String(node) << endl; unsigned int numChildren = node->getNumChildren(); ASTNodeType_t type = node->getType(); ASTNode* rightChild = node->getRightChild(); @@ -678,6 +678,7 @@ ExpressionAnalyser::analyse(bool minusXPlusYOnly) ASTNode* currentNode = (ASTNode*)*it; SubstitutionValues_t* value = createBlankSubstitutionValues(); + cout << "current node: " << SBML_formulaToL3String(currentNode) << endl; if (analyseNode(currentNode, value)) { value->odeIndex = odeIndex; diff --git a/src/sbml/conversion/test/TestExpressionAnalyser.cpp b/src/sbml/conversion/test/TestExpressionAnalyser.cpp index 9e8ad3bfa1..61febe50af 100644 --- a/src/sbml/conversion/test/TestExpressionAnalyser.cpp +++ b/src/sbml/conversion/test/TestExpressionAnalyser.cpp @@ -277,6 +277,124 @@ START_TEST(test_analyse_1) fail_unless(util_isNaN(value->k_real_value)); } END_TEST + +START_TEST(test_analyse_1_same) +{ + RateRule* rr = d->getModel()->createRateRule(); + rr->setVariable("a"); + rr->setMath(SBML_parseFormula("k + v - x - y")); + RateRule* rr1 = d->getModel()->createRateRule(); + rr1->setVariable("b"); + rr1->setMath(SBML_parseFormula("k + v - x - y")); + + converter->populateInitialODEinfo(); + ExpressionAnalyser* analyser = new ExpressionAnalyser(m, converter->getOdePairs()); + + fail_unless(analyser->getNumExpressions() == 0); + + analyser->analyse(); + + fail_unless(analyser->getNumExpressions() == 1); + SubstitutionValues_t* value = analyser->getExpression(0); + fail_unless(value->k_value == "k"); + fail_unless(value->x_value == "x"); + fail_unless(value->y_value == "y"); + fail_unless(value->z_value.empty()); + fail_unless(value->type == TYPE_K_PLUS_V_MINUS_X_MINUS_Y); + fail_unless(formulas_equal("k + v - x - y", value->current)); + fail_unless(formulas_equal("0", value->dxdt_expression)); + fail_unless(formulas_equal("0", value->dydt_expression)); + fail_unless(formulas_equal("v", value->v_expression)); + fail_unless(value->w_expression == NULL); + fail_unless(value->z_expression == NULL); + fail_unless(value->odeIndex == 0); + fail_unless(util_isNaN(value->k_real_value)); +} +END_TEST + + + +START_TEST(test_analyse_1_two_terms) +{ + RateRule* rr = d->getModel()->createRateRule(); + rr->setVariable("a"); + rr->setMath(SBML_parseFormula("(k + v - x - y) + (k - x)")); + + converter->populateInitialODEinfo(); + ExpressionAnalyser* analyser = new ExpressionAnalyser(m, converter->getOdePairs()); + + fail_unless(analyser->getNumExpressions() == 0); + + analyser->analyse(); + + fail_unless(analyser->getNumExpressions() == 2); + SubstitutionValues_t* value = analyser->getExpression(0); + fail_unless(value->k_value == "k"); + fail_unless(value->x_value == "x"); + fail_unless(value->y_value == "y"); + fail_unless(value->z_value.empty()); + fail_unless(value->type == TYPE_K_PLUS_V_MINUS_X_MINUS_Y); + fail_unless(formulas_equal("k + v - x - y", value->current)); + fail_unless(formulas_equal("0", value->dxdt_expression)); + fail_unless(formulas_equal("0", value->dydt_expression)); + fail_unless(formulas_equal("v", value->v_expression)); + fail_unless(value->w_expression == NULL); + fail_unless(value->z_expression == NULL); + fail_unless(value->odeIndex == 0); + fail_unless(util_isNaN(value->k_real_value)); + + SubstitutionValues_t* value1 = analyser->getExpression(1); + fail_unless(value1->k_value == "k"); + fail_unless(value1->x_value == "x"); + fail_unless(value1->y_value.empty()); + fail_unless(value1->z_value.empty()); + fail_unless(value1->type == TYPE_K_MINUS_X); + fail_unless(formulas_equal("k - x", value1->current)); + fail_unless(formulas_equal("0", value1->dxdt_expression)); + fail_unless(value1->dydt_expression == NULL); + fail_unless(value1->v_expression == NULL); + fail_unless(value1->w_expression == NULL); + fail_unless(value1->z_expression == NULL); + fail_unless(value1->odeIndex == 0); + fail_unless(util_isNaN(value1->k_real_value)); + +} +END_TEST + + +START_TEST(test_analyse_1_different) +{ + RateRule* rr = d->getModel()->createRateRule(); + rr->setVariable("a"); + rr->setMath(SBML_parseFormula("k + v - x - y")); + RateRule* rr1 = d->getModel()->createRateRule(); + rr1->setVariable("b"); + rr1->setMath(SBML_parseFormula("k + v - x - a")); + converter->populateInitialODEinfo(); + ExpressionAnalyser* analyser = new ExpressionAnalyser(m, converter->getOdePairs()); + + fail_unless(analyser->getNumExpressions() == 0); + + analyser->analyse(); + + fail_unless(analyser->getNumExpressions() == 2); + SubstitutionValues_t* value = analyser->getExpression(1); + fail_unless(value->k_value == "k"); + fail_unless(value->x_value == "x"); + fail_unless(value->y_value == "a"); + fail_unless(value->z_value.empty()); + fail_unless(value->type == TYPE_K_PLUS_V_MINUS_X_MINUS_Y); + fail_unless(formulas_equal("k + v - x - a", value->current)); + fail_unless(formulas_equal("0", value->dxdt_expression)); + fail_unless(formulas_equal("k + v - x - y", value->dydt_expression)); + fail_unless(formulas_equal("v", value->v_expression)); + fail_unless(value->w_expression == NULL); + fail_unless(value->z_expression == NULL); + fail_unless(value->odeIndex == 1); + fail_unless(util_isNaN(value->k_real_value)); +} +END_TEST + START_TEST(test_analyse_2) { RateRule* rr = d->getModel()->createRateRule(); @@ -598,7 +716,7 @@ END_TEST Suite * create_suite_TestExpressionAnalyser (void) { - bool testing = false; + bool testing = true; Suite *suite = suite_create("ExpressionAnalyser"); TCase *tcase = tcase_create("ExpressionAnalyser"); tcase_add_checked_fixture(tcase, @@ -606,7 +724,7 @@ Suite *suite = suite_create("ExpressionAnalyser"); if (testing) { - tcase_add_test(tcase, test_analyse_different_expression); + tcase_add_test(tcase, test_analyse_1_two_terms); } else { @@ -617,6 +735,9 @@ Suite *suite = suite_create("ExpressionAnalyser"); tcase_add_test(tcase, test_analyse_4); //k+v-x tcase_add_test(tcase, test_analyse_same_expression); //k-x-y tcase_add_test(tcase, test_analyse_different_expression); //k-x-y + tcase_add_test(tcase, test_analyse_1_same); //k+v-x-y + tcase_add_test(tcase, test_analyse_1_two_terms); //(k+v-x-y)+(k-x) + tcase_add_test(tcase, test_analyse_1_different); //k+v-x-y //tcase_add_test(tcase, test_order_of_replacements); //tcase_add_test(tcase, test_order_of_replacements1); //tcase_add_test(tcase, test_order_of_replacements2); diff --git a/src/sbml/conversion/test/test-data/test b/src/sbml/conversion/test/test-data/test index e64e063d23..3d8a043b62 100644 --- a/src/sbml/conversion/test/test-data/test +++ b/src/sbml/conversion/test/test-data/test @@ -154,3 +154,6 @@ reconstructModel plus return False values: k x dx v type=k+v-x + +hasExpressionAlreadyBeanRecorded + expressionExistsaround diff --git a/src/sbml/math/ASTNode.cpp b/src/sbml/math/ASTNode.cpp index 497ec9a228..c96fbeecbb 100644 --- a/src/sbml/math/ASTNode.cpp +++ b/src/sbml/math/ASTNode.cpp @@ -1130,6 +1130,19 @@ ASTNode::getListOfNodes (ASTNodePredicate predicate) const return lst; } +LIBSBML_EXTERN +ASTNodeLevels +ASTNode::getListOfNodesWithLevel() const +{ + ASTNodeLevels vector_pairs; + + + fillListOfNodesWithLevel((ASTNodePredicate)ASTNode_isOperator, vector_pairs, 0); + fillListOfNodesWithLevel((ASTNodePredicate)ASTNode_isName, vector_pairs, 0); + + return vector_pairs; +} + /* * This method is identical in functionality to getListOfNodes(), except @@ -1145,8 +1158,6 @@ ASTNode::fillListOfNodes (ASTNodePredicate predicate, List* lst) const unsigned int c; unsigned int numChildren = getNumChildren(); - - if (predicate(this) != 0) { lst->add( const_cast(this) ); @@ -1159,6 +1170,31 @@ ASTNode::fillListOfNodes (ASTNodePredicate predicate, List* lst) const } } +void ASTNode::fillListOfNodesWithLevel(ASTNodePredicate predicate, ASTNodeLevels& vector_pairs, unsigned int level) const +{ + if (this == NULL || + (vector_pairs.size() == 1 && vector_pairs.back().second == NULL) || + predicate == NULL) + return; + + ASTNode* child; + unsigned int c; + unsigned int numChildren = getNumChildren(); + + if (predicate(this) != 0) + { + cout << "Level " << level << ": " << SBML_formulaToL3String(this) << endl; + vector_pairs.push_back(std::make_pair(level, (ASTNode*)this)); + } + + for (c = 0; c < numChildren; c++) + { + child = getChild(c); + child->fillListOfNodesWithLevel(predicate, vector_pairs, level + 1); + } + +} + /* * @return the value of this ASTNode as a single character. This function diff --git a/src/sbml/math/ASTNode.h b/src/sbml/math/ASTNode.h index a6c19d3d8c..2ad1497f89 100644 --- a/src/sbml/math/ASTNode.h +++ b/src/sbml/math/ASTNode.h @@ -210,9 +210,14 @@ typedef int (*ASTNodePredicate) (const ASTNode_t *node); LIBSBML_CPP_NAMESPACE_END #ifdef __cplusplus - LIBSBML_CPP_NAMESPACE_BEGIN +typedef std::pair ASTNodePair; +typedef std::vector ASTNodeLevels; +typedef ASTNodeLevels::iterator ASTNodeLevelsIterator; + + + class List; class ASTBasePlugin; class ExtendedMathList; @@ -604,6 +609,10 @@ int (*ASTNodePredicate) (const ASTNode *node); List* getListOfNodes (ASTNodePredicate predicate) const; + LIBSBML_EXTERN + ASTNodeLevels getListOfNodesWithLevel () const; + + /** * Returns a list of nodes rooted at a given node and satisfying a given * predicate. @@ -635,6 +644,10 @@ int (*ASTNodePredicate) (const ASTNode_t *node); LIBSBML_EXTERN void fillListOfNodes (ASTNodePredicate predicate, List* lst) const; + LIBSBML_EXTERN + void fillListOfNodesWithLevel(ASTNodePredicate predicate, ASTNodeLevels& vector_pairs, unsigned int level) const; + + /** * Returns the value of this node as a single character. diff --git a/src/sbml/math/test/TestLevelNodeFunction.cpp b/src/sbml/math/test/TestLevelNodeFunction.cpp new file mode 100644 index 0000000000..ec3d7f3af1 --- /dev/null +++ b/src/sbml/math/test/TestLevelNodeFunction.cpp @@ -0,0 +1,159 @@ +/** + * \file TestLevelNodeFunctions.cpp + * \brief MathML unit tests for the level of a operator within an expression + * \author Sarah Keating + * + * */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +/** @cond doxygenLibsbmlInternal */ + +using namespace std; +LIBSBML_CPP_NAMESPACE_USE + +/** @endcond */ + +static bool +equals(const char* expected, const char* actual) +{ + if (!strcmp(expected, actual)) return true; + + printf("\nStrings are not equal:\n"); + printf("Expected:\n[%s]\n", expected); + printf("Actual:\n[%s]\n", actual); + + return false; +} + + + +static bool +formulas_equal(const char* expected, ASTNode* actual) +{ + return equals(expected, SBML_formulaToL3String(actual)); +} + + + +CK_CPPSTART + + +START_TEST(test_null) +{ + + ASTNode* node = NULL; + ASTNodeLevels node_levels = node->getListOfNodesWithLevel(); + fail_unless(node_levels.size() == 0); + + delete node; + node_levels.clear(); +} +END_TEST + +START_TEST(test_level_1) +{ + + ASTNode* node = SBML_parseL3Formula("x + y"); + ASTNodeLevels node_levels = node->getListOfNodesWithLevel(); + fail_unless(node_levels.size() == 3); + fail_unless(node_levels[0].first == 0); + fail_unless(formulas_equal("x + y", node_levels[0].second)); + fail_unless(node_levels[1].first == 1); + fail_unless(formulas_equal("x", node_levels[1].second)); + fail_unless(node_levels[2].first == 1); + fail_unless(formulas_equal("y", node_levels[2].second)); + + + delete node; + node_levels.clear(); +} +END_TEST + +START_TEST(test_level_2) +{ + + ASTNode* node = SBML_parseL3Formula("k - x - y"); + ASTNodeLevels node_levels = node->getListOfNodesWithLevel(); + fail_unless(node_levels.size() == 5); + fail_unless(node_levels[0].first == 0); + fail_unless(formulas_equal("k - x - y", node_levels[0].second)); + fail_unless(node_levels[1].first == 1); + fail_unless(formulas_equal("k - x", node_levels[1].second)); + fail_unless(node_levels[2].first == 2); + fail_unless(formulas_equal("k", node_levels[2].second)); + fail_unless(node_levels[3].first == 2); + fail_unless(formulas_equal("x", node_levels[3].second)); + fail_unless(node_levels[4].first == 1); + fail_unless(formulas_equal("y", node_levels[4].second)); + + + delete node; + node_levels.clear(); +} +END_TEST + +Suite * +create_suite_TestLevelNodeFunction() +{ + Suite *suite = suite_create("TestLevelNodeFunction"); + TCase *tcase = tcase_create("TestLevelNodeFunction"); + + tcase_add_test(tcase, test_null); + tcase_add_test(tcase, test_level_1); + tcase_add_test(tcase, test_level_2); + + suite_add_tcase(suite, tcase); + + return suite; +} + + +CK_CPPEND diff --git a/src/sbml/math/test/TestRunner.c b/src/sbml/math/test/TestRunner.c index 4a1241a190..57b964e550 100644 --- a/src/sbml/math/test/TestRunner.c +++ b/src/sbml/math/test/TestRunner.c @@ -84,6 +84,8 @@ Suite *create_suite_TestReadFromFileL3V2(void); Suite *create_suite_TestInferRnFunctions (void); Suite *create_suite_TestDerivativeFunctions(void); +Suite* create_suite_TestLevelNodeFunction(void); + /** * Global. @@ -128,32 +130,33 @@ main (void) setTestDataDirectory(); - //SRunner *runner = srunner_create(create_suite_TestChildFunctions() ); + SRunner *runner = srunner_create(create_suite_TestLevelNodeFunction() ); - SRunner *runner = srunner_create( create_suite_ASTNode() ); + //SRunner *runner = srunner_create( create_suite_ASTNode() ); - srunner_add_suite( runner, create_suite_FormulaFormatter () ); - srunner_add_suite( runner, create_suite_FormulaParser () ); - srunner_add_suite( runner, create_suite_L3FormulaFormatter () ); - srunner_add_suite( runner, create_suite_L3FormulaParser () ); - srunner_add_suite( runner, create_suite_L3FormulaParserC () ); - srunner_add_suite( runner, create_suite_FormulaTokenizer () ); - srunner_add_suite( runner, create_suite_ReadMathML () ); - srunner_add_suite( runner, create_suite_WriteMathML () ); - srunner_add_suite( runner, create_suite_WriteMathMLFromAST () ); + //srunner_add_suite( runner, create_suite_FormulaFormatter () ); + //srunner_add_suite( runner, create_suite_FormulaParser () ); + //srunner_add_suite( runner, create_suite_L3FormulaFormatter () ); + //srunner_add_suite( runner, create_suite_L3FormulaParser () ); + //srunner_add_suite( runner, create_suite_L3FormulaParserC () ); + //srunner_add_suite( runner, create_suite_FormulaTokenizer () ); + //srunner_add_suite( runner, create_suite_ReadMathML () ); + //srunner_add_suite( runner, create_suite_WriteMathML () ); + //srunner_add_suite( runner, create_suite_WriteMathMLFromAST () ); - srunner_add_suite( runner, create_suite_TestReadFromFile1() ); - srunner_add_suite( runner, create_suite_TestReadFromFile2() ); + //srunner_add_suite( runner, create_suite_TestReadFromFile1() ); + //srunner_add_suite( runner, create_suite_TestReadFromFile2() ); - srunner_add_suite( runner, create_suite_TestValidASTNode() ); + //srunner_add_suite( runner, create_suite_TestValidASTNode() ); - srunner_add_suite( runner, create_suite_TestChildFunctions() ); - srunner_add_suite( runner, create_suite_TestGetValue() ); + //srunner_add_suite( runner, create_suite_TestChildFunctions() ); + //srunner_add_suite( runner, create_suite_TestGetValue() ); - srunner_add_suite(runner, create_suite_TestReadFromFileL3V2()); - srunner_add_suite(runner, create_suite_TestInferRnFunctions()); - srunner_add_suite(runner, create_suite_TestDerivativeFunctions()); + //srunner_add_suite(runner, create_suite_TestReadFromFileL3V2()); + //srunner_add_suite(runner, create_suite_TestInferRnFunctions()); + //srunner_add_suite(runner, create_suite_TestDerivativeFunctions()); + //srunner_add_suite(runner, create_suite_TestLevelNodeFunction()); /* srunner_set_fork_status(runner, CK_NOFORK); */ srunner_run_all(runner, CK_NORMAL);