diff --git a/cmake/environmentchecks.cmake b/cmake/environmentchecks.cmake index 19dfcf88a7..646fed7af8 100644 --- a/cmake/environmentchecks.cmake +++ b/cmake/environmentchecks.cmake @@ -51,7 +51,7 @@ endif() find_package(Doxygen) find_package(Sphinx) -find_package(SWIG 3.0.3) +find_package(SWIG 4) set(_ORIGINAL_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index db92f95769..40d5c06485 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -45,6 +45,11 @@ configure_file( ) set(SOURCE_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/analyser.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/analyserequation.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/analyserequationast.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/analysermodel.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/analyservariable.cpp ${CMAKE_CURRENT_SOURCE_DIR}/component.cpp ${CMAKE_CURRENT_SOURCE_DIR}/componententity.cpp ${CMAKE_CURRENT_SOURCE_DIR}/entity.cpp @@ -72,6 +77,11 @@ set(SOURCE_FILES ) set(GIT_API_HEADER_FILES + ${CMAKE_CURRENT_SOURCE_DIR}/api/libcellml/analyser.h + ${CMAKE_CURRENT_SOURCE_DIR}/api/libcellml/analyserequation.h + ${CMAKE_CURRENT_SOURCE_DIR}/api/libcellml/analyserequationast.h + ${CMAKE_CURRENT_SOURCE_DIR}/api/libcellml/analysermodel.h + ${CMAKE_CURRENT_SOURCE_DIR}/api/libcellml/analyservariable.h ${CMAKE_CURRENT_SOURCE_DIR}/api/libcellml/component.h ${CMAKE_CURRENT_SOURCE_DIR}/api/libcellml/componententity.h ${CMAKE_CURRENT_SOURCE_DIR}/api/libcellml/entity.h diff --git a/src/analyser.cpp b/src/analyser.cpp new file mode 100644 index 0000000000..43c73dde06 --- /dev/null +++ b/src/analyser.cpp @@ -0,0 +1,1518 @@ +/* +Copyright libCellML Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "libcellml/analyser.h" + +#include "libcellml/analyserequation.h" +#include "libcellml/analyserequationast.h" +#include "libcellml/analysermodel.h" +#include "libcellml/analyservariable.h" +#include "libcellml/component.h" +#include "libcellml/model.h" +#include "libcellml/units.h" +#include "libcellml/validator.h" +#include "libcellml/variable.h" + +#include "analyserequation_p.h" +#include "analyserequationast_p.h" +#include "analysermodel_p.h" +#include "analyservariable_p.h" +#include "utilities.h" +#include "xmldoc.h" +#include "xmlutils.h" + +#ifdef TRUE +# undef TRUE +#endif + +#ifdef FALSE +# undef FALSE +#endif + +#ifdef NAN +# undef NAN +#endif + +namespace libcellml { + +static const size_t MAX_SIZE_T = std::numeric_limits::max(); + +struct AnalyserInternalEquation; +using AnalyserInternalEquationPtr = std::shared_ptr; + +struct AnalyserInternalVariable +{ + enum struct Type + { + UNKNOWN, + SHOULD_BE_STATE, + VARIABLE_OF_INTEGRATION, + STATE, + CONSTANT, + COMPUTED_TRUE_CONSTANT, + COMPUTED_VARIABLE_BASED_CONSTANT, + ALGEBRAIC, + OVERCONSTRAINED + }; + + size_t mIndex = MAX_SIZE_T; + Type mType = Type::UNKNOWN; + + VariablePtr mInitialisingVariable; + VariablePtr mVariable; + + explicit AnalyserInternalVariable(const VariablePtr &variable); + + void setVariable(const VariablePtr &variable, + bool checkInitialValue = true); + + void makeVoi(); + void makeState(); +}; + +using AnalyserInternalVariablePtr = std::shared_ptr; + +AnalyserInternalVariable::AnalyserInternalVariable(const VariablePtr &variable) +{ + setVariable(variable); +} + +void AnalyserInternalVariable::setVariable(const VariablePtr &variable, + bool checkInitialValue) +{ + if (checkInitialValue && !variable->initialValue().empty()) { + // The variable has an initial value, so it can either be a constant or + // a state. By default, we consider it to be a constant and, if we find + // an ODE for that variable, we will know that it was actually a state. + + mType = Type::CONSTANT; + + mInitialisingVariable = variable; + } + + mVariable = variable; +} + +void AnalyserInternalVariable::makeVoi() +{ + mType = Type::VARIABLE_OF_INTEGRATION; +} + +void AnalyserInternalVariable::makeState() +{ + if (mType == Type::UNKNOWN) { + mType = Type::SHOULD_BE_STATE; + } else if (mType == Type::CONSTANT) { + mType = Type::STATE; + } +} + +struct AnalyserInternalEquation +{ + enum struct Type + { + UNKNOWN, + TRUE_CONSTANT, + VARIABLE_BASED_CONSTANT, + RATE, + ALGEBRAIC + }; + + size_t mOrder = MAX_SIZE_T; + Type mType = Type::UNKNOWN; + + std::vector mDependencies; + + AnalyserEquationAstPtr mAst; + + std::vector mVariables; + std::vector mOdeVariables; + + AnalyserInternalVariablePtr mVariable; + ComponentPtr mComponent = nullptr; + + bool mComputedTrueConstant = true; + bool mComputedVariableBasedConstant = true; + + explicit AnalyserInternalEquation(const ComponentPtr &component); + + void addVariable(const AnalyserInternalVariablePtr &variable); + void addOdeVariable(const AnalyserInternalVariablePtr &odeVariable); + + static bool isKnownVariable(const AnalyserInternalVariablePtr &variable); + static bool isKnownOdeVariable(const AnalyserInternalVariablePtr &odeVariable); + + static bool hasKnownVariables(const std::vector &variables); + static bool hasNonConstantVariables(const std::vector &variables); + + bool check(size_t &equationOrder, size_t &stateIndex, size_t &variableIndex); +}; + +AnalyserInternalEquation::AnalyserInternalEquation(const ComponentPtr &component) + : mAst(AnalyserEquationAst::create()) + , mComponent(component) +{ +} + +void AnalyserInternalEquation::addVariable(const AnalyserInternalVariablePtr &variable) +{ + if (std::find(mVariables.begin(), mVariables.end(), variable) == mVariables.end()) { + mVariables.push_back(variable); + } +} + +void AnalyserInternalEquation::addOdeVariable(const AnalyserInternalVariablePtr &odeVariable) +{ + if (std::find(mOdeVariables.begin(), mOdeVariables.end(), odeVariable) == mOdeVariables.end()) { + mOdeVariables.push_back(odeVariable); + } +} + +bool AnalyserInternalEquation::isKnownVariable(const AnalyserInternalVariablePtr &variable) +{ + return variable->mType != AnalyserInternalVariable::Type::UNKNOWN; +} + +bool AnalyserInternalEquation::isKnownOdeVariable(const AnalyserInternalVariablePtr &odeVariable) +{ + return odeVariable->mIndex != MAX_SIZE_T; +} + +bool AnalyserInternalEquation::hasKnownVariables(const std::vector &variables) +{ + return std::find_if(variables.begin(), variables.end(), [](const AnalyserInternalVariablePtr &variable) { + return isKnownVariable(variable); + }) + != std::end(variables); +} + +bool AnalyserInternalEquation::hasNonConstantVariables(const std::vector &variables) +{ + return std::find_if(variables.begin(), variables.end(), [](const AnalyserInternalVariablePtr &variable) { + return (variable->mType != AnalyserInternalVariable::Type::UNKNOWN) + && (variable->mType != AnalyserInternalVariable::Type::CONSTANT) + && (variable->mType != AnalyserInternalVariable::Type::COMPUTED_TRUE_CONSTANT) + && (variable->mType != AnalyserInternalVariable::Type::COMPUTED_VARIABLE_BASED_CONSTANT); + }) + != std::end(variables); +} + +bool AnalyserInternalEquation::check(size_t &equationOrder, size_t &stateIndex, + size_t &variableIndex) +{ + // Nothing to check if the equation has already been given an order (i.e. + // everything is fine) or if there is one known (ODE) variable left (i.e. + // this equation is an overconstraint). + + if (mOrder != MAX_SIZE_T) { + return false; + } + + if (mVariables.size() + mOdeVariables.size() == 1) { + auto variable = (mVariables.size() == 1) ? mVariables.front() : mOdeVariables.front(); + + if ((variable->mIndex != MAX_SIZE_T) + && (variable->mType != AnalyserInternalVariable::Type::UNKNOWN) + && (variable->mType != AnalyserInternalVariable::Type::SHOULD_BE_STATE)) { + variable->mType = AnalyserInternalVariable::Type::OVERCONSTRAINED; + + return false; + } + } + + // Determine, from the (new) known (ODE) variables, whether the equation is + // used to compute a true constant or a variable-based constant. + + mComputedTrueConstant = mComputedTrueConstant + && !hasKnownVariables(mVariables) + && !hasKnownVariables(mOdeVariables); + mComputedVariableBasedConstant = mComputedVariableBasedConstant + && !hasNonConstantVariables(mVariables) + && !hasNonConstantVariables(mOdeVariables); + + // Add, as a dependency, the variables used to compute the (new) known (ODE) + // variables. + + for (const auto &variable : mVariables) { + if (isKnownVariable(variable)) { + mDependencies.push_back(variable->mVariable); + } + } + + // Stop tracking (new) known (ODE) variables. + + mVariables.erase(std::remove_if(mVariables.begin(), mVariables.end(), isKnownVariable), mVariables.end()); + mOdeVariables.erase(std::remove_if(mOdeVariables.begin(), mOdeVariables.end(), isKnownOdeVariable), mOdeVariables.end()); + + // If there is one (ODE) variable left then update its variable (to be the + // corresponding one in the component in which the equation is), its type + // (if it is currently unknown), determine its index and determine the type + // of our equation and set its order, if the (ODE) variable is a state, + // computed constant or algebraic variable. + + auto relevantCheck = false; + + if (mVariables.size() + mOdeVariables.size() == 1) { + auto variable = (mVariables.size() == 1) ? mVariables.front() : mOdeVariables.front(); + + for (size_t i = 0; i < mComponent->variableCount(); ++i) { + auto localVariable = mComponent->variable(i); + + if (isSameOrEquivalentVariable(variable->mVariable, localVariable)) { + variable->setVariable(localVariable, false); + + break; + } + } + + if (variable->mType == AnalyserInternalVariable::Type::UNKNOWN) { + variable->mType = mComputedTrueConstant ? + AnalyserInternalVariable::Type::COMPUTED_TRUE_CONSTANT : + mComputedVariableBasedConstant ? + AnalyserInternalVariable::Type::COMPUTED_VARIABLE_BASED_CONSTANT : + AnalyserInternalVariable::Type::ALGEBRAIC; + } + + if ((variable->mType == AnalyserInternalVariable::Type::STATE) + || (variable->mType == AnalyserInternalVariable::Type::COMPUTED_TRUE_CONSTANT) + || (variable->mType == AnalyserInternalVariable::Type::COMPUTED_VARIABLE_BASED_CONSTANT) + || (variable->mType == AnalyserInternalVariable::Type::ALGEBRAIC)) { + variable->mIndex = (variable->mType == AnalyserInternalVariable::Type::STATE) ? + ++stateIndex : + ++variableIndex; + + mOrder = ++equationOrder; + mType = (variable->mType == AnalyserInternalVariable::Type::STATE) ? + Type::RATE : + (variable->mType == AnalyserInternalVariable::Type::COMPUTED_TRUE_CONSTANT) ? + Type::TRUE_CONSTANT : + (variable->mType == AnalyserInternalVariable::Type::COMPUTED_VARIABLE_BASED_CONSTANT) ? + Type::VARIABLE_BASED_CONSTANT : + Type::ALGEBRAIC; + + mVariable = variable; + + relevantCheck = true; + } + } + + return relevantCheck; +} + +/** + * @brief The Analyser::AnalyserImpl struct. + * + * The private implementation for the Analyser class. + */ +struct Analyser::AnalyserImpl +{ + Analyser *mAnalyser = nullptr; + + AnalyserModelPtr mModel = nullptr; + + std::vector mInternalVariables; + std::vector mInternalEquations; + + explicit AnalyserImpl(Analyser *analyser); + + static bool compareVariablesByComponentAndName(const AnalyserInternalVariablePtr &variable1, + const AnalyserInternalVariablePtr &variable2); + + static bool isStateVariable(const AnalyserInternalVariablePtr &variable); + static bool isConstantOrAlgebraicVariable(const AnalyserInternalVariablePtr &variable); + + static bool compareVariablesByTypeAndIndex(const AnalyserInternalVariablePtr &variable1, + const AnalyserInternalVariablePtr &variable2); + + static bool compareEquationsByVariable(const AnalyserInternalEquationPtr &equation1, + const AnalyserInternalEquationPtr &equation2); + + size_t mathmlChildCount(const XmlNodePtr &node) const; + XmlNodePtr mathmlChildNode(const XmlNodePtr &node, size_t index) const; + + AnalyserInternalVariablePtr internalVariable(const VariablePtr &variable); + + VariablePtr voiFirstOccurrence(const VariablePtr &variable, + const ComponentPtr &component); + + void analyseNode(const XmlNodePtr &node, AnalyserEquationAstPtr &ast, + const AnalyserEquationAstPtr &astParent, + const ComponentPtr &component, + const AnalyserInternalEquationPtr &equation); + void analyseComponent(const ComponentPtr &component); + + void doEquivalentVariables(const VariablePtr &variable, + std::vector &equivalentVariables) const; + std::vector equivalentVariables(const VariablePtr &variable) const; + + void analyseEquationAst(const AnalyserEquationAstPtr &ast); + + double scalingFactor(const VariablePtr &variable); + + void scaleAst(const AnalyserEquationAstPtr &ast, + const AnalyserEquationAstPtr &astParent, + double scalingFactor); + void scaleEquationAst(const AnalyserEquationAstPtr &ast); + + bool isStateRateBased(const AnalyserEquationPtr &equation, + std::vector &checkedEquations); + + void analyseModel(const ModelPtr &model); +}; + +Analyser::AnalyserImpl::AnalyserImpl(Analyser *analyser) + : mAnalyser(analyser) + , mModel(std::shared_ptr {new AnalyserModel {}}) +{ +} + +bool Analyser::AnalyserImpl::compareVariablesByComponentAndName(const AnalyserInternalVariablePtr &variable1, + const AnalyserInternalVariablePtr &variable2) +{ + auto realComponent1 = owningComponent(variable1->mVariable); + auto realComponent2 = owningComponent(variable2->mVariable); + + if (realComponent1->name() == realComponent2->name()) { + return variable1->mVariable->name() < variable2->mVariable->name(); + } + + return realComponent1->name() < realComponent2->name(); +} + +bool Analyser::AnalyserImpl::isStateVariable(const AnalyserInternalVariablePtr &variable) +{ + return variable->mType == AnalyserInternalVariable::Type::STATE; +} + +bool Analyser::AnalyserImpl::isConstantOrAlgebraicVariable(const AnalyserInternalVariablePtr &variable) +{ + return (variable->mType == AnalyserInternalVariable::Type::CONSTANT) + || (variable->mType == AnalyserInternalVariable::Type::COMPUTED_TRUE_CONSTANT) + || (variable->mType == AnalyserInternalVariable::Type::COMPUTED_VARIABLE_BASED_CONSTANT) + || (variable->mType == AnalyserInternalVariable::Type::ALGEBRAIC); +} + +bool Analyser::AnalyserImpl::compareVariablesByTypeAndIndex(const AnalyserInternalVariablePtr &variable1, + const AnalyserInternalVariablePtr &variable2) +{ + if (isStateVariable(variable1) && isConstantOrAlgebraicVariable(variable2)) { + return true; + } + + if (isConstantOrAlgebraicVariable(variable1) && isStateVariable(variable2)) { + return false; + } + + return variable1->mIndex < variable2->mIndex; +} + +bool Analyser::AnalyserImpl::compareEquationsByVariable(const AnalyserInternalEquationPtr &equation1, + const AnalyserInternalEquationPtr &equation2) +{ + return compareVariablesByTypeAndIndex(equation1->mVariable, equation2->mVariable); +} + +size_t Analyser::AnalyserImpl::mathmlChildCount(const XmlNodePtr &node) const +{ + // Return the number of child elements, in the MathML namespace, for the + // given node. + + auto childNode = node->firstChild(); + size_t res = childNode->isMathmlElement() ? 1 : 0; + + while (childNode != nullptr) { + childNode = childNode->next(); + + if (childNode && childNode->isMathmlElement()) { + ++res; + } + } + + return res; +} + +XmlNodePtr Analyser::AnalyserImpl::mathmlChildNode(const XmlNodePtr &node, + size_t index) const +{ + // Return the nth child element of the given node, skipping anything that is + // not int the MathML namespace. + + auto res = node->firstChild(); + auto childNodeIndex = res->isMathmlElement() ? 0 : MAX_SIZE_T; + + while ((res != nullptr) && (childNodeIndex != index)) { + res = res->next(); + + if (res && res->isMathmlElement()) { + ++childNodeIndex; + } + } + + return res; +} + +AnalyserInternalVariablePtr Analyser::AnalyserImpl::internalVariable(const VariablePtr &variable) +{ + // Find and return, if there is one, the internal variable associated with + // the given variable. + + AnalyserInternalVariablePtr res = nullptr; + + for (const auto &internalVariable : mInternalVariables) { + if (isSameOrEquivalentVariable(variable, internalVariable->mVariable)) { + res = internalVariable; + + break; + } + } + + if (res != nullptr) { + return res; + } + + // No internal variable exists for the given variable, so create one, track + // it and return it. + + res = std::shared_ptr {new AnalyserInternalVariable {variable}}; + + mInternalVariables.push_back(res); + + return res; +} + +VariablePtr Analyser::AnalyserImpl::voiFirstOccurrence(const VariablePtr &variable, + const ComponentPtr &component) +{ + // Recursively look for the first occurrence of the given variable in the + // given component. + + for (size_t i = 0; i < component->variableCount(); ++i) { + auto componentVariable = component->variable(i); + + if (isSameOrEquivalentVariable(variable, componentVariable)) { + return componentVariable; + } + } + + VariablePtr res = nullptr; + + for (size_t i = 0; i < component->componentCount() && res == nullptr; ++i) { + res = voiFirstOccurrence(variable, component->component(i)); + } + + return res; +} + +void Analyser::AnalyserImpl::analyseNode(const XmlNodePtr &node, + AnalyserEquationAstPtr &ast, + const AnalyserEquationAstPtr &astParent, + const ComponentPtr &component, + const AnalyserInternalEquationPtr &equation) +{ + // Create the AST, if needed. + + if (ast.get() == nullptr) { + ast.reset(new AnalyserEquationAst {}); + } + + // Basic content elements. + + if (node->isMathmlElement("apply")) { + // We may have 2, 3 or more child nodes, e.g. + // + // +--------+ + // | + | + // "+a" ==> | / \ | + // | a nil | + // +--------+ + // + // +-------+ + // | + | + // "a+b" ==> | / \ | + // | a b | + // +-------+ + // + // +-------------+ + // | + | + // | / \ | + // | a + | + // | / \ | + // "a+b+c+d+e" ==> | b + | + // | / \ | + // | c + | + // | / \ | + // | d e | + // +-------------+ + + auto childCount = mathmlChildCount(node); + + analyseNode(mathmlChildNode(node, 0), ast, astParent, component, equation); + analyseNode(mathmlChildNode(node, 1), ast->mPimpl->mOwnedLeftChild, ast, component, equation); + + if (childCount >= 3) { + AnalyserEquationAstPtr astRightChild; + AnalyserEquationAstPtr tempAst; + + analyseNode(mathmlChildNode(node, childCount - 1), astRightChild, nullptr, component, equation); + + for (auto i = childCount - 2; i > 1; --i) { + tempAst = AnalyserEquationAst::create(); + + analyseNode(mathmlChildNode(node, 0), tempAst, nullptr, component, equation); + analyseNode(mathmlChildNode(node, i), tempAst->mPimpl->mOwnedLeftChild, tempAst, component, equation); + + astRightChild->mPimpl->mParent = tempAst; + + tempAst->mPimpl->mOwnedRightChild = astRightChild; + astRightChild = tempAst; + } + + if (astRightChild != nullptr) { + astRightChild->mPimpl->mParent = ast; + } + + ast->mPimpl->mOwnedRightChild = astRightChild; + } + + // Assignment, and relational and logical operators. + + } else if (node->isMathmlElement("eq")) { + // This element is used both to describe "a = b" and "a == b". We can + // distinguish between the two by checking its grand-parent. If it's a + // "math" element then it means that it is used to describe "a = b" + // otherwise it is used to describe "a == b". In the former case, there + // is nothing more we need to do since `ast` is already of + // AnalyserEquationAst::Type::ASSIGNMENT type. + + if (!node->parent()->parent()->isMathmlElement("math")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::EQ, astParent); + + mModel->mPimpl->mNeedEqFunction = true; + } + } else if (node->isMathmlElement("neq")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::NEQ, astParent); + + mModel->mPimpl->mNeedNeqFunction = true; + } else if (node->isMathmlElement("lt")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::LT, astParent); + + mModel->mPimpl->mNeedLtFunction = true; + } else if (node->isMathmlElement("leq")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::LEQ, astParent); + + mModel->mPimpl->mNeedLeqFunction = true; + } else if (node->isMathmlElement("gt")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::GT, astParent); + + mModel->mPimpl->mNeedGtFunction = true; + } else if (node->isMathmlElement("geq")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::GEQ, astParent); + + mModel->mPimpl->mNeedGeqFunction = true; + } else if (node->isMathmlElement("and")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::AND, astParent); + + mModel->mPimpl->mNeedAndFunction = true; + } else if (node->isMathmlElement("or")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::OR, astParent); + + mModel->mPimpl->mNeedOrFunction = true; + } else if (node->isMathmlElement("xor")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::XOR, astParent); + + mModel->mPimpl->mNeedXorFunction = true; + } else if (node->isMathmlElement("not")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::NOT, astParent); + + mModel->mPimpl->mNeedNotFunction = true; + + // Arithmetic operators. + + } else if (node->isMathmlElement("plus")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::PLUS, astParent); + } else if (node->isMathmlElement("minus")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::MINUS, astParent); + } else if (node->isMathmlElement("times")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::TIMES, astParent); + } else if (node->isMathmlElement("divide")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::DIVIDE, astParent); + } else if (node->isMathmlElement("power")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::POWER, astParent); + } else if (node->isMathmlElement("root")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::ROOT, astParent); + } else if (node->isMathmlElement("abs")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::ABS, astParent); + } else if (node->isMathmlElement("exp")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::EXP, astParent); + } else if (node->isMathmlElement("ln")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::LN, astParent); + } else if (node->isMathmlElement("log")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::LOG, astParent); + } else if (node->isMathmlElement("ceiling")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::CEILING, astParent); + } else if (node->isMathmlElement("floor")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::FLOOR, astParent); + } else if (node->isMathmlElement("min")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::MIN, astParent); + + mModel->mPimpl->mNeedMinFunction = true; + } else if (node->isMathmlElement("max")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::MAX, astParent); + + mModel->mPimpl->mNeedMaxFunction = true; + } else if (node->isMathmlElement("rem")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::REM, astParent); + + // Calculus elements. + + } else if (node->isMathmlElement("diff")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::DIFF, astParent); + + // Trigonometric operators. + + } else if (node->isMathmlElement("sin")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::SIN, astParent); + } else if (node->isMathmlElement("cos")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::COS, astParent); + } else if (node->isMathmlElement("tan")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::TAN, astParent); + } else if (node->isMathmlElement("sec")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::SEC, astParent); + + mModel->mPimpl->mNeedSecFunction = true; + } else if (node->isMathmlElement("csc")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::CSC, astParent); + + mModel->mPimpl->mNeedCscFunction = true; + } else if (node->isMathmlElement("cot")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::COT, astParent); + + mModel->mPimpl->mNeedCotFunction = true; + } else if (node->isMathmlElement("sinh")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::SINH, astParent); + } else if (node->isMathmlElement("cosh")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::COSH, astParent); + } else if (node->isMathmlElement("tanh")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::TANH, astParent); + } else if (node->isMathmlElement("sech")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::SECH, astParent); + + mModel->mPimpl->mNeedSechFunction = true; + } else if (node->isMathmlElement("csch")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::CSCH, astParent); + + mModel->mPimpl->mNeedCschFunction = true; + } else if (node->isMathmlElement("coth")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::COTH, astParent); + + mModel->mPimpl->mNeedCothFunction = true; + } else if (node->isMathmlElement("arcsin")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::ASIN, astParent); + } else if (node->isMathmlElement("arccos")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::ACOS, astParent); + } else if (node->isMathmlElement("arctan")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::ATAN, astParent); + } else if (node->isMathmlElement("arcsec")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::ASEC, astParent); + + mModel->mPimpl->mNeedAsecFunction = true; + } else if (node->isMathmlElement("arccsc")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::ACSC, astParent); + + mModel->mPimpl->mNeedAcscFunction = true; + } else if (node->isMathmlElement("arccot")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::ACOT, astParent); + + mModel->mPimpl->mNeedAcotFunction = true; + } else if (node->isMathmlElement("arcsinh")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::ASINH, astParent); + } else if (node->isMathmlElement("arccosh")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::ACOSH, astParent); + } else if (node->isMathmlElement("arctanh")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::ATANH, astParent); + } else if (node->isMathmlElement("arcsech")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::ASECH, astParent); + + mModel->mPimpl->mNeedAsechFunction = true; + } else if (node->isMathmlElement("arccsch")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::ACSCH, astParent); + + mModel->mPimpl->mNeedAcschFunction = true; + } else if (node->isMathmlElement("arccoth")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::ACOTH, astParent); + + mModel->mPimpl->mNeedAcothFunction = true; + + // Piecewise statement. + + } else if (node->isMathmlElement("piecewise")) { + auto childCount = mathmlChildCount(node); + + ast->mPimpl->populate(AnalyserEquationAst::Type::PIECEWISE, astParent); + + analyseNode(mathmlChildNode(node, 0), ast->mPimpl->mOwnedLeftChild, ast, component, equation); + + if (childCount >= 2) { + AnalyserEquationAstPtr astRight; + AnalyserEquationAstPtr tempAst; + + analyseNode(mathmlChildNode(node, childCount - 1), astRight, nullptr, component, equation); + + for (auto i = childCount - 2; i > 0; --i) { + tempAst = AnalyserEquationAst::create(); + + tempAst->mPimpl->populate(AnalyserEquationAst::Type::PIECEWISE, astParent); + + analyseNode(mathmlChildNode(node, i), tempAst->mPimpl->mOwnedLeftChild, tempAst, component, equation); + + astRight->mPimpl->mParent = tempAst; + + tempAst->mPimpl->mOwnedRightChild = astRight; + astRight = tempAst; + } + + astRight->mPimpl->mParent = ast; + + ast->mPimpl->mOwnedRightChild = astRight; + } + } else if (node->isMathmlElement("piece")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::PIECE, astParent); + + analyseNode(mathmlChildNode(node, 0), ast->mPimpl->mOwnedLeftChild, ast, component, equation); + analyseNode(mathmlChildNode(node, 1), ast->mPimpl->mOwnedRightChild, ast, component, equation); + } else if (node->isMathmlElement("otherwise")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::OTHERWISE, astParent); + + analyseNode(mathmlChildNode(node, 0), ast->mPimpl->mOwnedLeftChild, ast, component, equation); + + // Token elements. + + } else if (node->isMathmlElement("ci")) { + auto variableName = node->firstChild()->convertToStrippedString(); + auto variable = component->variable(variableName); + // Note: we always have a variable. Indeed, if we were not to have one, + // it would mean that `variableName` is the name of a variable + // that is referenced in an equation, but not defined anywhere, + // something that is not allowed in CellML and will therefore be + // reported when we validate the model. + + // Have our equation track the (ODE) variable (by ODE variable, we mean + // a variable that is used in a "diff" element). + + if (node->parent()->firstChild()->isMathmlElement("diff")) { + equation->addOdeVariable(internalVariable(variable)); + } else if (!(node->parent()->isMathmlElement("bvar") + && node->parent()->parent()->firstChild()->isMathmlElement("diff"))) { + equation->addVariable(internalVariable(variable)); + } + + // Add the variable to our AST. + + ast->mPimpl->populate(AnalyserEquationAst::Type::CI, variable, astParent); + } else if (node->isMathmlElement("cn")) { + if (mathmlChildCount(node) == 1) { + // We are dealing with an e-notation based CN value. + + ast->mPimpl->populate(AnalyserEquationAst::Type::CN, node->firstChild()->convertToStrippedString() + "e" + node->firstChild()->next()->next()->convertToStrippedString(), astParent); + } else { + ast->mPimpl->populate(AnalyserEquationAst::Type::CN, node->firstChild()->convertToStrippedString(), astParent); + } + + // Qualifier elements. + + } else if (node->isMathmlElement("degree")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::DEGREE, astParent); + + analyseNode(mathmlChildNode(node, 0), ast->mPimpl->mOwnedLeftChild, ast, component, equation); + } else if (node->isMathmlElement("logbase")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::LOGBASE, astParent); + + analyseNode(mathmlChildNode(node, 0), ast->mPimpl->mOwnedLeftChild, ast, component, equation); + } else if (node->isMathmlElement("bvar")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::BVAR, astParent); + + analyseNode(mathmlChildNode(node, 0), ast->mPimpl->mOwnedLeftChild, ast, component, equation); + + auto rightNode = mathmlChildNode(node, 1); + + if (rightNode != nullptr) { + analyseNode(rightNode, ast->mPimpl->mOwnedRightChild, ast, component, equation); + } + + // Constants. + + } else if (node->isMathmlElement("true")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::TRUE, astParent); + } else if (node->isMathmlElement("false")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::FALSE, astParent); + } else if (node->isMathmlElement("exponentiale")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::E, astParent); + } else if (node->isMathmlElement("pi")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::PI, astParent); + } else if (node->isMathmlElement("infinity")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::INF, astParent); + } else if (node->isMathmlElement("notanumber")) { + ast->mPimpl->populate(AnalyserEquationAst::Type::NAN, astParent); + } +} + +void Analyser::AnalyserImpl::analyseComponent(const ComponentPtr &component) +{ + // Retrieve the math string associated with the given component and analyse + // it, one equation at a time, keeping in mind that it may consist of + // several elements, hence our use of multiRootXml(). + + if (!component->math().empty()) { + for (const auto &doc : multiRootXml(component->math())) { + for (auto node = doc->rootNode()->firstChild(); node != nullptr; node = node->next()) { + if (node->isMathmlElement()) { + // Create and keep track of the equation associated with the + // given node. + + auto internalEquation = std::shared_ptr {new AnalyserInternalEquation {component}}; + + mInternalEquations.push_back(internalEquation); + + // Actually analyse the node. + + analyseNode(node, internalEquation->mAst, internalEquation->mAst->parent(), component, internalEquation); + } + } + } + } + + // Go through the given component's variables and make sure that everything + // makes sense. + + for (size_t i = 0; i < component->variableCount(); ++i) { + // Retrieve the variable's corresponding internal variable. + + auto variable = component->variable(i); + auto internalVariable = Analyser::AnalyserImpl::internalVariable(variable); + + // If `variable` has an initial value and the variable held by + // `internalVariable` doesn't, then replace the variable held by + // `internalVariable`. If `variable` and the variable held by + // `internalVariable` are different and both of them have an initial + // value then generate an error. + + if (!variable->initialValue().empty() + && internalVariable->mVariable->initialValue().empty()) { + internalVariable->setVariable(variable); + } else if ((variable != internalVariable->mVariable) + && !variable->initialValue().empty() + && !internalVariable->mVariable->initialValue().empty()) { + auto issue = Issue::create(); + auto trackedVariableComponent = owningComponent(internalVariable->mVariable); + + issue->setDescription("Variable '" + variable->name() + + "' in component '" + component->name() + + "' and variable '" + internalVariable->mVariable->name() + + "' in component '" + trackedVariableComponent->name() + + "' are equivalent and cannot therefore both be initialised."); + issue->setCause(Issue::Cause::VARIABLE); + + mAnalyser->addIssue(issue); + } + + if (!internalVariable->mVariable->initialValue().empty() + && !isCellMLReal(internalVariable->mVariable->initialValue())) { + // The initial value is not a double, so it has to be an existing + // variable of constant type. + // Note: we always have an initialising variable. Indeed, if we were + // not to have one, it would mean that the variable is + // initialised using a reference to a variable that is not + // defined anywhere, something that is not allowed in CellML + // and will therefore be reported when we validate the model. + + auto initialisingComponent = owningComponent(internalVariable->mVariable); + auto initialisingVariable = initialisingComponent->variable(internalVariable->mVariable->initialValue()); + auto initialisingInternalVariable = Analyser::AnalyserImpl::internalVariable(initialisingVariable); + + if (initialisingInternalVariable->mType != AnalyserInternalVariable::Type::CONSTANT) { + auto issue = Issue::create(); + + issue->setDescription("Variable '" + variable->name() + + "' in component '" + component->name() + + "' is initialised using variable '" + internalVariable->mVariable->initialValue() + + "', but it is not a constant."); + issue->setVariable(variable); + + mAnalyser->addIssue(issue); + } + } + } + + // Do the same for the components encapsulated by the given component. + + for (size_t i = 0; i < component->componentCount(); ++i) { + analyseComponent(component->component(i)); + } +} + +void Analyser::AnalyserImpl::doEquivalentVariables(const VariablePtr &variable, + std::vector &equivalentVariables) const +{ + for (size_t i = 0; i < variable->equivalentVariableCount(); ++i) { + auto equivalentVariable = variable->equivalentVariable(i); + + if (std::find(equivalentVariables.begin(), equivalentVariables.end(), equivalentVariable) == equivalentVariables.end()) { + equivalentVariables.push_back(equivalentVariable); + + doEquivalentVariables(equivalentVariable, equivalentVariables); + } + } +} + +std::vector Analyser::AnalyserImpl::equivalentVariables(const VariablePtr &variable) const +{ + std::vector res = {variable}; + + doEquivalentVariables(variable, res); + + return res; +} + +void Analyser::AnalyserImpl::analyseEquationAst(const AnalyserEquationAstPtr &ast) +{ + // Look for the definition of a variable of integration and make sure that + // we don't have more than one of it and that it's not initialised. + + auto astParent = ast->parent(); + auto astGrandParent = (astParent != nullptr) ? astParent->parent() : nullptr; + auto astGreatGrandParent = (astGrandParent != nullptr) ? astGrandParent->parent() : nullptr; + + if ((ast->mPimpl->mType == AnalyserEquationAst::Type::CI) + && (astParent != nullptr) && (astParent->mPimpl->mType == AnalyserEquationAst::Type::BVAR) + && (astGrandParent != nullptr) && (astGrandParent->mPimpl->mType == AnalyserEquationAst::Type::DIFF)) { + auto variable = ast->variable(); + + internalVariable(variable)->makeVoi(); + // Note: we must make the variable a variable of integration in all + // cases (i.e. even if there is, for example, already another + // variable of integration) otherwise unnecessary issue messages + // may be reported (since the type of the variable would be + // unknown). + + if (mModel->mPimpl->mVoi == nullptr) { + // We have found our variable of integration, but this may not be + // the one defined in our first component (i.e. the component under + // which we are likely to expect to see the variable of integration + // to be defined), so go through our components and look for the + // first occurrence of our variable of integration. + + auto model = owningModel(variable); + + for (size_t i = 0; i < model->componentCount(); ++i) { + auto voi = voiFirstOccurrence(variable, model->component(i)); + + if (voi != nullptr) { + // We have found the first occurrence of our variable of + // integration, but now we must ensure neither it (nor any + // of its equivalent variables) is initialised. + + bool isVoiInitialised = false; + + for (const auto &voiEquivalentVariable : equivalentVariables(voi)) { + if (!voiEquivalentVariable->initialValue().empty()) { + auto issue = Issue::create(); + + issue->setDescription("Variable '" + voiEquivalentVariable->name() + + "' in component '" + owningComponent(voiEquivalentVariable)->name() + + "' cannot be both a variable of integration and initialised."); + issue->setVariable(voiEquivalentVariable); + + mAnalyser->addIssue(issue); + + isVoiInitialised = true; + } + } + + if (!isVoiInitialised) { + mModel->mPimpl->mVoi = std::shared_ptr {new AnalyserVariable {}}; + + mModel->mPimpl->mVoi->mPimpl->populate(AnalyserVariable::Type::VARIABLE_OF_INTEGRATION, + 0, nullptr, voi, nullptr); + } + + break; + } + } + } else if (!isSameOrEquivalentVariable(variable, mModel->mPimpl->mVoi->variable())) { + auto issue = Issue::create(); + + issue->setDescription("Variable '" + mModel->mPimpl->mVoi->variable()->name() + + "' in component '" + owningComponent(mModel->mPimpl->mVoi->variable())->name() + + "' and variable '" + variable->name() + + "' in component '" + owningComponent(variable)->name() + + "' cannot both be the variable of integration."); + issue->setCause(Issue::Cause::VARIABLE); + + mAnalyser->addIssue(issue); + } + } + + // Make sure that we only use first-order ODEs. + + if ((ast->mPimpl->mType == AnalyserEquationAst::Type::CN) + && (astParent != nullptr) && (astParent->mPimpl->mType == AnalyserEquationAst::Type::DEGREE) + && (astGrandParent != nullptr) && (astGrandParent->mPimpl->mType == AnalyserEquationAst::Type::BVAR) + && (astGreatGrandParent != nullptr) && (astGreatGrandParent->mPimpl->mType == AnalyserEquationAst::Type::DIFF)) { + double value; + + if (!convertToDouble(ast->mPimpl->mValue, value) || !areEqual(value, 1.0)) { + auto issue = Issue::create(); + auto variable = astGreatGrandParent->mPimpl->mOwnedRightChild->variable(); + + issue->setDescription("The differential equation for variable '" + variable->name() + + "' in component '" + owningComponent(variable)->name() + + "' must be of the first order."); + issue->setCause(Issue::Cause::MATHML); + + mAnalyser->addIssue(issue); + } + } + + // Make a variable a state if it is used in an ODE. + + if ((ast->mPimpl->mType == AnalyserEquationAst::Type::CI) + && (astParent != nullptr) && (astParent->mPimpl->mType == AnalyserEquationAst::Type::DIFF)) { + internalVariable(ast->variable())->makeState(); + } + + // Recursively check the given AST's children. + + if (ast->mPimpl->mOwnedLeftChild != nullptr) { + analyseEquationAst(ast->mPimpl->mOwnedLeftChild); + } + + if (ast->mPimpl->mOwnedRightChild != nullptr) { + analyseEquationAst(ast->mPimpl->mOwnedRightChild); + } +} + +double Analyser::AnalyserImpl::scalingFactor(const VariablePtr &variable) +{ + // Return the scaling factor for the given variable. + + return Units::scalingFactor(variable->units(), internalVariable(variable)->mVariable->units()); +} + +void Analyser::AnalyserImpl::scaleAst(const AnalyserEquationAstPtr &ast, + const AnalyserEquationAstPtr &astParent, + double scalingFactor) +{ + // Scale the given AST using the given scaling factor. + + auto scaledAst = AnalyserEquationAst::create(); + + scaledAst->mPimpl->populate(AnalyserEquationAst::Type::TIMES, astParent); + + scaledAst->mPimpl->mOwnedLeftChild = AnalyserEquationAst::create(); + scaledAst->mPimpl->mOwnedRightChild = ast; + + scaledAst->mPimpl->mOwnedLeftChild->mPimpl->populate(AnalyserEquationAst::Type::CN, convertToString(scalingFactor), scaledAst); + + ast->mPimpl->mParent = scaledAst; + + if (astParent->mPimpl->mOwnedLeftChild == ast) { + astParent->mPimpl->mOwnedLeftChild = scaledAst; + } else { + astParent->mPimpl->mOwnedRightChild = scaledAst; + } +} + +void Analyser::AnalyserImpl::scaleEquationAst(const AnalyserEquationAstPtr &ast) +{ + // Recursively scale the given AST's children. + + if (ast->mPimpl->mOwnedLeftChild != nullptr) { + scaleEquationAst(ast->mPimpl->mOwnedLeftChild); + } + + if (ast->mPimpl->mOwnedRightChild != nullptr) { + scaleEquationAst(ast->mPimpl->mOwnedRightChild); + } + + // If the given AST node is a variable (i.e. a CI node) then we may need to + // do some scaling. + + if (ast->mPimpl->mType == AnalyserEquationAst::Type::CI) { + // The kind of scaling we may end up doing depends on whether we are + // dealing with a rate or some other variable, i.e. whether or not it + // has a DIFF node as a parent. + + auto astParent = ast->parent(); + + if (astParent->mPimpl->mType == AnalyserEquationAst::Type::DIFF) { + // We are dealing with a rate, so retrieve the scaling factor for + // its corresponding variable of integration and apply it, if + // needed. + + auto scalingFactor = Analyser::AnalyserImpl::scalingFactor(astParent->mPimpl->mOwnedLeftChild->mPimpl->mOwnedLeftChild->variable()); + + if (!areEqual(scalingFactor, 1.0)) { + // We need to scale using the inverse of the scaling factor, but + // how we do it depends on whether the rate is to be computed or + // used. + + auto astGrandParent = astParent->parent(); + + if ((astGrandParent->mPimpl->mType == AnalyserEquationAst::Type::ASSIGNMENT) + && (astGrandParent->mPimpl->mOwnedLeftChild == astParent)) { + scaleAst(astGrandParent->mPimpl->mOwnedRightChild, astGrandParent, 1.0 / scalingFactor); + } else { + scaleAst(astParent, astGrandParent, 1.0 / scalingFactor); + } + } + } + + if (((astParent->mPimpl->mType != AnalyserEquationAst::Type::ASSIGNMENT) + || (astParent->mPimpl->mOwnedLeftChild != ast)) + && (astParent->mPimpl->mType != AnalyserEquationAst::Type::BVAR)) { + // We are dealing with a variable which is neither a computed + // variable nor our variable of integration, so retrieve its scaling + // factor and apply it, if needed, distinguishing between a rate + // variable and an algebraic variable. + + auto scalingFactor = Analyser::AnalyserImpl::scalingFactor(ast->variable()); + + if (!areEqual(scalingFactor, 1.0)) { + if (astParent->mPimpl->mType == AnalyserEquationAst::Type::DIFF) { + scaleAst(astParent, astParent->parent(), scalingFactor); + } else { + scaleAst(ast, astParent, scalingFactor); + } + } + } + } +} + +bool Analyser::AnalyserImpl::isStateRateBased(const AnalyserEquationPtr &equation, + std::vector &checkedEquations) +{ + if (std::find(checkedEquations.begin(), checkedEquations.end(), equation) != checkedEquations.end()) { + return false; + } + + checkedEquations.push_back(equation); + + for (const auto &dependency : equation->dependencies()) { + if ((dependency->type() == AnalyserEquation::Type::RATE) + || isStateRateBased(dependency, checkedEquations)) { + return true; + } + } + + return false; +} + +void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) +{ + // Reset a few things in case this analyser was to be used to analyse more + // than one model. + + mAnalyser->removeAllIssues(); + + mModel = std::shared_ptr {new AnalyserModel {}}; + + mInternalVariables.clear(); + mInternalEquations.clear(); + + // Recursively analyse the model's components, so that we end up with an AST + // for each of the model's equations. + + for (size_t i = 0; i < model->componentCount(); ++i) { + analyseComponent(model->component(i)); + } + + // Some more analysis is needed, but it can only be done if we didn't come + // across any errors during the analysis of our components. + + if (mAnalyser->errorCount() == 0) { + // Analyse our different equations' AST to determine the type of our + // variables. + + for (const auto &internalEquation : mInternalEquations) { + analyseEquationAst(internalEquation->mAst); + } + } + + // Some post-analysis is now needed, but it can only be done if we didn't + // come across any errors during the analysis of our equations' AST. + + if (mAnalyser->errorCount() == 0) { + // Sort our variables, determine the index of our constant variables and + // then loop over our equations, checking which variables, if any, can + // be determined using a given equation. + + std::sort(mInternalVariables.begin(), mInternalVariables.end(), + compareVariablesByComponentAndName); + + auto variableIndex = MAX_SIZE_T; + + for (const auto &internalVariable : mInternalVariables) { + if (internalVariable->mType == AnalyserInternalVariable::Type::CONSTANT) { + internalVariable->mIndex = ++variableIndex; + } + } + + auto equationOrder = MAX_SIZE_T; + auto stateIndex = MAX_SIZE_T; + bool relevantCheck; + + do { + relevantCheck = false; + + for (const auto &internalEquation : mInternalEquations) { + relevantCheck = internalEquation->check(equationOrder, stateIndex, variableIndex) + || relevantCheck; + } + } while (relevantCheck); + + // Make sure that our variables are valid. + + for (const auto &internalVariable : mInternalVariables) { + std::string issueType; + + if (internalVariable->mType == AnalyserInternalVariable::Type::UNKNOWN) { + issueType = "is not computed"; + } else if (internalVariable->mType == AnalyserInternalVariable::Type::SHOULD_BE_STATE) { + issueType = "is used in an ODE, but it is not initialised"; + } else if (internalVariable->mType == AnalyserInternalVariable::Type::OVERCONSTRAINED) { + issueType = "is computed more than once"; + } + + if (!issueType.empty()) { + auto issue = Issue::create(); + auto realVariable = internalVariable->mVariable; + + issue->setDescription("Variable '" + realVariable->name() + + "' in component '" + owningComponent(realVariable)->name() + + "' " + issueType + "."); + issue->setVariable(realVariable); + + mAnalyser->addIssue(issue); + } + } + + // Determine the type of our model. + + auto hasUnderconstrainedVariables = std::find_if(mInternalVariables.begin(), mInternalVariables.end(), [](const AnalyserInternalVariablePtr &variable) { + return (variable->mType == AnalyserInternalVariable::Type::UNKNOWN) + || (variable->mType == AnalyserInternalVariable::Type::SHOULD_BE_STATE); + }) + != std::end(mInternalVariables); + auto hasOverconstrainedVariables = std::find_if(mInternalVariables.begin(), mInternalVariables.end(), [](const AnalyserInternalVariablePtr &variable) { + return variable->mType == AnalyserInternalVariable::Type::OVERCONSTRAINED; + }) + != std::end(mInternalVariables); + + if (hasUnderconstrainedVariables) { + if (hasOverconstrainedVariables) { + mModel->mPimpl->mType = AnalyserModel::Type::UNSUITABLY_CONSTRAINED; + } else { + mModel->mPimpl->mType = AnalyserModel::Type::UNDERCONSTRAINED; + } + } else if (hasOverconstrainedVariables) { + mModel->mPimpl->mType = AnalyserModel::Type::OVERCONSTRAINED; + } else if (mModel->mPimpl->mVoi != nullptr) { + mModel->mPimpl->mType = AnalyserModel::Type::ODE; + } else if (!mInternalVariables.empty()) { + mModel->mPimpl->mType = AnalyserModel::Type::ALGEBRAIC; + } + } else { + mModel->mPimpl->mType = AnalyserModel::Type::INVALID; + } + + // Some final post-analysis is now needed, if we have a valid model. + + if ((mModel->mPimpl->mType == AnalyserModel::Type::ODE) + || (mModel->mPimpl->mType == AnalyserModel::Type::ALGEBRAIC)) { + // Sort our internal variables and equations. + + std::sort(mInternalVariables.begin(), mInternalVariables.end(), + compareVariablesByTypeAndIndex); + std::sort(mInternalEquations.begin(), mInternalEquations.end(), + compareEquationsByVariable); + + std::map equationMappings; + std::map variableMappings; + + for (const auto &internalEquation : mInternalEquations) { + equationMappings[internalEquation->mVariable->mVariable] = std::shared_ptr {new AnalyserEquation {}}; + } + + // Make our internal variables available through our API. + + auto stateIndex = MAX_SIZE_T; + auto variableIndex = MAX_SIZE_T; + + for (const auto &internalVariable : mInternalVariables) { + // Determine the type of the variable. + + AnalyserVariable::Type type; + + if (internalVariable->mType == AnalyserInternalVariable::Type::STATE) { + type = AnalyserVariable::Type::STATE; + } else if (internalVariable->mType == AnalyserInternalVariable::Type::CONSTANT) { + type = AnalyserVariable::Type::CONSTANT; + } else if ((internalVariable->mType == AnalyserInternalVariable::Type::COMPUTED_TRUE_CONSTANT) + || (internalVariable->mType == AnalyserInternalVariable::Type::COMPUTED_VARIABLE_BASED_CONSTANT)) { + type = AnalyserVariable::Type::COMPUTED_CONSTANT; + } else if (internalVariable->mType == AnalyserInternalVariable::Type::ALGEBRAIC) { + type = AnalyserVariable::Type::ALGEBRAIC; + } else { + // This is the variable of integration, so skip it. + + continue; + } + + // Populate and keep track of the state/variable. + + auto stateOrVariable = std::shared_ptr {new AnalyserVariable {}}; + auto equation = equationMappings[internalVariable->mVariable]; + + stateOrVariable->mPimpl->populate(type, + (type == AnalyserVariable::Type::STATE) ? + ++stateIndex : + ++variableIndex, + internalVariable->mInitialisingVariable, + internalVariable->mVariable, + equation); + + variableMappings[equation] = stateOrVariable; + + if (type == AnalyserVariable::Type::STATE) { + mModel->mPimpl->mStates.push_back(stateOrVariable); + } else { + mModel->mPimpl->mVariables.push_back(stateOrVariable); + } + } + + // Make our internal equations available through our API. + + for (const auto &internalEquation : mInternalEquations) { + // Determine the type of the equation. + + auto equation = equationMappings[internalEquation->mVariable->mVariable]; + auto stateOrVariable = variableMappings[equation]; + AnalyserEquation::Type type; + + if (internalEquation->mType == AnalyserInternalEquation::Type::TRUE_CONSTANT) { + type = AnalyserEquation::Type::TRUE_CONSTANT; + } else if (internalEquation->mType == AnalyserInternalEquation::Type::VARIABLE_BASED_CONSTANT) { + type = AnalyserEquation::Type::VARIABLE_BASED_CONSTANT; + } else if (internalEquation->mType == AnalyserInternalEquation::Type::RATE) { + type = AnalyserEquation::Type::RATE; + } else { + type = AnalyserEquation::Type::ALGEBRAIC; + } + + // Scale our internal equation's AST to take into account the + // fact that we may have mapped variables that use compatible + // units rather than equivalent ones. + + scaleEquationAst(internalEquation->mAst); + + // Determine the equation's dependencies, i.e. the equations for + // the variables on which this equation depends. + // Note: an equation may depend on the variable of integration, for + // which there is no equation, hence we need to test + // equationDependency against nullptr. + + std::vector equationDependencies; + + for (const auto &variableDependency : internalEquation->mDependencies) { + auto equationDependency = equationMappings[variableDependency]; + + if (equationDependency != nullptr) { + equationDependencies.push_back(equationDependency); + } + } + + // Populate and keep track of the equation. + + equation->mPimpl->populate(type, internalEquation->mAst, + equationDependencies, + stateOrVariable); + + mModel->mPimpl->mEquations.push_back(equation); + } + + // Determine whether our equations are state/rate based. + // Note: obviously, this can only be done once all our equations are + // ready, hence we don't do this in the previous for loop. + + for (const auto &equation : mModel->mPimpl->mEquations) { + std::vector checkedEquations; + + equation->mPimpl->mIsStateRateBased = isStateRateBased(equation, checkedEquations); + } + } +} + +Analyser::Analyser() + : mPimpl(new AnalyserImpl {this}) +{ +} + +Analyser::~Analyser() +{ + delete mPimpl; +} + +AnalyserPtr Analyser::create() noexcept +{ + return std::shared_ptr {new Analyser {}}; +} + +void Analyser::analyseModel(const ModelPtr &model) +{ + // Make sure that we have a model and that it is valid before analysing it. + + if (model == nullptr) { + return; + } + + auto validator = Validator::create(); + + validator->validateModel(model); + + if (validator->issueCount() > 0) { + // The model is not valid, so retrieve the validation issues and make + // them our own. + + for (size_t i = 0; i < validator->issueCount(); ++i) { + addIssue(validator->issue(i)); + } + + mPimpl->mModel->mPimpl->mType = AnalyserModel::Type::INVALID; + + return; + } + + // Analyse the model. + + mPimpl->analyseModel(model); +} + +AnalyserModelPtr Analyser::model() const +{ + return mPimpl->mModel; +} + +} // namespace libcellml diff --git a/src/analyserequation.cpp b/src/analyserequation.cpp new file mode 100644 index 0000000000..f17232838f --- /dev/null +++ b/src/analyserequation.cpp @@ -0,0 +1,79 @@ +/* +Copyright libCellML Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "libcellml/analyserequation.h" + +#include "analyserequation_p.h" + +namespace libcellml { + +void AnalyserEquation::AnalyserEquationImpl::populate(AnalyserEquation::Type type, + const AnalyserEquationAstPtr &ast, + const std::vector &dependencies, + const AnalyserVariablePtr &variable) +{ + mType = type; + mAst = ast; + + for (const auto &dependency : dependencies) { + mDependencies.push_back(dependency); + } + + mVariable = variable; +} + +AnalyserEquation::AnalyserEquation() + : mPimpl(new AnalyserEquationImpl()) +{ +} + +AnalyserEquation::~AnalyserEquation() +{ + delete mPimpl; +} + +AnalyserEquation::Type AnalyserEquation::type() const +{ + return mPimpl->mType; +} + +AnalyserEquationAstPtr AnalyserEquation::ast() const +{ + return mPimpl->mAst.lock(); +} + +std::vector AnalyserEquation::dependencies() const +{ + std::vector res; + + for (const auto &dependency : mPimpl->mDependencies) { + res.push_back(dependency.lock()); + } + + return res; +} + +bool AnalyserEquation::isStateRateBased() const +{ + return mPimpl->mIsStateRateBased; +} + +AnalyserVariablePtr AnalyserEquation::variable() const +{ + return mPimpl->mVariable.lock(); +} + +} // namespace libcellml diff --git a/src/analyserequation_p.h b/src/analyserequation_p.h new file mode 100644 index 0000000000..32b737f04d --- /dev/null +++ b/src/analyserequation_p.h @@ -0,0 +1,44 @@ +/* +Copyright libCellML Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "libcellml/analyserequation.h" + +namespace libcellml { + +using AnalyserEquationWeakPtr = std::weak_ptr; /**< Type definition for weak analyser equation pointer. */ +using AnalyserEquationAstWeakPtr = std::weak_ptr; /**< Type definition for weak analyser equation AST pointer. */ +using AnalyserVariableWeakPtr = std::weak_ptr; /**< Type definition for weak analyser variable pointer. */ + +/** + * @brief The AnalyserEquation::AnalyserEquationImpl struct. + * + * The private implementation for the AnalyserEquation class. + */ +struct AnalyserEquation::AnalyserEquationImpl +{ + AnalyserEquation::Type mType = AnalyserEquation::Type::ALGEBRAIC; + AnalyserEquationAstWeakPtr mAst; + std::vector mDependencies; + bool mIsStateRateBased = false; + AnalyserVariableWeakPtr mVariable; + + void populate(AnalyserEquation::Type type, + const AnalyserEquationAstPtr &ast, + const std::vector &dependencies, + const AnalyserVariablePtr &variable); +}; + +} // namespace libcellml diff --git a/src/analyserequationast.cpp b/src/analyserequationast.cpp new file mode 100644 index 0000000000..9349314aa4 --- /dev/null +++ b/src/analyserequationast.cpp @@ -0,0 +1,133 @@ +/* +Copyright libCellML Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "libcellml/analyserequationast.h" + +#include "analyserequationast_p.h" + +namespace libcellml { + +void AnalyserEquationAst::AnalyserEquationAstImpl::populate(Type type, + const AnalyserEquationAstPtr &parent) +{ + mType = type; + mParent = parent; +} + +void AnalyserEquationAst::AnalyserEquationAstImpl::populate(Type type, + const std::string &value, + const AnalyserEquationAstPtr &parent) +{ + mType = type; + mValue = value; + mParent = parent; +} + +void AnalyserEquationAst::AnalyserEquationAstImpl::populate(Type type, + const VariablePtr &variable, + const AnalyserEquationAstPtr &parent) +{ + mType = type; + mVariable = variable; + mParent = parent; +} + +AnalyserEquationAst::AnalyserEquationAst() + : mPimpl(new AnalyserEquationAstImpl()) +{ +} + +AnalyserEquationAst::~AnalyserEquationAst() +{ + delete mPimpl; +} + +AnalyserEquationAstPtr AnalyserEquationAst::create() noexcept +{ + return std::shared_ptr {new AnalyserEquationAst {}}; +} + +AnalyserEquationAst::Type AnalyserEquationAst::type() const +{ + return mPimpl->mType; +} + +void AnalyserEquationAst::setType(Type type) +{ + mPimpl->mType = type; +} + +std::string AnalyserEquationAst::value() const +{ + return mPimpl->mValue; +} + +void AnalyserEquationAst::setValue(const std::string &value) +{ + mPimpl->mValue = value; +} + +VariablePtr AnalyserEquationAst::variable() const +{ + return mPimpl->mVariable.lock(); +} + +void AnalyserEquationAst::setVariable(const VariablePtr &variable) +{ + mPimpl->mVariable = variable; +} + +AnalyserEquationAstPtr AnalyserEquationAst::parent() const +{ + return mPimpl->mParent.lock(); +} + +void AnalyserEquationAst::setParent(const AnalyserEquationAstPtr &parent) +{ + mPimpl->mParent = parent; +} + +AnalyserEquationAstPtr AnalyserEquationAst::leftChild() const +{ + if (mPimpl->mOwnedLeftChild != nullptr) { + return mPimpl->mOwnedLeftChild; + } + + return mPimpl->mLeftChild.lock(); +} + +void AnalyserEquationAst::setLeftChild(const AnalyserEquationAstPtr &leftChild) +{ + mPimpl->mOwnedLeftChild = nullptr; + mPimpl->mLeftChild = leftChild; +} + +AnalyserEquationAstPtr AnalyserEquationAst::rightChild() const +{ + if (mPimpl->mOwnedRightChild != nullptr) { + return mPimpl->mOwnedRightChild; + } + + return mPimpl->mRightChild.lock(); +} + +void AnalyserEquationAst::setRightChild(const AnalyserEquationAstPtr &rightChild) +{ + mPimpl->mOwnedRightChild = nullptr; + mPimpl->mRightChild = rightChild; +} + +} // namespace libcellml diff --git a/src/analyserequationast_p.h b/src/analyserequationast_p.h new file mode 100644 index 0000000000..61311b3c4d --- /dev/null +++ b/src/analyserequationast_p.h @@ -0,0 +1,48 @@ +/* +Copyright libCellML Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "libcellml/analyserequationast.h" + +namespace libcellml { + +using AnalyserEquationAstWeakPtr = std::weak_ptr; /**< Type definition for weak analyser equation AST pointer. */ +using VariableWeakPtr = std::weak_ptr; /**< Type definition for weak variable pointer. */ + +/** + * @brief The AnalyserEquationAst::AnalyserEquationAstImpl struct. + * + * The private implementation for the AnalyserEquationAst class. + */ +struct AnalyserEquationAst::AnalyserEquationAstImpl +{ + AnalyserEquationAst::Type mType = Type::ASSIGNMENT; + std::string mValue; + VariableWeakPtr mVariable; + AnalyserEquationAstWeakPtr mParent; + AnalyserEquationAstPtr mOwnedLeftChild = nullptr; + AnalyserEquationAstPtr mOwnedRightChild = nullptr; + AnalyserEquationAstWeakPtr mLeftChild; + AnalyserEquationAstWeakPtr mRightChild; + + void populate(AnalyserEquationAst::Type type, + const AnalyserEquationAstPtr &parent); + void populate(AnalyserEquationAst::Type type, const std::string &value, + const AnalyserEquationAstPtr &parent); + void populate(AnalyserEquationAst::Type type, const VariablePtr &variable, + const AnalyserEquationAstPtr &parent); +}; + +} // namespace libcellml diff --git a/src/analysermodel.cpp b/src/analysermodel.cpp new file mode 100644 index 0000000000..98cb623bd0 --- /dev/null +++ b/src/analysermodel.cpp @@ -0,0 +1,351 @@ +/* +Copyright libCellML Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "libcellml/analysermodel.h" + +#include "analysermodel_p.h" + +namespace libcellml { + +AnalyserModel::AnalyserModel() + : mPimpl(new AnalyserModelImpl()) +{ +} + +AnalyserModel::~AnalyserModel() +{ + delete mPimpl; +} + +bool AnalyserModel::isValid() const +{ + return (mPimpl->mType == AnalyserModel::Type::ALGEBRAIC) + || (mPimpl->mType == AnalyserModel::Type::ODE); +} + +AnalyserModel::Type AnalyserModel::type() const +{ + return mPimpl->mType; +} + +AnalyserVariablePtr AnalyserModel::voi() const +{ + if (!isValid()) { + return {}; + } + + return mPimpl->mVoi; +} + +size_t AnalyserModel::stateCount() const +{ + if (!isValid()) { + return 0; + } + + return mPimpl->mStates.size(); +} + +std::vector AnalyserModel::states() const +{ + if (!isValid()) { + return {}; + } + + return mPimpl->mStates; +} + +AnalyserVariablePtr AnalyserModel::state(size_t index) const +{ + if (!isValid() + || (index >= mPimpl->mStates.size())) { + return {}; + } + + return mPimpl->mStates[index]; +} + +size_t AnalyserModel::variableCount() const +{ + if (!isValid()) { + return 0; + } + + return mPimpl->mVariables.size(); +} + +std::vector AnalyserModel::variables() const +{ + if (!isValid()) { + return {}; + } + + return mPimpl->mVariables; +} + +AnalyserVariablePtr AnalyserModel::variable(size_t index) const +{ + if (!isValid() || (index >= mPimpl->mVariables.size())) { + return {}; + } + + return mPimpl->mVariables[index]; +} + +size_t AnalyserModel::equationCount() const +{ + if (!isValid()) { + return 0; + } + + return mPimpl->mEquations.size(); +} + +std::vector AnalyserModel::equations() const +{ + if (!isValid()) { + return {}; + } + + return mPimpl->mEquations; +} + +AnalyserEquationPtr AnalyserModel::equation(size_t index) const +{ + if (!isValid() || (index >= mPimpl->mEquations.size())) { + return {}; + } + + return mPimpl->mEquations[index]; +} + +bool AnalyserModel::needEqFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedEqFunction; +} + +bool AnalyserModel::needNeqFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedNeqFunction; +} + +bool AnalyserModel::needLtFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedLtFunction; +} + +bool AnalyserModel::needLeqFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedLeqFunction; +} + +bool AnalyserModel::needGtFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedGtFunction; +} + +bool AnalyserModel::needGeqFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedGeqFunction; +} + +bool AnalyserModel::needAndFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedAndFunction; +} + +bool AnalyserModel::needOrFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedOrFunction; +} + +bool AnalyserModel::needXorFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedXorFunction; +} + +bool AnalyserModel::needNotFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedNotFunction; +} + +bool AnalyserModel::needMinFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedMinFunction; +} + +bool AnalyserModel::needMaxFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedMaxFunction; +} + +bool AnalyserModel::needSecFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedSecFunction; +} + +bool AnalyserModel::needCscFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedCscFunction; +} + +bool AnalyserModel::needCotFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedCotFunction; +} + +bool AnalyserModel::needSechFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedSechFunction; +} + +bool AnalyserModel::needCschFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedCschFunction; +} + +bool AnalyserModel::needCothFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedCothFunction; +} + +bool AnalyserModel::needAsecFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedAsecFunction; +} + +bool AnalyserModel::needAcscFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedAcscFunction; +} + +bool AnalyserModel::needAcotFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedAcotFunction; +} + +bool AnalyserModel::needAsechFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedAsechFunction; +} + +bool AnalyserModel::needAcschFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedAcschFunction; +} + +bool AnalyserModel::needAcothFunction() const +{ + if (!isValid()) { + return false; + } + + return mPimpl->mNeedAcothFunction; +} + +} // namespace libcellml diff --git a/src/analysermodel_p.h b/src/analysermodel_p.h new file mode 100644 index 0000000000..7135761c5b --- /dev/null +++ b/src/analysermodel_p.h @@ -0,0 +1,63 @@ +/* +Copyright libCellML Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "libcellml/analysermodel.h" + +namespace libcellml { + +/** + * @brief The AnalyserModel::AnalyserModelImpl struct. + * + * The private implementation for the AnalyserModel class. + */ +struct AnalyserModel::AnalyserModelImpl +{ + AnalyserModel::Type mType = Type::UNKNOWN; + + AnalyserVariablePtr mVoi = nullptr; + std::vector mStates; + std::vector mVariables; + std::vector mEquations; + + bool mNeedEqFunction = false; + bool mNeedNeqFunction = false; + bool mNeedLtFunction = false; + bool mNeedLeqFunction = false; + bool mNeedGtFunction = false; + bool mNeedGeqFunction = false; + bool mNeedAndFunction = false; + bool mNeedOrFunction = false; + bool mNeedXorFunction = false; + bool mNeedNotFunction = false; + + bool mNeedMinFunction = false; + bool mNeedMaxFunction = false; + + bool mNeedSecFunction = false; + bool mNeedCscFunction = false; + bool mNeedCotFunction = false; + bool mNeedSechFunction = false; + bool mNeedCschFunction = false; + bool mNeedCothFunction = false; + bool mNeedAsecFunction = false; + bool mNeedAcscFunction = false; + bool mNeedAcotFunction = false; + bool mNeedAsechFunction = false; + bool mNeedAcschFunction = false; + bool mNeedAcothFunction = false; +}; + +} // namespace libcellml diff --git a/src/analyservariable.cpp b/src/analyservariable.cpp new file mode 100644 index 0000000000..9e00168fe8 --- /dev/null +++ b/src/analyservariable.cpp @@ -0,0 +1,71 @@ +/* +Copyright libCellML Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "libcellml/analyservariable.h" + +#include "analyservariable_p.h" + +namespace libcellml { + +void AnalyserVariable::AnalyserVariableImpl::populate(AnalyserVariable::Type type, + size_t index, + const VariablePtr &initialisingVariable, + const VariablePtr &variable, + const AnalyserEquationPtr &equation) +{ + mType = type; + mIndex = index; + mInitialisingVariable = initialisingVariable; + mVariable = variable; + mEquation = equation; +} + +AnalyserVariable::AnalyserVariable() + : mPimpl(new AnalyserVariableImpl()) +{ +} + +AnalyserVariable::~AnalyserVariable() +{ + delete mPimpl; +} + +AnalyserVariable::Type AnalyserVariable::type() const +{ + return mPimpl->mType; +} + +size_t AnalyserVariable::index() const +{ + return mPimpl->mIndex; +} + +VariablePtr AnalyserVariable::initialisingVariable() const +{ + return mPimpl->mInitialisingVariable.lock(); +} + +VariablePtr AnalyserVariable::variable() const +{ + return mPimpl->mVariable.lock(); +} + +AnalyserEquationPtr AnalyserVariable::equation() const +{ + return mPimpl->mEquation.lock(); +} + +} // namespace libcellml diff --git a/src/analyservariable_p.h b/src/analyservariable_p.h new file mode 100644 index 0000000000..3f34b17643 --- /dev/null +++ b/src/analyservariable_p.h @@ -0,0 +1,43 @@ +/* +Copyright libCellML Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "libcellml/analyservariable.h" + +namespace libcellml { + +using AnalyserEquationWeakPtr = std::weak_ptr; /**< Type definition for weak analyser equation pointer. */ +using VariableWeakPtr = std::weak_ptr; /**< Type definition for weak variable pointer. */ + +/** + * @brief The AnalyserVariable::AnalyserVariableImpl struct. + * + * The private implementation for the AnalyserVariable class. + */ +struct AnalyserVariable::AnalyserVariableImpl +{ + AnalyserVariable::Type mType = Type::CONSTANT; + size_t mIndex = 0; + VariableWeakPtr mInitialisingVariable; + VariableWeakPtr mVariable; + AnalyserEquationWeakPtr mEquation; + + void populate(AnalyserVariable::Type type, size_t index, + const VariablePtr &initialisingVariable, + const VariablePtr &variable, + const AnalyserEquationPtr &equation); +}; + +} // namespace libcellml diff --git a/src/api/libcellml/analyser.h b/src/api/libcellml/analyser.h new file mode 100644 index 0000000000..b7e31aa881 --- /dev/null +++ b/src/api/libcellml/analyser.h @@ -0,0 +1,80 @@ +/* +Copyright libCellML Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#pragma once + +#include "libcellml/logger.h" + +namespace libcellml { + +/** + * @brief The Analyser class. + * + * The Analyser class is for representing a CellML Analyser, which aims to check + * whether a model makes mathematical sense. If a model makes mathematical sense + * then an @c AnalyserModel object can be retrieved, which can be used to + * generate code, for instance. + */ +class LIBCELLML_EXPORT Analyser: public Logger +{ +public: + ~Analyser() override; /**< Destructor */ + Analyser(const Analyser &rhs) = delete; /**< Copy constructor */ + Analyser(Analyser &&rhs) noexcept = delete; /**< Move constructor */ + Analyser &operator=(Analyser rhs) = delete; /**< Assignment operator */ + + /** + * @brief Create an @c Analyser object. + * + * Factory method to create an @c Analyser. Create an analyser with:: + * + * @code + * auto analyser = libcellml::Analyser::create(); + * @endcode + * + * @return A smart pointer to an @c Analyser object. + */ + static AnalyserPtr create() noexcept; + + /** + * @brief Analyse the @c Model. + * + * Analyse the @c Model using this @c Analyser. + * + * @param model The @c Model to analyse. + */ + void analyseModel(const ModelPtr &model); + + /** + * @brief Get the analysed model. + * + * Get the analysed model that is the result of the model analysis. This + * allows to retrieve some information about the type of the model, its + * variable of integration, states, variables, equations, and whether it + * needs some specific mathematical functions. + * + * @return The analysed model for the @c Model analysed by this @c Analyser. + */ + AnalyserModelPtr model() const; + +private: + Analyser(); /**< Constructor */ + + struct AnalyserImpl; + AnalyserImpl *mPimpl; +}; + +} // namespace libcellml diff --git a/src/api/libcellml/analyserequation.h b/src/api/libcellml/analyserequation.h new file mode 100644 index 0000000000..6202b1fd1a --- /dev/null +++ b/src/api/libcellml/analyserequation.h @@ -0,0 +1,114 @@ +/* +Copyright libCellML Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#pragma once + +#include "libcellml/analyser.h" + +namespace libcellml { + +/** + * @brief The AnalyserEquation class. + * + * The AnalyserEquation class is for representing an equation in the context of + * a CellML Analyser. + */ +class LIBCELLML_EXPORT AnalyserEquation +{ + friend class Analyser; + +public: + /** + * @brief The type of an equation. + * + * An equation can be of one of the following types: + * - TRUE_CONSTANT: an equation that computes a true constant, e.g. x = 3; + * - VARIABLE_BASED_CONSTANT: an equation that computes a variable-based + * constant, e.g. x = y+z where y and z are true constants; + * - RATE: an equation that computes a rate, e.g. d(y)/dt = f(t, x); or + * - ALGEBRAIC: an equation that computes an algebraic variable, e.g. + * y = f(x). + */ + enum class Type + { + TRUE_CONSTANT, + VARIABLE_BASED_CONSTANT, + RATE, + ALGEBRAIC + }; + + ~AnalyserEquation(); /**< Destructor */ + AnalyserEquation(const AnalyserEquation &rhs) = delete; /**< Copy constructor */ + AnalyserEquation(AnalyserEquation &&rhs) noexcept = delete; /**< Move constructor */ + AnalyserEquation &operator=(AnalyserEquation rhs) = delete; /**< Assignment operator */ + + /** + * @brief Get the @c Type of this @c AnalyserEquation. + * + * Return the @c Type of this @c AnalyserEquation. + * + * @return The @c Type. + */ + Type type() const; + + /** + * @brief Get the @c AnalyserEquationAst for this @c AnalyserEquation. + * + * Return the @c AnalyserEquationAst for this @c AnalyserEquation. + * + * @return The @c AnalyserEquationAst. + */ + AnalyserEquationAstPtr ast() const; + + /** + * @brief Get the list of @c AnalyserEquation dependencies. + * + * Return the list of @c AnalyserEquation items which correspond to the + * equations on which this @c AnalyserEquation depends. + * + * @return The list of @c AnalyserEquation dependencies. + */ + std::vector dependencies() const; + + /** + * @brief Test to determine if this @c AnalyserEquation relies on states + * and/or rates. + * + * Test to determine if this @c AnalyserEquation relies on states and/or + * rates, return @c true if it does and @c false otherwise. + * + * @return @c true if this @c AnalyserEquation relies on states and/or + * rates, @c false otherwise. + */ + bool isStateRateBased() const; + + /** + * @brief Get the @c AnalyserVariable for this @c AnalyserEquation. + * + * Return the @c AnalyserVariable for this @c AnalyserEquation. + * + * @return The @c AnalyserVariable. + */ + AnalyserVariablePtr variable() const; + +private: + AnalyserEquation(); /**< Constructor */ + + struct AnalyserEquationImpl; + AnalyserEquationImpl *mPimpl; +}; + +} // namespace libcellml diff --git a/src/api/libcellml/analyserequationast.h b/src/api/libcellml/analyserequationast.h new file mode 100644 index 0000000000..db8e363308 --- /dev/null +++ b/src/api/libcellml/analyserequationast.h @@ -0,0 +1,355 @@ +/* +Copyright libCellML Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#pragma once + +#include "libcellml/analyser.h" +#include "libcellml/generator.h" + +#ifdef NAN +# undef NAN +#endif + +namespace libcellml { + +/** + * @brief The AnalyserEquationAst class. + * + * The AnalyserEquationAst class is for representing an equation abstract syntax + * tree (AST) in the context of a CellML Analyser. + */ +class LIBCELLML_EXPORT AnalyserEquationAst +{ + friend class Analyser; + +public: + /** + * @brief The type of a node in an abstract syntax tree (AST). + * + * A node in an abstract syntax tree (AST) can be of one of the following + * types: + * - Assignment type: + * - ASSIGNMENT: the assignment operator + * - Relational and logical operators: + * - EQ: the equal to function; + * - NEQ: the not equal to function; + * - LT: the less than function; + * - LEQ: the less than or equal to function; + * - GT: the greater than function; + * - GEQ: the greater than or equal to function; + * - AND: the and function; + * - OR: the or function + * - XOR: the exclusive or function; + * - NOT: the not function; + * - Arithmetic operators: + * - PLUS: the plus operator; + * - MINUS: the minus operator; + * - TIMES: the times operator; + * - DIVIDE: the divide operator; + * - POWER: the power operator; + * - ROOT: the root operator; + * - ABS: the absolute value function; + * - EXP: the exponential function; + * - LN: the natural logarithm function; + * - LOG: the common logarithm function; + * - CEILING: the ceiling function; + * - FLOOR: the floor function; + * - MIN: the minimum function; + * - MAX: the maximum function; + * - REM: the remainder function; + * - Calculus elements: + * - DIFF: the differentiation operator; + * - Trigonometric operators: + * - SIN: the sine function; + * - COS: the cosine function; + * - TAN: the tangent function; + * - SEC: the secant function; + * - CSC: the cosecant function; + * - COT: the cotangent function; + * - SINH: the hyperbolic sine function; + * - COSH: the hyperbolic cosine function; + * - TANH: the hyperbolic tangent function; + * - SECH: the hyperbolic secant function; + * - CSCH: the hyperbolic cosecant function; + * - COTH: the hyperbolic cotangent function; + * - ASIN: the arc sine function; + * - ACOS: the arc cosine function; + * - ATAN: the arc tangent function; + * - ASEC: the arc secant function; + * - ACSC: the arc cosecant function; + * - ACOT: the arc cotangent function; + * - ASINH: the arc hyperbolic sine function; + * - ACOSH: the arc hyperbolic cosine function; + * - ATANH: the arc hyperbolic tangent function; + * - ASECH: the arc hyperbolic secant function; + * - ACSCH: the arc hyperbolic cosecant function; + * - ACOTH: the arc hyperbolic cotangent function; + * - Piecewise statement: + * - PIECEWISE: the "piecewise" statement; + * - PIECE: the "piece" part of a "piecewise" statement; + * - OTHERWISE: the "otherwise" part of a "piecewise" statement; + * - Token elements: + * - CI: an identifier (i.e. the name of a model variable); + * - CN: a number; + * - Qualifier elements: + * - DEGREE: the degree of a root operator (it is only used when its + * value is not 2); + * - LOGBASE: the base with respect to which the logarithm is taken; + * - BVAR: the bound variable of a differential equation; + * - Constants: + * - TRUE: the "true" boolean; + * - FALSE: the "false" boolean; + * - E: Euler's number; + * - PI: the Ï€ constant; + * - INF: the infinity value; or + * - NAN: the not-a-number value. + */ + enum class Type + { + // Assignment. + + ASSIGNMENT, + + // Relational and logical operators. + + EQ, + NEQ, + LT, + LEQ, + GT, + GEQ, + AND, + OR, + XOR, + NOT, + + // Arithmetic operators. + + PLUS, + MINUS, + TIMES, + DIVIDE, + POWER, + ROOT, + ABS, + EXP, + LN, + LOG, + CEILING, + FLOOR, + MIN, + MAX, + REM, + + // Calculus elements. + + DIFF, + + // Trigonometric operators. + + SIN, + COS, + TAN, + SEC, + CSC, + COT, + SINH, + COSH, + TANH, + SECH, + CSCH, + COTH, + ASIN, + ACOS, + ATAN, + ASEC, + ACSC, + ACOT, + ASINH, + ACOSH, + ATANH, + ASECH, + ACSCH, + ACOTH, + + // Piecewise statement. + + PIECEWISE, + PIECE, + OTHERWISE, + + // Token elements. + + CI, + CN, + + // Qualifier elements. + + DEGREE, + LOGBASE, + BVAR, + + // Constants. + + TRUE, + FALSE, + E, + PI, + INF, + NAN + }; + + ~AnalyserEquationAst(); /**< Destructor */ + AnalyserEquationAst(const AnalyserEquationAst &rhs) = delete; /**< Copy constructor */ + AnalyserEquationAst(AnalyserEquationAst &&rhs) noexcept = delete; /**< Move constructor */ + AnalyserEquationAst &operator=(AnalyserEquationAst rhs) = delete; /**< Assignment operator */ + + /** + * @brief Create an @c AnalyserEquationAst object. + * + * Factory method to create an @c AnalyserEquationAst. Create a blank + * equation AST with:: + * + * @code + * auto ast = libcellml::AnalyserEquationAst::create(); + * @endcode + * + * @return A smart pointer to an @c AnalyserEquationAst object. + */ + static AnalyserEquationAstPtr create() noexcept; + + /** + * @brief Get the @c Type of this @c AnalyserEquationAst. + * + * Return the @c Type of this @c AnalyserEquationAst. + * + * @return The @c Type. + */ + Type type() const; + + /** + * @brief Set the type of this @c AnalyserEquationAst. + * + * Set the type of this @c AnalyserEquationAst. + * + * @param parent The @c AnalyserEquationAst to be set as the type of this + * @c AnalyserEquationAst. + */ + void setType(Type type); + + /** + * @brief Get the value for this @c AnalyserEquationAst. + * + * Return the value for this @c AnalyserEquationAst. + * + * @return The value. + */ + std::string value() const; + + /** + * @brief Set the value for this @c AnalyserEquationAst. + * + * Set the value for this @c AnalyserEquationAst. + * + * @param value The @c std::string to be set as the value for this + * @c AnalyserEquationAst. + */ + void setValue(const std::string &value); + + /** + * @brief Get the @c Variable for this @c AnalyserEquationAst. + * + * Return the @c Variable for this @c AnalyserEquationAst. + * + * @return The variable. + */ + VariablePtr variable() const; + + /** + * @brief Set the @c Variable for this @c AnalyserEquationAst. + * + * Set the @c Variable for this @c AnalyserEquationAst. + * + * @param variable The @c Variable to be set as the variable for this + * @c AnalyserEquationAst. + */ + void setVariable(const VariablePtr &variable); + + /** + * @brief Get the parent of this @c AnalyserEquationAst. + * + * Return the parent of this @c AnalyserEquationAst. + * + * @return The parent. + */ + AnalyserEquationAstPtr parent() const; + + /** + * @brief Set the parent of this @c AnalyserEquationAst. + * + * Set the parent of this @c AnalyserEquationAst. + * + * @param parent The @c AnalyserEquationAst to be set as the parent of this + * @c AnalyserEquationAst. + */ + void setParent(const AnalyserEquationAstPtr &parent); + + /** + * @brief Get the left child for this @c AnalyserEquationAst. + * + * Return the left child of this @c AnalyserEquationAst. + * + * @return The left child. + */ + AnalyserEquationAstPtr leftChild() const; + + /** + * @brief Set the left child of this @c AnalyserEquationAst. + * + * Set the left child of this @c AnalyserEquationAst. + * + * @param leftChild The @c AnalyserEquationAst to be set as the left child + * of this @c AnalyserEquationAst. + */ + void setLeftChild(const AnalyserEquationAstPtr &leftChild); + + /** + * @brief Get the right child for this @c AnalyserEquationAst. + * + * Return the right child of this @c AnalyserEquationAst. + * + * @return The right child. + */ + AnalyserEquationAstPtr rightChild() const; + + /** + * @brief Set the right child of this @c AnalyserEquationAst. + * + * Set the right child of this @c AnalyserEquationAst. + * + * @param rightChild The @c AnalyserEquationAst to be set as the right child + * of this @c AnalyserEquationAst. + */ + void setRightChild(const AnalyserEquationAstPtr &rightChild); + +private: + AnalyserEquationAst(); /**< Constructor */ + + struct AnalyserEquationAstImpl; + AnalyserEquationAstImpl *mPimpl; +}; + +} // namespace libcellml diff --git a/src/api/libcellml/analysermodel.h b/src/api/libcellml/analysermodel.h new file mode 100644 index 0000000000..a65798e2e8 --- /dev/null +++ b/src/api/libcellml/analysermodel.h @@ -0,0 +1,471 @@ +/* +Copyright libCellML Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#pragma once + +#include "libcellml/analyser.h" + +namespace libcellml { + +/** + * @brief The AnalyserModel class. + * + * The AnalyserModel class is for representing a model in the context of a + * CellML Analyser. + */ +class LIBCELLML_EXPORT AnalyserModel +{ + friend class Analyser; + +public: + /** + * @brief The type of a model. + * + * A model can be of one of the following types: + * - UNKNOWN: the type of the model is unknown; + * - ALGEBRAIC: the model defines a system of algebraic equations; + * - ODE: the model defines a system of ordinary differential equations; + * - INVALID: the model is invalid; + * - UNDERCONSTRAINED: the model is underconstrainted; + * - OVERCONSTRAINED: the model is overconstrained; or + * - UNSUITABLY_CONSTRAINED: the model is unsuitably constrained. + */ + enum class Type + { + UNKNOWN, + ALGEBRAIC, + ODE, + INVALID, + UNDERCONSTRAINED, + OVERCONSTRAINED, + UNSUITABLY_CONSTRAINED + }; + + ~AnalyserModel(); /**< Destructor */ + AnalyserModel(const AnalyserModel &rhs) = delete; /**< Copy constructor */ + AnalyserModel(AnalyserModel &&rhs) noexcept = delete; /**< Move constructor */ + AnalyserModel &operator=(AnalyserModel rhs) = delete; /**< Assignment operator */ + + /** + * @brief Test to determine if @c AnalyserModel is a valid model. + * + * Test to determine if @c AnalyserModel is a valid model, return @c true if + * it is a valid model (i.e. either an algebraic or an ODE model) and + * @c false otherwise. + * + * @return @c true if @c AnalyserModel is a valid model, @c false otherwise. + */ + bool isValid() const; + + /** + * @brief Get the @c Type of the @c AnalyserModel. + * + * Return the @c Type of the @c AnalyserModel. + * + * @return The @c Type. + */ + Type type() const; + + /** + * @brief Get the @c Variable of integration. + * + * Return the @c Variable of integration of the @c AnalyserModel, in the + * case of an ODE model, @c nullptr otherwise. + * + * @return The @c Variable of integration, if an ODE model, @c nullptr + * otherwise. + */ + AnalyserVariablePtr voi() const; + + /** + * @brief Get the number of states. + * + * Return the number of states in the @c AnalyserModel. + * + * @return The number of states. + */ + size_t stateCount() const; + + /** + * @brief Get the states. + * + * Return the states in the @c AnalyserModel. + * + * @return The states as a @c std::vector. + */ + std::vector states() const; + + /** + * @brief Get the state at @p index. + * + * Return the state at the index @p index for the @c AnalyserModel. + * + * @param index The index of the state to return. + * + * @return The state at the given @p index on success, @c nullptr on + * failure. + */ + AnalyserVariablePtr state(size_t index) const; + + /** + * @brief Get the number of variables. + * + * Return the number of variables in the @c AnalyserModel. + * + * @return The number of variables. + */ + size_t variableCount() const; + + /** + * @brief Get the variables. + * + * Return the variables in the @c AnalyserModel. + * + * @return The variables as a @c std::vector. + */ + std::vector variables() const; + + /** + * @brief Get the variable at @p index. + * + * Return the variable at the index @p index for the @c AnalyserModel. + * + * @param index The index of the variable to return. + * + * @return The variable at the given @p index on success, @c nullptr on + * failure. + */ + AnalyserVariablePtr variable(size_t index) const; + + /** + * @brief Get the number of equations. + * + * Return the number of equations in the @c AnalyserModel. + * + * @return The number of equations. + */ + size_t equationCount() const; + + /** + * @brief Get the equations. + * + * Return the equations in the @c AnalyserModel. + * + * @return The equations as a @c std::vector. + */ + std::vector equations() const; + + /** + * @brief Get the equation at @p index. + * + * Return the equation at the index @p index for the @c AnalyserModel. + * + * @param index The index of the equation to return. + * + * @return The equation at the given @p index on success, @c nullptr on + * failure. + */ + AnalyserEquationPtr equation(size_t index) const; + + /** + * @brief Test to determine if @c AnalyserModel needs an "equal to" + * function. + * + * Test to determine if @c AnalyserModel needs an "equal to" function, + * return @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs an "equal to" function, + * @c false otherwise. + */ + bool needEqFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs a "not equal to" + * function. + * + * Test to determine if @c AnalyserModel needs a "not equal to" function, + * return @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs a "not equal to" function, + * @c false otherwise. + */ + bool needNeqFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs a "less than" + * function. + * + * Test to determine if @c AnalyserModel needs a "less than" function, + * return @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs a "less than" function, + * @c false otherwise. + */ + bool needLtFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs a "less than or equal + * to" function. + * + * Test to determine if @c AnalyserModel needs a "less than or equal to" + * function, return @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs a "less than or equal to" + * function, @c false otherwise. + */ + bool needLeqFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs a "greater than" + * function. + * + * Test to determine if @c AnalyserModel needs a "greater than" function, + * return @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs a "greater than" function, + * @c false otherwise. + */ + bool needGtFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs a "greater than or + * equal to" function. + * + * Test to determine if @c AnalyserModel needs a "greater than or equal to" + * function, return @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs a "greater than or equal to" + * function, @c false otherwise. + */ + bool needGeqFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs an "and" function. + * + * Test to determine if @c AnalyserModel needs an "and" function, return + * @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs an "and" function, @c false + * otherwise. + */ + bool needAndFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs an "or" function. + * + * Test to determine if @c AnalyserModel needs an "or" function, return + * @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs an "or" function, @c false + * otherwise. + */ + bool needOrFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs a "exclusive or" + * function. + * + * Test to determine if @c AnalyserModel needs a "exclusive or" function, + * return @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs a "exclusive or" function, + * @c false otherwise. + */ + bool needXorFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs a "not" function. + * + * Test to determine if @c AnalyserModel needs a "not" function, return + * @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs a "not" function, @c false + * otherwise. + */ + bool needNotFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs a "minimum" function. + * + * Test to determine if @c AnalyserModel needs a "minimum" function, return + * @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs a "minimum" function, @c false + * otherwise. + */ + bool needMinFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs a "maximum" function. + * + * Test to determine if @c AnalyserModel needs a "maximum" function, return + * @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs a "maximum" function, @c false + * otherwise. + */ + bool needMaxFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs a "secant" function. + * + * Test to determine if @c AnalyserModel needs a "secant" function, return + * @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs a "secant" function, @c false + * otherwise. + */ + bool needSecFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs a "cosecant" function. + * + * Test to determine if @c AnalyserModel needs a "cosecant" function, return + * @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs a "cosecant" function, @c false + * otherwise. + */ + bool needCscFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs a "cotangent" + * function. + * + * Test to determine if @c AnalyserModel needs a "cotangent" function, + * return @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs a "cotangent" function, + * @c false otherwise. + */ + bool needCotFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs a "hyperbolic secant" + * function. + * + * Test to determine if @c AnalyserModel needs a "hyperbolic secant" + * function, return @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs a "hyperbolic secant" function, + * @c false otherwise. + */ + bool needSechFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs a "hyperbolic + * cosecant" function. + * + * Test to determine if @c AnalyserModel needs a "hyperbolic cosecant" + * function, return @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs a "hyperbolic cosecant" + * function, @c false otherwise. + */ + bool needCschFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs a "hyperbolic + * cotangent" function. + * + * Test to determine if @c AnalyserModel needs a "hyperbolic cotangent" + * function, return @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs a "hyperbolic cotangent" + * function, @c false otherwise. + */ + bool needCothFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs an "arc secant" + * function. + * + * Test to determine if @c AnalyserModel needs an "arc secant" function, + * return @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs an "arc secant" function, + * @c false otherwise. + */ + bool needAsecFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs an "arc cosecant" + * function. + * + * Test to determine if @c AnalyserModel needs an "arc cosecant" function, + * return @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs an "arc cosecant" function, + * @c false otherwise. + */ + bool needAcscFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs an "arc cotangent" + * function. + * + * Test to determine if @c AnalyserModel needs an "arc cotangent" function, + * return @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs an "arc cotangent" function, + * @c false otherwise. + */ + bool needAcotFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs an "arc hyperbolic + * secant" function. + * + * Test to determine if @c AnalyserModel needs an "arc hyperbolic secant" + * function, return @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs an "arc hyperbolic secant" + * function, @c false otherwise. + */ + bool needAsechFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs an "arc hyperbolic + * cosecant" function. + * + * Test to determine if @c AnalyserModel needs an "arc hyperbolic cosecant" + * function, return @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs an "arc hyperbolic cosecant" + * function, @c false otherwise. + */ + bool needAcschFunction() const; + + /** + * @brief Test to determine if @c AnalyserModel needs an "arc hyperbolic + * cotangent" function. + * + * Test to determine if @c AnalyserModel needs an "arc hyperbolic + * cotangent" function, return @c true if it does and @c false otherwise. + * + * @return @c true if @c AnalyserModel needs an "arc hyperbolic cotangent" + * function, @c false otherwise. + */ + bool needAcothFunction() const; + +private: + AnalyserModel(); /**< Constructor */ + + struct AnalyserModelImpl; + AnalyserModelImpl *mPimpl; +}; + +} // namespace libcellml diff --git a/src/api/libcellml/analyservariable.h b/src/api/libcellml/analyservariable.h new file mode 100644 index 0000000000..c099ccd434 --- /dev/null +++ b/src/api/libcellml/analyservariable.h @@ -0,0 +1,131 @@ +/* +Copyright libCellML Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#pragma once + +#include "libcellml/analyser.h" + +namespace libcellml { + +/** + * @brief The AnalyserVariable class. + * + * The AnalyserVariable class is for representing a variable in the context of a + * CellML Analyser, i.e. a constant, a computed constant or an algebraic + * variable. + */ +class LIBCELLML_EXPORT AnalyserVariable +{ + friend class Analyser; + +public: + /** + * @brief The type of a variable. + * + * A variable can be of one of the following types: + * - VARIABLE_OF_INTEGRATION: the variable is the variable of integration; + * - STATE: the variable is a state; + * - CONSTANT: the variable is a constant (e.g. x = 3); + * - COMPUTED_CONSTANT: the variable is a computed constant (e.g. x = 3+5, + * x = 3+z, x = y+z where y and z are constants); or + * - ALGEBRAIC: the variable is an algebraic variable. + */ + enum class Type + { + VARIABLE_OF_INTEGRATION, + STATE, + CONSTANT, + COMPUTED_CONSTANT, + ALGEBRAIC + }; + + ~AnalyserVariable(); /**< Destructor */ + AnalyserVariable(const AnalyserVariable &rhs) = delete; /**< Copy constructor */ + AnalyserVariable(AnalyserVariable &&rhs) noexcept = delete; /**< Move constructor */ + AnalyserVariable &operator=(AnalyserVariable rhs) = delete; /**< Assignment operator */ + + /** + * @brief Get the @c Type of this @c AnalyserVariable. + * + * Return the @c Type of this @c AnalyserVariable. + * + * @return The @c Type. + */ + Type type() const; + + /** + * @brief Get the index of this @c AnalyserVariable. + * + * Return the index of this @c AnalyserVariable. + * + * @return The index. + */ + size_t index() const; + + /** + * @brief Get the initialising @c Variable for this @c AnalyserVariable. + * + * Return the initialising @c Variable for this @c AnalyserVariable. It is + * used to retrieve the initial value of the @c Variable, if there is one. + * It may or may not be the same @c Variable as the one returned by + * @sa variable. If it is not the same (e.g., a state variable is + * initialised in one component and computed in another) then the initial + * value retrieved from this variable may have to be scaled to account for + * the variables' units not being equivalent (e.g., a variable is expressed + * in millivolts and its connected variable is expressed in volts, so the + * initial value will have to be multiplied or divided by 1000). + * + * @sa variable + * @sa scalingFactor + * + * @return The initialising @c Variable, if there is one, or @c nullptr. + */ + VariablePtr initialisingVariable() const; + + /** + * @brief Get the @c Variable for this @c AnalyserVariable. + * + * Return the @c Variable for this @c AnalyserVariable. Its @c Component is + * the one in which the @c Variable is first defined (in the case of the + * variable of integration), initialised (in the case of a constant) or + * computed (in the case of a state, computed constant or algebraic + * variable). It may or may not be the same @c Variable as the one returned + * by @sa initialisingVariable (e.g., a state variable is initialised in one + * component and computed in another). + * + * @sa initialisingVariable + * + * @return The @c Variable. + */ + VariablePtr variable() const; + + /** + * @brief Get the @c AnalyserEquation for this @c AnalyserVariable. + * + * Return the @c AnalyserEquation for this @c AnalyserVariable. + * + * @return The @c AnalyserEquation. + */ + AnalyserEquationPtr equation() const; + +private: + AnalyserVariable(); /**< Constructor */ + + struct AnalyserVariableImpl; + AnalyserVariableImpl *mPimpl; +}; + +} // namespace libcellml diff --git a/src/api/libcellml/generator.h b/src/api/libcellml/generator.h index 4bede80aa8..b600cba139 100644 --- a/src/api/libcellml/generator.h +++ b/src/api/libcellml/generator.h @@ -18,123 +18,20 @@ limitations under the License. #include -#include "libcellml/logger.h" +#include "libcellml/exportdefinitions.h" +#include "libcellml/types.h" namespace libcellml { -class Generator; - -/** - * @brief The GeneratorVariable class. - * - * The GeneratorVariable class is for representing a variable in the context - * of a CellML Generator, i.e. a constant, a computed constant or an algebraic - * variable. - */ -class LIBCELLML_EXPORT GeneratorVariable -{ - friend class Generator; - -public: - enum class Type - { - VARIABLE_OF_INTEGRATION, - STATE, - CONSTANT, - COMPUTED_CONSTANT, - ALGEBRAIC - }; - - ~GeneratorVariable(); /**< Destructor */ - GeneratorVariable(const GeneratorVariable &rhs) = delete; /**< Copy constructor */ - GeneratorVariable(GeneratorVariable &&rhs) noexcept = delete; /**< Move constructor */ - GeneratorVariable &operator=(GeneratorVariable rhs) = delete; /**< Assignment operator */ - - /** - * @brief Create a @c GeneratorVariable object. - * - * Factory method to create a @c GeneratorVariable. Create a - * generator variable with:: - * - * GeneratorVariablePtr generatorVariable = libcellml::GeneratorVariable::create(); - * - * @return A smart pointer to a @c GeneratorVariable object. - */ - static GeneratorVariablePtr create() noexcept; - - /** - * @brief Get the initialising @c Variable for this @c GeneratorVariable. - * - * Return the initialising @c Variable of this @c GeneratorVariable. It is - * used to retrieve the initial value of the @c Variable, if there is one. - * It may or may not be the same @c Variable as the one returned by - * @sa variable. If it is not the same (e.g., a state variable is - * initialised in one component and computed in another) then the initial - * value retrieved from this variable may have to be scaled to account for - * the variables' units not being equivalent (e.g., a variable is expressed - * in millivolts and its connected variable is expressed in volts, so the - * initial value will have to be multiplied or divided by 1000). - * - * @sa variable - * @sa scalingFactor - * - * @return The initialising @c Variable, if there is one, or @c nullptr. - */ - VariablePtr initialisingVariable() const; - - /** - * @brief Get the @c Variable for this @c GeneratorVariable. - * - * Return the @c Variable of this @c GeneratorVariable. Its @c Component is - * the one in which the @c Variable is first defined (in the case of the - * variable of integration), initialised (in the case of a constant) or - * computed (in the case of a state, computed constant or algebraic - * variable). It may or may not be the same @c Variable as the one returned - * by @sa initialisingVariable (e.g., a state variable is initialised in one - * component and computed in another). - * - * @sa initialisingVariable - * - * @return The @c Variable. - */ - VariablePtr variable() const; - - /** - * @brief Get the @c Type for this @c GeneratorVariable. - * - * Return the @c Type of this @c GeneratorVariable. - * - * @return The @c Type. - */ - GeneratorVariable::Type type() const; - -private: - GeneratorVariable(); /**< Constructor */ - - struct GeneratorVariableImpl; - GeneratorVariableImpl *mPimpl; -}; - /** * @brief The Generator class. * * The Generator class is for representing a CellML Generator. */ -class LIBCELLML_EXPORT Generator: public Logger +class LIBCELLML_EXPORT Generator { public: - enum class ModelType - { - UNKNOWN, - ALGEBRAIC, - ODE, - INVALID, - UNDERCONSTRAINED, - OVERCONSTRAINED, - UNSUITABLY_CONSTRAINED - }; - - ~Generator() override; /**< Destructor */ + ~Generator(); /**< Destructor */ Generator(const Generator &rhs) = delete; /**< Copy constructor */ Generator(Generator &&rhs) noexcept = delete; /**< Move constructor */ Generator &operator=(Generator rhs) = delete; /**< Assignment operator */ @@ -142,10 +39,11 @@ class LIBCELLML_EXPORT Generator: public Logger /** * @brief Create a @c Generator object. * - * Factory method to create a @c Generator. Create a - * generator with:: + * Factory method to create a @c Generator. Create a generator with:: * - * GeneratorPtr generator = libcellml::Generator::create(); + * @code + * auto generator = libcellml::Generator::create(); + * @endcode * * @return A smart pointer to a @c Generator object. */ @@ -170,90 +68,40 @@ class LIBCELLML_EXPORT Generator: public Logger void setProfile(const GeneratorProfilePtr &profile); /** - * @brief Process the @c Model. - * - * Process the @c Model using this @c Generator. - * - * @param model The @c Model to process. - */ - void processModel(const ModelPtr &model); - - /** - * @brief Get the @c ModelType of the @c Model. - * - * Return the @c ModelType of the @c Model processed by this @c Generator. - * - * @return The @c ModelType. - */ - ModelType modelType() const; - - /** - * @brief Get the number of states in the @c Model. - * - * Return the number of states in the @c Model processed by this - * @c Generator. - * - * @return The number of states. - */ - size_t stateCount() const; - - /** - * @brief Get the number of variables in the @c Model. - * - * Return the number of variables in the @c Model processed by this - * @c Generator. - * - * @return The number of variables. - */ - size_t variableCount() const; - - /** - * @brief Get the variable of integration of the @c Model. - * - * Return the @c Variable of integration of the @c Model processed by this - * @c Generator. - * - * @return The @c Type. - */ - GeneratorVariablePtr voi() const; - - /** - * @brief Get the state at @p index. + * @brief Get the @c AnalyserModel. * - * Return the state at the index @p index for the @c Model processed by this - * @c Generator. + * Get the @c AnalyserModel used by this @c Generator. * - * @param index The index of the state to return. + * @return The @c AnalyserModel used. */ - GeneratorVariablePtr state(size_t index) const; + AnalyserModelPtr model(); /** - * @brief Get the variable at @p index. + * @brief Set the @c AnalyserModel. * - * Return the variable at the index @p index for the @c Model processed by - * this @c Generator. + * Set the @c AnalyserModel to be used by this @c Generator. * - * @param index The index of the variable to return. + * @param model The @c AnalyserModel to set. */ - GeneratorVariablePtr variable(size_t index) const; + void setModel(const AnalyserModelPtr &model); /** - * @brief Get the interface code for the @c Model. + * @brief Get the interface code for the @c AnalyserModel. * - * Return the interface code for the @c Model processed by this - * @c Generator, using its @c GeneratorProfile. + * Return the interface code for the @c AnalyserModel, using the + * @c GeneratorProfile. * - * @return The code. + * @return The interface code as a @c std::string. */ std::string interfaceCode() const; /** - * @brief Get the implementation code for the @c Model. + * @brief Get the implementation code for the @c AnalyserModel. * - * Return the implementation code for the @c Model processed by this - * @c Generator, using its @c GeneratorProfile. + * Return the implementation code for the @c AnalyserModel, using the + * @c GeneratorProfile. * - * @return The code. + * @return The implementation code as a @c std::string. */ std::string implementationCode() const; diff --git a/src/api/libcellml/generatorprofile.h b/src/api/libcellml/generatorprofile.h index e71d40909c..66478df39f 100644 --- a/src/api/libcellml/generatorprofile.h +++ b/src/api/libcellml/generatorprofile.h @@ -16,7 +16,6 @@ limitations under the License. #pragma once -#include #include #include "libcellml/exportdefinitions.h" @@ -32,6 +31,13 @@ namespace libcellml { class LIBCELLML_EXPORT GeneratorProfile { public: + /** + * @brief The type of a profile. + * + * A profile can be of one of the following types: + * - C: a profile that targets the C language; or + * - PYTHON: a profile that targets the Python language. + */ enum class Profile { C, @@ -105,1833 +111,2101 @@ class LIBCELLML_EXPORT GeneratorProfile // Assignment. /** - * @brief Get the @c std::string for the assignment operator. + * @brief Get the @c std::string representing the MathML "assignment" + * operator. * - * Return the @c std::string for the assignment operator. + * Return the @c std::string representing the MathML "assignment" operator. * - * @return The @c std::string for the assignment operator. + * @return The @c std::string representing the MathML "assignment" + * operator. */ std::string assignmentString() const; /** - * @brief Set the @c std::string for the assignment operator. + * @brief Set the @c std::string representing the MathML "assignment" + * operator. * - * Set this @c std::string for the assignment operator. + * Set the @c std::string representing the MathML "assignment" operator. * - * @param assignmentString The @c std::string to use for the assignment - * operator. + * @param assignmentString The @c std::string representing the MathML + * "assignment" operator. */ void setAssignmentString(const std::string &assignmentString); // Relational and logical operators. /** - * @brief Get the @c std::string for the equivalence operator. + * @brief Get the @c std::string representing the MathML "equal to" + * operator. * - * Return the @c std::string for the equivalence operator. + * Return the @c std::string representing the MathML "equal to" operator. * - * @return The @c std::string for the equivalence operator. + * @return The @c std::string representing the MathML "equal to" operator. */ std::string eqString() const; /** - * @brief Set the @c std::string for the equivalence operator. + * @brief Set the @c std::string representing the MathML "equal to" + * operator. * - * Set this @c std::string for the equivalence operator. + * Set the @c std::string representing the MathML "equal to" operator. * - * @param eqString The @c std::string to use for the equivalence operator. + * @param eqString The @c std::string representing the MathML "equal to" + * operator. */ void setEqString(const std::string &eqString); /** - * @brief Get the @c std::string for the nonequivalence operator. + * @brief Get the @c std::string representing the MathML "not equal to" + * operator. * - * Return the @c std::string for the nonequivalence operator. + * Return the @c std::string representing the MathML "not equal to" + * operator. * - * @return The @c std::string for the nonequivalence operator. + * @return The @c std::string representing the MathML "not equal to" + * operator. */ std::string neqString() const; /** - * @brief Set the @c std::string for the nonequivalence operator. + * @brief Set the @c std::string representing the MathML "not equal to" + * operator. * - * Set this @c std::string for the nonequivalence operator. + * Set the @c std::string representing the MathML "not equal to" operator. * - * @param neqString The @c std::string to use for the nonequivalence - * operator. + * @param neqString The @c std::string representing the MathML "not equal + * to" operator. */ void setNeqString(const std::string &neqString); /** - * @brief Get the @c std::string for the lower than operator. + * @brief Get the @c std::string representing the MathML "less than" + * operator. * - * Return the @c std::string for the lower than operator. + * Return the @c std::string representing the MathML "less than" operator. * - * @return The @c std::string for the lower than operator. + * @return The @c std::string representing the MathML "less than" operator. */ std::string ltString() const; /** - * @brief Set the @c std::string for the lower than operator. + * @brief Set the @c std::string representing the MathML "less than" + * operator. * - * Set this @c std::string for the lower than operator. + * Set the @c std::string representing the MathML "less than" operator. * - * @param ltString The @c std::string to use for the lower than operator. + * @param ltString The @c std::string representing the MathML "less than" + * operator. */ void setLtString(const std::string <String); /** - * @brief Get the @c std::string for the lower or equal than operator. + * @brief Get the @c std::string representing the MathML "less than or + * equal to" operator. * - * Return the @c std::string for the lower or equal than operator. + * Return the @c std::string representing the MathML "less than or equal + * to" operator. * - * @return The @c std::string for the lower or equal than operator. + * @return The @c std::string representing the MathML "less than or equal + * to" operator. */ std::string leqString() const; /** - * @brief Set the @c std::string for the lower or equal than operator. - * - * Set this @c std::string for the lower or equal than operator. + * @brief Set the @c std::string representing the MathML "less than or + * equal to" operator. * - * @param leqString The @c std::string to use for the lower or equal than + * Set the @c std::string representing the MathML "less than or equal to" * operator. + * + * @param leqString The @c std::string representing the MathML "less than or + * equal to" operator. */ void setLeqString(const std::string &leqString); /** - * @brief Get the @c std::string for the greater than operator. + * @brief Get the @c std::string representing the MathML "greater than" + * operator. * - * Return the @c std::string for the greater than operator. + * Return the @c std::string representing the MathML "greater than" + * operator. * - * @return The @c std::string for the greater than operator. + * @return The @c std::string representing the MathML "greater than" + * operator. */ std::string gtString() const; /** - * @brief Set the @c std::string for the greater than operator. + * @brief Set the @c std::string representing the MathML "greater than" + * operator. * - * Set this @c std::string for the greater than operator. + * Set the @c std::string representing the MathML "greater than" operator. * - * @param gtString The @c std::string to use for the greater than operator. + * @param gtString The @c std::string representing the MathML "greater than" + * operator. */ void setGtString(const std::string >String); /** - * @brief Get the @c std::string for the greater or equal than operator. + * @brief Get the @c std::string representing the MathML "greater than or + * equal to" operator. * - * Return the @c std::string for the greater or equal than operator. + * Return the @c std::string representing the MathML "greater than or equal + * to" operator. * - * @return The @c std::string for the greater or equal than operator. + * @return The @c std::string representing the MathML "greater than or + * equal to" operator. */ std::string geqString() const; /** - * @brief Set the @c std::string for the greater or equal than operator. - * - * Set this @c std::string for the greater or equal than operator. + * @brief Set the @c std::string representing the MathML "greater than or + * equal to" operator. * - * @param geqString The @c std::string to use for the greater or equal than + * Set the @c std::string representing the MathML "greater than or equal to" * operator. + * + * @param geqString The @c std::string representing the MathML "greater than + * or equal to" operator. */ void setGeqString(const std::string &geqString); /** - * @brief Get the @c std::string for the and operator. + * @brief Get the @c std::string representing the MathML "and" operator. * - * Return the @c std::string for the and operator. + * Return the @c std::string representing the MathML "and" operator. * - * @return The @c std::string for the and operator. + * @return The @c std::string representing the MathML "and" operator. */ std::string andString() const; /** - * @brief Set the @c std::string for the and operator. + * @brief Set the @c std::string representing the MathML "and" operator. * - * Set this @c std::string for the and operator. + * Set the @c std::string representing the MathML "and" operator. * - * @param andString The @c std::string to use for the and operator. + * @param andString The @c std::string representing the MathML "and" + * operator. */ void setAndString(const std::string &andString); /** - * @brief Get the @c std::string for the or operator. + * @brief Get the @c std::string representing the MathML "or" operator. * - * Return the @c std::string for the or operator. + * Return the @c std::string representing the MathML "or" operator. * - * @return The @c std::string for the or operator. + * @return The @c std::string representing the MathML "or" operator. */ std::string orString() const; /** - * @brief Set the @c std::string for the or operator. + * @brief Set the @c std::string representing the MathML "or" operator. * - * Set this @c std::string for the or operator. + * Set the @c std::string representing the MathML "or" operator. * - * @param orString The @c std::string to use for the or operator. + * @param orString The @c std::string representing the MathML "or" operator. */ void setOrString(const std::string &orString); /** - * @brief Get the @c std::string for the xor operator. + * @brief Get the @c std::string representing the MathML "exclusive or" + * operator. * - * Return the @c std::string for the xor operator. + * Return the @c std::string representing the MathML "exclusive or" + * operator. * - * @return The @c std::string for the xor operator. + * @return The @c std::string representing the MathML "exclusive or" + * operator. */ std::string xorString() const; /** - * @brief Set the @c std::string for the xor operator. + * @brief Set the @c std::string representing the MathML "exclusive or" + * operator. * - * Set this @c std::string for the xor operator. + * Set the @c std::string representing the MathML "exclusive or" operator. * - * @param xorString The @c std::string to use for the xor operator. + * @param xorString The @c std::string representing the MathML "exclusive + * or" operator. */ void setXorString(const std::string &xorString); /** - * @brief Get the @c std::string for the not operator. + * @brief Get the @c std::string representing the MathML "not" operator. * - * Return the @c std::string for the not operator. + * Return the @c std::string representing the MathML "not" operator. * - * @return The @c std::string for the not operator. + * @return The @c std::string representing the MathML "not" operator. */ std::string notString() const; /** - * @brief Set the @c std::string for the not operator. + * @brief Set the @c std::string representing the MathML "not" operator. * - * Set this @c std::string for the not operator. + * Set the @c std::string representing the MathML "not" operator. * - * @param notString The @c std::string to use for the not operator. + * @param notString The @c std::string representing the MathML "not" + * operator. */ void setNotString(const std::string ¬String); /** - * @brief Test if this @c GeneratorProfile has an equivalence operator. + * @brief Test if this @c GeneratorProfile has an "equal to" operator. * - * Test if this @c GeneratorProfile has an equivalence operator. + * Test if this @c GeneratorProfile has an "equal to" operator. * - * @return @c true if the @c GeneratorProfile has an equivalence operator, + * @return @c true if the @c GeneratorProfile has an "equal to" operator, * @c false otherwise. */ bool hasEqOperator() const; /** - * @brief Set whether this @c GeneratorProfile has an equivalence operator. + * @brief Set whether this @c GeneratorProfile has an "equal to" operator. * - * Set whether this @c GeneratorProfile has an equivalence operator. + * Set whether this @c GeneratorProfile has an "equal to" operator. * * @param hasEqOperator A @c bool to determine whether this - * @c GeneratorProfile has an equivalence operator. + * @c GeneratorProfile has an "equal to" operator. */ void setHasEqOperator(bool hasEqOperator); /** - * @brief Test if this @c GeneratorProfile has a nonequivalence operator. + * @brief Test if this @c GeneratorProfile has a "not equal to" operator. * - * Test if this @c GeneratorProfile has a nonequivalence operator. + * Test if this @c GeneratorProfile has a "not equal to" operator. * - * @return @c true if the @c GeneratorProfile has a nonequivalence operator, - * @c false otherwise. + * @return @c true if the @c GeneratorProfile has a "not equal to" + * operator, @c false otherwise. */ bool hasNeqOperator() const; /** - * @brief Set whether this @c GeneratorProfile has a nonequivalence operator. + * @brief Set whether this @c GeneratorProfile has a "not equal to" + * operator. * - * Set whether this @c GeneratorProfile has a nonequivalence operator. + * Set whether this @c GeneratorProfile has a "not equal to" operator. * * @param hasNeqOperator A @c bool to determine whether this - * @c GeneratorProfile has a nonequivalence operator. + * @c GeneratorProfile has a "not equal to" operator. */ void setHasNeqOperator(bool hasNeqOperator); /** - * @brief Test if this @c GeneratorProfile has a lower than operator. + * @brief Test if this @c GeneratorProfile has a "less than" operator. * - * Test if this @c GeneratorProfile has a lower than operator. + * Test if this @c GeneratorProfile has a "less than" operator. * - * @return @c true if the @c GeneratorProfile has a lower than operator, + * @return @c true if the @c GeneratorProfile has a "less than" operator, * @c false otherwise. */ bool hasLtOperator() const; /** - * @brief Set whether this @c GeneratorProfile has a lower than operator. + * @brief Set whether this @c GeneratorProfile has a "less than" operator. * - * Set whether this @c GeneratorProfile has a lower than operator. + * Set whether this @c GeneratorProfile has a "less than" operator. * * @param hasLtOperator A @c bool to determine whether this - * @c GeneratorProfile has a lower than operator. + * @c GeneratorProfile has a "less than" operator. */ void setHasLtOperator(bool hasLtOperator); /** - * @brief Test if this @c GeneratorProfile has a lower or equal than + * @brief Test if this @c GeneratorProfile has a "less than or equal to" * operator. * - * Test if this @c GeneratorProfile has a lower or equal than operator. + * Test if this @c GeneratorProfile has a "less than or equal to" operator. * - * @return @c true if the @c GeneratorProfile has a lower or equal than + * @return @c true if the @c GeneratorProfile has a "less than or equal to" * operator, * @c false otherwise. */ bool hasLeqOperator() const; /** - * @brief Set whether this @c GeneratorProfile has a lower or equal than + * @brief Set whether this @c GeneratorProfile has a "less than or equal to" * operator. * - * Set whether this @c GeneratorProfile has a lower or equal than operator. + * Set whether this @c GeneratorProfile has a "less than or equal to" + * operator. * * @param hasLeqOperator A @c bool to determine whether this - * @c GeneratorProfile has a lower or equal than operator. + * @c GeneratorProfile has a "less than or equal to" operator. */ void setHasLeqOperator(bool hasLeqOperator); /** - * @brief Test if this @c GeneratorProfile has a greater than operator. + * @brief Test if this @c GeneratorProfile has a "greater than" operator. * - * Test if this @c GeneratorProfile has a greater than operator. + * Test if this @c GeneratorProfile has a "greater than" operator. * - * @return @c true if the @c GeneratorProfile has a greater than operator, + * @return @c true if the @c GeneratorProfile has a "greater than" operator, * @c false otherwise. */ bool hasGtOperator() const; /** - * @brief Set whether this @c GeneratorProfile has a greater than operator. + * @brief Set whether this @c GeneratorProfile has a "greater than" + * operator. * - * Set whether this @c GeneratorProfile has a greater than operator. + * Set whether this @c GeneratorProfile has a "greater than" operator. * * @param hasGtOperator A @c bool to determine whether this - * @c GeneratorProfile has a greater than operator. + * @c GeneratorProfile has a "greater than" operator. */ void setHasGtOperator(bool hasGtOperator); /** - * @brief Test if this @c GeneratorProfile has a greater or equal than + * @brief Test if this @c GeneratorProfile has a "greater than or equal to" * operator. * - * Test if this @c GeneratorProfile has a greater or equal than operator. + * Test if this @c GeneratorProfile has a "greater than or equal to" operator. * - * @return @c true if the @c GeneratorProfile has a greater or equal than - * operator, + * @return @c true if the @c GeneratorProfile has a "greater than or equal + * to" operator, * @c false otherwise. */ bool hasGeqOperator() const; /** - * @brief Set whether this @c GeneratorProfile has a greater or equal than - * operator. + * @brief Set whether this @c GeneratorProfile has a "greater than or equal + * to" operator. * - * Set whether this @c GeneratorProfile has a greater or equal than + * Set whether this @c GeneratorProfile has a "greater than or equal to" * operator. * * @param hasGeqOperator A @c bool to determine whether this - * @c GeneratorProfile has a greater or equal than operator. + * @c GeneratorProfile has a "greater than or equal to" operator. */ void setHasGeqOperator(bool hasGeqOperator); /** - * @brief Test if this @c GeneratorProfile has an and operator. + * @brief Test if this @c GeneratorProfile has an "and" operator. * - * Test if this @c GeneratorProfile has an and operator. + * Test if this @c GeneratorProfile has an "and" operator. * - * @return @c true if the @c GeneratorProfile has an and operator, + * @return @c true if the @c GeneratorProfile has an "and" operator, * @c false otherwise. */ bool hasAndOperator() const; /** - * @brief Set whether this @c GeneratorProfile has an and operator. + * @brief Set whether this @c GeneratorProfile has an "and" operator. * - * Set whether this @c GeneratorProfile has an and operator. + * Set whether this @c GeneratorProfile has an "and" operator. * * @param hasAndOperator A @c bool to determine whether this - * @c GeneratorProfile has an and operator. + * @c GeneratorProfile has an "and" operator. */ void setHasAndOperator(bool hasAndOperator); /** - * @brief Test if this @c GeneratorProfile has an or operator. + * @brief Test if this @c GeneratorProfile has an "or" operator. * - * Test if this @c GeneratorProfile has an or operator. + * Test if this @c GeneratorProfile has an "or" operator. * - * @return @c true if the @c GeneratorProfile has an or operator, + * @return @c true if the @c GeneratorProfile has an "or" operator, * @c false otherwise. */ bool hasOrOperator() const; /** - * @brief Set whether this @c GeneratorProfile has an or operator. + * @brief Set whether this @c GeneratorProfile has an "or" operator. * - * Set whether this @c GeneratorProfile has an or operator. + * Set whether this @c GeneratorProfile has an "or" operator. * * @param hasOrOperator A @c bool to determine whether this - * @c GeneratorProfile has an or operator. + * @c GeneratorProfile has an "or" operator. */ void setHasOrOperator(bool hasOrOperator); /** - * @brief Test if this @c GeneratorProfile has a xor operator. + * @brief Test if this @c GeneratorProfile has a "exclusive or" operator. * - * Test if this @c GeneratorProfile has a xor operator. + * Test if this @c GeneratorProfile has a "exclusive or" operator. * - * @return @c true if the @c GeneratorProfile has a xor operator, + * @return @c true if the @c GeneratorProfile has a "exclusive or" operator, * @c false otherwise. */ bool hasXorOperator() const; /** - * @brief Set whether this @c GeneratorProfile has a xor operator. + * @brief Set whether this @c GeneratorProfile has a "exclusive or" + * operator. * - * Set whether this @c GeneratorProfile has a xor operator. + * Set whether this @c GeneratorProfile has a "exclusive or" operator. * * @param hasXorOperator A @c bool to determine whether this - * @c GeneratorProfile has a xor operator. + * @c GeneratorProfile has a "exclusive or" operator. */ void setHasXorOperator(bool hasXorOperator); /** - * @brief Test if this @c GeneratorProfile has a not operator. + * @brief Test if this @c GeneratorProfile has a "not" operator. * - * Test if this @c GeneratorProfile has a not operator. + * Test if this @c GeneratorProfile has a "not" operator. * - * @return @c true if the @c GeneratorProfile has a not operator, + * @return @c true if the @c GeneratorProfile has a "not" operator, * @c false otherwise. */ bool hasNotOperator() const; /** - * @brief Set whether this @c GeneratorProfile has a not operator. + * @brief Set whether this @c GeneratorProfile has a "not" operator. * - * Set whether this @c GeneratorProfile has a not operator. + * Set whether this @c GeneratorProfile has a "not" operator. * * @param hasNotOperator A @c bool to determine whether this - * @c GeneratorProfile has a not operator. + * @c GeneratorProfile has a "not" operator. */ void setHasNotOperator(bool hasNotOperator); // Arithmetic operators. /** - * @brief Get the @c std::string for an addition. + * @brief Get the @c std::string representing the MathML "plus" operator. * - * Return the @c std::string for an addition. + * Return the @c std::string representing the MathML "plus" operator. * - * @return The @c std::string for an addition. + * @return The @c std::string representing the MathML "plus" operator. */ std::string plusString() const; /** - * @brief Set the @c std::string for an addition. + * @brief Set the @c std::string representing the MathML "plus" operator. * - * Set this @c std::string for an addition. + * Set the @c std::string representing the MathML "plus" operator. * - * @param plusString The @c std::string to use for an addition. + * @param plusString The @c std::string representing the MathML "plus" + * operator. */ void setPlusString(const std::string &plusString); /** - * @brief Get the @c std::string for a subtraction. + * @brief Get the @c std::string representing the MathML "minus" operator. * - * Return the @c std::string for a subtraction. + * Return the @c std::string representing the MathML "minus" operator. * - * @return The @c std::string for a subtraction. + * @return The @c std::string representing the MathML "minus" operator. */ std::string minusString() const; /** - * @brief Set the @c std::string for a subtraction. + * @brief Set the @c std::string representing the MathML "minus" operator. * - * Set this @c std::string for a subtraction. + * Set the @c std::string representing the MathML "minus" operator. * - * @param minusString The @c std::string to use for a subtraction. + * @param minusString The @c std::string representing the MathML "minus" + * operator. */ void setMinusString(const std::string &minusString); /** - * @brief Get the @c std::string for a multiplication. + * @brief Get the @c std::string representing the MathML "times" operator. * - * Return the @c std::string for a multiplication. + * Return the @c std::string representing the MathML "times" operator. * - * @return The @c std::string for a multiplication. + * @return The @c std::string representing the MathML "times" operator. */ std::string timesString() const; /** - * @brief Set the @c std::string for a multiplication. + * @brief Set the @c std::string representing the MathML "times" operator. * - * Set this @c std::string for a multiplication. + * Set the @c std::string representing the MathML "times" operator. * - * @param timesString The @c std::string to use for a multiplication. + * @param timesString The @c std::string representing the MathML "times" + * operator. */ void setTimesString(const std::string ×String); /** - * @brief Get the @c std::string for a division. + * @brief Get the @c std::string representing the MathML "divide" operator. * - * Return the @c std::string for a division. + * Return the @c std::string representing the MathML "divide" operator. * - * @return The @c std::string for a division. + * @return The @c std::string representing the MathML "divide" operator. */ std::string divideString() const; /** - * @brief Set the @c std::string for a division. + * @brief Set the @c std::string representing the MathML "divide" operator. * - * Set this @c std::string for a division. + * Set the @c std::string representing the MathML "divide" operator. * - * @param divideString The @c std::string to use for a division. + * @param divideString The @c std::string representing the MathML "divide" + * operator. */ void setDivideString(const std::string ÷String); /** - * @brief Get the @c std::string for a power. + * @brief Get the @c std::string representing the MathML "power" operator or + * function. * - * Return the @c std::string for a power. + * Return the @c std::string representing the MathML "power" operator or + * function. * - * @return The @c std::string for a power. + * @return The @c std::string representing the MathML "power" operator or + * function. */ std::string powerString() const; /** - * @brief Set the @c std::string for a power. + * @brief Set the @c std::string representing the MathML "power" operator or + * function. * - * Set this @c std::string for a power. + * Set the @c std::string representing the MathML "power" operator or + * function. * - * @param powerString The @c std::string to use for a power. + * @param powerString The @c std::string representing the MathML "power" + * operator or function. */ void setPowerString(const std::string &powerString); /** - * @brief Get the @c std::string for a square root. + * @brief Get the @c std::string representing the MathML "square root" + * function. * - * Return the @c std::string for a square root. + * Return the @c std::string representing the MathML "square root" function. * - * @return The @c std::string for a square root. + * @return The @c std::string representing the MathML "square root" + * function. */ std::string squareRootString() const; /** - * @brief Set the @c std::string for a square root. + * @brief Set the @c std::string representing the MathML "square root" + * function. * - * Set this @c std::string for a square root. + * Set the @c std::string representing the MathML "square root" function. * - * @param squareRootString The @c std::string to use for a square root. + * @param squareRootString The @c std::string representing the MathML + * "square root" function. */ void setSquareRootString(const std::string &squareRootString); /** - * @brief Get the @c std::string for a square. + * @brief Get the @c std::string representing the MathML "square" function. * - * Return the @c std::string for a square. + * Return the @c std::string representing the MathML "square" function. * - * @return The @c std::string for a square. + * @return The @c std::string representing the MathML "square" function. */ std::string squareString() const; /** - * @brief Set the @c std::string for a square. + * @brief Set the @c std::string representing the MathML "square" function. * - * Set this @c std::string for a square. + * Set the @c std::string representing the MathML "square" function. * - * @param squareString The @c std::string to use for a square. + * @param squareString The @c std::string representing the MathML "square" + * function. */ void setSquareString(const std::string &squareString); /** - * @brief Get the @c std::string for an absolute value. + * @brief Get the @c std::string representing the MathML "absolute value" + * function. * - * Return the @c std::string for an absolute value. + * Return the @c std::string representing the MathML "absolute value" + * function. * - * @return The @c std::string for an absolute value. + * @return The @c std::string representing the MathML "absolute value" + * function. */ std::string absoluteValueString() const; /** - * @brief Set the @c std::string for an absolute value. + * @brief Set the @c std::string representing the MathML "absolute value" + * function. * - * Set this @c std::string for an absolute value. + * Set the @c std::string representing the MathML "absolute value" function. * - * @param absoluteValueString The @c std::string to use for an absolute - * value. + * @param absoluteValueString The @c std::string representing the MathML + * "absolute value" function. */ void setAbsoluteValueString(const std::string &absoluteValueString); /** - * @brief Get the @c std::string for an exponential. + * @brief Get the @c std::string representing the MathML "exponential" + * function. * - * Return the @c std::string for an exponential. + * Return the @c std::string representing the MathML "exponential" + * function. * - * @return The @c std::string for an exponential. + * @return The @c std::string representing the MathML "exponential" + * function. */ std::string exponentialString() const; /** - * @brief Set the @c std::string for an exponential. + * @brief Set the @c std::string representing the MathML "exponential" + * function. * - * Set this @c std::string for an exponential. + * Set the @c std::string representing the MathML "exponential" function. * - * @param exponentialString The @c std::string to use for an exponential. + * @param exponentialString The @c std::string representing the MathML + * "exponential" function. */ void setExponentialString(const std::string &exponentialString); /** - * @brief Get the @c std::string for a Napierian logarithm. + * @brief Get the @c std::string representing the MathML "natural logarithm" + * function. * - * Return the @c std::string for a Napierian logarithm. + * Return the @c std::string representing the MathML "natural logarithm" + * function. * - * @return The @c std::string for a Napierian logarithm. + * @return The @c std::string representing the MathML "natural logarithm" + * function. */ - std::string napierianLogarithmString() const; + std::string naturalLogarithmString() const; /** - * @brief Set the @c std::string for a Napierian logarithm. + * @brief Set the @c std::string representing the MathML "natural logarithm" + * function. * - * Set this @c std::string for a Napierian logarithm. + * Set the @c std::string representing the MathML "natural logarithm" + * function. * - * @param napierianLogarithmString The @c std::string to use for a Napierian - * logarithm. + * @param naturalLogarithmString The @c std::string representing the MathML + * "natural logarithm" function. */ - void setNapierianLogarithmString(const std::string &napierianLogarithmString); + void setNaturalLogarithmString(const std::string &naturalLogarithmString); /** - * @brief Get the @c std::string for a common logarithm. + * @brief Get the @c std::string representing the MathML "common logarithm" + * function. * - * Return the @c std::string for a common logarithm. + * Return the @c std::string representing the MathML "common logarithm" + * function. * - * @return The @c std::string for a common logarithm. + * @return The @c std::string representing the MathML "common logarithm" + * function. */ std::string commonLogarithmString() const; /** - * @brief Set the @c std::string for a common logarithm. + * @brief Set the @c std::string representing the MathML "common logarithm" + * function. * - * Set this @c std::string for a common logarithm. + * Set the @c std::string representing the MathML "common logarithm" + * function. * - * @param commonLogarithmString The @c std::string to use for a common - * logarithm. + * @param commonLogarithmString The @c std::string representing the MathML + * "common logarithm" function. */ void setCommonLogarithmString(const std::string &commonLogarithmString); /** - * @brief Get the @c std::string for a ceiling. + * @brief Get the @c std::string representing the MathML "ceiling" function. * - * Return the @c std::string for a ceiling. + * Return the @c std::string representing the MathML "ceiling" function. * - * @return The @c std::string for a ceiling. + * @return The @c std::string representing the MathML "ceiling" function. */ std::string ceilingString() const; /** - * @brief Set the @c std::string for a ceiling. + * @brief Set the @c std::string representing the MathML "ceiling" function. * - * Set this @c std::string for a ceiling. + * Set the @c std::string representing the MathML "ceiling" function. * - * @param ceilingString The @c std::string to use for a ceiling. + * @param ceilingString The @c std::string representing the MathML "ceiling" + * function. */ void setCeilingString(const std::string &ceilingString); /** - * @brief Get the @c std::string for a floor. + * @brief Get the @c std::string representing the MathML "floor" function. * - * Return the @c std::string for a floor. + * Return the @c std::string representing the MathML "floor" function. * - * @return The @c std::string for a floor. + * @return The @c std::string representing the MathML "floor" function. */ std::string floorString() const; /** - * @brief Set the @c std::string for a floor. + * @brief Set the @c std::string representing the MathML "floor" function. * - * Set this @c std::string for a floor. + * Set the @c std::string representing the MathML "floor" function. * - * @param floorString The @c std::string to use for a floor. + * @param floorString The @c std::string representing the MathML "floor" + * function. */ void setFloorString(const std::string &floorString); /** - * @brief Get the @c std::string for a minimum. + * @brief Get the @c std::string representing the MathML "minimum" function. * - * Return the @c std::string for a minimum. + * Return the @c std::string representing the MathML "minimum" function. * - * @return The @c std::string for a minimum. + * @return The @c std::string representing the MathML "minimum" function. */ std::string minString() const; /** - * @brief Set the @c std::string for a minimum. + * @brief Set the @c std::string representing the MathML "minimum" function. * - * Set this @c std::string for a minimum. + * Set the @c std::string representing the MathML "minimum" function. * - * @param minString The @c std::string to use for a minimum. + * @param minString The @c std::string representing the MathML "minimum" + * function. */ void setMinString(const std::string &minString); /** - * @brief Get the @c std::string for a maximum. + * @brief Get the @c std::string representing the MathML "maximum" function. * - * Return the @c std::string for a maximum. + * Return the @c std::string representing the MathML "maximum" function. * - * @return The @c std::string for a maximum. + * @return The @c std::string representing the MathML "maximum" function. */ std::string maxString() const; /** - * @brief Set the @c std::string for a maximum. + * @brief Set the @c std::string representing the MathML "maximum" function. * - * Set this @c std::string for a maximum. + * Set the @c std::string representing the MathML "maximum" function. * - * @param maxString The @c std::string to use for a maximum. + * @param maxString The @c std::string representing the MathML "maximum" + * function. */ void setMaxString(const std::string &maxString); /** - * @brief Get the @c std::string for a remainder. + * @brief Get the @c std::string representing the MathML "remainder" + * function. * - * Return the @c std::string for a remainder. + * Return the @c std::string representing the MathML "remainder" function. * - * @return The @c std::string for a remainder. + * @return The @c std::string representing the MathML "remainder" function. */ std::string remString() const; /** - * @brief Set the @c std::string for a remainder. + * @brief Set the @c std::string representing the MathML "remainder" + * function. * - * Set this @c std::string for a remainder. + * Set the @c std::string representing the MathML "remainder" function. * - * @param remString The @c std::string to use for a remainder. + * @param remString The @c std::string representing the MathML "remainder" + * function. */ void setRemString(const std::string &remString); /** - * @brief Test if this @c GeneratorProfile has a power operator. + * @brief Test if this @c GeneratorProfile has a "power" operator. * - * Test if this @c GeneratorProfile has a power operator. + * Test if this @c GeneratorProfile has a "power" operator. * - * @return @c true if the @c GeneratorProfile has a power operator, + * @return @c true if the @c GeneratorProfile has a "power" operator, * @c false otherwise. */ bool hasPowerOperator() const; /** - * @brief Set whether this @c GeneratorProfile has a power operator. + * @brief Set whether this @c GeneratorProfile has a "power" operator. * - * Set whether this @c GeneratorProfile has a power operator. + * Set whether this @c GeneratorProfile has a "power" operator. * * @param hasPowerOperator A @c bool to determine whether this - * @c GeneratorProfile has a power operator. + * @c GeneratorProfile has a "power" operator. */ void setHasPowerOperator(bool hasPowerOperator); // Trigonometric operators. /** - * @brief Get the @c std::string for sine. + * @brief Get the @c std::string representing the MathML "sine" function. * - * Return the @c std::string for sine. + * Return the @c std::string representing the MathML "sine" function. * - * @return The @c std::string for sine. + * @return The @c std::string representing the MathML "sine" function. */ std::string sinString() const; /** - * @brief Set the @c std::string for sine. + * @brief Set the @c std::string representing the MathML "sine" function. * - * Set this @c std::string for sine. + * Set the @c std::string representing the MathML "sine" function. * - * @param sinString The @c std::string to use for sine. + * @param sinString The @c std::string representing the MathML "sine" + * function. */ void setSinString(const std::string &sinString); /** - * @brief Get the @c std::string for cosine. + * @brief Get the @c std::string representing the MathML "cosine" function. * - * Return the @c std::string for cosine. + * Return the @c std::string representing the MathML "cosine" function. * - * @return The @c std::string for cosine. + * @return The @c std::string representing the MathML "cosine" function. */ std::string cosString() const; /** - * @brief Set the @c std::string for cosine. + * @brief Set the @c std::string representing the MathML "cosine" function. * - * Set this @c std::string for cosine. + * Set the @c std::string representing the MathML "cosine" function. * - * @param cosString The @c std::string to use for cosine. + * @param cosString The @c std::string representing the MathML "cosine" + * function. */ void setCosString(const std::string &cosString); /** - * @brief Get the @c std::string for tangent. + * @brief Get the @c std::string representing the MathML "tangent" function. * - * Return the @c std::string for tangent. + * Return the @c std::string representing the MathML "tangent" function. * - * @return The @c std::string for tangent. + * @return The @c std::string representing the MathML "tangent" function. */ std::string tanString() const; /** - * @brief Set the @c std::string for tangent. + * @brief Set the @c std::string representing the MathML "tangent" function. * - * Set this @c std::string for tangent. + * Set the @c std::string representing the MathML "tangent" function. * - * @param tanString The @c std::string to use for tangent. + * @param tanString The @c std::string representing the MathML "tangent" + * function. */ void setTanString(const std::string &tanString); /** - * @brief Get the @c std::string for secant. + * @brief Get the @c std::string representing the MathML "secant" function. * - * Return the @c std::string for secant. + * Return the @c std::string representing the MathML "secant" function. * - * @return The @c std::string for secant. + * @return The @c std::string representing the MathML "secant" function. */ std::string secString() const; /** - * @brief Set the @c std::string for secant. + * @brief Set the @c std::string representing the MathML "secant" function. * - * Set this @c std::string for secant. + * Set the @c std::string representing the MathML "secant" function. * - * @param secString The @c std::string to use for secant. + * @param secString The @c std::string representing the MathML "secant" + * function. */ void setSecString(const std::string &secString); /** - * @brief Get the @c std::string for cosecant. + * @brief Get the @c std::string representing the MathML "cosecant" + * function. * - * Return the @c std::string for cosecant. + * Return the @c std::string representing the MathML "cosecant" function. * - * @return The @c std::string for cosecant. + * @return The @c std::string representing the MathML "cosecant" function. */ std::string cscString() const; /** - * @brief Set the @c std::string for cosecant. + * @brief Set the @c std::string representing the MathML "cosecant" + * function. * - * Set this @c std::string for cosecant. + * Set the @c std::string representing the MathML "cosecant" function. * - * @param cscString The @c std::string to use for cosecant. + * @param cscString The @c std::string representing the MathML "cosecant" + * function. */ void setCscString(const std::string &cscString); /** - * @brief Get the @c std::string for cotangent. + * @brief Get the @c std::string representing the MathML "cotangent" + * function. * - * Return the @c std::string for cotangent. + * Return the @c std::string representing the MathML "cotangent" function. * - * @return The @c std::string for cotangent. + * @return The @c std::string representing the MathML "cotangent" function. */ std::string cotString() const; /** - * @brief Set the @c std::string for cotangent. + * @brief Set the @c std::string representing the MathML "cotangent" + * function. * - * Set this @c std::string for cotangent. + * Set the @c std::string representing the MathML "cotangent" function. * - * @param cotString The @c std::string to use for cotangent. + * @param cotString The @c std::string representing the MathML "cotangent" + * function. */ void setCotString(const std::string &cotString); /** - * @brief Get the @c std::string for hyperbolic sine. + * @brief Get the @c std::string representing the MathML "hyperbolic sine" + * function. * - * Return the @c std::string for hyperbolic sine. + * Return the @c std::string representing the MathML "hyperbolic sine" + * function. * - * @return The @c std::string for hyperbolic sine. + * @return The @c std::string representing the MathML "hyperbolic sine" + * function. */ std::string sinhString() const; /** - * @brief Set the @c std::string for hyperbolic sine. + * @brief Set the @c std::string representing the MathML "hyperbolic sine" + * function. * - * Set this @c std::string for hyperbolic sine. + * Set the @c std::string representing the MathML "hyperbolic sine" + * function. * - * @param sinhString The @c std::string to use for hyperbolic sine. + * @param sinhString The @c std::string representing the MathML "hyperbolic + * sine" function. */ void setSinhString(const std::string &sinhString); /** - * @brief Get the @c std::string for hyperbolic cosine. + * @brief Get the @c std::string representing the MathML "hyperbolic cosine" + * function. * - * Return the @c std::string for hyperbolic cosine. + * Return the @c std::string representing the MathML "hyperbolic cosine" + * function. * - * @return The @c std::string for hyperbolic cosine. + * @return The @c std::string representing the MathML "hyperbolic cosine" + * function. */ std::string coshString() const; /** - * @brief Set the @c std::string for hyperbolic cosine. + * @brief Set the @c std::string representing the MathML "hyperbolic cosine" + * function. * - * Set this @c std::string for hyperbolic cosine. + * Set the @c std::string representing the MathML "hyperbolic cosine" + * function. * - * @param coshString The @c std::string to use for hyperbolic cosine. + * @param coshString The @c std::string representing the MathML "hyperbolic + * cosine" function. */ void setCoshString(const std::string &coshString); /** - * @brief Get the @c std::string for hyperbolic tangent. + * @brief Get the @c std::string representing the MathML "hyperbolic + * tangent" function. * - * Return the @c std::string for hyperbolic tangent. + * Return the @c std::string representing the MathML "hyperbolic tangent" + * function. * - * @return The @c std::string for hyperbolic tangent. + * @return The @c std::string representing the MathML "hyperbolic tangent" + * function. */ std::string tanhString() const; /** - * @brief Set the @c std::string for hyperbolic tangent. + * @brief Set the @c std::string representing the MathML "hyperbolic + * tangent" function. * - * Set this @c std::string for hyperbolic tangent. + * Set the @c std::string representing the MathML "hyperbolic tangent" + * function. * - * @param tanhString The @c std::string to use for hyperbolic tangent. + * @param tanhString The @c std::string representing the MathML "hyperbolic + * tangent" function. */ void setTanhString(const std::string &tanhString); /** - * @brief Get the @c std::string for hyperbolic secant. + * @brief Get the @c std::string representing the MathML "hyperbolic secant" + * function. * - * Return the @c std::string for hyperbolic secant. + * Return the @c std::string representing the MathML "hyperbolic secant" + * function. * - * @return The @c std::string for hyperbolic secant. + * @return The @c std::string representing the MathML "hyperbolic secant" + * function. */ std::string sechString() const; /** - * @brief Set the @c std::string for hyperbolic secant. + * @brief Set the @c std::string representing the MathML "hyperbolic secant" + * function. * - * Set this @c std::string for hyperbolic secant. + * Set the @c std::string representing the MathML "hyperbolic secant" + * function. * - * @param sechString The @c std::string to use for hyperbolic secant. + * @param sechString The @c std::string representing the MathML "hyperbolic + * secant" function. */ void setSechString(const std::string &sechString); /** - * @brief Get the @c std::string for hyperbolic cosecant. + * @brief Get the @c std::string representing the MathML "hyperbolic + * cosecant" function. * - * Return the @c std::string for hyperbolic cosecant. + * Return the @c std::string representing the MathML "hyperbolic cosecant" + * function. * - * @return The @c std::string for hyperbolic cosecant. + * @return The @c std::string representing the MathML "hyperbolic cosecant" + * function. */ std::string cschString() const; /** - * @brief Set the @c std::string for hyperbolic cosecant. + * @brief Set the @c std::string representing the MathML "hyperbolic + * cosecant" function. * - * Set this @c std::string for hyperbolic cosecant. + * Set the @c std::string representing the MathML "hyperbolic cosecant" + * function. * - * @param cschString The @c std::string to use for hyperbolic cosecant. + * @param cschString The @c std::string representing the MathML "hyperbolic + * cosecant" function. */ void setCschString(const std::string &cschString); /** - * @brief Get the @c std::string for hyperbolic cotangent. + * @brief Get the @c std::string representing the MathML "hyperbolic + * cotangent" function. * - * Return the @c std::string for hyperbolic cotangent. + * Return the @c std::string representing the MathML "hyperbolic cotangent" + * function. * - * @return The @c std::string for hyperbolic cotangent. + * @return The @c std::string representing the MathML "hyperbolic cotangent" + * function. */ std::string cothString() const; /** - * @brief Set the @c std::string for hyperbolic cotangent. + * @brief Set the @c std::string representing the MathML "hyperbolic + * cotangent" function. * - * Set this @c std::string for hyperbolic cotangent. + * Set the @c std::string representing the MathML "hyperbolic cotangent" + * function. * - * @param cothString The @c std::string to use for hyperbolic cotangent. + * @param cothString The @c std::string representing the MathML "hyperbolic + * cotangent" function. */ void setCothString(const std::string &cothString); /** - * @brief Get the @c std::string for inverse sine. + * @brief Get the @c std::string representing the MathML "arc sine" + * function. * - * Return the @c std::string for inverse sine. + * Return the @c std::string representing the MathML "arc sine" function. * - * @return The @c std::string for inverse sine. + * @return The @c std::string representing the MathML "arc sine" function. */ std::string asinString() const; /** - * @brief Set the @c std::string for inverse sine. + * @brief Set the @c std::string representing the MathML "arc sine" + * function. * - * Set this @c std::string for inverse sine. + * Set the @c std::string representing the MathML "arc sine" function. * - * @param asinString The @c std::string to use for inverse sine. + * @param asinString The @c std::string representing the MathML "arc sine" + * function. */ void setAsinString(const std::string &asinString); /** - * @brief Get the @c std::string for inverse cosine. + * @brief Get the @c std::string representing the MathML "arc cosine" + * function. * - * Return the @c std::string for inverse cosine. + * Return the @c std::string representing the MathML "arc cosine" function. * - * @return The @c std::string for inverse cosine. + * @return The @c std::string representing the MathML "arc cosine" function. */ std::string acosString() const; /** - * @brief Set the @c std::string for inverse cosine. + * @brief Set the @c std::string representing the MathML "arc cosine" + * function. * - * Set this @c std::string for inverse cosine. + * Set the @c std::string representing the MathML "arc cosine" function. * - * @param acosString The @c std::string to use for inverse cosine. + * @param acosString The @c std::string representing the MathML "arc cosine" + * function. */ void setAcosString(const std::string &acosString); /** - * @brief Get the @c std::string for inverse tangent. + * @brief Get the @c std::string representing the MathML "arc tangent" + * function. * - * Return the @c std::string for inverse tangent. + * Return the @c std::string representing the MathML "arc tangent" function. * - * @return The @c std::string for inverse tangent. + * @return The @c std::string representing the MathML "arc tangent" + * function. */ std::string atanString() const; /** - * @brief Set the @c std::string for inverse tangent. + * @brief Set the @c std::string representing the MathML "arc tangent" + * function. * - * Set this @c std::string for inverse tangent. + * Set the @c std::string representing the MathML "arc tangent" function. * - * @param atanString The @c std::string to use for inverse tangent. + * @param atanString The @c std::string representing the MathML "arc + * tangent" function. */ void setAtanString(const std::string &atanString); /** - * @brief Get the @c std::string for inverse secant. + * @brief Get the @c std::string representing the MathML "arc secant" + * function. * - * Return the @c std::string for inverse secant. + * Return the @c std::string representing the MathML "arc secant" function. * - * @return The @c std::string for inverse secant. + * @return The @c std::string representing the MathML "arc secant" function. */ std::string asecString() const; /** - * @brief Set the @c std::string for inverse secant. + * @brief Set the @c std::string representing the MathML "arc secant" + * function. * - * Set this @c std::string for inverse secant. + * Set the @c std::string representing the MathML "arc secant" function. * - * @param asecString The @c std::string to use for inverse secant. + * @param asecString The @c std::string representing the MathML "arc secant" + * function. */ void setAsecString(const std::string &asecString); /** - * @brief Get the @c std::string for inverse cosecant. + * @brief Get the @c std::string representing the MathML "arc cosecant" + * function. * - * Return the @c std::string for inverse cosecant. + * Return the @c std::string representing the MathML "arc cosecant" + * function. * - * @return The @c std::string for inverse cosecant. + * @return The @c std::string representing the MathML "arc cosecant" + * function. */ std::string acscString() const; /** - * @brief Set the @c std::string for inverse cosecant. + * @brief Set the @c std::string representing the MathML "arc cosecant" + * function. * - * Set this @c std::string for inverse cosecant. + * Set the @c std::string representing the MathML "arc cosecant" function. * - * @param acscString The @c std::string to use for inverse cosecant. + * @param acscString The @c std::string representing the MathML "arc + * cosecant" function. */ void setAcscString(const std::string &acscString); /** - * @brief Get the @c std::string for inverse cotangent. + * @brief Get the @c std::string representing the MathML "arc cotangent" + * function. * - * Return the @c std::string for inverse cotangent. + * Return the @c std::string representing the MathML "arc cotangent" + * function. * - * @return The @c std::string for inverse cotangent. + * @return The @c std::string representing the MathML "arc cotangent" + * function. */ std::string acotString() const; /** - * @brief Set the @c std::string for inverse cotangent. + * @brief Set the @c std::string representing the MathML "arc cotangent" + * function. * - * Set this @c std::string for inverse cotangent. + * Set the @c std::string representing the MathML "arc cotangent" function. * - * @param acotString The @c std::string to use for inverse cotangent. + * @param acotString The @c std::string representing the MathML "arc + * cotangent" function. */ void setAcotString(const std::string &acotString); /** - * @brief Get the @c std::string for inverse hyperbolic sine. + * @brief Get the @c std::string representing the MathML "arc hyperbolic + * sine" function. * - * Return the @c std::string for inverse hyperbolic sine. + * Return the @c std::string representing the MathML "arc hyperbolic sine" + * function. * - * @return The @c std::string for inverse hyperbolic sine. + * @return The @c std::string representing the MathML "arc hyperbolic sine" + * function. */ std::string asinhString() const; /** - * @brief Set the @c std::string for inverse hyperbolic sine. + * @brief Set the @c std::string representing the MathML "arc hyperbolic + * sine" function. * - * Set this @c std::string for inverse hyperbolic sine. + * Set the @c std::string representing the MathML "arc hyperbolic sine" + * function. * - * @param asinhString The @c std::string to use for inverse hyperbolic sine. + * @param asinhString The @c std::string representing the MathML "arc + * hyperbolic sine" function. */ void setAsinhString(const std::string &asinhString); /** - * @brief Get the @c std::string for inverse hyperbolic cosine. + * @brief Get the @c std::string representing the MathML "arc hyperbolic + * cosine" function. * - * Return the @c std::string for inverse hyperbolic cosine. + * Return the @c std::string representing the MathML "arc hyperbolic cosine" + * function. * - * @return The @c std::string for inverse hyperbolic cosine. + * @return The @c std::string representing the MathML "arc hyperbolic + * cosine" function. */ std::string acoshString() const; /** - * @brief Set the @c std::string for inverse hyperbolic cosine. + * @brief Set the @c std::string representing the MathML "arc hyperbolic + * cosine" function. * - * Set this @c std::string for inverse hyperbolic cosine. + * Set the @c std::string representing the MathML "arc hyperbolic cosine" + * function. * - * @param acoshString The @c std::string to use for inverse hyperbolic - * cosine. + * @param acoshString The @c std::string representing the MathML "arc + * hyperbolic cosine" function. */ void setAcoshString(const std::string &acoshString); /** - * @brief Get the @c std::string for inverse hyperbolic tangent. + * @brief Get the @c std::string representing the MathML "arc hyperbolic + * tangent" function. * - * Return the @c std::string for inverse hyperbolic tangent. + * Return the @c std::string representing the MathML "arc hyperbolic + * tangent" function. * - * @return The @c std::string for inverse hyperbolic tangent. + * @return The @c std::string representing the MathML "arc hyperbolic + * tangent" function. */ std::string atanhString() const; /** - * @brief Set the @c std::string for inverse hyperbolic tangent. + * @brief Set the @c std::string representing the MathML "arc hyperbolic + * tangent" function. * - * Set this @c std::string for inverse hyperbolic tangent. + * Set the @c std::string representing the MathML "arc hyperbolic tangent" + * function. * - * @param atanhString The @c std::string to use for inverse hyperbolic - * tangent. + * @param atanhString The @c std::string representing the MathML "arc + * hyperbolic tangent" function. */ void setAtanhString(const std::string &atanhString); /** - * @brief Get the @c std::string for inverse hyperbolic secant. + * @brief Get the @c std::string representing the MathML "arc hyperbolic + * secant" function. * - * Return the @c std::string for inverse hyperbolic secant. + * Return the @c std::string representing the MathML "arc hyperbolic + * secant" function. * - * @return The @c std::string for inverse hyperbolic secant. + * @return The @c std::string representing the MathML "arc hyperbolic + * secant" function. */ std::string asechString() const; /** - * @brief Set the @c std::string for inverse hyperbolic secant. + * @brief Set the @c std::string representing the MathML "arc hyperbolic + * secant" function. * - * Set this @c std::string for inverse hyperbolic secant. + * Set the @c std::string representing the MathML "arc hyperbolic secant" + * function. * - * @param asechString The @c std::string to use for inverse hyperbolic - * secant. + * @param asechString The @c std::string representing the MathML "arc + * hyperbolic secant" function. */ void setAsechString(const std::string &asechString); /** - * @brief Get the @c std::string for inverse hyperbolic cosecant. + * @brief Get the @c std::string representing the MathML "arc hyperbolic + * cosecant" function. * - * Return the @c std::string for inverse hyperbolic cosecant. + * Return the @c std::string representing the MathML "arc hyperbolic + * cosecant" function. * - * @return The @c std::string for inverse hyperbolic cosecant. + * @return The @c std::string representing the MathML "arc hyperbolic + * cosecant" function. */ std::string acschString() const; /** - * @brief Set the @c std::string for inverse hyperbolic cosecant. + * @brief Set the @c std::string representing the MathML "arc hyperbolic + * cosecant" function. * - * Set this @c std::string for inverse hyperbolic cosecant. + * Set the @c std::string representing the MathML "arc hyperbolic cosecant" + * function. * - * @param acschString The @c std::string to use for inverse hyperbolic - * cosecant. + * @param acschString The @c std::string representing the MathML "arc + * hyperbolic cosecant" function. */ void setAcschString(const std::string &acschString); /** - * @brief Get the @c std::string for inverse hyperbolic cotangent. + * @brief Get the @c std::string representing the MathML "arc hyperbolic + * cotangent" function. * - * Return the @c std::string for inverse hyperbolic cotangent. + * Return the @c std::string representing the MathML "arc hyperbolic + * cotangent" function. * - * @return The @c std::string for inverse hyperbolic cotangent. + * @return The @c std::string representing the MathML "arc hyperbolic + * cotangent" function. */ std::string acothString() const; /** - * @brief Set the @c std::string for inverse hyperbolic cotangent. + * @brief Set the @c std::string representing the MathML "arc hyperbolic + * cotangent" function. * - * Set this @c std::string for inverse hyperbolic cotangent. + * Set the @c std::string representing the MathML "arc hyperbolic cotangent" + * function. * - * @param acothString The @c std::string to use for inverse hyperbolic - * cotangent. + * @param acothString The @c std::string representing the MathML "arc + * hyperbolic cotangent" function. */ void setAcothString(const std::string &acothString); // Piecewise statement. /** - * @brief Get the @c std::string for the if part of a condition statement. + * @brief Get the @c std::string representing the MathML "if" part of a + * "conditional" statement or operator. * - * Return the @c std::string for the if part of a condition statement. + * Return the @c std::string representing the MathML "if" part of a + * "conditional" statement or operator. * - * @return The @c std::string for the if part of a condition statement. + * @return The @c std::string representing the MathML "if" part of a + * "conditional" statement or operator. */ std::string conditionalOperatorIfString() const; /** - * @brief Set the @c std::string for the if part of a condition statement. + * @brief Set the @c std::string representing the MathML "if" part of a + * "conditional" statement or operator. * - * Set this @c std::string for the if part of a condition statement. + * Set the @c std::string representing the MathML "if" part of a + * "conditional" statement or operator. * - * @param conditionalOperatorIfString The @c std::string to use for the if - * part of a condition statement. + * @param conditionalOperatorIfString The @c std::string representing the + * MathML "if" part of a "conditional" statement or operator. */ void setConditionalOperatorIfString(const std::string &conditionalOperatorIfString); /** - * @brief Get the @c std::string for the else part of a condition statement. + * @brief Get the @c std::string representing the MathML "else" part of a + * "conditional" statement or operator. * - * Return the @c std::string for the else part of a condition statement. + * Return the @c std::string representing the MathML "else" part of a + * "conditional" statement or operator. * - * @return The @c std::string for the else part of a condition statement. + * @return The @c std::string representing the MathML "else" part of a + * "conditional" statement or operator. */ std::string conditionalOperatorElseString() const; /** - * @brief Set the @c std::string for the else part of a condition statement. + * @brief Set the @c std::string representing the MathML "else" part of a + * "conditional" statement or operator. * - * Set this @c std::string for the else part of a condition statement. + * Set the @c std::string representing the MathML "else" part of a + * "conditional" statement or operator. * - * @param conditionalOperatorElseString The @c std::string to use for the - * else part of a condition statement. + * @param conditionalOperatorElseString The @c std::string representing the + * MathML "else" part of a "conditional" statement or operator. */ void setConditionalOperatorElseString(const std::string &conditionalOperatorElseString); /** - * @brief Get the @c std::string for the if part of a piecewise statement. + * @brief Get the @c std::string representing the MathML "if" part of a + * "piecewise" statement. * - * Return the @c std::string for the if part of a piecewise statement. + * Return the @c std::string representing the MathML "if" part of a + * "piecewise" statement. * - * @return The @c std::string for the if part of a piecewise statement. + * @return The @c std::string representing the MathML "if" part of a + * "piecewise" statement. */ std::string piecewiseIfString() const; /** - * @brief Set the @c std::string for the if part of a piecewise statement. + * @brief Set the @c std::string representing the MathML "if" part of a + * "piecewise" statement. * - * Set this @c std::string for the if part of a piecewise statement. + * Set the @c std::string representing the MathML "if" part of a "piecewise" + * statement. * - * @param piecewiseIfString The @c std::string to use for the if part of a - * piecewise statement. + * @param piecewiseIfString The @c std::string representing the MathML "if" + * part of a "piecewise" statement. */ void setPiecewiseIfString(const std::string &piecewiseIfString); /** - * @brief Get the @c std::string for the else part of a piecewise statement. + * @brief Get the @c std::string representing the MathML "else" part of a + * "piecewise" statement. * - * Return the @c std::string for the else part of a piecewise statement. + * Return the @c std::string representing the MathML "else" part of a + * "piecewise" statement. * - * @return The @c std::string for the else part of a piecewise statement. + * @return The @c std::string representing the MathML "else" part of a + * "piecewise" statement. */ std::string piecewiseElseString() const; /** - * @brief Set the @c std::string for the else part of a piecewise statement. + * @brief Set the @c std::string representing the MathML "else" part of a + * "piecewise" statement. * - * Set this @c std::string for the else part of a piecewise statement. + * Set the @c std::string representing the MathML "else" part of a + * "piecewise" statement. * - * @param piecewiseElseString The @c std::string to use for the else part of - * a piecewise statement. + * @param piecewiseElseString The @c std::string representing the MathML + * "else" part of a "piecewise" statement. */ void setPiecewiseElseString(const std::string &piecewiseElseString); /** - * @brief Test if this @c GeneratorProfile has a conditional operator. + * @brief Test if this @c GeneratorProfile has a "conditional" operator. * - * Test if this @c GeneratorProfile has a conditional operator. + * Test if this @c GeneratorProfile has a "conditional" operator. * - * @return @c true if the @c GeneratorProfile has a conditional operator, + * @return @c true if the @c GeneratorProfile has a "conditional" operator, * @c false otherwise. */ bool hasConditionalOperator() const; /** - * @brief Set whether this @c GeneratorProfile has a conditional operator. + * @brief Set whether this @c GeneratorProfile has a "conditional" operator. * - * Set whether this @c GeneratorProfile has a conditional operator. + * Set whether this @c GeneratorProfile has a "conditional" operator. * * @param hasConditionalOperator A @c bool to determine whether this - * @c GeneratorProfile has a conditional operator. + * @c GeneratorProfile has a "conditional" operator. */ void setHasConditionalOperator(bool hasConditionalOperator); // Constants. /** - * @brief Get the @c std::string for true. + * @brief Get the @c std::string representing the MathML "true" boolean. * - * Return the @c std::string for true. + * Return the @c std::string representing the MathML "true" boolean. * - * @return The @c std::string for true. + * @return The @c std::string representing the MathML "true" boolean. */ std::string trueString() const; /** - * @brief Set the @c std::string for true. + * @brief Set the @c std::string representing the MathML "true" boolean. * - * Set this @c std::string for true. + * Set the @c std::string representing the MathML "true" boolean. * - * @param trueString The @c std::string to use for true. + * @param trueString The @c std::string representing the MathML "true" + * boolean. */ void setTrueString(const std::string &trueString); /** - * @brief Get the @c std::string for false. + * @brief Get the @c std::string representing the MathML "false" boolean. * - * Return the @c std::string for false. + * Return the @c std::string representing the MathML "false" boolean. * - * @return The @c std::string for false. + * @return The @c std::string representing the MathML "false" boolean. */ std::string falseString() const; /** - * @brief Set the @c std::string for false. + * @brief Set the @c std::string representing the MathML "false" boolean. * - * Set this @c std::string for false. + * Set the @c std::string representing the MathML "false" boolean. * - * @param falseString The @c std::string to use for false. + * @param falseString The @c std::string representing the MathML "false" + * boolean. */ void setFalseString(const std::string &falseString); /** - * @brief Get the @c std::string for exponential constant. + * @brief Get the @c std::string representing the MathML "Euler's number". * - * Return the @c std::string for exponential constant. + * Return the @c std::string representing the MathML "Euler's number". * - * @return The @c std::string for exponential constant. + * @return The @c std::string representing the MathML "Euler's number". */ std::string eString() const; /** - * @brief Set the @c std::string for exponential constant. + * @brief Set the @c std::string representing the MathML "Euler's number". * - * Set this @c std::string for exponential constant. + * Set the @c std::string representing the MathML "Euler's number". * - * @param eString The @c std::string to use for exponential constant. + * @param eString The @c std::string representing the MathML "Euler's + * number". */ void setEString(const std::string &eString); /** - * @brief Get the @c std::string for Ï€. + * @brief Get the @c std::string representing the MathML "Ï€" constant. * - * Return the @c std::string for Ï€. + * Return the @c std::string representing the MathML "Ï€" constant. * - * @return The @c std::string for Ï€. + * @return The @c std::string representing the MathML "Ï€" constant. */ std::string piString() const; /** - * @brief Set the @c std::string for Ï€. + * @brief Set the @c std::string representing the MathML "Ï€" constant. * - * Set this @c std::string for Ï€. + * Set the @c std::string representing the MathML "Ï€" constant. * - * @param piString The @c std::string to use for Ï€. + * @param piString The @c std::string representing the MathML "Ï€" constant. */ void setPiString(const std::string &piString); /** - * @brief Get the @c std::string for infinity. + * @brief Get the @c std::string representing the MathML "infinity" value. * - * Return the @c std::string for infinity. + * Return the @c std::string representing the MathML "infinity" value. * - * @return The @c std::string for infinity. + * @return The @c std::string representing the MathML "infinity" value. */ std::string infString() const; /** - * @brief Set the @c std::string for infinity. + * @brief Set the @c std::string representing the MathML "infinity" value. * - * Set this @c std::string for infinity. + * Set the @c std::string representing the MathML "infinity" value. * - * @param infString The @c std::string to use for infinity. + * @param infString The @c std::string representing the MathML "infinity" + * value. */ void setInfString(const std::string &infString); /** - * @brief Get the @c std::string for NaN. + * @brief Get the @c std::string representing the MathML "not-a-number" + * value. * - * Return the @c std::string for NaN. + * Return the @c std::string representing the MathML "not-a-number" value. * - * @return The @c std::string for NaN. + * @return The @c std::string representing the MathML "not-a-number" value. */ std::string nanString() const; /** - * @brief Set the @c std::string for NaN. + * @brief Set the @c std::string representing the MathML "not-a-number" + * value. * - * Set this @c std::string for NaN. + * Set the @c std::string representing the MathML "not-a-number" value. * - * @param nanString The @c std::string to use for NaN. + * @param nanString The @c std::string representing the MathML + * "not-a-number" value. */ void setNanString(const std::string &nanString); // Arithmetic functions. /** - * @brief Get the @c std::string for the equivalence function. + * @brief Get the @c std::string for the "equal to" function implementation. * - * Return the @c std::string for the equivalence function. + * Return the @c std::string for the "equal to" function implementation. * - * @return The @c std::string for the equivalence function. + * @return The @c std::string for the "equal to" function implementation. */ std::string eqFunctionString() const; /** - * @brief Set the @c std::string for the equivalence function. + * @brief Set the @c std::string for the "equal to" function implementation. * - * Set this @c std::string for the equivalence function. + * Set the @c std::string for the "equal to" function implementation. * - * @param eqFunctionString The @c std::string to use for the equivalence - * function. + * @param eqFunctionString The @c std::string for the "equal to" function + * implementation. */ void setEqFunctionString(const std::string &eqFunctionString); /** - * @brief Get the @c std::string for the nonequivalence function. + * @brief Get the @c std::string for the "not equal to" function + * implementation. * - * Return the @c std::string for the nonequivalence function. + * Return the @c std::string for the "not equal to" function implementation. * - * @return The @c std::string for the nonequivalence function. + * @return The @c std::string for the "not equal to" function + * implementation. */ std::string neqFunctionString() const; /** - * @brief Set the @c std::string for the nonequivalence function. + * @brief Set the @c std::string for the "not equal to" function + * implementation. * - * Set this @c std::string for the nonequivalence function. + * Set the @c std::string for the "not equal to" function implementation. * - * @param neqFunctionString The @c std::string to use for the nonequivalence - * function. + * @param neqFunctionString The @c std::string for the "not + * equal to" function implementation. */ void setNeqFunctionString(const std::string &neqFunctionString); /** - * @brief Get the @c std::string for the lower than function. + * @brief Get the @c std::string for the "less than" function + * implementation. * - * Return the @c std::string for the lower than function. + * Return the @c std::string for the "less than" function implementation. * - * @return The @c std::string for the lower than function. + * @return The @c std::string for the "less than" function implementation. */ std::string ltFunctionString() const; /** - * @brief Set the @c std::string for the lower than function. + * @brief Set the @c std::string for the "less than" function + * implementation. * - * Set this @c std::string for the lower than function. + * Set the @c std::string for the "less than" function implementation. * - * @param ltFunctionString The @c std::string to use for the lower than - * function. + * @param ltFunctionString The @c std::string for the "less than" function + * implementation. */ void setLtFunctionString(const std::string <FunctionString); /** - * @brief Get the @c std::string for the lower or equal than function. + * @brief Get the @c std::string for the "less than or equal to" function + * implementation. * - * Return the @c std::string for the lower or equal than function. + * Return the @c std::string for the "less than or equal to" function + * implementation. * - * @return The @c std::string for the lower or equal than function. + * @return The @c std::string for the "less than or equal to" function + * implementation. */ std::string leqFunctionString() const; /** - * @brief Set the @c std::string for the lower or equal than function. + * @brief Set the @c std::string for the "less than or equal to" function + * implementation. * - * Set this @c std::string for the lower or equal than function. + * Set the @c std::string for the "less than or equal to" function + * implementation. * - * @param leqFunctionString The @c std::string to use for the lower or equal - * than function. + * @param leqFunctionString The @c std::string for the "less than or equal + * to" function implementation. */ void setLeqFunctionString(const std::string &leqFunctionString); /** - * @brief Get the @c std::string for the greater than function. + * @brief Get the @c std::string for the "greater than" function + * implementation. * - * Return the @c std::string for the greater than function. + * Return the @c std::string for the "greater than" function implementation. * - * @return The @c std::string for the greater than function. + * @return The @c std::string for the "greater than" function + * implementation. */ std::string gtFunctionString() const; /** - * @brief Set the @c std::string for the greater than function. + * @brief Set the @c std::string for the "greater than" function + * implementation. * - * Set this @c std::string for the greater than function. + * Set the @c std::string for the "greater than" function implementation. * - * @param gtFunctionString The @c std::string to use for the greater than - * function. + * @param gtFunctionString The @c std::string for the "greater than" + * function implementation. */ void setGtFunctionString(const std::string >FunctionString); /** - * @brief Get the @c std::string for the greater or equal than function. + * @brief Get the @c std::string for the "greater than or equal to" function + * implementation. * - * Return the @c std::string for the greater or equal than function. + * Return the @c std::string for the "greater than or equal to" function + * implementation. * - * @return The @c std::string for the greater or equal than function. + * @return The @c std::string for the "greater than or equal to" function + * implementation. */ std::string geqFunctionString() const; /** - * @brief Set the @c std::string for the greater or equal than function. + * @brief Set the @c std::string for the "greater than or equal to" function + * implementation. * - * Set this @c std::string for the greater or equal than function. + * Set the @c std::string for the "greater than or equal to" function + * implementation. * - * @param geqFunctionString The @c std::string to use for the greater or - * equal than function. + * @param geqFunctionString The @c std::string for the "greater than or + * equal to" function implementation. */ void setGeqFunctionString(const std::string &geqFunctionString); /** - * @brief Get the @c std::string for the and function. + * @brief Get the @c std::string for the "and" function implementation. * - * Return the @c std::string for the and function. + * Return the @c std::string for the "and" function implementation. * - * @return The @c std::string for the and function. + * @return The @c std::string for the "and" function implementation. */ std::string andFunctionString() const; /** - * @brief Set the @c std::string for the and function. + * @brief Set the @c std::string for the "and" function implementation. * - * Set this @c std::string for the and function. + * Set the @c std::string for the "and" function implementation. * - * @param andFunctionString The @c std::string to use for the and function. + * @param andFunctionString The @c std::string for the "and" + * function implementation. */ void setAndFunctionString(const std::string &andFunctionString); /** - * @brief Get the @c std::string for the or function. + * @brief Get the @c std::string for the "or" function implementation. * - * Return the @c std::string for the or function. + * Return the @c std::string for the "or" function implementation. * - * @return The @c std::string for the or function. + * @return The @c std::string for the "or" function implementation. */ std::string orFunctionString() const; /** - * @brief Set the @c std::string for the or function. + * @brief Set the @c std::string for the "or" function implementation. * - * Set this @c std::string for the or function. + * Set the @c std::string for the "or" function implementation. * - * @param orFunctionString The @c std::string to use for the or function. + * @param orFunctionString The @c std::string for the "or" + * function implementation. */ void setOrFunctionString(const std::string &orFunctionString); /** - * @brief Get the @c std::string for the xor function. + * @brief Get the @c std::string for the "exclusive or" function + * implementation. * - * Return the @c std::string for the xor function. + * Return the @c std::string for the "exclusive or" function implementation. * - * @return The @c std::string for the xor function. + * @return The @c std::string for the "exclusive or" function + * implementation. */ std::string xorFunctionString() const; /** - * @brief Set the @c std::string for the xor function. + * @brief Set the @c std::string for the "exclusive or" function + * implementation. * - * Set this @c std::string for the xor function. + * Set the @c std::string for the "exclusive or" function implementation. * - * @param xorFunctionString The @c std::string to use for the xor function. + * @param xorFunctionString The @c std::string for the "exclusive or" + * function implementation. */ void setXorFunctionString(const std::string &xorFunctionString); /** - * @brief Get the @c std::string for the not function. + * @brief Get the @c std::string for the "not" function implementation. * - * Return the @c std::string for the not function. + * Return the @c std::string for the "not" function implementation. * - * @return The @c std::string for the not function. + * @return The @c std::string for the "not" function implementation. */ std::string notFunctionString() const; /** - * @brief Set the @c std::string for the not function. + * @brief Set the @c std::string for the "not" function implementation. * - * Set this @c std::string for the not function. + * Set the @c std::string for the "not" function implementation. * - * @param notFunctionString The @c std::string to use for the not function. + * @param notFunctionString The @c std::string for the "not" function + * implementation. */ void setNotFunctionString(const std::string ¬FunctionString); /** - * @brief Get the @c std::string for the minimum function. + * @brief Get the @c std::string for the "minimum" function implementation. * - * Return the @c std::string for the minimum function. + * Return the @c std::string for the "minimum" function implementation. * - * @return The @c std::string for the minimum function. + * @return The @c std::string for the "minimum" function implementation. */ std::string minFunctionString() const; /** - * @brief Set the @c std::string for the minimum function. + * @brief Set the @c std::string for the "minimum" function implementation. * - * Set this @c std::string for the minimum function. + * Set the @c std::string for the "minimum" function implementation. * - * @param minFunctionString The @c std::string to use for the minimum - * function. + * @param minFunctionString The @c std::string for the "minimum" function + * implementation. */ void setMinFunctionString(const std::string &minFunctionString); /** - * @brief Get the @c std::string for the maximum function. + * @brief Get the @c std::string for the "maximum" function implementation. * - * Return the @c std::string for the maximum function. + * Return the @c std::string for the "maximum" function implementation. * - * @return The @c std::string for the maximum function. + * @return The @c std::string for the "maximum" function implementation. */ std::string maxFunctionString() const; /** - * @brief Set the @c std::string for the maximum function. + * @brief Set the @c std::string for the "maximum" function implementation. * - * Set this @c std::string for the maximum function. + * Set the @c std::string for the "maximum" function implementation. * - * @param maxFunctionString The @c std::string to use for the maximum - * function. + * @param maxFunctionString The @c std::string for the "maximum" function + * implementation. */ void setMaxFunctionString(const std::string &maxFunctionString); - // Trigonometric functions. + // Trigonometric function implementations. /** - * @brief Get the @c std::string for the secant function. + * @brief Get the @c std::string for the "secant" function implementation. * - * Return the @c std::string for the secant function. + * Return the @c std::string for the "secant" function implementation. * - * @return The @c std::string for the secant function. + * @return The @c std::string for the "secant" function implementation. */ std::string secFunctionString() const; /** - * @brief Set the @c std::string for the secant function. + * @brief Set the @c std::string for the "secant" function implementation. * - * Set this @c std::string for the secant function. + * Set the @c std::string for the "secant" function implementation. * - * @param secFunctionString The @c std::string to use for the secant - * function. + * @param secFunctionString The @c std::string for the "secant" function + * implementation. */ void setSecFunctionString(const std::string &secFunctionString); /** - * @brief Get the @c std::string for the cosecant function. + * @brief Get the @c std::string for the "cosecant" function implementation. * - * Return the @c std::string for the cosecant function. + * Return the @c std::string for the "cosecant" function implementation. * - * @return The @c std::string for the cosecant function. + * @return The @c std::string for the "cosecant" function implementation. */ std::string cscFunctionString() const; /** - * @brief Set the @c std::string for the cosecant function. + * @brief Set the @c std::string for the "cosecant" function implementation. * - * Set this @c std::string for the cosecant function. + * Set the @c std::string for the "cosecant" function implementation. * - * @param cscFunctionString The @c std::string to use for the cosecant - * function. + * @param cscFunctionString The @c std::string for the "cosecant" function + * implementation. */ void setCscFunctionString(const std::string &cscFunctionString); /** - * @brief Get the @c std::string for the cotangent function. + * @brief Get the @c std::string for the "cotangent" function + * implementation. * - * Return the @c std::string for the cotangent function. + * Return the @c std::string for the "cotangent" function implementation. * - * @return The @c std::string for the cotangent function. + * @return The @c std::string for the "cotangent" function implementation. */ std::string cotFunctionString() const; /** - * @brief Set the @c std::string for the cotangent function. + * @brief Set the @c std::string for the "cotangent" function + * implementation. * - * Set this @c std::string for the cotangent function. + * Set the @c std::string for the "cotangent" function implementation. * - * @param cotFunctionString The @c std::string to use for the cotangent - * function. + * @param cotFunctionString The @c std::string for the "cotangent" function + * implementation. */ void setCotFunctionString(const std::string &cotFunctionString); /** - * @brief Get the @c std::string for the hyperbolic secant function. + * @brief Get the @c std::string for the "hyperbolic secant" function + * implementation. * - * Return the @c std::string for the hyperbolic secant function. + * Return the @c std::string for the "hyperbolic secant" function + * implementation. * - * @return The @c std::string for the hyperbolic secant function. + * @return The @c std::string for the "hyperbolic secant" function + * implementation. */ std::string sechFunctionString() const; /** - * @brief Set the @c std::string for the hyperbolic secant function. + * @brief Set the @c std::string for the "hyperbolic secant" function + * implementation. * - * Set this @c std::string for the hyperbolic secant function. + * Set the @c std::string for the "hyperbolic secant" function + * implementation. * - * @param sechFunctionString The @c std::string to use for the hyperbolic - * secant function. + * @param sechFunctionString The @c std::string for the "hyperbolic secant" + * function implementation. */ void setSechFunctionString(const std::string &sechFunctionString); /** - * @brief Get the @c std::string for the hyperbolic cosecant function. + * @brief Get the @c std::string for the "hyperbolic cosecant" function + * implementation. * - * Return the @c std::string for the hyperbolic cosecant function. + * Return the @c std::string for the "hyperbolic cosecant" function + * implementation. * - * @return The @c std::string for the hyperbolic cosecant function. + * @return The @c std::string for the "hyperbolic cosecant" function + * implementation. */ std::string cschFunctionString() const; /** - * @brief Set the @c std::string for the hyperbolic cosecant function. + * @brief Set the @c std::string for the "hyperbolic cosecant" function + * implementation. * - * Set this @c std::string for the hyperbolic cosecant function. + * Set the @c std::string for the "hyperbolic cosecant" function + * implementation. * - * @param cschFunctionString The @c std::string to use for the hyperbolic - * cosecant function. + * @param cschFunctionString The @c std::string for the "hyperbolic + * cosecant" function implementation. */ void setCschFunctionString(const std::string &cschFunctionString); /** - * @brief Get the @c std::string for the hyperbolic cotangent function. + * @brief Get the @c std::string for the "hyperbolic cotangent" function + * implementation. * - * Return the @c std::string for the hyperbolic cotangent function. + * Return the @c std::string for the "hyperbolic cotangent" function + * implementation. * - * @return The @c std::string for the hyperbolic cotangent function. + * @return The @c std::string for the "hyperbolic cotangent" function + * implementation. */ std::string cothFunctionString() const; /** - * @brief Set the @c std::string for the hyperbolic cotangent function. + * @brief Set the @c std::string for the "hyperbolic cotangent" function + * implementation. * - * Set this @c std::string for the hyperbolic cotangent function. + * Set the @c std::string for the "hyperbolic cotangent" function + * implementation. * - * @param cothFunctionString The @c std::string to use for the hyperbolic - * cotangent function. + * @param cothFunctionString The @c std::string for the "hyperbolic + * cotangent" function implementation. */ void setCothFunctionString(const std::string &cothFunctionString); /** - * @brief Get the @c std::string for the inverse secant function. + * @brief Get the @c std::string for the "arc secant" function + * implementation. * - * Return the @c std::string for the inverse secant function. + * Return the @c std::string for the "arc secant" function implementation. * - * @return The @c std::string for the inverse secant function. + * @return The @c std::string for the "arc secant" function implementation. */ std::string asecFunctionString() const; /** - * @brief Set the @c std::string for the inverse secant function. + * @brief Set the @c std::string for the "arc secant" function + * implementation. * - * Set this @c std::string for the inverse secant function. + * Set the @c std::string for the "arc secant" function implementation. * - * @param asecFunctionString The @c std::string to use for the inverse - * secant function. + * @param asecFunctionString The @c std::string for the "arc secant" + * function implementation. */ void setAsecFunctionString(const std::string &asecFunctionString); /** - * @brief Get the @c std::string for the inverse cosecant function. + * @brief Get the @c std::string for the "arc cosecant" function + * implementation. * - * Return the @c std::string for the inverse cosecant function. + * Return the @c std::string for the "arc cosecant" function implementation. * - * @return The @c std::string for the inverse cosecant function. + * @return The @c std::string for the "arc cosecant" function + * implementation. */ std::string acscFunctionString() const; /** - * @brief Set the @c std::string for the inverse cosecant function. + * @brief Set the @c std::string for the "arc cosecant" function + * implementation. * - * Set this @c std::string for the inverse cosecant function. + * Set the @c std::string for the "arc cosecant" function implementation. * - * @param acscFunctionString The @c std::string to use for the inverse - * cosecant function. + * @param acscFunctionString The @c std::string for the "arc cosecant" + * function implementation. */ void setAcscFunctionString(const std::string &acscFunctionString); /** - * @brief Get the @c std::string for the inverse cotangent function. + * @brief Get the @c std::string for the "arc cotangent" function + * implementation. * - * Return the @c std::string for the inverse cotangent function. + * Return the @c std::string for the "arc cotangent" function + * implementation. * - * @return The @c std::string for the inverse cotangent function. + * @return The @c std::string for the "arc cotangent" function + * implementation. */ std::string acotFunctionString() const; /** - * @brief Set the @c std::string for the inverse cotangent function. + * @brief Set the @c std::string for the "arc cotangent" function implementation. * - * Set this @c std::string for the inverse cotangent function. + * Set the @c std::string for the "arc cotangent" function implementation. * - * @param acotFunctionString The @c std::string to use for the inverse - * cotangent function. + * @param acotFunctionString The @c std::string for the "arc cotangent" + * function implementation. */ void setAcotFunctionString(const std::string &acotFunctionString); /** - * @brief Get the @c std::string for the inverse hyperbolic secant function. + * @brief Get the @c std::string for the "arc hyperbolic secant" function + * implementation. * - * Return the @c std::string for the inverse hyperbolic secant function. + * Return the @c std::string for the "arc hyperbolic secant" function + * implementation. * - * @return The @c std::string for the inverse hyperbolic secant function. + * @return The @c std::string for the "arc hyperbolic secant" function + * implementation. */ std::string asechFunctionString() const; /** - * @brief Set the @c std::string for the inverse hyperbolic secant function. + * @brief Set the @c std::string for the "arc hyperbolic secant" function + * implementation. * - * Set this @c std::string for the inverse hyperbolic secant function. + * Set the @c std::string for the "arc hyperbolic secant" function + * implementation. * - * @param asechFunctionString The @c std::string to use for the inverse - * hyperbolic secant function. + * @param asechFunctionString The @c std::string for the "arc hyperbolic + * secant" function implementation. */ void setAsechFunctionString(const std::string &asechFunctionString); /** - * @brief Get the @c std::string for the inverse hyperbolic cosecant - * function. + * @brief Get the @c std::string for the "arc hyperbolic cosecant" function + * implementation. * - * Return the @c std::string for the inverse hyperbolic cosecant function. + * Return the @c std::string for the "arc hyperbolic cosecant" function + * implementation. * - * @return The @c std::string for the inverse hyperbolic cosecant function. + * @return The @c std::string for the "arc hyperbolic cosecant" function + * implementation. */ std::string acschFunctionString() const; /** - * @brief Set the @c std::string for the inverse hyperbolic cosecant - * function. + * @brief Set the @c std::string for the "arc hyperbolic cosecant" function + * implementation. * - * Set this @c std::string for the inverse hyperbolic cosecant function. + * Set the @c std::string for the "arc hyperbolic cosecant" function + * implementation. * - * @param acschFunctionString The @c std::string to use for the inverse - * hyperbolic cosecant function. + * @param acschFunctionString The @c std::string for the "arc hyperbolic + * cosecant" function implementation. */ void setAcschFunctionString(const std::string &acschFunctionString); /** - * @brief Get the @c std::string for the inverse hyperbolic cotangent - * function. + * @brief Get the @c std::string for the "arc hyperbolic cotangent" function + * implementation. * - * Return the @c std::string for the inverse hyperbolic cotangent function. + * Return the @c std::string for the "arc hyperbolic cotangent" function + * implementation. * - * @return The @c std::string for the inverse hyperbolic cotangent function. + * @return The @c std::string for the "arc hyperbolic cotangent" function + * implementation. */ std::string acothFunctionString() const; /** - * @brief Set the @c std::string for the inverse hyperbolic cotangent - * function. + * @brief Set the @c std::string for the "arc hyperbolic cotangent" function + * implementation. * - * Set this @c std::string for the inverse hyperbolic cotangent function. + * Set the @c std::string for the "arc hyperbolic cotangent" function + * implementation. * - * @param acothFunctionString The @c std::string to use for the inverse - * hyperbolic cotangent function. + * @param acothFunctionString The @c std::string for the "arc hyperbolic + * cotangent" function implementation. */ void setAcothFunctionString(const std::string &acothFunctionString); @@ -1949,7 +2223,7 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for a comment. * - * Set this @c std::string for a comment. To be useful, the string should + * Set the @c std::string for a comment. To be useful, the string should * contain the tag, which will be replaced with a (proper) comment. * * @param commentString The @c std::string to use for a comment. @@ -1968,7 +2242,7 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for an origin comment. * - * Set this @c std::string for an origin comment. To be useful, the string + * Set the @c std::string for an origin comment. To be useful, the string * should contain the and tags, * which will be replaced with some profile information and the version of * libCellML used. @@ -1990,7 +2264,7 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for the interface file name. * - * Set this @c std::string for the interface file name. + * Set the @c std::string for the interface file name. * * @param interfaceFileNameString The @c std::string to use the interface * file name. @@ -2009,7 +2283,7 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for the interface of a header. * - * Set this @c std::string for the interface of a header. + * Set the @c std::string for the interface of a header. * * @param interfaceHeaderString The @c std::string to use the interface of a * header. @@ -2028,7 +2302,7 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for an implementation header. * - * Set this @c std::string for an implementation header. + * Set the @c std::string for an implementation header. * * @param implementationHeaderString The @c std::string to use for an * implementation header. @@ -2047,7 +2321,7 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for the interface of the version constant. * - * Set this @c std::string for the interface of the version constant. + * Set the @c std::string for the interface of the version constant. * * @param interfaceVersionString The @c std::string to use for the interface * of the version constant. @@ -2069,7 +2343,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the implementation of the version * constant. * - * Set this @c std::string for the implementation of the version constant. + * Set the @c std::string for the implementation of the version constant. * * @param implementationVersionString The @c std::string to use for the * implementation of the version constant. @@ -2092,7 +2366,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the interface of the libCellML version * constant. * - * Set this @c std::string for the interface of the libCellML version + * Set the @c std::string for the interface of the libCellML version * constant. * * @param interfaceLibcellmlVersionString The @c std::string to use for the @@ -2116,7 +2390,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the implementation of the libCellML * version constant. * - * Set this @c std::string for the implementation of the libCellML version + * Set the @c std::string for the implementation of the libCellML version * constant. To be useful, the string should contain the * tag, which will be replaced with the version of libCellML used. * @@ -2139,7 +2413,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the interface of the state count * constant. * - * Set this @c std::string for the interface of the state count constant. + * Set the @c std::string for the interface of the state count constant. * * @param interfaceStateCountString The @c std::string to use for the * interface of the state count constant. @@ -2162,7 +2436,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the implementation of the state count * constant. * - * Set this @c std::string for the implementation of the state count + * Set the @c std::string for the implementation of the state count * constant. To be useful, the string should contain the tag, * which will be replaced with the number of states in the model. * @@ -2187,7 +2461,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the interface of the variable count * constant. * - * Set this @c std::string for the interface of the variable count constant. + * Set the @c std::string for the interface of the variable count constant. * * @param interfaceVariableCountString The @c std::string to use for the * interface of the variable count constant. @@ -2210,7 +2484,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the implementation of the variable * count constant. * - * Set this @c std::string for the implementation of the variable count + * Set the @c std::string for the implementation of the variable count * constant. To be useful, the string should contain the * tag, which will be replaced with the number of states in the model. * @@ -2235,8 +2509,8 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the data structure for the variable * type object. * - * Set this @c std::string for the data structure for the variable - * type object. + * Set the @c std::string for the data structure for the variable type + * object. * * @param variableTypeObjectString The @c std::string to use for the data * structure for the variable type object. @@ -2255,7 +2529,7 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for the name of the constant variable type. * - * Set this @c std::string for the name of the constant variable type. + * Set the @c std::string for the name of the constant variable type. * * @param statesArrayString The @c std::string to use for the name of the * constant variable type. @@ -2278,7 +2552,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the name of the computed constant * variable type. * - * Set this @c std::string for the name of the computed constant variable + * Set the @c std::string for the name of the computed constant variable * type. * * @param statesArrayString The @c std::string to use for the name of the @@ -2300,7 +2574,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the name of the algebraic variable * type. * - * Set this @c std::string for the name of the algebraic variable type. + * Set the @c std::string for the name of the algebraic variable type. * * @param statesArrayString The @c std::string to use for the name of the * algebraic variable type. @@ -2323,7 +2597,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the data structure for the variable * information object. * - * Set this @c std::string for the data structure for the variable + * Set the @c std::string for the data structure for the variable * information object. To be useful, the string should contain the * , and tags, which will be * replaced with the maximum size of a string for holding the name of a @@ -2350,7 +2624,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the data structure for the variable * information (incl. its type) object. * - * Set this @c std::string for the data structure for the variable + * Set the @c std::string for the data structure for the variable * information (incl. its type) object. To be useful, the string should * contain the , and tags, which * will be replaced with the maximum size of a string for holding the name @@ -2377,7 +2651,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the interface of some information about * the variable of integration. * - * Set this @c std::string for the interface of some information about the + * Set the @c std::string for the interface of some information about the * variable of integration. * * @param interfaceVoiInfoString The @c std::string to use for the interface @@ -2401,7 +2675,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the implementation of some information * about the variable of integration. * - * Set this @c std::string for the implementation of some information about + * Set the @c std::string for the implementation of some information about * the variable of integration. To be useful, the string should contain the * tag, which will be replaced with some information about the * variable of integration. @@ -2427,7 +2701,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the interface of some information about * the different states. * - * Set this @c std::string for the interface of some information about the + * Set the @c std::string for the interface of some information about the * different states. * * @param interfaceStateInfoString The @c std::string to use for the @@ -2451,7 +2725,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the implementation of some information * about the different states. * - * Set this @c std::string for the implementation of some information about + * Set the @c std::string for the implementation of some information about * the different states. To be useful, the string should contain the * tag, which will be replaced with some information about the different * states. @@ -2477,7 +2751,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the interface of some information about * the different variables. * - * Set this @c std::string for the interface of some information about the + * Set the @c std::string for the interface of some information about the * different variables. * * @param interfaceVariableInfoString The @c std::string to use for the @@ -2501,7 +2775,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the implementation of some information * about the different variables. * - * Set this @c std::string for the implementation of some information about + * Set the @c std::string for the implementation of some information about * the different variables. To be useful, the string should contain the * tag, which will be replaced with some information about the * different variables. @@ -2527,7 +2801,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for an entry in an array for some * information about a variable. * - * Set this @c std::string for an entry in an array for some information + * Set the @c std::string for an entry in an array for some information * about a variable. To be useful, the string should contain the * , and tags, which will be replaced with the * name of the component, name and units of a variable. @@ -2553,7 +2827,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for an entry in an array for some * information about a variable (incl. its type). * - * Set this @c std::string for an entry in an array for some information + * Set the @c std::string for an entry in an array for some information * about a variable (incl. its type). To be useful, the string should * contain the , and tags, which will be replaced * with the name of the component, name and units of a variable. @@ -2577,7 +2851,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the name of the variable of * integration. * - * Set this @c std::string for the name of the variable of integration. + * Set the @c std::string for the name of the variable of integration. * * @param voiString The @c std::string to use for the name of the variable * of integration. @@ -2596,7 +2870,7 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for the name of the states array. * - * Set this @c std::string for the name of the states array. + * Set the @c std::string for the name of the states array. * * @param statesArrayString The @c std::string to use for the name of the * states array. @@ -2615,7 +2889,7 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for the name of the rates array. * - * Set this @c std::string for the name of the rates array. + * Set the @c std::string for the name of the rates array. * * @param ratesArrayString The @c std::string to use for the name of the * rates array. @@ -2634,7 +2908,7 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for the name of the variables array. * - * Set this @c std::string for the name of the variables array. + * Set the @c std::string for the name of the variables array. * * @param variablesArrayString The @c std::string to use for the name of the * variables array. @@ -2655,9 +2929,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the interface to create the states * array. * - * Set this @c std::string for the interface to create the states array. To - * be useful, the string should contain the tag, which will be - * replaced with some code to create the states array. + * Set the @c std::string for the interface to create the states array. * * @param interfaceCreateStatesArrayMethodString The @c std::string to use * for the interface to create the states array. @@ -2680,9 +2952,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the implementation to create the states * array. * - * Set this @c std::string for the implementation to create the states - * array. To be useful, the string should contain the tag, which will - * be replaced with some code to create the states array. + * Set the @c std::string for the implementation to create the states array. * * @param implementationCreateStatesArrayMethodString The @c std::string to * use for the implementation to create the states array. @@ -2703,9 +2973,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the interface to create variables * array. * - * Set this @c std::string for the interface to create variables array. To - * be useful, the string should contain the tag, which will be - * replaced with some code to create the variables array. + * Set the @c std::string for the interface to create variables array. * * @param interfaceCreateVariablesArrayMethodString The @c std::string to * use for the interface to create variables array. @@ -2728,9 +2996,8 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the implementation to create the * variables array. * - * Set this @c std::string for the implementation to create the variables - * array. To be useful, the string should contain the tag, which will - * be replaced with some code to create the variables array. + * Set the @c std::string for the implementation to create the variables + * array. * * @param implementationCreateVariablesArrayMethodString The @c std::string * to use for the implementation to create the variables array. @@ -2749,7 +3016,7 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for the interface to delete an array. * - * Set this @c std::string for the interface to delete an array. + * Set the @c std::string for the interface to delete an array. * * @param interfaceDeleteArrayMethodString The @c std::string to use for the * interface to delete an array. @@ -2768,7 +3035,7 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for the implementation to delete an array. * - * Set this @c std::string for the implementation to delete an array. + * Set the @c std::string for the implementation to delete an array. * * @param implementationDeleteArrayMethodString The @c std::string to use * for the implementation to delete an array. @@ -2785,20 +3052,20 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the interface to initialise states and * constants. */ - std::string interfaceInitializeStatesAndConstantsMethodString() const; + std::string interfaceInitialiseStatesAndConstantsMethodString() const; /** * @brief Set the @c std::string for the interface to initialise states and * constants. * - * Set this @c std::string for the interface to initialise states and + * Set the @c std::string for the interface to initialise states and * constants. * - * @param interfaceInitializeStatesAndConstantsMethodString The + * @param interfaceInitialiseStatesAndConstantsMethodString The * @c std::string to use for the interface to initialise states and * constants. */ - void setInterfaceInitializeStatesAndConstantsMethodString(const std::string &interfaceInitializeStatesAndConstantsMethodString); + void setInterfaceInitialiseStatesAndConstantsMethodString(const std::string &interfaceInitialiseStatesAndConstantsMethodString); /** * @brief Get the @c std::string for the implementation to initialise states @@ -2810,20 +3077,21 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation to initialise states * and constants. */ - std::string implementationInitializeStatesAndConstantsMethodString() const; + std::string implementationInitialiseStatesAndConstantsMethodString() const; /** * @brief Set the @c std::string for the implementation to initialise states * and constants. * - * Set this @c std::string for the implementation to initialise states and - * constants. + * Set the @c std::string for the implementation to initialise states and + * constants. To be useful, the string should contain the tag, which + * will be replaced with some code to initialise states and constants. * - * @param implementationInitializeStatesAndConstantsMethodString The + * @param implementationInitialiseStatesAndConstantsMethodString The * @c std::string to use for the implementation to initialise states and * constants. */ - void setImplementationInitializeStatesAndConstantsMethodString(const std::string &implementationInitializeStatesAndConstantsMethodString); + void setImplementationInitialiseStatesAndConstantsMethodString(const std::string &implementationInitialiseStatesAndConstantsMethodString); /** * @brief Get the @c std::string for the interface to compute computed @@ -2841,7 +3109,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the interface to compute computed * constants. * - * Set this @c std::string for the interface to compute computed constants. + * Set the @c std::string for the interface to compute computed constants. * * @param interfaceComputeComputedConstantsMethodString The @c std::string * to use for the interface to compute computed constants. @@ -2864,8 +3132,9 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the implementation to compute computed * constants. * - * Set this @c std::string for the implementation to compute computed - * constants. + * Set the @c std::string for the implementation to compute computed + * constants. To be useful, the string should contain the tag, which + * will be replaced with some code to compute computed constants. * * @param implementationComputeComputedConstantsMethodString The * @c std::string to use for the implementation to compute computed @@ -2885,7 +3154,7 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for the interface to compute rates. * - * Set this @c std::string for the interface to compute rates. + * Set the @c std::string for the interface to compute rates. * * @param interfaceComputeRatesMethodString The @c std::string to use for * the interface to compute rates. @@ -2904,7 +3173,9 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for the implementation to compute rates. * - * Set this @c std::string for the implementation to compute rates. + * Set the @c std::string for the implementation to compute rates. To be + * useful, the string should contain the tag, which will be replaced + * with a parameter for some code to compute rates. * * @param implementationComputeRatesMethodString The @c std::string to use * for the implementation to compute rates. @@ -2923,7 +3194,7 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for the interface to compute variables. * - * Set this @c std::string for the interface to compute variables. + * Set the @c std::string for the interface to compute variables. * * @param interfaceComputeVariablesMethodString The @c std::string to use * for the interface to compute variables. @@ -2944,7 +3215,9 @@ class LIBCELLML_EXPORT GeneratorProfile * @brief Set the @c std::string for the implementation to compute * variables. * - * Set this @c std::string for the implementation to compute variables. + * Set the @c std::string for the implementation to compute variables. To be + * useful, the string should contain the tag, which will be replaced + * with a parameter for some code to compute rates. * * @param implementationComputeVariablesMethodString The @c std::string to * use for the implementation to compute variables. @@ -2963,7 +3236,7 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for an empty method. * - * Set this @c std::string for an empty method. + * Set the @c std::string for an empty method. * * @param emptyMethodString The @c std::string to use for an empty method. */ @@ -2981,49 +3254,49 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for an indent. * - * Set this @c std::string for an indent. + * Set the @c std::string for an indent. * * @param indentString The @c std::string to use for an indent. */ void setIndentString(const std::string &indentString); /** - * @brief Get the @c std::string for opening an array initializer. + * @brief Get the @c std::string for opening an array initialiser. * - * Return the @c std::string for opening an array initializer. + * Return the @c std::string for opening an array initialiser. * - * @return The @c std::string for opening an array initializer. + * @return The @c std::string for opening an array initialiser. */ - std::string openArrayInitializerString() const; + std::string openArrayInitialiserString() const; /** - * @brief Set the @c std::string for opening an array initializer. + * @brief Set the @c std::string for opening an array initialiser. * - * Set this @c std::string for opening an array initializer. + * Set the @c std::string for opening an array initialiser. * - * @param openArrayInitializerString The @c std::string to use for opening - * an array initializer. + * @param openArrayInitialiserString The @c std::string to use for opening + * an array initialiser. */ - void setOpenArrayInitializerString(const std::string &openArrayInitializerString); + void setOpenArrayInitialiserString(const std::string &openArrayInitialiserString); /** - * @brief Get the @c std::string for closing an array initializer. + * @brief Get the @c std::string for closing an array initialiser. * - * Return the @c std::string for closing an array initializer. + * Return the @c std::string for closing an array initialiser. * - * @return The @c std::string for closing an array initializer. + * @return The @c std::string for closing an array initialiser. */ - std::string closeArrayInitializerString() const; + std::string closeArrayInitialiserString() const; /** - * @brief Set the @c std::string for closing an array initializer. + * @brief Set the @c std::string for closing an array initialiser. * - * Set this @c std::string for closing an array initializer. + * Set the @c std::string for closing an array initialiser. * - * @param closeArrayInitializerString The @c std::string to use for closing - * an array initializer. + * @param closeArrayInitialiserString The @c std::string to use for closing + * an array initialiser. */ - void setCloseArrayInitializerString(const std::string &closeArrayInitializerString); + void setCloseArrayInitialiserString(const std::string &closeArrayInitialiserString); /** * @brief Get the @c std::string for opening an array. @@ -3037,7 +3310,7 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for opening an array. * - * Set this @c std::string for opening an array. + * Set the @c std::string for opening an array. * * @param openArrayString The @c std::string to use for opening an array. */ @@ -3055,7 +3328,7 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for closing an array. * - * Set this @c std::string for closing an array. + * Set the @c std::string for closing an array. * * @param closeArrayString The @c std::string to use for closing an array. */ @@ -3073,7 +3346,7 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for separating elements in an array. * - * Set this @c std::string for separating elements in an array. + * Set the @c std::string for separating elements in an array. * * @param arrayElementSeparatorString The @c std::string to use for * separating elements in an array. @@ -3092,7 +3365,7 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for a string delimiter. * - * Set this @c std::string for a string delimiter. + * Set the @c std::string for a string delimiter. * * @param stringDelimiterString The @c std::string to use for a string * delimiter. @@ -3111,7 +3384,7 @@ class LIBCELLML_EXPORT GeneratorProfile /** * @brief Set the @c std::string for a command separator. * - * Set this @c std::string for a command separator. + * Set the @c std::string for a command separator. * * @param commandSeparatorString The @c std::string to use for a command * separator. diff --git a/src/api/libcellml/importer.h b/src/api/libcellml/importer.h index ff045beb7b..bb0d577c8c 100644 --- a/src/api/libcellml/importer.h +++ b/src/api/libcellml/importer.h @@ -56,9 +56,9 @@ class LIBCELLML_EXPORT Importer: public Logger * resources and having no imports. * * @sa clone - * + * * @param model A @c ModelPtr whose imports will be resolved. - * + * * @return If the operation is successful, a new @c ModelPtr to the flattened model; otherwise, the @c nullptr. */ ModelPtr flattenModel(const ModelPtr &model); @@ -121,7 +121,7 @@ class LIBCELLML_EXPORT Importer: public Logger * * If the given key already exists in the library, the function will return false * and the library will not be changed. - * + * * @sa replaceModel * * @param model a @c ModelPtr instance to add. @@ -152,7 +152,7 @@ class LIBCELLML_EXPORT Importer: public Logger /** * @brief Clear the links with other models from all import sources. - * + * * Clear the links with other models from all import sources. */ void clearImports(ModelPtr &model); diff --git a/src/api/libcellml/issue.h b/src/api/libcellml/issue.h index 5bd78c36d3..5e011a08e6 100644 --- a/src/api/libcellml/issue.h +++ b/src/api/libcellml/issue.h @@ -103,7 +103,6 @@ class LIBCELLML_EXPORT Issue COMPONENT, CONNECTION, ENCAPSULATION, - GENERATOR, IMPORT, MATHML, MODEL, diff --git a/src/api/libcellml/module/libcellml b/src/api/libcellml/module/libcellml index fb5e9ffa34..ab6809a461 100644 --- a/src/api/libcellml/module/libcellml +++ b/src/api/libcellml/module/libcellml @@ -24,6 +24,11 @@ limitations under the License. * * This is the source code documentation for the libCellML C++ library. */ +#include "libcellml/analyser.h" +#include "libcellml/analyserequation.h" +#include "libcellml/analyserequationast.h" +#include "libcellml/analysermodel.h" +#include "libcellml/analyservariable.h" #include "libcellml/component.h" #include "libcellml/generator.h" #include "libcellml/generatorprofile.h" diff --git a/src/api/libcellml/types.h b/src/api/libcellml/types.h index 68d0a8a2f4..2e1b893d59 100644 --- a/src/api/libcellml/types.h +++ b/src/api/libcellml/types.h @@ -21,12 +21,20 @@ limitations under the License. namespace libcellml { // General classes. +class Analyser; /**< Forward declaration of Analyser class. */ +using AnalyserPtr = std::shared_ptr; /**< Type definition for shared analyser pointer. */ +class AnalyserEquation; /**< Forward declaration of AnalyserEquation class. */ +using AnalyserEquationPtr = std::shared_ptr; /**< Type definition for shared analyser equation pointer. */ +class AnalyserEquationAst; /**< Forward declaration of AnalyserEquationAst class. */ +using AnalyserEquationAstPtr = std::shared_ptr; /**< Type definition for shared analyser equation AST pointer. */ +class AnalyserModel; /**< Forward declaration of AnalyserModel class. */ +using AnalyserModelPtr = std::shared_ptr; /**< Type definition for shared analyser model pointer. */ +class AnalyserVariable; /**< Forward declaration of AnalyserVariable class. */ +using AnalyserVariablePtr = std::shared_ptr; /**< Type definition for shared analyser variable pointer. */ class Generator; /**< Forward declaration of Generator class. */ using GeneratorPtr = std::shared_ptr; /**< Type definition for shared generator pointer. */ class GeneratorProfile; /**< Forward declaration of GeneratorProfile class. */ using GeneratorProfilePtr = std::shared_ptr; /**< Type definition for shared generator variable pointer. */ -class GeneratorVariable; /**< Forward declaration of GeneratorVariable class. */ -using GeneratorVariablePtr = std::shared_ptr; /**< Type definition for shared generator variable pointer. */ class Importer; /**< Forward declaration of Importer class. */ using ImporterPtr = std::shared_ptr; /**< Type definition for shared importer pointer. */ class Issue; /**< Forward declaration of Issue class. */ diff --git a/src/api/libcellml/units.h b/src/api/libcellml/units.h index 91a5480e71..2eb4b65640 100644 --- a/src/api/libcellml/units.h +++ b/src/api/libcellml/units.h @@ -28,7 +28,9 @@ limitations under the License. // macro gets defined for backward compatibility, so we can safely undefine it. // (See https://stackoverflow.com/questions/2774171/what-is-far-pascal for more // information.) -#undef PASCAL +#ifdef PASCAL +# undef PASCAL +#endif #ifndef SWIG template class LIBCELLML_EXPORT std::weak_ptr; diff --git a/src/api/libcellml/variable.h b/src/api/libcellml/variable.h index 983cce4584..757015798c 100644 --- a/src/api/libcellml/variable.h +++ b/src/api/libcellml/variable.h @@ -22,7 +22,7 @@ limitations under the License. #include "libcellml/namedentity.h" #include "libcellml/types.h" -#ifndef SWIG +#if defined(_WIN32) && !defined(SWIG) template class LIBCELLML_EXPORT std::weak_ptr; #endif diff --git a/src/bindings/interface/analyser.i b/src/bindings/interface/analyser.i new file mode 100644 index 0000000000..d7de8eec52 --- /dev/null +++ b/src/bindings/interface/analyser.i @@ -0,0 +1,27 @@ +%module(package="libcellml") analyser + +#define LIBCELLML_EXPORT + +%import "createconstructor.i" +%import "logger.i" + +%feature("docstring") libcellml::Analyser +"Creates an :class:`Analyser` object."; + +%feature("docstring") libcellml::Analyser::analyseModel +"Analyses the model to determine whether it can be used for simulation purposes."; + +%feature("docstring") libcellml::Analyser::model +"Returns the :class:`AnalysedModel` object which results from the analysis of a model."; + +%{ +#include "libcellml/analyser.h" +%} + +%pythoncode %{ +# libCellML generated wrapper code starts here. +%} + +%create_constructor(Analyser) + +%include "libcellml/analyser.h" diff --git a/src/bindings/interface/analyserequation.i b/src/bindings/interface/analyserequation.i new file mode 100644 index 0000000000..f490b7d011 --- /dev/null +++ b/src/bindings/interface/analyserequation.i @@ -0,0 +1,40 @@ +%module(package="libcellml") analyserequation + +#define LIBCELLML_EXPORT + +%include +%include + +%feature("docstring") libcellml::AnalyserEquation +"Creates an :class:`AnalyserEquation` object."; + +%feature("docstring") libcellml::AnalyserEquation::type +"Returns the :enum:`AnalyserEquation::Type` for this :class:`AnalyserEquation` object."; + +%feature("docstring") libcellml::AnalyserEquation::ast +"Returns the :class:`AnalyserEquationAst` object for this :class:`AnalyserEquation` object."; + +%feature("docstring") libcellml::AnalyserEquation::dependencies +"Returns the list of :class:`AnalyserEquation` objects which corresponds to the equations on which this +:class:`AnalyserEquation` object depends."; + +%feature("docstring") libcellml::AnalyserEquation::isStateRateBased +"Tests if this :class:`AnalyserEquation` object relies on states and/or rates."; + +%feature("docstring") libcellml::AnalyserEquation::variable +"Returns the :class:`AnalyserVariable` object for this :class:`AnalyserEquation` object."; + +%{ +#include "libcellml/analyserequation.h" +%} + +%template(AnalyserEquationVector) std::vector; + +%pythoncode %{ +# libCellML generated wrapper code starts here. +%} + +%shared_ptr(libcellml::AnalyserEquation); + +%include "libcellml/types.h" +%include "libcellml/analyserequation.h" diff --git a/src/bindings/interface/analyserequationast.i b/src/bindings/interface/analyserequationast.i new file mode 100644 index 0000000000..2d5cd1ddda --- /dev/null +++ b/src/bindings/interface/analyserequationast.i @@ -0,0 +1,60 @@ +%module(package="libcellml") analyserequationast + +#define LIBCELLML_EXPORT + +%include + +%import "createconstructor.i" +%import "types.i" + +%feature("docstring") libcellml::AnalyserEquationAst +"Creates an :class:`AnalyserEquationAst` object."; + +%feature("docstring") libcellml::AnalyserEquationAst::type +"Returns the :enum:`AnalyserEquationAst::Type` for this :class:`AnalyserEquationAst` object."; + +%feature("docstring") libcellml::AnalyserEquationAst::setType +"Sets the :enum:`AnalyserEquationAst::Type` for this :class:`AnalyserEquationAst` object."; + +%feature("docstring") libcellml::AnalyserEquationAst::value +"Returns the value string for this :class:`AnalyserEquationAst` object."; + +%feature("docstring") libcellml::AnalyserEquationAst::setValue +"Sets the value string for this :class:`AnalyserEquationAst` object."; + +%feature("docstring") libcellml::AnalyserEquationAst::variable +"Returns the :class:`Variable` for this :class:`AnalyserEquationAst` object."; + +%feature("docstring") libcellml::AnalyserEquationAst::setVariable +"Sets the :class:`Variable` for this :class:`AnalyserEquationAst` object."; + +%feature("docstring") libcellml::AnalyserEquationAst::parent +"Returns the :class:`AnalyserEquationAst` parent for this :class:`AnalyserEquationAst` object."; + +%feature("docstring") libcellml::AnalyserEquationAst::setParent +"Sets the :class:`AnalyserEquationAst` parent for this :class:`AnalyserEquationAst` object."; + +%feature("docstring") libcellml::AnalyserEquationAst::leftChild +"Returns the :class:`AnalyserEquationAst` left child for this :class:`AnalyserEquationAst` object."; + +%feature("docstring") libcellml::AnalyserEquationAst::setLeftChild +"Sets the :class:`AnalyserEquationAst` left child for this :class:`AnalyserEquationAst` object."; + +%feature("docstring") libcellml::AnalyserEquationAst::rightChild +"Returns the :class:`AnalyserEquationAst` right child for this :class:`AnalyserEquationAst` object."; + +%feature("docstring") libcellml::AnalyserEquationAst::setRightChild +"Sets the :class:`AnalyserEquationAst` right child for this :class:`AnalyserEquationAst` object."; + +%{ +#include "libcellml/analyserequationast.h" +%} + +%pythoncode %{ +# libCellML generated wrapper code starts here. +%} + +%create_constructor(AnalyserEquationAst) + +%include "libcellml/types.h" +%include "libcellml/analyserequationast.h" diff --git a/src/bindings/interface/analysermodel.i b/src/bindings/interface/analysermodel.i new file mode 100644 index 0000000000..c60b847cd4 --- /dev/null +++ b/src/bindings/interface/analysermodel.i @@ -0,0 +1,133 @@ +%module(package="libcellml") analysermodel + +#define LIBCELLML_EXPORT + +%include +%include + +%feature("docstring") libcellml::AnalyserModel +"Creates an :class:`AnalyserModel` object."; + +%feature("docstring") libcellml::AnalyserModel::isValid +"Tests if this :class:`AnalyserModel` object is valid."; + +%feature("docstring") libcellml::AnalyserModel::type +"Returns the :enum:`AnalyserModel::Type`."; + +%feature("docstring") libcellml::AnalyserModel::voi +"Returns the :class:`AnalyserVariable` for the variable of integration."; + +%feature("docstring") libcellml::AnalyserModel::stateCount +"Returns the number of states contained by this :class:`AnalyserModel` object."; + +%feature("docstring") libcellml::AnalyserModel::states +"Returns the states contained by this :class:`AnalyserModel` object."; + +%feature("docstring") libcellml::AnalyserModel::state +"Returns the state, specified by index, contained by this :class:`AnalyserModel` object."; + +%feature("docstring") libcellml::AnalyserModel::variableCount +"Returns the number of variables contained by this :class:`AnalyserModel` object."; + +%feature("docstring") libcellml::AnalyserModel::variables +"Returns the variables contained by this :class:`AnalyserModel` object."; + +%feature("docstring") libcellml::AnalyserModel::variable +"Returns the variable, specified by index, contained by this :class:`AnalyserModel` object."; + +%feature("docstring") libcellml::AnalyserModel::equationCount +"Returns the number of equations contained by this :class:`AnalyserModel` object."; + +%feature("docstring") libcellml::AnalyserModel::equations +"Returns the equations contained by this :class:`AnalyserModel` object."; + +%feature("docstring") libcellml::AnalyserModel::equation +"Returns the equation, specified by index, contained by this :class:`AnalyserModel` object."; + +%feature("docstring") libcellml::AnalyserModel::needEqFunction +"Tests if this :class:`AnalyserModel` object needs an \"equal to\" function."; + +%feature("docstring") libcellml::AnalyserModel::needNeqFunction +"Tests if this :class:`AnalyserModel` object needs a \"not equal to\" function."; + +%feature("docstring") libcellml::AnalyserModel::needLtFunction +"Tests if this :class:`AnalyserModel` object needs a \"less than\" function."; + +%feature("docstring") libcellml::AnalyserModel::needLeqFunction +"Tests if this :class:`AnalyserModel` object needs a \"less than or equal to\" function."; + +%feature("docstring") libcellml::AnalyserModel::needGtFunction +"Tests if this :class:`AnalyserModel` object needs a \"greater than\" function."; + +%feature("docstring") libcellml::AnalyserModel::needGeqFunction +"Tests if this :class:`AnalyserModel` object needs a \"greater than or equal to\" function."; + +%feature("docstring") libcellml::AnalyserModel::needAndFunction +"Tests if this :class:`AnalyserModel` object needs an \"and\" function."; + +%feature("docstring") libcellml::AnalyserModel::needOrFunction +"Tests if this :class:`AnalyserModel` object needs an \"or\" function."; + +%feature("docstring") libcellml::AnalyserModel::needXorFunction +"Tests if this :class:`AnalyserModel` object needs a \"exclusive or\" function."; + +%feature("docstring") libcellml::AnalyserModel::needNotFunction +"Tests if this :class:`AnalyserModel` object needs a \"not\" function."; + +%feature("docstring") libcellml::AnalyserModel::needMinFunction +"Tests if this :class:`AnalyserModel` object needs a \"minimum\" function."; + +%feature("docstring") libcellml::AnalyserModel::needMaxFunction +"Tests if this :class:`AnalyserModel` object needs a \"maximum\" function."; + +%feature("docstring") libcellml::AnalyserModel::needSecFunction +"Tests if this :class:`AnalyserModel` object needs a \"secant\" function."; + +%feature("docstring") libcellml::AnalyserModel::needCscFunction +"Tests if this :class:`AnalyserModel` object needs a \"cosecant\" function."; + +%feature("docstring") libcellml::AnalyserModel::needCotFunction +"Tests if this :class:`AnalyserModel` object needs a \"cotangent\" function."; + +%feature("docstring") libcellml::AnalyserModel::needSechFunction +"Tests if this :class:`AnalyserModel` object needs a \"hyperbolic secant\" function."; + +%feature("docstring") libcellml::AnalyserModel::needCschFunction +"Tests if this :class:`AnalyserModel` object needs a \"hyperbolic cosecant\" function."; + +%feature("docstring") libcellml::AnalyserModel::needCothFunction +"Tests if this :class:`AnalyserModel` object needs a \"hyperbolic cotangent\" function."; + +%feature("docstring") libcellml::AnalyserModel::needAsecFunction +"Tests if this :class:`AnalyserModel` object needs an \"arc secant\" function."; + +%feature("docstring") libcellml::AnalyserModel::needAcscFunction +"Tests if this :class:`AnalyserModel` object needs an \"arc cosecant\" function."; + +%feature("docstring") libcellml::AnalyserModel::needAcotFunction +"Tests if this :class:`AnalyserModel` object needs an \"arc cotangent\" function."; + +%feature("docstring") libcellml::AnalyserModel::needAsechFunction +"Tests if this :class:`AnalyserModel` object needs an \"arc hyperbolic secant\" function."; + +%feature("docstring") libcellml::AnalyserModel::needAcschFunction +"Tests if this :class:`AnalyserModel` object needs an \"arc hyperbolic cosecant\" function."; + +%feature("docstring") libcellml::AnalyserModel::needAcothFunction +"Tests if this :class:`AnalyserModel` object needs an \"arc hyperbolic cotangent\" function."; + +%{ +#include "libcellml/analysermodel.h" +%} + +%template(AnalyserEquationVector) std::vector; +%template(AnalyserVariableVector) std::vector; + +%pythoncode %{ +# libCellML generated wrapper code starts here. +%} + +%shared_ptr(libcellml::AnalyserModel); + +%include "libcellml/types.h" +%include "libcellml/analysermodel.h" diff --git a/src/bindings/interface/analyservariable.i b/src/bindings/interface/analyservariable.i new file mode 100644 index 0000000000..90fb1cf691 --- /dev/null +++ b/src/bindings/interface/analyservariable.i @@ -0,0 +1,36 @@ +%module(package="libcellml") analyservariable + +#define LIBCELLML_EXPORT + +%include + +%feature("docstring") libcellml::AnalyserVariable +"Creates an :class:`AnalyserVariable` object."; + +%feature("docstring") libcellml::AnalyserVariable::type +"Returns the :enum:`AnalyserVariable::Type`."; + +%feature("docstring") libcellml::AnalyserVariable::index +"Returns the index."; + +%feature("docstring") libcellml::AnalyserVariable::initialisingVariable +"Returns the initialising :class:`Variable`."; + +%feature("docstring") libcellml::AnalyserVariable::variable +"Returns the :class:`Variable`."; + +%feature("docstring") libcellml::AnalyserVariable::equation +"Returns the :class:`AnalyserEquation`."; + +%{ +#include "libcellml/analyservariable.h" +%} + +%pythoncode %{ +# libCellML generated wrapper code starts here. +%} + +%shared_ptr(libcellml::AnalyserVariable); + +%include "libcellml/types.h" +%include "libcellml/analyservariable.h" diff --git a/src/bindings/interface/generator.i b/src/bindings/interface/generator.i index 7abc67bb96..96e4f4fa85 100644 --- a/src/bindings/interface/generator.i +++ b/src/bindings/interface/generator.i @@ -4,60 +4,30 @@ %include +%import "analysermodel.i" %import "createconstructor.i" %import "generatorprofile.i" -%import "logger.i" -%import "types.i" - - -%feature("docstring") libcellml::GeneratorVariable -"Defines a variable created by processing a :class:`Model` with the :class:`Generator`."; - -%feature("docstring") libcellml::GeneratorVariable::initialisingVariable -"Return the initialising :class:`Variable`."; - -%feature("docstring") libcellml::GeneratorVariable::variable -"Return the :class:`Variable`."; - -%feature("docstring") libcellml::GeneratorVariable::type -"Return the :enum:`GeneratorVariable::Type`."; %feature("docstring") libcellml::Generator -"Can generate code from a :class:`Model` according to a code generation profile."; +"Creates a :class:`Generator` object."; %feature("docstring") libcellml::Generator::profile -"Returns the :enum:`Profile` type."; +"Returns the profile used for code generation."; %feature("docstring") libcellml::Generator::setProfile -"Sets this :class:`Generator`'s profile."; - -%feature("docstring") libcellml::Generator::processModel -"Process the :class:`Model` given, analysing, and -preparing for code generation."; +"Sets the profile to use for code generation."; -%feature("docstring") libcellml::Generator::modelType -"Return the :enum:`ModelType` of the :class:`Model` that has been processed."; +%feature("docstring") libcellml::Generator::model +"Returns the model used for code generation."; -%feature("docstring") libcellml::Generator::stateCount -"Return the number of states found in the processed :class:`Model`."; - -%feature("docstring") libcellml::Generator::variableCount -"Return the number of variables found in the processed :class:`Model`."; - -%feature("docstring") libcellml::Generator::voi -"Return the variable of integration found in the processed :class:`Model`."; - -%feature("docstring") libcellml::Generator::state -"Return the state at the given index from the state array."; - -%feature("docstring") libcellml::Generator::variable -"Return the variable at the given index from the variable array."; +%feature("docstring") libcellml::Generator::setModel +"Sets the model to use for code generation."; %feature("docstring") libcellml::Generator::interfaceCode -"Return the interface code for the :class:`Model` processed."; +"Returns the interface code."; %feature("docstring") libcellml::Generator::implementationCode -"Return the implementation code for the :class:`Model` processed."; +"Returns the implementation code."; %{ #include "libcellml/generator.h" @@ -67,14 +37,6 @@ preparing for code generation."; # libCellML generated wrapper code starts here. %} -%pythonappend libcellml::Generator::Generator %{ -from libcellml import GeneratorProfile -profile = GeneratorProfile(GeneratorProfile.Profile.PYTHON) -self.setProfile(profile) -%} - -%create_constructor(GeneratorVariable) %create_constructor(Generator) -%include "libcellml/types.h" %include "libcellml/generator.h" diff --git a/src/bindings/interface/generatorprofile.i b/src/bindings/interface/generatorprofile.i index bba7c2f5a1..696e317cf5 100644 --- a/src/bindings/interface/generatorprofile.i +++ b/src/bindings/interface/generatorprofile.i @@ -8,8 +8,7 @@ %import "types.i" %feature("docstring") libcellml::GeneratorProfile -"Holds the information for the :class:`Generator` to generate code -according to this profile."; +"Holds the information for the :class:`Generator` to generate code according to this profile."; %feature("docstring") libcellml::GeneratorProfile::profile "Return the :enum:`GeneratorProfile::Profile` for this :class:`GeneratorProfile`."; @@ -24,602 +23,601 @@ according to this profile."; "Set whether this :class:`GeneratorProfile` requires an interface."; %feature("docstring") libcellml::GeneratorProfile::assignmentString -"Return the assigment operator."; +"Return the string representing the MathML \"assigment\" operator."; %feature("docstring") libcellml::GeneratorProfile::setAssignmentString -"Set the assigment operator."; +"Set the string representing the MathML \"assigment\" operator."; %feature("docstring") libcellml::GeneratorProfile::eqString -"Return the equivalence operator."; +"Return the string representing the MathML \"equal to\" operator."; %feature("docstring") libcellml::GeneratorProfile::setEqString -"Set the equivalence operator."; +"Set the string representing the MathML \"equal to\" operator."; %feature("docstring") libcellml::GeneratorProfile::neqString -"Return the the nonequivalence operator."; +"Return the the string representing the MathML \"not equal to\" operator."; %feature("docstring") libcellml::GeneratorProfile::setNeqString -"Set the nonequivalence operator."; +"Set the string representing the MathML \"not equal to\" operator."; %feature("docstring") libcellml::GeneratorProfile::ltString -"Return the less than operator."; +"Return the string representing the MathML \"less than\" operator."; %feature("docstring") libcellml::GeneratorProfile::setLtString -"Set the less than operator."; +"Set the string representing the MathML \"less than\" operator."; %feature("docstring") libcellml::GeneratorProfile::leqString -"Return the less than or equal operator."; +"Return the string representing the MathML \"less than or equal to\" operator."; %feature("docstring") libcellml::GeneratorProfile::setLeqString -"Set the less than or equal operator."; +"Set the string representing the MathML \"less than or equal to\" operator."; %feature("docstring") libcellml::GeneratorProfile::gtString -"Return the greater than operator."; +"Return the string representing the MathML \"greater than\" operator."; %feature("docstring") libcellml::GeneratorProfile::setGtString -"Set the greater than operator."; +"Set the string representing the MathML \"greater than\" operator."; %feature("docstring") libcellml::GeneratorProfile::geqString -"Return the greater than or equal operator."; +"Return the string representing the MathML \"greater than or equal to\ operator."; %feature("docstring") libcellml::GeneratorProfile::setGeqString -"Set the greater than or equal operator."; +"Set the string representing the MathML \"greater than or equal to\" operator."; %feature("docstring") libcellml::GeneratorProfile::andString -"Return the and operator."; +"Return the string representing the MathML \"and\" operator."; %feature("docstring") libcellml::GeneratorProfile::setAndString -"Set the and operator."; +"Set the string representing the MathML \"and\" operator."; %feature("docstring") libcellml::GeneratorProfile::orString -"Return the or operator."; +"Return the string representing the MathML \"or\" operator."; %feature("docstring") libcellml::GeneratorProfile::setOrString -"Set the or operator."; +"Set the string representing the MathML \"or\" operator."; %feature("docstring") libcellml::GeneratorProfile::xorString -"Return the exclusive or operator."; +"Return the string representing the MathML \"exclusive or\" operator."; %feature("docstring") libcellml::GeneratorProfile::setXorString -"Set the exclusive or operator."; +"Set the string representing the MathML \"exclusive or\" operator."; %feature("docstring") libcellml::GeneratorProfile::notString -"Return the not operator."; +"Return the string representing the MathML \"not\" operator."; %feature("docstring") libcellml::GeneratorProfile::setNotString -"Set the not operator."; +"Set the string representing the MathML \"not\" operator."; %feature("docstring") libcellml::GeneratorProfile::hasEqOperator -"Test if this :class:`GeneratorProfile` has an equivalence operator."; +"Test if this :class:`GeneratorProfile` has an \"equal to\" operator."; %feature("docstring") libcellml::GeneratorProfile::setHasEqOperator -"Set whether this :class:`GeneratorProfile` has an equivalence operator."; +"Set whether this :class:`GeneratorProfile` has an \"equal to\" operator."; %feature("docstring") libcellml::GeneratorProfile::hasNeqOperator -"Test if this :class:`GeneratorProfile` has a nonequivalence operator."; +"Test if this :class:`GeneratorProfile` has a \"not equal to\" operator."; %feature("docstring") libcellml::GeneratorProfile::setHasNeqOperator -"Set whether this :class:`GeneratorProfile` has a nonequivalence operator."; +"Set whether this :class:`GeneratorProfile` has a \"not equal to\" operator."; %feature("docstring") libcellml::GeneratorProfile::hasLtOperator -"Test if this :class:`GeneratorProfile` has a less than operator."; +"Test if this :class:`GeneratorProfile` has a \"less than\" operator."; %feature("docstring") libcellml::GeneratorProfile::setHasLtOperator -"Set whether this :class:`GeneratorProfile` has a less than operator."; +"Set whether this :class:`GeneratorProfile` has a \"less than\" operator."; %feature("docstring") libcellml::GeneratorProfile::hasLeqOperator -"Test if this :class:`GeneratorProfile` has a less than or equal to operator."; +"Test if this :class:`GeneratorProfile` has a \"less than or equal to\" operator."; %feature("docstring") libcellml::GeneratorProfile::setHasLeqOperator -"Set whether this :class:`GeneratorProfile` has a less than or equal to operator."; +"Set whether this :class:`GeneratorProfile` has a \"less than or equal to\" operator."; %feature("docstring") libcellml::GeneratorProfile::hasGtOperator -"Test if this :class:`GeneratorProfile` has a greater than operator."; +"Test if this :class:`GeneratorProfile` has a \"greater than\" operator."; %feature("docstring") libcellml::GeneratorProfile::setHasGtOperator -"Set whether this :class:`GeneratorProfile` has a greater than operator."; +"Set whether this :class:`GeneratorProfile` has a \"greater than\" operator."; %feature("docstring") libcellml::GeneratorProfile::hasGeqOperator -"Test if this :class:`GeneratorProfile` has a greater than or equal to operator."; +"Test if this :class:`GeneratorProfile` has a \"greater than or equal to\" operator."; %feature("docstring") libcellml::GeneratorProfile::setHasGeqOperator -"Set whether this :class:`GeneratorProfile` has a greater than or equal to operator."; +"Set whether this :class:`GeneratorProfile` has a \"greater than or equal to\" operator."; %feature("docstring") libcellml::GeneratorProfile::hasAndOperator -"Test if this :class:`GeneratorProfile` has an and operator."; +"Test if this :class:`GeneratorProfile` has an \"and\" operator."; %feature("docstring") libcellml::GeneratorProfile::setHasAndOperator -"Set whether this :class:`GeneratorProfile` has an and operator."; +"Set whether this :class:`GeneratorProfile` has an \"and\" operator."; %feature("docstring") libcellml::GeneratorProfile::hasOrOperator -"Test if this :class:`GeneratorProfile` has an or operator."; +"Test if this :class:`GeneratorProfile` has an \"or\" operator."; %feature("docstring") libcellml::GeneratorProfile::setHasOrOperator -"Set whether this :class:`GeneratorProfile` has an or operator."; +"Set whether this :class:`GeneratorProfile` has an \"or\" operator."; %feature("docstring") libcellml::GeneratorProfile::hasXorOperator -"Test if this :class:`GeneratorProfile` has an exclusive or operator."; +"Test if this :class:`GeneratorProfile` has an \"exclusive or\" operator."; %feature("docstring") libcellml::GeneratorProfile::setHasXorOperator -"Set whether this :class:`GeneratorProfile` has an exclusive or operator."; +"Set whether this :class:`GeneratorProfile` has an \"exclusive or\" operator."; %feature("docstring") libcellml::GeneratorProfile::hasNotOperator -"Test if this :class:`GeneratorProfile` has a not operator."; +"Test if this :class:`GeneratorProfile` has a \"not\" operator."; %feature("docstring") libcellml::GeneratorProfile::setHasNotOperator -"Set whether this :class:`GeneratorProfile` has a not operator."; +"Set whether this :class:`GeneratorProfile` has a \"not\" operator."; %feature("docstring") libcellml::GeneratorProfile::plusString -"Return the string for addition."; +"Return the string representing the MathML \"plus\" operator."; %feature("docstring") libcellml::GeneratorProfile::setPlusString -"Set the string for addition."; +"Set the string representing the MathML \"plus\" operator."; %feature("docstring") libcellml::GeneratorProfile::minusString -"Return the string for subtraction."; +"Return the string representing the MathML \"minus\" operator."; %feature("docstring") libcellml::GeneratorProfile::setMinusString -"Set the string for subtraction."; +"Set the string representing the MathML \"minus\" operator."; %feature("docstring") libcellml::GeneratorProfile::timesString -"Return the string for multiplication."; +"Return the string representing the MathML \"times\" operator."; %feature("docstring") libcellml::GeneratorProfile::setTimesString -"Set the string for multiplication."; +"Set the string representing the MathML \"times\" operator."; %feature("docstring") libcellml::GeneratorProfile::divideString -"Return the string for division."; +"Return the string representing the MathML \"divide\" operator."; %feature("docstring") libcellml::GeneratorProfile::setDivideString -"Set the string for division."; +"Set the string representing the MathML \"divide\" operator."; %feature("docstring") libcellml::GeneratorProfile::powerString -"Return the string for power."; +"Return the string representing the MathML \"power\" operator or function."; %feature("docstring") libcellml::GeneratorProfile::setPowerString -"Set the string for power."; +"Set the string representing the MathML \"power\" operator or function."; %feature("docstring") libcellml::GeneratorProfile::squareRootString -"Return the string for square root."; +"Return the string representing the MathML \"square root\" function."; %feature("docstring") libcellml::GeneratorProfile::setSquareRootString -"Set the string for square root."; +"Set the string representing the MathML \"square root\" function."; %feature("docstring") libcellml::GeneratorProfile::squareString -"Return the string for square."; +"Return the string representing the MathML \"square\" function."; %feature("docstring") libcellml::GeneratorProfile::setSquareString -"Set the string for square."; +"Set the string representing the MathML \"square\" function."; %feature("docstring") libcellml::GeneratorProfile::absoluteValueString -"Return the string for absolute value."; +"Return the string representing the MathML \"absolute value\" function."; %feature("docstring") libcellml::GeneratorProfile::setAbsoluteValueString -"Set the string for absolute value."; +"Set the string representing the MathML \"absolute value\" function."; %feature("docstring") libcellml::GeneratorProfile::exponentialString -"Return the string for addition."; +"Return the string representing the MathML \"exponential\" function."; %feature("docstring") libcellml::GeneratorProfile::setExponentialString -"Set the string for exponential."; +"Set the string representing the MathML \"exponential\" function."; -%feature("docstring") libcellml::GeneratorProfile::napierianLogarithmString -"Return the string for Napierian logarithm."; +%feature("docstring") libcellml::GeneratorProfile::naturalLogarithmString +"Return the string representing the MathML \"natural logarithm\" function."; -%feature("docstring") libcellml::GeneratorProfile::setNapierianLogarithmString -"Set the string for Napierian logarithm."; +%feature("docstring") libcellml::GeneratorProfile::setNaturalLogarithmString +"Set the string representing the MathML \"natural logarithm\" function."; %feature("docstring") libcellml::GeneratorProfile::commonLogarithmString -"Return the string for common logarithm."; +"Return the string representing the MathML \"common logarithm\" function."; %feature("docstring") libcellml::GeneratorProfile::setCommonLogarithmString -"Set the string for common logarithm."; +"Set the string representing the MathML \"common logarithm\" function."; %feature("docstring") libcellml::GeneratorProfile::ceilingString -"Return the string for ceiling."; +"Return the string representing the MathML \"ceiling\" function."; %feature("docstring") libcellml::GeneratorProfile::setCeilingString -"Set the string for ceiling."; +"Set the string representing the MathML \"ceiling\" function."; %feature("docstring") libcellml::GeneratorProfile::floorString -"Return the string for floor."; +"Return the string representing the MathML \"floor\" function."; %feature("docstring") libcellml::GeneratorProfile::setFloorString -"Set the string for floor."; +"Set the string representing the MathML \"floor\" function."; %feature("docstring") libcellml::GeneratorProfile::minString -"Return the string for minimum."; +"Return the string representing the MathML \"minimum\" function."; %feature("docstring") libcellml::GeneratorProfile::setMinString -"Set the string for minimum."; +"Set the string representing the MathML \"minimum\" function."; %feature("docstring") libcellml::GeneratorProfile::maxString -"Return the string for maximum."; +"Return the string representing the MathML \"maximum\" function."; %feature("docstring") libcellml::GeneratorProfile::setMaxString -"Set the string for maximum."; +"Set the string representing the MathML \"maximum\" function."; %feature("docstring") libcellml::GeneratorProfile::remString -"Return the string for remainder."; +"Return the string representing the MathML \"remainder\" function."; %feature("docstring") libcellml::GeneratorProfile::setRemString -"Set the string for remainder."; +"Set the string representing the MathML \"remainder\" function."; %feature("docstring") libcellml::GeneratorProfile::hasPowerOperator -"Test if this :class:`GeneratorProfile` has a power operator."; +"Test if this :class:`GeneratorProfile` has a \"power\" operator."; %feature("docstring") libcellml::GeneratorProfile::setHasPowerOperator -"Set whether this :class:`GeneratorProfile` has a power operator."; +"Set whether this :class:`GeneratorProfile` has a \"power\" operator."; %feature("docstring") libcellml::GeneratorProfile::sinString -"Return the string for sine."; +"Return the string representing the MathML \"sine\" function."; %feature("docstring") libcellml::GeneratorProfile::setSinString -"Set the string for sine."; +"Set the string representing the MathML \"sine\" function."; %feature("docstring") libcellml::GeneratorProfile::cosString -"Return the string for cosine."; +"Return the string representing the MathML \"cosine\" function."; %feature("docstring") libcellml::GeneratorProfile::setCosString -"Set the string for cosine."; +"Set the string representing the MathML \"cosine\" function."; %feature("docstring") libcellml::GeneratorProfile::tanString -"Return the string for tangent."; +"Return the string representing the MathML \"tangent\" function."; %feature("docstring") libcellml::GeneratorProfile::setTanString -"Set the string for tangent."; +"Set the string representing the MathML \"tangent\" function."; %feature("docstring") libcellml::GeneratorProfile::secString -"Return the string for secant."; +"Return the string representing the MathML \"secant\" function."; %feature("docstring") libcellml::GeneratorProfile::setSecString -"Set the string for secant."; +"Set the string representing the MathML \"secant\" function."; %feature("docstring") libcellml::GeneratorProfile::cscString -"Return the string for cosecant."; +"Return the string representing the MathML \"cosecant\" function."; %feature("docstring") libcellml::GeneratorProfile::setCscString -"Set the string for cosecant."; +"Set the string representing the MathML \"cosecant\" function."; %feature("docstring") libcellml::GeneratorProfile::cotString -"Return the string for cotangent."; +"Return the string representing the MathML \"cotangent\" function."; %feature("docstring") libcellml::GeneratorProfile::setCotString -"Set the string for cotangent."; +"Set the string representing the MathML \"cotangent\" function."; %feature("docstring") libcellml::GeneratorProfile::sinhString -"Return the string for hyperbolic sine."; +"Return the string representing the MathML \"hyperbolic sine\" function."; %feature("docstring") libcellml::GeneratorProfile::setSinhString -"Set the string for hyperbolic sine."; +"Set the string representing the MathML \"hyperbolic sine\" function."; %feature("docstring") libcellml::GeneratorProfile::coshString -"Return the string for hyperbolic cosine."; +"Return the string representing the MathML \"hyperbolic cosine\" function."; %feature("docstring") libcellml::GeneratorProfile::setCoshString -"Set the string for hyperbolic cosine."; +"Set the string representing the MathML \"hyperbolic cosine\" function."; %feature("docstring") libcellml::GeneratorProfile::tanhString -"Return the string for hyperbolic tangent."; +"Return the string representing the MathML \"hyperbolic tangent\" function."; %feature("docstring") libcellml::GeneratorProfile::setTanhString -"Set the string for hyperbolic tangent."; +"Set the string representing the MathML \"hyperbolic tangent\" function."; %feature("docstring") libcellml::GeneratorProfile::sechString -"Return the string for hyperbolic secant."; +"Return the string representing the MathML \"hyperbolic secant\" function."; %feature("docstring") libcellml::GeneratorProfile::setSechString -"Set the string for hyperbolic secant."; +"Set the string representing the MathML \"hyperbolic secant\" function."; %feature("docstring") libcellml::GeneratorProfile::cschString -"Return the string for hyperbolic cosecant."; +"Return the string representing the MathML \"hyperbolic cosecant\" function."; %feature("docstring") libcellml::GeneratorProfile::setCschString -"Set the string for hyperbolic cosecant."; +"Set the string representing the MathML \"hyperbolic cosecant\" function."; %feature("docstring") libcellml::GeneratorProfile::cothString -"Return the string for hyperbolic cotangent."; +"Return the string representing the MathML \"hyperbolic cotangent\" function."; %feature("docstring") libcellml::GeneratorProfile::setCothString -"Set the string for hyperbolic cotangent."; +"Set the string representing the MathML \"hyperbolic cotangent\" function."; %feature("docstring") libcellml::GeneratorProfile::asinString -"Return the string for inverse sine."; +"Return the string representing the MathML \"arc sine\" function."; %feature("docstring") libcellml::GeneratorProfile::setAsinString -"Set the string for inverse sine."; +"Set the string representing the MathML \"arc sine\" function."; %feature("docstring") libcellml::GeneratorProfile::acosString -"Return the string for inverse cosine."; +"Return the string representing the MathML \"arc cosine\" function."; %feature("docstring") libcellml::GeneratorProfile::setAcosString -"Set the string for inverse cosine."; +"Set the string representing the MathML \"arc cosine\" function."; %feature("docstring") libcellml::GeneratorProfile::atanString -"Return the string for inverse tangent."; +"Return the string representing the MathML \"arc tangent\" function."; %feature("docstring") libcellml::GeneratorProfile::setAtanString -"Set the string for inverse tangent."; +"Set the string representing the MathML \"arc tangent\" function."; %feature("docstring") libcellml::GeneratorProfile::asecString -"Return the string for inverse secant."; +"Return the string representing the MathML \"arc secant\" function."; %feature("docstring") libcellml::GeneratorProfile::setAsecString -"Set the string for inverse secant."; +"Set the string representing the MathML \"arc secant\" function."; %feature("docstring") libcellml::GeneratorProfile::acscString -"Return the string for inverse cosecant."; +"Return the string representing the MathML \"arc cosecant\" function."; %feature("docstring") libcellml::GeneratorProfile::setAcscString -"Set the string for inverse cosecant."; +"Set the string representing the MathML \"arc cosecant\" function."; %feature("docstring") libcellml::GeneratorProfile::acotString -"Return the string for inverse cotangent."; +"Return the string representing the MathML \"arc cotangent\" function."; %feature("docstring") libcellml::GeneratorProfile::setAcotString -"Set the string for inverse cotangent."; +"Set the string representing the MathML \"arc cotangent\" function."; %feature("docstring") libcellml::GeneratorProfile::asinhString -"Return the string for inverse hyperbolic sine."; +"Return the string representing the MathML \"arc hyperbolic sine\" function."; %feature("docstring") libcellml::GeneratorProfile::setAsinhString -"Set the string for inverse hyperbolic sine."; +"Set the string representing the MathML \"arc hyperbolic sine\" function."; %feature("docstring") libcellml::GeneratorProfile::acoshString -"Return the string for inverse hyperbolic cosine."; +"Return the string representing the MathML \"arc hyperbolic cosine\" function."; %feature("docstring") libcellml::GeneratorProfile::setAcoshString -"Set the string for inverse hyperbolic cosine."; +"Set the string representing the MathML \"arc hyperbolic cosine\" function."; %feature("docstring") libcellml::GeneratorProfile::atanhString -"Return the string for inverse hyperbolic tangent."; +"Return the string representing the MathML \"arc hyperbolic tangent\" function."; %feature("docstring") libcellml::GeneratorProfile::setAtanhString -"Set the string for inverse hyperbolic tangent."; +"Set the string representing the MathML \"arc hyperbolic tangent\" function."; %feature("docstring") libcellml::GeneratorProfile::asechString -"Return the string for inverse hyperbolic secant."; +"Return the string representing the MathML \"arc hyperbolic secant\" function."; %feature("docstring") libcellml::GeneratorProfile::setAsechString -"Set the string for inverse hyperbolic secant."; +"Set the string representing the MathML \"arc hyperbolic secant\" function."; %feature("docstring") libcellml::GeneratorProfile::acschString -"Return the string for inverse hyperbolic cosecant."; +"Return the string representing the MathML \"arc hyperbolic cosecant\" function."; %feature("docstring") libcellml::GeneratorProfile::setAcschString -"Set the string for inverse hyperbolic cosecant."; +"Set the string representing the MathML \"arc hyperbolic cosecant\" function."; %feature("docstring") libcellml::GeneratorProfile::acothString -"Return the string for inverse hyperbolic tangent."; +"Return the string representing the MathML \"arc hyperbolic tangent\" function."; %feature("docstring") libcellml::GeneratorProfile::setAcothString -"Set the string for inverse hyperbolic tangent."; +"Set the string representing the MathML \"arc hyperbolic tangent\" function."; %feature("docstring") libcellml::GeneratorProfile::conditionalOperatorIfString -"Return the if part of a condition statement."; +"Return the string representing the MathML \"if\" part of a \"conditional\" statement or operator."; %feature("docstring") libcellml::GeneratorProfile::setConditionalOperatorIfString -"Set the if part of a condition statement."; +"Set the string representing the MathML \"if\" part of a \"conditional\" statement or operator."; %feature("docstring") libcellml::GeneratorProfile::conditionalOperatorElseString -"Return the else part of a condition statement."; +"Return the string representing the MathML \"else\" part of a \"conditional\" statement or operator."; %feature("docstring") libcellml::GeneratorProfile::setConditionalOperatorElseString -"Set the else part of a condition statement."; +"Set the string representing the MathML \"else\" part of a \"conditional\" statement or operator."; %feature("docstring") libcellml::GeneratorProfile::piecewiseIfString -"Return the if part of a piecewise statement."; +"Return the string representing the MathML \"if\" part of a \"piecewise\" statement."; %feature("docstring") libcellml::GeneratorProfile::setPiecewiseIfString -"Set the if part of a piecewise statement."; +"Set the string representing the MathML \"if\" part of a \"piecewise\" statement."; %feature("docstring") libcellml::GeneratorProfile::piecewiseElseString -"Return the else part of a piecewise statement."; +"Return the string representing the MathML \"else\" part of a \"piecewise\" statement."; %feature("docstring") libcellml::GeneratorProfile::setPiecewiseElseString -"Set the else part of a piecewise statement."; +"Set the string representing the MathML \"else\" part of a \"piecewise\" statement."; %feature("docstring") libcellml::GeneratorProfile::hasConditionalOperator -"Test if this :class:`GeneratorProfile` has a conditional operator."; +"Test if this :class:`GeneratorProfile` has a \"conditional\" operator."; %feature("docstring") libcellml::GeneratorProfile::setHasConditionalOperator -"Set whether this :class:`GeneratorProfile` has a conditional operator."; +"Set whether this :class:`GeneratorProfile` has a \"conditional\" operator."; %feature("docstring") libcellml::GeneratorProfile::trueString -"Return the string for true."; +"Return the string representing the MathML \"true\" boolean."; %feature("docstring") libcellml::GeneratorProfile::setTrueString -"Set the string for true."; +"Set the string representing the MathML \"true\" boolean."; %feature("docstring") libcellml::GeneratorProfile::falseString -"Return the string for false."; +"Return the string representing the MathML \"false\" boolean."; %feature("docstring") libcellml::GeneratorProfile::setFalseString -"Set the string for false."; +"Set the string representing the MathML \"false\" boolean."; %feature("docstring") libcellml::GeneratorProfile::eString -"Return the string for exponential constant."; +"Return the string representing the MathML \"Euler's number\"."; %feature("docstring") libcellml::GeneratorProfile::setEString -"Set the string for exponential constant."; +"Set the string representing the MathML \"Euler's number\"."; %feature("docstring") libcellml::GeneratorProfile::piString -"Return the string for pi."; +"Return the string representing the MathML \"Ï€\" constant."; %feature("docstring") libcellml::GeneratorProfile::setPiString -"Set the string for pi."; +"Set the string representing the MathML \"Ï€\" constant."; %feature("docstring") libcellml::GeneratorProfile::infString -"Return the string for infinity."; +"Return the string representing the MathML \"infinity\" value."; %feature("docstring") libcellml::GeneratorProfile::setInfString -"Set the string for infinity."; +"Set the string representing the MathML \"infinity\" value."; %feature("docstring") libcellml::GeneratorProfile::nanString -"Return the string for NaN."; +"Return the string representing the MathML \"not-a-number\" value."; %feature("docstring") libcellml::GeneratorProfile::setNanString -"Set the string for NaN."; +"Set the string representing the MathML \"not-a-number\" value."; %feature("docstring") libcellml::GeneratorProfile::eqFunctionString -"Return the string for the equivalence function."; +"Return the string for the \"equal to\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setEqFunctionString -"Set the string for the equivalence function."; +"Set the string for the \"equal to\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::neqFunctionString -"Return the string for the nonequivalence function."; +"Return the string for the \"not equal to\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setNeqFunctionString -"Set the string for the nonequivalence function."; +"Set the string for the \"not equal to\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::ltFunctionString -"Return the string for the less than function."; +"Return the string for the \"less than\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setLtFunctionString -"Set the string for the less than function."; +"Set the string for the \"less than\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::leqFunctionString -"Return the string for the less than or equal to function."; +"Return the string for the \"less than or equal to\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setLeqFunctionString -"Set the string for the less than or equal to function."; +"Set the string for the \"less than or equal to\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::gtFunctionString -"Return the string for the greater than function."; +"Return the string for the \"greater than\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setGtFunctionString -"Set the string for the greater than function."; +"Set the string for the \"greater than\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::geqFunctionString -"Return the string for the greater than or equal to function."; +"Return the string for the \"greater than or equal to\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setGeqFunctionString -"Set the string for the greater than or equal to function."; +"Set the string for the \"greater than or equal to\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::andFunctionString -"Return the string for the and function."; +"Return the string for the \"and\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setAndFunctionString -"Set the string for the and function."; +"Set the string for the \"and\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::orFunctionString -"Return the string for the or function."; +"Return the string for the \"or\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setOrFunctionString -"Set the string for the or function."; +"Set the string for the \"or\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::xorFunctionString -"Return the string for the exclusive or function."; +"Return the string for the \"exclusive or\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setXorFunctionString -"Set the string for the exclusive function."; +"Set the string for the \"exclusive or\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::notFunctionString -"Return the string for the not function."; +"Return the string for the \"not\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setNotFunctionString -"Set the string for the not function."; +"Set the string for the \"not\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::minFunctionString -"Return the string for the minimum function."; +"Return the string for the \"minimum\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setMinFunctionString -"Set the string for the minimum function."; +"Set the string for the \"minimum\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::maxFunctionString -"Return the string for the maximum function."; +"Return the string for the \"maximum\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setMaxFunctionString -"Set the string for the maximum function."; +"Set the string for the \"maximum\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::secFunctionString -"Return the string for the secant function."; +"Return the string for the \"secant\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setSecFunctionString -"Set the string for the secant function."; +"Set the string for the \"secant\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::cscFunctionString -"Return the string for the cosecant function."; +"Return the string for the \"cosecant\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setCscFunctionString -"Set the string for the cosecant function."; +"Set the string for the \"cosecant\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::cotFunctionString -"Return the string for the cotangent function."; +"Return the string for the \"cotangent\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setCotFunctionString -"Set the string for the cotangent function."; +"Set the string for the \"cotangent\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::sechFunctionString -"Return the string for the hyperbolic secant function."; +"Return the string for the \"hyperbolic secant\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setSechFunctionString -"Set the string for the hyperbolic secant function."; +"Set the string for the \"hyperbolic secant\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::cschFunctionString -"Return the string for the hyperbolic cosecant function."; +"Return the string for the \"hyperbolic cosecant\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setCschFunctionString -"Set the string for the hyperbolic cosecant function."; +"Set the string for the \"hyperbolic cosecant\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::cothFunctionString -"Return the string for the hyperbolic cotangent function."; +"Return the string for the \"hyperbolic cotangent\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setCothFunctionString -"Set the string for the hyperbolic cotangent function."; +"Set the string for the \"hyperbolic cotangent\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::asecFunctionString -"Return the string for the inverse secant function."; +"Return the string for the \"arc secant\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setAsecFunctionString -"Set the string for the inverse secant function."; +"Set the string for the \"arc secant\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::acscFunctionString -"Return the string for the inverse cosecant function."; +"Return the string for the \"arc cosecant\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setAcscFunctionString -"Set the string for the inverse cosecant function."; +"Set the string for the \"arc cosecant\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::acotFunctionString -"Return the string for the inverse cotangent function."; +"Return the string for the \"arc cotangent\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setAcotFunctionString -"Set the string for the inverse cotangent function."; +"Set the string for the \"arc cotangent\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::asechFunctionString -"Return the string for the inverse hyperbolic secant function."; +"Return the string for the \"arc hyperbolic secant\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setAsechFunctionString -"Set the string for the inverse hyperbolic secant function."; +"Set the string for the \"arc hyperbolic secant\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::acschFunctionString -"Return the string for the inverse hyperbolic cosecant function."; +"Return the string for the \"arc hyperbolic cosecant\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setAcschFunctionString -"Set the string for the inverse hyperbolic cosecant function."; +"Set the string for the \"arc hyperbolic cosecant\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::acothFunctionString -"Return the string for the inverse hyperbolic cotangent function."; +"Return the string for the \"arc hyperbolic cotangent\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::setAcothFunctionString -"Set the string for the inverse hyperbolic cotangent function."; +"Set the string for the \"arc hyperbolic cotangent\" function implementation."; %feature("docstring") libcellml::GeneratorProfile::commentString "Return the string for a comment."; %feature("docstring") libcellml::GeneratorProfile::setCommentString -"Set the string for a comment. To be useful, the string should -contain the tag, which will be replaced with a (proper) comment."; +"Set the string for a comment. To be useful, the string should contain the tag, which will be replaced +with a (proper) comment."; %feature("docstring") libcellml::GeneratorProfile::originCommentString "Return the string for an origin comment."; %feature("docstring") libcellml::GeneratorProfile::setOriginCommentString -"Set the string for an origin comment. To be useful, the string -should contain the and tags, -which will be replaced with a statement about the profile and the version of -libCellML used respectively."; +"Set the string for an origin comment. To be useful, the string should contain the and + tags, which will be replaced with a statement about the profile and the version of libCellML +used respectively."; %feature("docstring") libcellml::GeneratorProfile::interfaceFileNameString "Return the string for the interface file name."; @@ -673,9 +671,8 @@ libCellML used respectively."; "Return the string for the implementation of the state count constant."; %feature("docstring") libcellml::GeneratorProfile::setImplementationStateCountString -"Set the string for the implementation of the state count -constant. To be useful, the string should contain the tag, -which will be replaced with the number of states in the model."; +"Set the string for the implementation of the state count constant. To be useful, the string should contain the + tag, which will be replaced with the number of states in the model."; %feature("docstring") libcellml::GeneratorProfile::interfaceVariableCountString "Return the string for the interface of the variable count constant."; @@ -687,16 +684,14 @@ which will be replaced with the number of states in the model."; "Return the string for the implementation of the variable count constant."; %feature("docstring") libcellml::GeneratorProfile::setImplementationVariableCountString -"Set the string for the implementation of the variable count -constant. To be useful, the string should contain the -tag, which will be replaced with the number of states in the model."; +"Set the string for the implementation of the variable count constant. To be useful, the string should contain +the tag, which will be replaced with the number of states in the model."; %feature("docstring") libcellml::GeneratorProfile::variableTypeObjectString "Return the string for the data structure for the variable type object."; %feature("docstring") libcellml::GeneratorProfile::setVariableTypeObjectString -"Set the string for the data structure for the variable -type object."; +"Set the string for the data structure for the variable type object."; %feature("docstring") libcellml::GeneratorProfile::constantVariableTypeString "Return the string for the name of the constant variable type."; @@ -717,100 +712,77 @@ type object."; "Set the string for the name of the algebraic variable type."; %feature("docstring") libcellml::GeneratorProfile::variableInfoObjectString -"Return the string for the data structure for the variable -information object."; +"Return the string for the data structure for the variable information object."; %feature("docstring") libcellml::GeneratorProfile::setVariableInfoObjectString -"Set the string for the data structure for the variable -information object. To be useful, the string should contain the -, and tags, which will be -replaced with the maximum size of a string for holding the name of a -component, variable and units, respectively."; +"Set the string for the data structure for the variable information object. To be useful, the string should +contain the , and tags, which will be replaced with the maximum size of +a string for holding the name of a component, variable and units, respectively."; %feature("docstring") libcellml::GeneratorProfile::variableInfoWithTypeObjectString -"Return the string for the data structure for the variable -information (incl. its type) object."; +"Return the string for the data structure for the variable information (incl. its type) object."; %feature("docstring") libcellml::GeneratorProfile::setVariableInfoWithTypeObjectString -"Set the string for the data structure for the variable -information (incl. its type) object. To be useful, the string should -contain the , and tags, which -will be replaced with the maximum size of a string for holding the name -of a component, variable and units, respectively."; +"Set the string for the data structure for the variable information (incl. its type) object. To be useful, the +string should contain the , and tags, which will be replaced with the +maximum size of a string for holding the name of a component, variable and units, respectively."; %feature("docstring") libcellml::GeneratorProfile::interfaceVoiInfoString -"Return the string for the interface of some information about the -variable of integration."; +"Return the string for the interface of some information about the variable of integration."; %feature("docstring") libcellml::GeneratorProfile::setInterfaceVoiInfoString -"Set the string for the interface of some information about the -variable of integration."; +"Set the string for the interface of some information about the variable of integration."; %feature("docstring") libcellml::GeneratorProfile::implementationVoiInfoString -"Return the string for the implementation of some information -about the variable of integration."; +"Return the string for the implementation of some information about the variable of integration."; %feature("docstring") libcellml::GeneratorProfile::setImplementationVoiInfoString -"Set the string for the implementation of some information about -the variable of integration. To be useful, the string should contain the - tag, which will be replaced with some information about the -variable of integration."; +"Set the string for the implementation of some information about the variable of integration. To be useful, the +string should contain the tag, which will be replaced with some information about the variable of +integration."; %feature("docstring") libcellml::GeneratorProfile::interfaceStateInfoString -"Return the string for the interface of some information about the -different states."; +"Return the string for the interface of some information about the different states."; %feature("docstring") libcellml::GeneratorProfile::setInterfaceStateInfoString -"Set the string for the interface of some information about the -different states."; +"Set the string for the interface of some information about the different states."; %feature("docstring") libcellml::GeneratorProfile::implementationStateInfoString -"Return the string for the implementation of some information -about the different states."; +"Return the string for the implementation of some information about the different states."; %feature("docstring") libcellml::GeneratorProfile::setImplementationStateInfoString -"Set the string for the implementation of some information about -the different states. To be useful, the string should contain the -tag, which will be replaced with some information about the different -states."; +"Set the string for the implementation of some information about the different states. To be useful, the string +should contain the tag, which will be replaced with some information about the different states."; %feature("docstring") libcellml::GeneratorProfile::interfaceVariableInfoString -"Return the string for the interface of some information about the -different variables."; +"Return the string for the interface of some information about the different variables."; %feature("docstring") libcellml::GeneratorProfile::setInterfaceVariableInfoString -"Set the string for the interface of some information about the -different variables."; +"Set the string for the interface of some information about the different variables."; %feature("docstring") libcellml::GeneratorProfile::implementationVariableInfoString -"Return the string for the implementation of some information -about the different variables."; +"Return the string for the implementation of some information about the different variables."; %feature("docstring") libcellml::GeneratorProfile::setImplementationVariableInfoString -"Set the string for the implementation of some information about -the different variables. To be useful, the string should contain the - tag, which will be replaced with some information about the -different variables."; +"Set the string for the implementation of some information about the different variables. To be useful, the +string should contain the tag, which will be replaced with some information about the different +variables."; %feature("docstring") libcellml::GeneratorProfile::variableInfoEntryString -"Return the string for an entry in an array for some information -about a variable."; +"Return the string for an entry in an array for some information about a variable."; %feature("docstring") libcellml::GeneratorProfile::setVariableInfoEntryString -"Set the string for an entry in an array for some information -about a variable. To be useful, the string should contain the -, and tags, which will be replaced with the -name of the component, name and units of a variable respectively."; +"Set the string for an entry in an array for some information about a variable. To be useful, the string should +contain the , and tags, which will be replaced with the name of the component, name +and units of a variable respectively."; %feature("docstring") libcellml::GeneratorProfile::variableInfoWithTypeEntryString -"Return the string for an entry in an array for some information -about a variable (incl. its type)."; +"Return the string for an entry in an array for some information about a variable (incl. its type)."; %feature("docstring") libcellml::GeneratorProfile::setVariableInfoWithTypeEntryString -"Set the string for an entry in an array for some information -about a variable (incl. its type). To be useful, the string should -contain the , and tags, which will be replaced -with the name of the component, name and units of a variable."; +"Set the string for an entry in an array for some information about a variable (incl. its type). To be useful, +the string should contain the , and tags, which will be replaced with the name of the +component, name and units of a variable."; %feature("docstring") libcellml::GeneratorProfile::voiString "Return the string for the name of the variable of integration."; @@ -837,42 +809,36 @@ with the name of the component, name and units of a variable."; "Set the string for the name of the variables array."; %feature("docstring") libcellml::GeneratorProfile::setReturnCreatedArrayString -"Set the string for returning a created array. To be useful, the -string should contain the tag, which will be replaced with -the size of the array to be created."; +"Set the string for returning a created array. To be useful, the string should contain the tag, +which will be replaced with the size of the array to be created."; %feature("docstring") libcellml::GeneratorProfile::interfaceCreateStatesArrayMethodString "Return the string for the interface to create the states array."; %feature("docstring") libcellml::GeneratorProfile::setInterfaceCreateStatesArrayMethodString -"Set the string for the interface to create the states array. To -be useful, the string should contain the tag, which will be -replaced with some code to create the states array."; +"Set the string for the interface to create the states array. To be useful, the string should contain the +tag, which will be replaced with some code to create the states array."; %feature("docstring") libcellml::GeneratorProfile::implementationCreateStatesArrayMethodString -"Return the string for the implementation to create the states -array."; +"Return the string for the implementation to create the states array."; %feature("docstring") libcellml::GeneratorProfile::setImplementationCreateStatesArrayMethodString -"Set the string for the implementation to create the states -array. To be useful, the string should contain the tag, which will -be replaced with some code to create the states array."; +"Set the string for the implementation to create the states array. To be useful, the string should contain the + tag, which will be replaced with some code to create the states array."; %feature("docstring") libcellml::GeneratorProfile::interfaceCreateVariablesArrayMethodString "Return the string for the interface to create variables array."; %feature("docstring") libcellml::GeneratorProfile::setInterfaceCreateVariablesArrayMethodString -"Set the string for the interface to create variables array. To -be useful, the string should contain the tag, which will be -replaced with some code to create the variables array."; +"Set the string for the interface to create variables array. To be useful, the string should contain the +tag, which will be replaced with some code to create the variables array."; %feature("docstring") libcellml::GeneratorProfile::implementationCreateVariablesArrayMethodString "Return the string for the implementation to create the variables array."; %feature("docstring") libcellml::GeneratorProfile::setImplementationCreateVariablesArrayMethodString -"Set the string for the implementation to create the variables -array. To be useful, the string should contain the tag, which will -be replaced with some code to create the variables array."; +"Set the string for the implementation to create the variables array. To be useful, the string should contain the + tag, which will be replaced with some code to create the variables array."; %feature("docstring") libcellml::GeneratorProfile::interfaceDeleteArrayMethodString "Return the string for the interface to delete an array."; @@ -886,16 +852,16 @@ be replaced with some code to create the variables array."; %feature("docstring") libcellml::GeneratorProfile::setImplementationDeleteArrayMethodString "Set the string for the implementation to delete an array."; -%feature("docstring") libcellml::GeneratorProfile::interfaceInitializeStatesAndConstantsMethodString +%feature("docstring") libcellml::GeneratorProfile::interfaceInitialiseStatesAndConstantsMethodString "Return the string for the interface to initialise states and constants."; -%feature("docstring") libcellml::GeneratorProfile::setInterfaceInitializeStatesAndConstantsMethodString +%feature("docstring") libcellml::GeneratorProfile::setInterfaceInitialiseStatesAndConstantsMethodString "Set the string for the interface to initialise states and constants."; -%feature("docstring") libcellml::GeneratorProfile::implementationInitializeStatesAndConstantsMethodString +%feature("docstring") libcellml::GeneratorProfile::implementationInitialiseStatesAndConstantsMethodString "Return the string for the implementation to initialise states and constants."; -%feature("docstring") libcellml::GeneratorProfile::setImplementationInitializeStatesAndConstantsMethodString +%feature("docstring") libcellml::GeneratorProfile::setImplementationInitialiseStatesAndConstantsMethodString "Set the string for the implementation to initialise states and constants."; %feature("docstring") libcellml::GeneratorProfile::interfaceComputeComputedConstantsMethodString @@ -946,17 +912,17 @@ be replaced with some code to create the variables array."; %feature("docstring") libcellml::GeneratorProfile::setIndentString "Set the string for an indent."; -%feature("docstring") libcellml::GeneratorProfile::openArrayInitializerString -"Return the string for opening an array initializer."; +%feature("docstring") libcellml::GeneratorProfile::openArrayInitialiserString +"Return the string for opening an array initialiser."; -%feature("docstring") libcellml::GeneratorProfile::setOpenArrayInitializerString -"Set the string for opening an array initializer."; +%feature("docstring") libcellml::GeneratorProfile::setOpenArrayInitialiserString +"Set the string for opening an array initialiser."; -%feature("docstring") libcellml::GeneratorProfile::closeArrayInitializerString -"Return the string for closing an array initializer."; +%feature("docstring") libcellml::GeneratorProfile::closeArrayInitialiserString +"Return the string for closing an array initialiser."; -%feature("docstring") libcellml::GeneratorProfile::setCloseArrayInitializerString -"Set the string for closing an array initializer."; +%feature("docstring") libcellml::GeneratorProfile::setCloseArrayInitialiserString +"Set the string for closing an array initialiser."; %feature("docstring") libcellml::GeneratorProfile::openArrayString "Return the string for opening an array."; diff --git a/src/bindings/interface/types.i b/src/bindings/interface/types.i index 73e27fb49c..48ec5813e8 100644 --- a/src/bindings/interface/types.i +++ b/src/bindings/interface/types.i @@ -5,12 +5,16 @@ Only meant to be included, shouldn't be passed to cmake as a module! */ %include +%shared_ptr(libcellml::Analyser) +%shared_ptr(libcellml::AnalyserEquation) +%shared_ptr(libcellml::AnalyserEquationAst) +%shared_ptr(libcellml::AnalyserModel) +%shared_ptr(libcellml::AnalyserVariable) %shared_ptr(libcellml::Component) %shared_ptr(libcellml::ComponentEntity) %shared_ptr(libcellml::Entity) %shared_ptr(libcellml::Generator) %shared_ptr(libcellml::GeneratorProfile) -%shared_ptr(libcellml::GeneratorVariable) %shared_ptr(libcellml::Importer) %shared_ptr(libcellml::ImportSource) %shared_ptr(libcellml::ImportedEntity) @@ -27,12 +31,12 @@ Only meant to be included, shouldn't be passed to cmake as a module! // Shared typemaps -%typemap(in) libcellml::Generator::ModelType (int val, int ecode) { +%typemap(in) libcellml::AnalyserEquationAst::Type (int val, int ecode) { ecode = SWIG_AsVal(int)($input, &val); if (!SWIG_IsOK(ecode)) { %argument_fail(ecode, "$type", $symname, $argnum); } else { - if (val < %static_cast($type::UNKNOWN, int) || %static_cast($type::UNSUITABLY_CONSTRAINED, int) < val) { + if (val < %static_cast($type::ASSIGNMENT, int) || %static_cast($type::NAN, int) < val) { %argument_fail(ecode, "$type is not a valid value for the enumeration.", $symname, $argnum); } $1 = %static_cast(val,$basetype); diff --git a/src/bindings/python/CMakeLists.txt b/src/bindings/python/CMakeLists.txt index 70f9507919..0d21a71403 100644 --- a/src/bindings/python/CMakeLists.txt +++ b/src/bindings/python/CMakeLists.txt @@ -19,6 +19,11 @@ endif() # Add swig interface files # Note: These filenames double as (generated .so file) module names! set(SWIG_INTERFACE_SRCS + ../interface/analyser.i + ../interface/analyserequation.i + ../interface/analyserequationast.i + ../interface/analysermodel.i + ../interface/analyservariable.i ../interface/component.i ../interface/componententity.i ../interface/entity.i diff --git a/src/bindings/python/__init__.py b/src/bindings/python/__init__.py index 10e87b3858..09f2ebe347 100644 --- a/src/bindings/python/__init__.py +++ b/src/bindings/python/__init__.py @@ -8,9 +8,13 @@ """ import libcellml +from libcellml.analyser import Analyser +from libcellml.analyserequation import AnalyserEquation +from libcellml.analyserequationast import AnalyserEquationAst +from libcellml.analysermodel import AnalyserModel +from libcellml.analyservariable import AnalyserVariable from libcellml.component import Component from libcellml.generator import Generator -from libcellml.generator import GeneratorVariable from libcellml.generatorprofile import GeneratorProfile from libcellml.importer import Importer from libcellml.importsource import ImportSource @@ -46,7 +50,104 @@ class Object: setattr(base if new_base is None else new_base, enum, obj) -convert(Generator, 'ModelType', [ +convert(AnalyserEquation, 'Type', [ + 'TRUE_CONSTANT', + 'VARIABLE_BASED_CONSTANT', + 'RATE', + 'ALGEBRAIC', +]) +convert(AnalyserEquationAst, 'Type', [ + 'ASSIGNMENT', + + # Relational and logical operators. + + 'EQ', + 'NEQ', + 'LT', + 'LEQ', + 'GT', + 'GEQ', + 'AND', + 'OR', + 'XOR', + 'NOT', + + # Arithmetic operators. + + 'PLUS', + 'MINUS', + 'TIMES', + 'DIVIDE', + 'POWER', + 'ROOT', + 'ABS', + 'EXP', + 'LN', + 'LOG', + 'CEILING', + 'FLOOR', + 'MIN', + 'MAX', + 'REM', + + # Calculus elements. + + 'DIFF', + + # Trigonometric operators. + + 'SIN', + 'COS', + 'TAN', + 'SEC', + 'CSC', + 'COT', + 'SINH', + 'COSH', + 'TANH', + 'SECH', + 'CSCH', + 'COTH', + 'ASIN', + 'ACOS', + 'ATAN', + 'ASEC', + 'ACSC', + 'ACOT', + 'ASINH', + 'ACOSH', + 'ATANH', + 'ASECH', + 'ACSCH', + 'ACOTH', + + # Piecewise statement. + + 'PIECEWISE', + 'PIECE', + 'OTHERWISE', + + # Token elements. + + 'CI', + 'CN', + + # Qualifier elements. + + 'DEGREE', + 'LOGBASE', + 'BVAR', + + # Constants. + + 'TRUE', + 'FALSE', + 'E', + 'PI', + 'INF', + 'NAN', +]) +convert(AnalyserModel, 'Type', [ 'UNKNOWN', 'ALGEBRAIC', 'ODE', @@ -55,22 +156,21 @@ class Object: 'OVERCONSTRAINED', 'UNSUITABLY_CONSTRAINED', ]) -convert(GeneratorProfile, 'Profile', [ - 'C', - 'PYTHON', -]) -convert(GeneratorVariable, 'Type', [ +convert(AnalyserVariable, 'Type', [ 'VARIABLE_OF_INTEGRATION', 'STATE', 'CONSTANT', 'COMPUTED_CONSTANT', 'ALGEBRAIC', ]) +convert(GeneratorProfile, 'Profile', [ + 'C', + 'PYTHON', +]) convert(Issue, 'Cause', [ 'COMPONENT', 'CONNECTION', 'ENCAPSULATION', - 'GENERATOR', 'IMPORT', 'MATHML', 'MODEL', diff --git a/src/debug.cpp b/src/debug.cpp index f4756e5ea3..af61c8ade4 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -16,10 +16,13 @@ limitations under the License. #include "debug.h" +#include "libcellml/analyserequationast.h" #include "libcellml/generator.h" #include "libcellml/variable.h" -#undef NAN +#ifdef NAN +# undef NAN +#endif namespace libcellml { @@ -63,23 +66,23 @@ void printStringStringMap(const StringStringMap &map) static const std::string SPACES = " "; static const std::string TRUNK = " │"; -struct GeneratorEquationAstTrunk +struct AnalyserEquationAstTrunk { - GeneratorEquationAstTrunk *mPrev; + AnalyserEquationAstTrunk *mPrev; std::string mStr; - GeneratorEquationAstTrunk(GeneratorEquationAstTrunk *prev, - const std::string &str); + AnalyserEquationAstTrunk(AnalyserEquationAstTrunk *prev, + const std::string &str); }; -GeneratorEquationAstTrunk::GeneratorEquationAstTrunk(GeneratorEquationAstTrunk *prev, - const std::string &str) +AnalyserEquationAstTrunk::AnalyserEquationAstTrunk(AnalyserEquationAstTrunk *prev, + const std::string &str) : mPrev(prev) , mStr(str) { } -void doPrintAst(GeneratorEquationAstTrunk *trunk) +void doPrintAst(AnalyserEquationAstTrunk *trunk) { if (trunk == nullptr) { return; @@ -95,294 +98,294 @@ void doPrintAst(GeneratorEquationAstTrunk *trunk) std::cout << trunk->mStr; } -std::string doPrintAst(const GeneratorEquationAstPtr &ast) +std::string doPrintAst(const AnalyserEquationAstPtr &ast) { std::string res; - switch (ast->mType) { + switch (ast->type()) { // Assignment. - case GeneratorEquationAst::Type::ASSIGNMENT: + case AnalyserEquationAst::Type::ASSIGNMENT: res = "ASSIGNMENT"; break; // Relational and logical operators. - case GeneratorEquationAst::Type::EQ: + case AnalyserEquationAst::Type::EQ: res = "EQ"; break; - case GeneratorEquationAst::Type::NEQ: + case AnalyserEquationAst::Type::NEQ: res = "NEQ"; break; - case GeneratorEquationAst::Type::LT: + case AnalyserEquationAst::Type::LT: res = "LT"; break; - case GeneratorEquationAst::Type::LEQ: + case AnalyserEquationAst::Type::LEQ: res = "LEQ"; break; - case GeneratorEquationAst::Type::GT: + case AnalyserEquationAst::Type::GT: res = "GT"; break; - case GeneratorEquationAst::Type::GEQ: + case AnalyserEquationAst::Type::GEQ: res = "LEQ"; break; - case GeneratorEquationAst::Type::AND: + case AnalyserEquationAst::Type::AND: res = "AND"; break; - case GeneratorEquationAst::Type::OR: + case AnalyserEquationAst::Type::OR: res = "OR"; break; - case GeneratorEquationAst::Type::XOR: + case AnalyserEquationAst::Type::XOR: res = "XOR"; break; - case GeneratorEquationAst::Type::NOT: + case AnalyserEquationAst::Type::NOT: res = "NOT"; break; // Arithmetic operators. - case GeneratorEquationAst::Type::PLUS: + case AnalyserEquationAst::Type::PLUS: res = "PLUS"; break; - case GeneratorEquationAst::Type::MINUS: + case AnalyserEquationAst::Type::MINUS: res = "MINUS"; break; - case GeneratorEquationAst::Type::TIMES: + case AnalyserEquationAst::Type::TIMES: res = "TIMES"; break; - case GeneratorEquationAst::Type::DIVIDE: + case AnalyserEquationAst::Type::DIVIDE: res = "DIVIDE"; break; - case GeneratorEquationAst::Type::POWER: + case AnalyserEquationAst::Type::POWER: res = "POWER"; break; - case GeneratorEquationAst::Type::ROOT: + case AnalyserEquationAst::Type::ROOT: res = "ROOT"; break; - case GeneratorEquationAst::Type::ABS: + case AnalyserEquationAst::Type::ABS: res = "ABS"; break; - case GeneratorEquationAst::Type::EXP: + case AnalyserEquationAst::Type::EXP: res = "EXP"; break; - case GeneratorEquationAst::Type::LN: + case AnalyserEquationAst::Type::LN: res = "LN"; break; - case GeneratorEquationAst::Type::LOG: + case AnalyserEquationAst::Type::LOG: res = "LOG"; break; - case GeneratorEquationAst::Type::CEILING: + case AnalyserEquationAst::Type::CEILING: res = "CEILING"; break; - case GeneratorEquationAst::Type::FLOOR: + case AnalyserEquationAst::Type::FLOOR: res = "FLOOR"; break; - case GeneratorEquationAst::Type::MIN: + case AnalyserEquationAst::Type::MIN: res = "MIN"; break; - case GeneratorEquationAst::Type::MAX: + case AnalyserEquationAst::Type::MAX: res = "MAX"; break; - case GeneratorEquationAst::Type::REM: + case AnalyserEquationAst::Type::REM: res = "REM"; break; // Calculus elements. - case GeneratorEquationAst::Type::DIFF: + case AnalyserEquationAst::Type::DIFF: res = "DIFF"; break; // Trigonometric operators. - case GeneratorEquationAst::Type::SIN: + case AnalyserEquationAst::Type::SIN: res = "SIN"; break; - case GeneratorEquationAst::Type::COS: + case AnalyserEquationAst::Type::COS: res = "COS"; break; - case GeneratorEquationAst::Type::TAN: + case AnalyserEquationAst::Type::TAN: res = "TAN"; break; - case GeneratorEquationAst::Type::SEC: + case AnalyserEquationAst::Type::SEC: res = "SEC"; break; - case GeneratorEquationAst::Type::CSC: + case AnalyserEquationAst::Type::CSC: res = "CSC"; break; - case GeneratorEquationAst::Type::COT: + case AnalyserEquationAst::Type::COT: res = "COT"; break; - case GeneratorEquationAst::Type::SINH: + case AnalyserEquationAst::Type::SINH: res = "SINH"; break; - case GeneratorEquationAst::Type::COSH: + case AnalyserEquationAst::Type::COSH: res = "COSH"; break; - case GeneratorEquationAst::Type::TANH: + case AnalyserEquationAst::Type::TANH: res = "TANH"; break; - case GeneratorEquationAst::Type::SECH: + case AnalyserEquationAst::Type::SECH: res = "SECH"; break; - case GeneratorEquationAst::Type::CSCH: + case AnalyserEquationAst::Type::CSCH: res = "CSCH"; break; - case GeneratorEquationAst::Type::COTH: + case AnalyserEquationAst::Type::COTH: res = "COTH"; break; - case GeneratorEquationAst::Type::ASIN: + case AnalyserEquationAst::Type::ASIN: res = "ASIN"; break; - case GeneratorEquationAst::Type::ACOS: + case AnalyserEquationAst::Type::ACOS: res = "ACOS"; break; - case GeneratorEquationAst::Type::ATAN: + case AnalyserEquationAst::Type::ATAN: res = "ATAN"; break; - case GeneratorEquationAst::Type::ASEC: + case AnalyserEquationAst::Type::ASEC: res = "ASEC"; break; - case GeneratorEquationAst::Type::ACSC: + case AnalyserEquationAst::Type::ACSC: res = "ACSC"; break; - case GeneratorEquationAst::Type::ACOT: + case AnalyserEquationAst::Type::ACOT: res = "ACOT"; break; - case GeneratorEquationAst::Type::ASINH: + case AnalyserEquationAst::Type::ASINH: res = "ASINH"; break; - case GeneratorEquationAst::Type::ACOSH: + case AnalyserEquationAst::Type::ACOSH: res = "ACOSH"; break; - case GeneratorEquationAst::Type::ATANH: + case AnalyserEquationAst::Type::ATANH: res = "ATANH"; break; - case GeneratorEquationAst::Type::ASECH: + case AnalyserEquationAst::Type::ASECH: res = "ASECH"; break; - case GeneratorEquationAst::Type::ACSCH: + case AnalyserEquationAst::Type::ACSCH: res = "ACSCH"; break; - case GeneratorEquationAst::Type::ACOTH: + case AnalyserEquationAst::Type::ACOTH: res = "ACOTH"; break; // Piecewise statement. - case GeneratorEquationAst::Type::PIECEWISE: + case AnalyserEquationAst::Type::PIECEWISE: res = "PIECEWISE"; break; - case GeneratorEquationAst::Type::PIECE: + case AnalyserEquationAst::Type::PIECE: res = "PIECE"; break; - case GeneratorEquationAst::Type::OTHERWISE: + case AnalyserEquationAst::Type::OTHERWISE: res = "OTHERWISE"; break; // Token elements. - case GeneratorEquationAst::Type::CI: - res = ast->mVariable->name(); + case AnalyserEquationAst::Type::CI: + res = ast->variable()->name(); break; - case GeneratorEquationAst::Type::CN: - res = ast->mValue; + case AnalyserEquationAst::Type::CN: + res = ast->value(); break; // Qualifier elements. - case GeneratorEquationAst::Type::DEGREE: + case AnalyserEquationAst::Type::DEGREE: res = "DEGREE"; break; - case GeneratorEquationAst::Type::LOGBASE: + case AnalyserEquationAst::Type::LOGBASE: res = "LOGBASE"; break; - case GeneratorEquationAst::Type::BVAR: + case AnalyserEquationAst::Type::BVAR: res = "BVAR"; break; // Constants. - case GeneratorEquationAst::Type::TRUE: + case AnalyserEquationAst::Type::TRUE: res = "TRUE"; break; - case GeneratorEquationAst::Type::FALSE: + case AnalyserEquationAst::Type::FALSE: res = "FALSE"; break; - case GeneratorEquationAst::Type::E: + case AnalyserEquationAst::Type::E: res = "E"; break; - case GeneratorEquationAst::Type::PI: + case AnalyserEquationAst::Type::PI: res = "PI"; break; - case GeneratorEquationAst::Type::INF: + case AnalyserEquationAst::Type::INF: res = "INF"; break; - case GeneratorEquationAst::Type::NAN: + case AnalyserEquationAst::Type::NAN: res = "NAN"; break; @@ -391,17 +394,17 @@ std::string doPrintAst(const GeneratorEquationAstPtr &ast) return res; } -void doPrintAst(const GeneratorEquationAstPtr &ast, - GeneratorEquationAstTrunk *prevTrunk, bool isLeft) +void doPrintAst(const AnalyserEquationAstPtr &ast, + AnalyserEquationAstTrunk *prevTrunk, bool isLeft) { if (ast == nullptr) { return; } std::string prevStr = SPACES; - GeneratorEquationAstTrunk trunk(prevTrunk, prevStr); + AnalyserEquationAstTrunk trunk(prevTrunk, prevStr); - doPrintAst(ast->mLeft, &trunk, true); + doPrintAst(ast->leftChild(), &trunk, true); if (prevTrunk == nullptr) { trunk.mStr = "──"; @@ -423,10 +426,10 @@ void doPrintAst(const GeneratorEquationAstPtr &ast, trunk.mStr = TRUNK; - doPrintAst(ast->mRight, &trunk, false); + doPrintAst(ast->rightChild(), &trunk, false); } -void printAst(const GeneratorEquationAstPtr &ast) +void printAst(const AnalyserEquationAstPtr &ast) { doPrintAst(ast, nullptr, false); } diff --git a/src/debug.h b/src/debug.h index 276384d05c..77e18e31ed 100644 --- a/src/debug.h +++ b/src/debug.h @@ -19,7 +19,6 @@ limitations under the License. #include #include -#include "generatorequationast.h" #include "internaltypes.h" namespace libcellml { @@ -97,6 +96,6 @@ struct Debug void printStack(const IndexStack &stack); void printEquivalenceMap(const EquivalenceMap &map); void printStringStringMap(const StringStringMap &map); -void printAst(const GeneratorEquationAstPtr &ast); +void printAst(const AnalyserEquationAstPtr &ast); } // namespace libcellml diff --git a/src/generator.cpp b/src/generator.cpp index b51fafcbcf..bd6f111455 100644 --- a/src/generator.cpp +++ b/src/generator.cpp @@ -16,1755 +16,278 @@ limitations under the License. #include "libcellml/generator.h" -#include -#include -#include #include #include -#include +#include "libcellml/analyserequation.h" +#include "libcellml/analyserequationast.h" +#include "libcellml/analysermodel.h" +#include "libcellml/analyservariable.h" #include "libcellml/component.h" #include "libcellml/generatorprofile.h" -#include "libcellml/model.h" #include "libcellml/units.h" -#include "libcellml/validator.h" -#include "libcellml/variable.h" #include "libcellml/version.h" -#include "generatorequationast.h" +#include "analyserequationast_p.h" #include "utilities.h" -#include "xmldoc.h" -#ifdef __linux__ -# undef TRUE -# undef FALSE +#ifdef NAN +# undef NAN #endif -#undef NAN - -namespace libcellml { - -static const size_t MAX_SIZE_T = std::numeric_limits::max(); - -/** - * @brief The GeneratorVariable::GeneratorVariableImpl struct. - * - * The private implementation for the GeneratorVariable class. - */ -struct GeneratorVariable::GeneratorVariableImpl -{ - VariablePtr mInitialisingVariable; - VariablePtr mVariable; - GeneratorVariable::Type mType = GeneratorVariable::Type::CONSTANT; - - void populate(const VariablePtr &initialisingVariable, - const VariablePtr &variable, - GeneratorVariable::Type type); -}; - -void GeneratorVariable::GeneratorVariableImpl::populate(const VariablePtr &initialisingVariable, - const VariablePtr &variable, - GeneratorVariable::Type type) -{ - mInitialisingVariable = initialisingVariable; - mVariable = variable; - mType = type; -} - -GeneratorVariable::GeneratorVariable() - : mPimpl(new GeneratorVariableImpl()) -{ -} - -GeneratorVariable::~GeneratorVariable() -{ - delete mPimpl; -} - -GeneratorVariablePtr GeneratorVariable::create() noexcept -{ - return std::shared_ptr {new GeneratorVariable {}}; -} - -VariablePtr GeneratorVariable::initialisingVariable() const -{ - return mPimpl->mInitialisingVariable; -} - -VariablePtr GeneratorVariable::variable() const -{ - return mPimpl->mVariable; -} - -GeneratorVariable::Type GeneratorVariable::type() const -{ - return mPimpl->mType; -} - -struct GeneratorEquation; -using GeneratorEquationPtr = std::shared_ptr; -using GeneratorEquationWeakPtr = std::weak_ptr; - -struct GeneratorInternalVariable -{ - enum struct Type - { - UNKNOWN, - SHOULD_BE_STATE, - VARIABLE_OF_INTEGRATION, - STATE, - CONSTANT, - COMPUTED_TRUE_CONSTANT, - COMPUTED_VARIABLE_BASED_CONSTANT, - ALGEBRAIC, - OVERCONSTRAINED - }; - - size_t mIndex = MAX_SIZE_T; - Type mType = Type::UNKNOWN; - - VariablePtr mInitialisingVariable; - VariablePtr mVariable; - - GeneratorEquationWeakPtr mEquation; - - explicit GeneratorInternalVariable(const VariablePtr &variable); - - void setVariable(const VariablePtr &variable, - bool checkInitialValue = true); - - void makeVoi(); - void makeState(); -}; - -using GeneratorInternalVariablePtr = std::shared_ptr; - -GeneratorInternalVariable::GeneratorInternalVariable(const VariablePtr &variable) -{ - setVariable(variable); -} - -void GeneratorInternalVariable::setVariable(const VariablePtr &variable, - bool checkInitialValue) -{ - if (checkInitialValue && !variable->initialValue().empty()) { - // The variable has an initial value, so it can either be a constant or - // a state. By default, we consider it to be a constant and, if we find - // an ODE for that variable, we will know that it was actually a state. - - mType = Type::CONSTANT; - - mInitialisingVariable = variable; - } - - mVariable = variable; -} - -void GeneratorInternalVariable::makeVoi() -{ - mType = Type::VARIABLE_OF_INTEGRATION; -} - -void GeneratorInternalVariable::makeState() -{ - if (mType == Type::UNKNOWN) { - mType = Type::SHOULD_BE_STATE; - } else if (mType == Type::CONSTANT) { - mType = Type::STATE; - } -} - -GeneratorEquationAst::GeneratorEquationAst() = default; - -GeneratorEquationAst::GeneratorEquationAst(Type type, - const GeneratorEquationAstPtr &parent) - : mType(type) - , mParent(parent) -{ -} - -GeneratorEquationAst::GeneratorEquationAst(Type type, const std::string &value, - const GeneratorEquationAstPtr &parent) - : mType(type) - , mValue(value) - , mParent(parent) -{ -} - -GeneratorEquationAst::GeneratorEquationAst(Type type, const VariablePtr &variable, - const GeneratorEquationAstPtr &parent) - : mType(type) - , mVariable(variable) - , mParent(parent) -{ -} - -GeneratorEquationAst::GeneratorEquationAst(const GeneratorEquationAstPtr &ast, - const GeneratorEquationAstPtr &parent) - : mType(ast->mType) - , mVariable(ast->mVariable) - , mParent(parent) - , mLeft(ast->mLeft) - , mRight(ast->mRight) -{ -} - -#ifdef SWIG -struct GeneratorEquation -#else -struct GeneratorEquation: public std::enable_shared_from_this -#endif -{ - enum struct Type - { - UNKNOWN, - TRUE_CONSTANT, - VARIABLE_BASED_CONSTANT, - RATE, - ALGEBRAIC - }; - - size_t mOrder = MAX_SIZE_T; - Type mType = Type::UNKNOWN; - - std::list mDependencies; - - GeneratorEquationAstPtr mAst; - - std::list mVariables; - std::list mOdeVariables; - - GeneratorInternalVariablePtr mVariable = nullptr; - ComponentPtr mComponent = nullptr; - - bool mComputedTrueConstant = true; - bool mComputedVariableBasedConstant = true; - - bool mIsStateRateBased = false; - - explicit GeneratorEquation(const ComponentPtr &component); - - void addVariable(const GeneratorInternalVariablePtr &variable); - void addOdeVariable(const GeneratorInternalVariablePtr &odeVariable); - - static bool containsNonUnknownVariables(const std::list &variables); - static bool containsNonConstantVariables(const std::list &variables); - - static bool knownVariable(const GeneratorInternalVariablePtr &variable); - static bool knownOdeVariable(const GeneratorInternalVariablePtr &odeVariable); - - bool check(size_t & equationOrder, size_t & stateIndex, size_t & variableIndex); -}; - -GeneratorEquation::GeneratorEquation(const ComponentPtr &component) - : mAst(std::make_shared()) - , mComponent(component) -{ -} - -void GeneratorEquation::addVariable(const GeneratorInternalVariablePtr &variable) -{ - if (std::find(mVariables.begin(), mVariables.end(), variable) == mVariables.end()) { - mVariables.push_back(variable); - } -} - -void GeneratorEquation::addOdeVariable(const GeneratorInternalVariablePtr &odeVariable) -{ - if (std::find(mOdeVariables.begin(), mOdeVariables.end(), odeVariable) == mOdeVariables.end()) { - mOdeVariables.push_back(odeVariable); - } -} - -bool GeneratorEquation::containsNonUnknownVariables(const std::list &variables) -{ - return std::find_if(variables.begin(), variables.end(), [](const GeneratorInternalVariablePtr &variable) { - return (variable->mType != GeneratorInternalVariable::Type::UNKNOWN); - }) - != std::end(variables); -} - -bool GeneratorEquation::containsNonConstantVariables(const std::list &variables) -{ - return std::find_if(variables.begin(), variables.end(), [](const GeneratorInternalVariablePtr &variable) { - return (variable->mType != GeneratorInternalVariable::Type::UNKNOWN) - && (variable->mType != GeneratorInternalVariable::Type::CONSTANT) - && (variable->mType != GeneratorInternalVariable::Type::COMPUTED_TRUE_CONSTANT) - && (variable->mType != GeneratorInternalVariable::Type::COMPUTED_VARIABLE_BASED_CONSTANT); - }) - != std::end(variables); -} - -bool GeneratorEquation::knownVariable(const GeneratorInternalVariablePtr &variable) -{ - return (variable->mIndex != MAX_SIZE_T) - || (variable->mType == GeneratorInternalVariable::Type::VARIABLE_OF_INTEGRATION) - || (variable->mType == GeneratorInternalVariable::Type::STATE) - || (variable->mType == GeneratorInternalVariable::Type::CONSTANT) - || (variable->mType == GeneratorInternalVariable::Type::COMPUTED_TRUE_CONSTANT) - || (variable->mType == GeneratorInternalVariable::Type::COMPUTED_VARIABLE_BASED_CONSTANT); -} - -bool GeneratorEquation::knownOdeVariable(const GeneratorInternalVariablePtr &odeVariable) -{ - return (odeVariable->mIndex != MAX_SIZE_T) - || (odeVariable->mType == GeneratorInternalVariable::Type::VARIABLE_OF_INTEGRATION); -} - -bool sameOrEquivalentVariable(const VariablePtr &variable1, - const VariablePtr &variable2) -{ - // Return whether the given variables are the same or are equivalent (be it - // directly or indirectly). - - return (variable1 == variable2) || variable1->hasEquivalentVariable(variable2, true); -} - -bool GeneratorEquation::check(size_t &equationOrder, size_t &stateIndex, - size_t &variableIndex) -{ - // Nothing to check if the equation has already been given an order (i.e. - // everything is fine) or if there is one known (ODE) variable left (i.e. - // this equation is an overconstraint). - - if (mOrder != MAX_SIZE_T) { - return false; - } - - if (mVariables.size() + mOdeVariables.size() == 1) { - GeneratorInternalVariablePtr variable = (mVariables.size() == 1) ? mVariables.front() : mOdeVariables.front(); - - if ((variable->mIndex != MAX_SIZE_T) - && (variable->mType != GeneratorInternalVariable::Type::UNKNOWN) - && (variable->mType != GeneratorInternalVariable::Type::SHOULD_BE_STATE)) { - variable->mType = GeneratorInternalVariable::Type::OVERCONSTRAINED; - - return false; - } - } - - // Determine, from the (new) known (ODE) variables, whether the equation is - // truly a constant or a variable-based constant. - - mComputedTrueConstant = mComputedTrueConstant - && !containsNonUnknownVariables(mVariables) - && !containsNonUnknownVariables(mOdeVariables); - mComputedVariableBasedConstant = mComputedVariableBasedConstant - && !containsNonConstantVariables(mVariables) - && !containsNonConstantVariables(mOdeVariables); - - // Determine whether the equation is state/rate based and add, as a - // dependency, the equations used to compute the (new) known variables. - // (Note that we don't account for the (new) known ODE variables since their - // corresponding equation can obviously not be of algebraic type.) - - if (!mIsStateRateBased) { - mIsStateRateBased = !mOdeVariables.empty(); - } - - for (const auto &variable : mVariables) { - if (knownVariable(variable)) { - GeneratorEquationPtr equation = variable->mEquation.lock(); - - if (!mIsStateRateBased) { - mIsStateRateBased = (equation == nullptr) ? - (variable->mType == GeneratorInternalVariable::Type::STATE) : - equation->mIsStateRateBased; - } - - if (equation != nullptr) { - mDependencies.push_back(equation); - } - } - } - - // Stop tracking (new) known (ODE) variables. - - mVariables.remove_if(knownVariable); - mOdeVariables.remove_if(knownOdeVariable); - - // If there is one (ODE) variable left then update its viariable (to be the - // corresponding one in the component in which the equation is), its type - // (if it is currently unknown), determine its index and determine the type - // of our equation and set its order, if the (ODE) variable is a state, - // computed constant or algebraic variable. - - bool relevantCheck = false; - - if (mVariables.size() + mOdeVariables.size() == 1) { - GeneratorInternalVariablePtr variable = (mVariables.size() == 1) ? mVariables.front() : mOdeVariables.front(); - - for (size_t i = 0; i < mComponent->variableCount(); ++i) { - VariablePtr localVariable = mComponent->variable(i); - - if (sameOrEquivalentVariable(variable->mVariable, localVariable)) { - variable->setVariable(localVariable, false); - - break; - } - } - - if (variable->mType == GeneratorInternalVariable::Type::UNKNOWN) { - variable->mType = mComputedTrueConstant ? - GeneratorInternalVariable::Type::COMPUTED_TRUE_CONSTANT : - mComputedVariableBasedConstant ? - GeneratorInternalVariable::Type::COMPUTED_VARIABLE_BASED_CONSTANT : - GeneratorInternalVariable::Type::ALGEBRAIC; - } - - if ((variable->mType == GeneratorInternalVariable::Type::STATE) - || (variable->mType == GeneratorInternalVariable::Type::COMPUTED_TRUE_CONSTANT) - || (variable->mType == GeneratorInternalVariable::Type::COMPUTED_VARIABLE_BASED_CONSTANT) - || (variable->mType == GeneratorInternalVariable::Type::ALGEBRAIC)) { - variable->mIndex = (variable->mType == GeneratorInternalVariable::Type::STATE) ? - ++stateIndex : - ++variableIndex; - - variable->mEquation = shared_from_this(); - - mOrder = ++equationOrder; - mType = (variable->mType == GeneratorInternalVariable::Type::STATE) ? - Type::RATE : - (variable->mType == GeneratorInternalVariable::Type::COMPUTED_TRUE_CONSTANT) ? - Type::TRUE_CONSTANT : - (variable->mType == GeneratorInternalVariable::Type::COMPUTED_VARIABLE_BASED_CONSTANT) ? - Type::VARIABLE_BASED_CONSTANT : - Type::ALGEBRAIC; - - mVariable = variable; - - relevantCheck = true; - } - } - - return relevantCheck; -} - -/** - * @brief The Generator::GeneratorImpl struct. - * - * The private implementation for the Generator class. - */ -struct Generator::GeneratorImpl -{ - Generator *mGenerator = nullptr; - - Generator::ModelType mModelType = Generator::ModelType::UNKNOWN; - - std::list mInternalVariables; - std::list mEquations; - - GeneratorVariablePtr mVoi = nullptr; - std::vector mStates; - std::vector mVariables; - - GeneratorProfilePtr mProfile = libcellml::GeneratorProfile::create(); - - bool mNeedEq = false; - bool mNeedNeq = false; - bool mNeedLt = false; - bool mNeedLeq = false; - bool mNeedGt = false; - bool mNeedGeq = false; - bool mNeedAnd = false; - bool mNeedOr = false; - bool mNeedXor = false; - bool mNeedNot = false; - - bool mNeedMin = false; - bool mNeedMax = false; - - bool mNeedSec = false; - bool mNeedCsc = false; - bool mNeedCot = false; - bool mNeedSech = false; - bool mNeedCsch = false; - bool mNeedCoth = false; - bool mNeedAsec = false; - bool mNeedAcsc = false; - bool mNeedAcot = false; - bool mNeedAsech = false; - bool mNeedAcsch = false; - bool mNeedAcoth = false; - - static bool compareVariablesByName(const GeneratorInternalVariablePtr &variable1, - const GeneratorInternalVariablePtr &variable2); - - static bool isStateVariable(const GeneratorInternalVariablePtr &variable); - static bool isConstantOrAlgebraicVariable(const GeneratorInternalVariablePtr &variable); - - static bool compareVariablesByTypeAndIndex(const GeneratorInternalVariablePtr &variable1, - const GeneratorInternalVariablePtr &variable2); - - static bool compareEquationsByVariable(const GeneratorEquationPtr &equation1, - const GeneratorEquationPtr &equation2); - - bool hasValidModel() const; - - size_t mathmlChildCount(const XmlNodePtr &node) const; - XmlNodePtr mathmlChildNode(const XmlNodePtr &node, size_t index) const; - - GeneratorInternalVariablePtr generatorVariable(const VariablePtr &variable); - - VariablePtr voiFirstOccurrence(const VariablePtr &variable, - const ComponentPtr &component); - - void processNode(const XmlNodePtr &node, GeneratorEquationAstPtr &ast, - const GeneratorEquationAstPtr &astParent, - const ComponentPtr &component, - const GeneratorEquationPtr &equation); - GeneratorEquationPtr processNode(const XmlNodePtr &node, - const ComponentPtr &component); - void processComponent(const ComponentPtr &component); - - void doEquivalentVariables(const VariablePtr &variable, - std::vector &equivalentVariables) const; - std::vector equivalentVariables(const VariablePtr &variable) const; - - void processEquationAst(const GeneratorEquationAstPtr &ast); - - double scalingFactor(const VariablePtr &variable); - - void scaleAst(const GeneratorEquationAstPtr &ast, - const GeneratorEquationAstPtr &astParent, - double scalingFactor); - void scaleEquationAst(const GeneratorEquationAstPtr &ast); - - void processModel(const ModelPtr &model); - - bool isRelationalOperator(const GeneratorEquationAstPtr &ast) const; - bool isAndOperator(const GeneratorEquationAstPtr &ast) const; - bool isOrOperator(const GeneratorEquationAstPtr &ast) const; - bool isXorOperator(const GeneratorEquationAstPtr &ast) const; - bool isLogicalOperator(const GeneratorEquationAstPtr &ast) const; - bool isPlusOperator(const GeneratorEquationAstPtr &ast) const; - bool isMinusOperator(const GeneratorEquationAstPtr &ast) const; - bool isTimesOperator(const GeneratorEquationAstPtr &ast) const; - bool isDivideOperator(const GeneratorEquationAstPtr &ast) const; - bool isPowerOperator(const GeneratorEquationAstPtr &ast) const; - bool isRootOperator(const GeneratorEquationAstPtr &ast) const; - bool isPiecewiseStatement(const GeneratorEquationAstPtr &ast) const; - - std::string replace(std::string string, const std::string &from, - const std::string &to); - - void updateVariableInfoSizes(size_t &componentSize, size_t &nameSize, - size_t &unitsSize, - const GeneratorVariablePtr &variable); - - bool modifiedProfile() const; - - void addOriginCommentCode(std::string &code); - - void addInterfaceHeaderCode(std::string &code) const; - void addImplementationHeaderCode(std::string &code); - - void addVersionAndLibcellmlVersionCode(std::string &code, - bool interface = false); - - void addStateAndVariableCountCode(std::string &code, - bool interface = false); - - void addVariableTypeObjectCode(std::string &code) const; - - std::string generateVariableInfoObjectCode(const std::string &objectString); - - void addVariableInfoObjectCode(std::string &code); - void addVariableInfoWithTypeObjectCode(std::string &code); - - std::string generateVariableInfoEntryCode(const std::string &name, - const std::string &units, - const std::string &component); - - void addInterfaceVoiStateAndVariableInfoCode(std::string &code) const; - void addImplementationVoiInfoCode(std::string &code); - void addImplementationStateInfoCode(std::string &code); - void addImplementationVariableInfoCode(std::string &code); - - void addArithmeticFunctionsCode(std::string &code) const; - void addTrigonometricFunctionsCode(std::string &code) const; - - void addInterfaceCreateDeleteArrayMethodsCode(std::string &code) const; - void addImplementationCreateStatesArrayMethodCode(std::string &code) const; - void addImplementationCreateVariablesArrayMethodCode(std::string &code) const; - void addImplementationDeleteArrayMethodCode(std::string &code) const; - - std::string generateMethodBodyCode(const std::string &methodBody) const; - - std::string generateDoubleCode(const std::string &value); - std::string generateDoubleOrConstantVariableNameCode(const VariablePtr &variable); - std::string generateVariableNameCode(const VariablePtr &variable, - const GeneratorEquationAstPtr &ast = nullptr); - - std::string generateOperatorCode(const std::string &op, - const GeneratorEquationAstPtr &ast); - std::string generateMinusUnaryCode(const GeneratorEquationAstPtr &ast); - std::string generateOneParameterFunctionCode(const std::string &function, - const GeneratorEquationAstPtr &ast); - std::string generateTwoParameterFunctionCode(const std::string &function, - const GeneratorEquationAstPtr &ast); - std::string generatePiecewiseIfCode(const std::string &condition, - const std::string &value); - std::string generatePiecewiseElseCode(const std::string &value); - std::string generateCode(const GeneratorEquationAstPtr &ast); - - std::string generateInitializationCode(const GeneratorInternalVariablePtr &variable); - std::string generateEquationCode(const GeneratorEquationPtr &equation, - std::vector &remainingEquations, - bool onlyStateRateBasedEquations = false); - - void addInterfaceComputeModelMethodsCode(std::string &code) const; - void addImplementationInitializeStatesAndConstantsMethodCode(std::string &code, - std::vector &remainingEquations); - void addImplementationComputeComputedConstantsMethodCode(std::string &code, - std::vector &remainingEquations); - void addImplementationComputeRatesMethodCode(std::string &code, - std::vector &remainingEquations); - void addImplementationComputeVariablesMethodCode(std::string &code, - std::vector &remainingEquations); -}; - -bool Generator::GeneratorImpl::compareVariablesByName(const GeneratorInternalVariablePtr &variable1, - const GeneratorInternalVariablePtr &variable2) -{ - ComponentPtr realComponent1 = owningComponent(variable1->mVariable); - ComponentPtr realComponent2 = owningComponent(variable2->mVariable); - - if (realComponent1->name() == realComponent2->name()) { - return variable1->mVariable->name() < variable2->mVariable->name(); - } - - return realComponent1->name() < realComponent2->name(); -} - -bool Generator::GeneratorImpl::isStateVariable(const GeneratorInternalVariablePtr &variable) -{ - return variable->mType == GeneratorInternalVariable::Type::STATE; -} - -bool Generator::GeneratorImpl::isConstantOrAlgebraicVariable(const GeneratorInternalVariablePtr &variable) -{ - return (variable->mType == GeneratorInternalVariable::Type::CONSTANT) - || (variable->mType == GeneratorInternalVariable::Type::COMPUTED_TRUE_CONSTANT) - || (variable->mType == GeneratorInternalVariable::Type::COMPUTED_VARIABLE_BASED_CONSTANT) - || (variable->mType == GeneratorInternalVariable::Type::ALGEBRAIC); -} - -bool Generator::GeneratorImpl::compareVariablesByTypeAndIndex(const GeneratorInternalVariablePtr &variable1, - const GeneratorInternalVariablePtr &variable2) -{ - if (isStateVariable(variable1) && isConstantOrAlgebraicVariable(variable2)) { - return true; - } - - if (isConstantOrAlgebraicVariable(variable1) && isStateVariable(variable2)) { - return false; - } - - return variable1->mIndex < variable2->mIndex; -} - -bool Generator::GeneratorImpl::compareEquationsByVariable(const GeneratorEquationPtr &equation1, - const GeneratorEquationPtr &equation2) -{ - return compareVariablesByTypeAndIndex(equation1->mVariable, equation2->mVariable); -} - -bool Generator::GeneratorImpl::hasValidModel() const -{ - return (mModelType == Generator::ModelType::ALGEBRAIC) - || (mModelType == Generator::ModelType::ODE); -} - -size_t Generator::GeneratorImpl::mathmlChildCount(const XmlNodePtr &node) const -{ - // Return the number of child elements, in the MathML namespace, for the - // given node. - - XmlNodePtr childNode = node->firstChild(); - size_t res = childNode->isMathmlElement() ? 1 : 0; - - while (childNode != nullptr) { - childNode = childNode->next(); - - if (childNode && childNode->isMathmlElement()) { - ++res; - } - } - - return res; -} - -XmlNodePtr Generator::GeneratorImpl::mathmlChildNode(const XmlNodePtr &node, size_t index) const -{ - // Return the nth child element of the given node, skipping anything that is - // not int he MathML namespace. - - XmlNodePtr res = node->firstChild(); - size_t childNodeIndex = res->isMathmlElement() ? 0 : MAX_SIZE_T; - - while ((res != nullptr) && (childNodeIndex != index)) { - res = res->next(); - - if (res && res->isMathmlElement()) { - ++childNodeIndex; - } - } - - return res; -} - -GeneratorInternalVariablePtr Generator::GeneratorImpl::generatorVariable(const VariablePtr &variable) -{ - // Find and return, if there is one, the generator variable associated with - // the given variable. - - for (const auto &internalVariable : mInternalVariables) { - if (sameOrEquivalentVariable(variable, internalVariable->mVariable)) { - return internalVariable; - } - } - - // No generator variable exists for the given variable, so create one, track - // it and return it. - - GeneratorInternalVariablePtr internalVariable = std::make_shared(variable); - - mInternalVariables.push_back(internalVariable); - - return internalVariable; -} - -VariablePtr Generator::GeneratorImpl::voiFirstOccurrence(const VariablePtr &variable, - const ComponentPtr &component) -{ - // Recursively look for the first occurrence of the given variable in the - // given component. - - for (size_t i = 0; i < component->variableCount(); ++i) { - VariablePtr localVariable = component->variable(i); - - if (sameOrEquivalentVariable(variable, localVariable)) { - return localVariable; - } - } - - VariablePtr voi = nullptr; - - for (size_t i = 0; i < component->componentCount() && voi == nullptr; ++i) { - voi = voiFirstOccurrence(variable, component->component(i)); - } - - return voi; -} - -void Generator::GeneratorImpl::processNode(const XmlNodePtr &node, - GeneratorEquationAstPtr &ast, - const GeneratorEquationAstPtr &astParent, - const ComponentPtr &component, - const GeneratorEquationPtr &equation) -{ - // Basic content elements. - - if (node->isMathmlElement("apply")) { - // We may have 2, 3 or more child nodes, e.g. - // - // +--------+ - // | + | - // "+a" ==> | / \ | - // | a nil | - // +--------+ - // - // +-------+ - // | + | - // "a+b" ==> | / \ | - // | a b | - // +-------+ - // - // +-------------+ - // | + | - // | / \ | - // | a + | - // | / \ | - // "a+b+c+d+e" ==> | b + | - // | / \ | - // | c + | - // | / \ | - // | d e | - // +-------------+ - - size_t childCount = mathmlChildCount(node); - - processNode(mathmlChildNode(node, 0), ast, astParent, component, equation); - processNode(mathmlChildNode(node, 1), ast->mLeft, ast, component, equation); - - if (childCount >= 3) { - GeneratorEquationAstPtr astRight; - GeneratorEquationAstPtr tempAst; - - processNode(mathmlChildNode(node, childCount - 1), astRight, nullptr, component, equation); - - for (size_t i = childCount - 2; i > 1; --i) { - processNode(mathmlChildNode(node, 0), tempAst, nullptr, component, equation); - processNode(mathmlChildNode(node, i), tempAst->mLeft, tempAst, component, equation); - - astRight->mParent = tempAst; - - tempAst->mRight = astRight; - astRight = tempAst; - } - - if (astRight != nullptr) { - astRight->mParent = ast; - } - - ast->mRight = astRight; - } - - // Assignment, and relational and logical operators. - - } else if (node->isMathmlElement("eq")) { - // This element is used both to describe "a = b" and "a == b". We can - // distinguish between the two by checking its grand-parent. If it's a - // "math" element then it means that it is used to describe "a = b" - // otherwise it is used to describe "a == b". In the former case, there - // is nothing more we need to do since `ast` is already of - // GeneratorEquationAst::Type::ASSIGNMENT type. - - if (!node->parent()->parent()->isMathmlElement("math")) { - ast = std::make_shared(GeneratorEquationAst::Type::EQ, astParent); - - mNeedEq = true; - } - } else if (node->isMathmlElement("neq")) { - ast = std::make_shared(GeneratorEquationAst::Type::NEQ, astParent); - - mNeedNeq = true; - } else if (node->isMathmlElement("lt")) { - ast = std::make_shared(GeneratorEquationAst::Type::LT, astParent); - - mNeedLt = true; - } else if (node->isMathmlElement("leq")) { - ast = std::make_shared(GeneratorEquationAst::Type::LEQ, astParent); - - mNeedLeq = true; - } else if (node->isMathmlElement("gt")) { - ast = std::make_shared(GeneratorEquationAst::Type::GT, astParent); - - mNeedGt = true; - } else if (node->isMathmlElement("geq")) { - ast = std::make_shared(GeneratorEquationAst::Type::GEQ, astParent); - - mNeedGeq = true; - } else if (node->isMathmlElement("and")) { - ast = std::make_shared(GeneratorEquationAst::Type::AND, astParent); - - mNeedAnd = true; - } else if (node->isMathmlElement("or")) { - ast = std::make_shared(GeneratorEquationAst::Type::OR, astParent); - - mNeedOr = true; - } else if (node->isMathmlElement("xor")) { - ast = std::make_shared(GeneratorEquationAst::Type::XOR, astParent); - - mNeedXor = true; - } else if (node->isMathmlElement("not")) { - ast = std::make_shared(GeneratorEquationAst::Type::NOT, astParent); - - mNeedNot = true; - - // Arithmetic operators. - - } else if (node->isMathmlElement("plus")) { - ast = std::make_shared(GeneratorEquationAst::Type::PLUS, astParent); - } else if (node->isMathmlElement("minus")) { - ast = std::make_shared(GeneratorEquationAst::Type::MINUS, astParent); - } else if (node->isMathmlElement("times")) { - ast = std::make_shared(GeneratorEquationAst::Type::TIMES, astParent); - } else if (node->isMathmlElement("divide")) { - ast = std::make_shared(GeneratorEquationAst::Type::DIVIDE, astParent); - } else if (node->isMathmlElement("power")) { - ast = std::make_shared(GeneratorEquationAst::Type::POWER, astParent); - } else if (node->isMathmlElement("root")) { - ast = std::make_shared(GeneratorEquationAst::Type::ROOT, astParent); - } else if (node->isMathmlElement("abs")) { - ast = std::make_shared(GeneratorEquationAst::Type::ABS, astParent); - } else if (node->isMathmlElement("exp")) { - ast = std::make_shared(GeneratorEquationAst::Type::EXP, astParent); - } else if (node->isMathmlElement("ln")) { - ast = std::make_shared(GeneratorEquationAst::Type::LN, astParent); - } else if (node->isMathmlElement("log")) { - ast = std::make_shared(GeneratorEquationAst::Type::LOG, astParent); - } else if (node->isMathmlElement("ceiling")) { - ast = std::make_shared(GeneratorEquationAst::Type::CEILING, astParent); - } else if (node->isMathmlElement("floor")) { - ast = std::make_shared(GeneratorEquationAst::Type::FLOOR, astParent); - } else if (node->isMathmlElement("min")) { - ast = std::make_shared(GeneratorEquationAst::Type::MIN, astParent); - - mNeedMin = true; - } else if (node->isMathmlElement("max")) { - ast = std::make_shared(GeneratorEquationAst::Type::MAX, astParent); - - mNeedMax = true; - } else if (node->isMathmlElement("rem")) { - ast = std::make_shared(GeneratorEquationAst::Type::REM, astParent); - - // Calculus elements. - - } else if (node->isMathmlElement("diff")) { - ast = std::make_shared(GeneratorEquationAst::Type::DIFF, astParent); - - // Trigonometric operators. - - } else if (node->isMathmlElement("sin")) { - ast = std::make_shared(GeneratorEquationAst::Type::SIN, astParent); - } else if (node->isMathmlElement("cos")) { - ast = std::make_shared(GeneratorEquationAst::Type::COS, astParent); - } else if (node->isMathmlElement("tan")) { - ast = std::make_shared(GeneratorEquationAst::Type::TAN, astParent); - } else if (node->isMathmlElement("sec")) { - ast = std::make_shared(GeneratorEquationAst::Type::SEC, astParent); - - mNeedSec = true; - } else if (node->isMathmlElement("csc")) { - ast = std::make_shared(GeneratorEquationAst::Type::CSC, astParent); - - mNeedCsc = true; - } else if (node->isMathmlElement("cot")) { - ast = std::make_shared(GeneratorEquationAst::Type::COT, astParent); - - mNeedCot = true; - } else if (node->isMathmlElement("sinh")) { - ast = std::make_shared(GeneratorEquationAst::Type::SINH, astParent); - } else if (node->isMathmlElement("cosh")) { - ast = std::make_shared(GeneratorEquationAst::Type::COSH, astParent); - } else if (node->isMathmlElement("tanh")) { - ast = std::make_shared(GeneratorEquationAst::Type::TANH, astParent); - } else if (node->isMathmlElement("sech")) { - ast = std::make_shared(GeneratorEquationAst::Type::SECH, astParent); - - mNeedSech = true; - } else if (node->isMathmlElement("csch")) { - ast = std::make_shared(GeneratorEquationAst::Type::CSCH, astParent); - - mNeedCsch = true; - } else if (node->isMathmlElement("coth")) { - ast = std::make_shared(GeneratorEquationAst::Type::COTH, astParent); - - mNeedCoth = true; - } else if (node->isMathmlElement("arcsin")) { - ast = std::make_shared(GeneratorEquationAst::Type::ASIN, astParent); - } else if (node->isMathmlElement("arccos")) { - ast = std::make_shared(GeneratorEquationAst::Type::ACOS, astParent); - } else if (node->isMathmlElement("arctan")) { - ast = std::make_shared(GeneratorEquationAst::Type::ATAN, astParent); - } else if (node->isMathmlElement("arcsec")) { - ast = std::make_shared(GeneratorEquationAst::Type::ASEC, astParent); - - mNeedAsec = true; - } else if (node->isMathmlElement("arccsc")) { - ast = std::make_shared(GeneratorEquationAst::Type::ACSC, astParent); - - mNeedAcsc = true; - } else if (node->isMathmlElement("arccot")) { - ast = std::make_shared(GeneratorEquationAst::Type::ACOT, astParent); - - mNeedAcot = true; - } else if (node->isMathmlElement("arcsinh")) { - ast = std::make_shared(GeneratorEquationAst::Type::ASINH, astParent); - } else if (node->isMathmlElement("arccosh")) { - ast = std::make_shared(GeneratorEquationAst::Type::ACOSH, astParent); - } else if (node->isMathmlElement("arctanh")) { - ast = std::make_shared(GeneratorEquationAst::Type::ATANH, astParent); - } else if (node->isMathmlElement("arcsech")) { - ast = std::make_shared(GeneratorEquationAst::Type::ASECH, astParent); - - mNeedAsech = true; - } else if (node->isMathmlElement("arccsch")) { - ast = std::make_shared(GeneratorEquationAst::Type::ACSCH, astParent); - - mNeedAcsch = true; - } else if (node->isMathmlElement("arccoth")) { - ast = std::make_shared(GeneratorEquationAst::Type::ACOTH, astParent); - - mNeedAcoth = true; - - // Piecewise statement. - - } else if (node->isMathmlElement("piecewise")) { - size_t childCount = mathmlChildCount(node); - - ast = std::make_shared(GeneratorEquationAst::Type::PIECEWISE, astParent); - - processNode(mathmlChildNode(node, 0), ast->mLeft, ast, component, equation); - - if (childCount >= 2) { - GeneratorEquationAstPtr astRight; - GeneratorEquationAstPtr tempAst; - - processNode(mathmlChildNode(node, childCount - 1), astRight, nullptr, component, equation); - - for (size_t i = childCount - 2; i > 0; --i) { - tempAst = std::make_shared(GeneratorEquationAst::Type::PIECEWISE, astParent); - - processNode(mathmlChildNode(node, i), tempAst->mLeft, tempAst, component, equation); - - astRight->mParent = tempAst; - - tempAst->mRight = astRight; - astRight = tempAst; - } - - astRight->mParent = ast; - - ast->mRight = astRight; - } - } else if (node->isMathmlElement("piece")) { - ast = std::make_shared(GeneratorEquationAst::Type::PIECE, astParent); - - processNode(mathmlChildNode(node, 0), ast->mLeft, ast, component, equation); - processNode(mathmlChildNode(node, 1), ast->mRight, ast, component, equation); - } else if (node->isMathmlElement("otherwise")) { - ast = std::make_shared(GeneratorEquationAst::Type::OTHERWISE, astParent); - - processNode(mathmlChildNode(node, 0), ast->mLeft, ast, component, equation); - - // Token elements. - - } else if (node->isMathmlElement("ci")) { - std::string variableName = node->firstChild()->convertToStrippedString(); - VariablePtr variable = component->variable(variableName); - - if (variable != nullptr) { - // Have our equation track the (ODE) variable (by ODE variable, we - // mean a variable that is used in a "diff" element). - - if (node->parent()->firstChild()->isMathmlElement("diff")) { - equation->addOdeVariable(generatorVariable(variable)); - } else if (!(node->parent()->isMathmlElement("bvar") - && node->parent()->parent()->firstChild()->isMathmlElement("diff"))) { - equation->addVariable(generatorVariable(variable)); - } - - // Add the variable to our AST. - - ast = std::make_shared(GeneratorEquationAst::Type::CI, variable, astParent); - } else { - IssuePtr issue = Issue::create(); - - issue->setDescription("Variable '" + variableName - + "' in component '" + component->name() - + "' of model '" + owningModel(component)->name() - + "' is referenced in an equation, but it is not defined anywhere."); - issue->setCause(Issue::Cause::GENERATOR); - - mGenerator->addIssue(issue); - } - } else if (node->isMathmlElement("cn")) { - if (mathmlChildCount(node) == 1) { - // We are dealing with an e-notation based CN value. - - ast = std::make_shared(GeneratorEquationAst::Type::CN, node->firstChild()->convertToStrippedString() + "e" + node->firstChild()->next()->next()->convertToStrippedString(), astParent); - } else { - ast = std::make_shared(GeneratorEquationAst::Type::CN, node->firstChild()->convertToStrippedString(), astParent); - } - - // Qualifier elements. - - } else if (node->isMathmlElement("degree")) { - ast = std::make_shared(GeneratorEquationAst::Type::DEGREE, astParent); - - processNode(mathmlChildNode(node, 0), ast->mLeft, ast, component, equation); - } else if (node->isMathmlElement("logbase")) { - ast = std::make_shared(GeneratorEquationAst::Type::LOGBASE, astParent); - - processNode(mathmlChildNode(node, 0), ast->mLeft, ast, component, equation); - } else if (node->isMathmlElement("bvar")) { - ast = std::make_shared(GeneratorEquationAst::Type::BVAR, astParent); - - processNode(mathmlChildNode(node, 0), ast->mLeft, ast, component, equation); - - XmlNodePtr rightNode = mathmlChildNode(node, 1); - - if (rightNode != nullptr) { - processNode(rightNode, ast->mRight, ast, component, equation); - } - - // Constants. +namespace libcellml { - } else if (node->isMathmlElement("true")) { - ast = std::make_shared(GeneratorEquationAst::Type::TRUE, astParent); - } else if (node->isMathmlElement("false")) { - ast = std::make_shared(GeneratorEquationAst::Type::FALSE, astParent); - } else if (node->isMathmlElement("exponentiale")) { - ast = std::make_shared(GeneratorEquationAst::Type::E, astParent); - } else if (node->isMathmlElement("pi")) { - ast = std::make_shared(GeneratorEquationAst::Type::PI, astParent); - } else if (node->isMathmlElement("infinity")) { - ast = std::make_shared(GeneratorEquationAst::Type::INF, astParent); - } else if (node->isMathmlElement("notanumber")) { - ast = std::make_shared(GeneratorEquationAst::Type::NAN, astParent); - } -} +using AnalyserModelWeakPtr = std::weak_ptr; /**< Type definition for weak analyser model pointer. */ +using GeneratorProfileWeakPtr = std::weak_ptr; /**< Type definition for weak generator profile pointer. */ -GeneratorEquationPtr Generator::GeneratorImpl::processNode(const XmlNodePtr &node, - const ComponentPtr &component) +/** + * @brief The Generator::GeneratorImpl struct. + * + * The private implementation for the Generator class. + */ +struct Generator::GeneratorImpl { - // Create and keep track of the equation associated with the given node. - - GeneratorEquationPtr equation = std::make_shared(component); - - mEquations.push_back(equation); - - // Actually process the node and return its corresponding equation. - - processNode(node, equation->mAst, equation->mAst->mParent.lock(), component, equation); + Generator *mGenerator = nullptr; - return equation; -} + AnalyserModelWeakPtr mModel; + AnalyserModelPtr mLockedModel; -void Generator::GeneratorImpl::processComponent(const ComponentPtr &component) -{ - // Retrieve the math string associated with the given component and process - // it, one equation at a time. + std::string mCode; - XmlDocPtr xmlDoc = std::make_shared(); - std::string math = component->math(); + GeneratorProfilePtr mOwnedProfile = libcellml::GeneratorProfile::create(); + GeneratorProfileWeakPtr mProfile; + GeneratorProfilePtr mLockedProfile; - if (!math.empty()) { - xmlDoc->parseMathML(math, false); + bool retrieveLockedModelAndProfile(); + void resetLockedModelAndProfile(); - XmlNodePtr mathNode = xmlDoc->rootNode(); + AnalyserVariablePtr analyserVariable(const VariablePtr &variable) const; - for (XmlNodePtr node = mathNode->firstChild(); node != nullptr; node = node->next()) { - if (node->isMathmlElement()) { - processNode(node, component); - } - } - } + double scalingFactor(const VariablePtr &variable) const; - // Go through the given component's variables and make sure that everything - // makes sense. + bool isRelationalOperator(const AnalyserEquationAstPtr &ast) const; + bool isAndOperator(const AnalyserEquationAstPtr &ast) const; + bool isOrOperator(const AnalyserEquationAstPtr &ast) const; + bool isXorOperator(const AnalyserEquationAstPtr &ast) const; + bool isLogicalOperator(const AnalyserEquationAstPtr &ast) const; + bool isPlusOperator(const AnalyserEquationAstPtr &ast) const; + bool isMinusOperator(const AnalyserEquationAstPtr &ast) const; + bool isTimesOperator(const AnalyserEquationAstPtr &ast) const; + bool isDivideOperator(const AnalyserEquationAstPtr &ast) const; + bool isPowerOperator(const AnalyserEquationAstPtr &ast) const; + bool isRootOperator(const AnalyserEquationAstPtr &ast) const; + bool isPiecewiseStatement(const AnalyserEquationAstPtr &ast) const; - for (size_t i = 0; i < component->variableCount(); ++i) { - // Retrieve the variable's corresponding generator variable. + void updateVariableInfoSizes(size_t &componentSize, size_t &nameSize, + size_t &unitsSize, + const AnalyserVariablePtr &variable) const; - VariablePtr variable = component->variable(i); - GeneratorInternalVariablePtr generatorVariable = Generator::GeneratorImpl::generatorVariable(variable); + bool modifiedProfile() const; - // Replace the variable held by `generatorVariable`, in case the - // existing one has no initial value while `variable` does and after - // insuring that the initial value is either a double or an existing - // variable. Otherwise, generate an error if the variable held by - // `generatorVariable` and `variable` are both initialised. + void addOriginCommentCode(); - if (!variable->initialValue().empty() - && generatorVariable->mVariable->initialValue().empty()) { - generatorVariable->setVariable(variable); - } else if ((variable != generatorVariable->mVariable) - && !variable->initialValue().empty() - && !generatorVariable->mVariable->initialValue().empty()) { - IssuePtr issue = Issue::create(); - ComponentPtr trackedVariableComponent = owningComponent(generatorVariable->mVariable); + void addInterfaceHeaderCode(); + void addImplementationHeaderCode(); - issue->setDescription("Variable '" + variable->name() - + "' in component '" + component->name() - + "' of model '" + owningModel(component)->name() - + "' and variable '" + generatorVariable->mVariable->name() - + "' in component '" + trackedVariableComponent->name() - + "' of model '" + owningModel(trackedVariableComponent)->name() - + "' are equivalent and cannot therefore both be initialised."); - issue->setCause(Issue::Cause::GENERATOR); + void addVersionAndLibcellmlVersionCode(bool interface = false); - mGenerator->addIssue(issue); - } + void addStateAndVariableCountCode(bool interface = false); - if (!generatorVariable->mVariable->initialValue().empty() - && !isCellMLReal(generatorVariable->mVariable->initialValue())) { - // The initial value is not a double, so it has to be an existing - // variable of constant type. + void addVariableTypeObjectCode(); - ComponentPtr initialisingComponent = owningComponent(generatorVariable->mVariable); - VariablePtr initialisingVariable = initialisingComponent->variable(generatorVariable->mVariable->initialValue()); + std::string generateVariableInfoObjectCode(const std::string &objectString) const; - if (initialisingVariable == nullptr) { - IssuePtr issue = Issue::create(); + void addVariableInfoObjectCode(); + void addVariableInfoWithTypeObjectCode(); - issue->setDescription("Variable '" + variable->name() - + "' in component '" + component->name() - + "' of model '" + owningModel(component)->name() - + "' is initialised using variable '" + generatorVariable->mVariable->initialValue() - + "', but it is not defined anywhere."); - issue->setCause(Issue::Cause::GENERATOR); + std::string generateVariableInfoEntryCode(const std::string &name, + const std::string &units, + const std::string &component) const; - mGenerator->addIssue(issue); - } else { - GeneratorInternalVariablePtr generatorInitialValueVariable = Generator::GeneratorImpl::generatorVariable(initialisingVariable); + void addInterfaceVoiStateAndVariableInfoCode(); + void addImplementationVoiInfoCode(); + void addImplementationStateInfoCode(); + void addImplementationVariableInfoCode(); - if (generatorInitialValueVariable->mType != GeneratorInternalVariable::Type::CONSTANT) { - IssuePtr issue = Issue::create(); + void addArithmeticFunctionsCode(); + void addTrigonometricFunctionsCode(); - issue->setDescription("Variable '" + variable->name() - + "' in component '" + component->name() - + "' of model '" + owningModel(component)->name() - + "' is initialised using variable '" + generatorVariable->mVariable->initialValue() - + "', but it is not a constant."); - issue->setCause(Issue::Cause::GENERATOR); + void addInterfaceCreateDeleteArrayMethodsCode(); + void addImplementationCreateStatesArrayMethodCode(); + void addImplementationCreateVariablesArrayMethodCode(); + void addImplementationDeleteArrayMethodCode(); - mGenerator->addIssue(issue); - } - } - } - } + std::string generateMethodBodyCode(const std::string &methodBody) const; - // Do the same for the components encapsulated by the given component. + std::string generateDoubleCode(const std::string &value) const; + std::string generateDoubleOrConstantVariableNameCode(const VariablePtr &variable) const; + std::string generateVariableNameCode(const VariablePtr &variable, + const AnalyserEquationAstPtr &ast = nullptr) const; - for (size_t i = 0; i < component->componentCount(); ++i) { - processComponent(component->component(i)); - } -} + std::string generateOperatorCode(const std::string &op, + const AnalyserEquationAstPtr &ast) const; + std::string generateMinusUnaryCode(const AnalyserEquationAstPtr &ast) const; + std::string generateOneParameterFunctionCode(const std::string &function, + const AnalyserEquationAstPtr &ast) const; + std::string generateTwoParameterFunctionCode(const std::string &function, + const AnalyserEquationAstPtr &ast) const; + std::string generatePiecewiseIfCode(const std::string &condition, + const std::string &value) const; + std::string generatePiecewiseElseCode(const std::string &value) const; + std::string generateCode(const AnalyserEquationAstPtr &ast) const; + + std::string generateInitializationCode(const AnalyserVariablePtr &variable) const; + std::string generateEquationCode(const AnalyserEquationPtr &equation, + std::vector &remainingEquations, + bool onlyStateRateBasedEquations = false) const; + + void addInterfaceComputeModelMethodsCode(); + void addImplementationInitialiseStatesAndConstantsMethodCode(std::vector &remainingEquations); + void addImplementationComputeComputedConstantsMethodCode(std::vector &remainingEquations); + void addImplementationComputeRatesMethodCode(std::vector &remainingEquations); + void addImplementationComputeVariablesMethodCode(std::vector &remainingEquations); +}; -void Generator::GeneratorImpl::doEquivalentVariables(const VariablePtr &variable, - std::vector &equivalentVariables) const +bool Generator::GeneratorImpl::retrieveLockedModelAndProfile() { - for (size_t i = 0; i < variable->equivalentVariableCount(); ++i) { - VariablePtr equivalentVariable = variable->equivalentVariable(i); + mLockedModel = mGenerator->model(); + mLockedProfile = mGenerator->profile(); - if (std::find(equivalentVariables.begin(), equivalentVariables.end(), equivalentVariable) == equivalentVariables.end()) { - equivalentVariables.push_back(equivalentVariable); - - doEquivalentVariables(equivalentVariable, equivalentVariables); - } - } + return (mLockedModel != nullptr) && (mLockedProfile != nullptr); } -std::vector Generator::GeneratorImpl::equivalentVariables(const VariablePtr &variable) const +void Generator::GeneratorImpl::resetLockedModelAndProfile() { - std::vector res = {variable}; - - doEquivalentVariables(variable, res); - - return res; + mLockedModel = nullptr; + mLockedProfile = nullptr; } -void Generator::GeneratorImpl::processEquationAst(const GeneratorEquationAstPtr &ast) +AnalyserVariablePtr Generator::GeneratorImpl::analyserVariable(const VariablePtr &variable) const { - // Look for the definition of a variable of integration and make sure that - // we don't have more than one of it and that it's not initialised. - - GeneratorEquationAstPtr astParent = ast->mParent.lock(); - GeneratorEquationAstPtr astGrandParent = (astParent != nullptr) ? astParent->mParent.lock() : nullptr; - GeneratorEquationAstPtr astGreatGrandParent = (astGrandParent != nullptr) ? astGrandParent->mParent.lock() : nullptr; - - if ((ast->mType == GeneratorEquationAst::Type::CI) - && (astParent != nullptr) && (astParent->mType == GeneratorEquationAst::Type::BVAR) - && (astGrandParent != nullptr) && (astGrandParent->mType == GeneratorEquationAst::Type::DIFF)) { - VariablePtr variable = ast->mVariable; - - generatorVariable(variable)->makeVoi(); - // Note: we must make the variable a variable of integration in all - // cases (i.e. even if there is, for example, already another - // variable of integration) otherwise unnecessary issue messages - // may be reported (since the type of the variable would be - // unknown). - - if (mVoi == nullptr) { - // We have found our variable of integration, but this may not be - // the one defined in our first component (i.e. the component under - // which we are likely to expect to see the variable of integration - // to be defined), so go through our components and look for the - // first occurrence of our variable of integration. - - ModelPtr model = owningModel(variable); - - for (size_t i = 0; i < model->componentCount(); ++i) { - VariablePtr voi = voiFirstOccurrence(variable, model->component(i)); - - if (voi != nullptr) { - // We have found the first occurrence of our variable of - // integration, but now we must ensure that it (or one of - // its equivalent variables) is not initialised. - - bool isVoiInitialized = false; - - for (const auto &voiEquivalentVariable : equivalentVariables(voi)) { - if (!voiEquivalentVariable->initialValue().empty()) { - IssuePtr issue = Issue::create(); - - issue->setDescription("Variable '" + voiEquivalentVariable->name() - + "' in component '" + owningComponent(voiEquivalentVariable)->name() - + "' of model '" + owningModel(voiEquivalentVariable)->name() - + "' cannot be both a variable of integration and initialised."); - issue->setCause(Issue::Cause::GENERATOR); + // Find and return the analyser variable associated with the given variable. - mGenerator->addIssue(issue); + AnalyserVariablePtr res; + auto modelVoi = mLockedModel->voi(); - isVoiInitialized = true; - } - } + if ((modelVoi != nullptr) + && isSameOrEquivalentVariable(variable, modelVoi->variable())) { + res = modelVoi; + } else { + for (const auto &modelState : mLockedModel->states()) { + if (isSameOrEquivalentVariable(variable, modelState->variable())) { + res = modelState; - if (!isVoiInitialized) { - mVoi = GeneratorVariable::create(); + break; + } + } - mVoi->mPimpl->populate(nullptr, voi, - GeneratorVariable::Type::VARIABLE_OF_INTEGRATION); - } + if (res == nullptr) { + for (const auto &modelVariable : mLockedModel->variables()) { + if (isSameOrEquivalentVariable(variable, modelVariable->variable())) { + res = modelVariable; break; } } - } else if (!sameOrEquivalentVariable(variable, mVoi->variable())) { - IssuePtr issue = Issue::create(); - - issue->setDescription("Variable '" + mVoi->variable()->name() - + "' in component '" + owningComponent(mVoi->variable())->name() - + "' of model '" + owningModel(mVoi->variable())->name() - + "' and variable '" + variable->name() - + "' in component '" + owningComponent(variable)->name() - + "' of model '" + owningModel(variable)->name() - + "' cannot both be the variable of integration."); - issue->setCause(Issue::Cause::GENERATOR); - - mGenerator->addIssue(issue); - } - } - - // Make sure that we only use first-order ODEs. - - if ((ast->mType == GeneratorEquationAst::Type::CN) - && (astParent != nullptr) && (astParent->mType == GeneratorEquationAst::Type::DEGREE) - && (astGrandParent != nullptr) && (astGrandParent->mType == GeneratorEquationAst::Type::BVAR) - && (astGreatGrandParent != nullptr) && (astGreatGrandParent->mType == GeneratorEquationAst::Type::DIFF)) { - double value; - if (!convertToDouble(ast->mValue, value) || !areEqual(value, 1.0)) { - IssuePtr issue = Issue::create(); - VariablePtr variable = astGreatGrandParent->mRight->mVariable; - - issue->setDescription("The differential equation for variable '" + variable->name() - + "' in component '" + owningComponent(variable)->name() - + "' of model '" + owningModel(variable)->name() - + "' must be of the first order."); - issue->setCause(Issue::Cause::GENERATOR); - - mGenerator->addIssue(issue); } } - // Make a variable a state if it is used in an ODE. - - if ((ast->mType == GeneratorEquationAst::Type::CI) - && (astParent != nullptr) && (astParent->mType == GeneratorEquationAst::Type::DIFF)) { - generatorVariable(ast->mVariable)->makeState(); - } - - // Recursively check the given AST's children. - - if (ast->mLeft != nullptr) { - processEquationAst(ast->mLeft); - } - - if (ast->mRight != nullptr) { - processEquationAst(ast->mRight); - } + return res; } -double Generator::GeneratorImpl::scalingFactor(const VariablePtr &variable) +double Generator::GeneratorImpl::scalingFactor(const VariablePtr &variable) const { // Return the scaling factor for the given variable. return Units::scalingFactor(variable->units(), - generatorVariable(variable)->mVariable->units()); -} - -void Generator::GeneratorImpl::scaleAst(const GeneratorEquationAstPtr &ast, - const GeneratorEquationAstPtr &astParent, - double scalingFactor) -{ - // Scale the given AST using the given scaling factor - - GeneratorEquationAstPtr scaledAst = std::make_shared(GeneratorEquationAst::Type::TIMES, astParent); - - scaledAst->mLeft = std::make_shared(GeneratorEquationAst::Type::CN, convertToString(scalingFactor), scaledAst); - scaledAst->mRight = ast; - - ast->mParent = scaledAst; - - if (astParent->mLeft == ast) { - astParent->mLeft = scaledAst; - } else { - astParent->mRight = scaledAst; - } -} - -void Generator::GeneratorImpl::scaleEquationAst(const GeneratorEquationAstPtr &ast) -{ - // Recursively scale the given AST's children. - - if (ast->mLeft != nullptr) { - scaleEquationAst(ast->mLeft); - } - - if (ast->mRight != nullptr) { - scaleEquationAst(ast->mRight); - } - - // If the given AST node is a variabe (i.e. a CI node) then we may need to - // do some scaling. - - if (ast->mType == GeneratorEquationAst::Type::CI) { - // The kind of scaling we may end up doing depends on whether we are - // dealing with a rate or some other variable, i.e. whether or not it - // has a DIFF node as a parent. - - GeneratorEquationAstPtr astParent = ast->mParent.lock(); - if (astParent->mType == GeneratorEquationAst::Type::DIFF) { - // We are dealing with a rate, so retrieve the scaling factor for - // its corresponding variable of integration and apply it, if - // needed. - - double scalingFactor = Generator::GeneratorImpl::scalingFactor(astParent->mLeft->mLeft->mVariable); - - if (!areEqual(scalingFactor, 1.0)) { - // We need to scale using the inverse of the scaling factor, but - // how we do it depends on whether the rate is to be computed or - // used. - - GeneratorEquationAstPtr astGrandParent = astParent->mParent.lock(); - - if ((astGrandParent->mType == GeneratorEquationAst::Type::ASSIGNMENT) - && (astGrandParent->mLeft == astParent)) { - scaleAst(astGrandParent->mRight, astGrandParent, 1.0 / scalingFactor); - } else { - scaleAst(astParent, astGrandParent, 1.0 / scalingFactor); - } - } - } - - if (((astParent->mType != GeneratorEquationAst::Type::ASSIGNMENT) - || (astParent->mLeft != ast)) - && (astParent->mType != GeneratorEquationAst::Type::BVAR)) { - // We are dealing with a variable which is neither a computed - // variable nor our variable of integration, so retrieve its scaling - // factor and apply it, if needed, distinguishing between a rate - // variable and an algebraic variable. - - double scalingFactor = Generator::GeneratorImpl::scalingFactor(ast->mVariable); - - if (!areEqual(scalingFactor, 1.0)) { - if (astParent->mType == GeneratorEquationAst::Type::DIFF) { - scaleAst(astParent, astParent->mParent.lock(), scalingFactor); - } else { - scaleAst(ast, astParent, scalingFactor); - } - } - } - } -} - -void Generator::GeneratorImpl::processModel(const ModelPtr &model) -{ - // Reset a few things in case we were to process the model more than once. - // Note: one would normally process the model only once, so we shouldn't - // need to do this, but better be safe than sorry. - - mModelType = Generator::ModelType::UNKNOWN; - - mInternalVariables.clear(); - mEquations.clear(); - - mVoi = nullptr; - mStates.clear(); - mVariables.clear(); - - mNeedMin = false; - mNeedMax = false; - - mNeedSec = false; - mNeedCsc = false; - mNeedCot = false; - mNeedSech = false; - mNeedCsch = false; - mNeedCoth = false; - mNeedAsec = false; - mNeedAcsc = false; - mNeedAcot = false; - mNeedAsech = false; - mNeedAcsch = false; - mNeedAcoth = false; - - mGenerator->removeAllIssues(); - - // Recursively process the model's components, so that we end up with an AST - // for each of the model's equations. - - for (size_t i = 0; i < model->componentCount(); ++i) { - processComponent(model->component(i)); - } - - // Some more processing is needed, but it can only be done if we didn't come - // across any errors during the processing of our components. - - if (mGenerator->errorCount() == 0) { - // Process our different equations' AST to determine the type of our - // variables. - - for (const auto &equation : mEquations) { - processEquationAst(equation->mAst); - } - } - - // Some post-processing is now needed, but it can only be done if we didn't - // come across any errors during the processing of our equations' AST. - - if (mGenerator->errorCount() == 0) { - // Sort our variables, determine the index of our constant variables and - // then loop over our equations, checking which variables, if any, can - // be determined using a given equation. - - mInternalVariables.sort(compareVariablesByName); - - size_t variableIndex = MAX_SIZE_T; - - for (const auto &internalVariable : mInternalVariables) { - if (internalVariable->mType == GeneratorInternalVariable::Type::CONSTANT) { - internalVariable->mIndex = ++variableIndex; - } - } - - size_t equationOrder = MAX_SIZE_T; - size_t stateIndex = MAX_SIZE_T; - - for (;;) { - bool relevantCheck = false; - - for (const auto &equation : mEquations) { - relevantCheck = equation->check(equationOrder, stateIndex, variableIndex) - || relevantCheck; - } - - if (!relevantCheck) { - break; - } - } - - // Make sure that our variables are valid. - - for (const auto &internalVariable : mInternalVariables) { - std::string issueType; - - switch (internalVariable->mType) { - case GeneratorInternalVariable::Type::UNKNOWN: - issueType = "is not computed"; - - break; - case GeneratorInternalVariable::Type::SHOULD_BE_STATE: - issueType = "is used in an ODE, but it is not initialised"; - - break; - case GeneratorInternalVariable::Type::VARIABLE_OF_INTEGRATION: - case GeneratorInternalVariable::Type::STATE: - case GeneratorInternalVariable::Type::CONSTANT: - case GeneratorInternalVariable::Type::COMPUTED_TRUE_CONSTANT: - case GeneratorInternalVariable::Type::COMPUTED_VARIABLE_BASED_CONSTANT: - case GeneratorInternalVariable::Type::ALGEBRAIC: - break; - case GeneratorInternalVariable::Type::OVERCONSTRAINED: - issueType = "is computed more than once"; - - break; - } - - if (!issueType.empty()) { - IssuePtr issue = Issue::create(); - VariablePtr realVariable = internalVariable->mVariable; - - issue->setDescription("Variable '" + realVariable->name() - + "' in component '" + owningComponent(realVariable)->name() - + "' of model '" + owningModel(realVariable)->name() - + "' " + issueType + "."); - issue->setCause(Issue::Cause::GENERATOR); - - mGenerator->addIssue(issue); - } - } - - // Determine the type of our model. - - bool hasUnderconstrainedVariables = std::find_if(mInternalVariables.begin(), mInternalVariables.end(), [](const GeneratorInternalVariablePtr &variable) { - return (variable->mType == GeneratorInternalVariable::Type::UNKNOWN) - || (variable->mType == GeneratorInternalVariable::Type::SHOULD_BE_STATE); - }) - != std::end(mInternalVariables); - bool hasOverconstrainedVariables = std::find_if(mInternalVariables.begin(), mInternalVariables.end(), [](const GeneratorInternalVariablePtr &variable) { - return variable->mType == GeneratorInternalVariable::Type::OVERCONSTRAINED; - }) - != std::end(mInternalVariables); - - if (hasUnderconstrainedVariables) { - if (hasOverconstrainedVariables) { - mModelType = Generator::ModelType::UNSUITABLY_CONSTRAINED; - } else { - mModelType = Generator::ModelType::UNDERCONSTRAINED; - } - } else if (hasOverconstrainedVariables) { - mModelType = Generator::ModelType::OVERCONSTRAINED; - } else if (mVoi != nullptr) { - mModelType = Generator::ModelType::ODE; - } else if (!mInternalVariables.empty()) { - mModelType = Generator::ModelType::ALGEBRAIC; - } - } else { - mModelType = Generator::ModelType::INVALID; - } - - // Some final post-processing is now needed, if we have a valid model. - - if ((mModelType == Generator::ModelType::ODE) - || (mModelType == Generator::ModelType::ALGEBRAIC)) { - // Scale our equations' AST, i.e. take into account the fact that we may - // have mapped variables that use compatible units rather than - // equivalent ones. - - for (const auto &equation : mEquations) { - scaleEquationAst(equation->mAst); - } - - // Sort our variables and equations and make our internal variables - // available through our API. - - mInternalVariables.sort(compareVariablesByTypeAndIndex); - mEquations.sort(compareEquationsByVariable); - - for (const auto &internalVariable : mInternalVariables) { - GeneratorVariable::Type type; - - if (internalVariable->mType == GeneratorInternalVariable::Type::STATE) { - type = GeneratorVariable::Type::STATE; - } else if (internalVariable->mType == GeneratorInternalVariable::Type::CONSTANT) { - type = GeneratorVariable::Type::CONSTANT; - } else if ((internalVariable->mType == GeneratorInternalVariable::Type::COMPUTED_TRUE_CONSTANT) - || (internalVariable->mType == GeneratorInternalVariable::Type::COMPUTED_VARIABLE_BASED_CONSTANT)) { - type = GeneratorVariable::Type::COMPUTED_CONSTANT; - } else if (internalVariable->mType == GeneratorInternalVariable::Type::ALGEBRAIC) { - type = GeneratorVariable::Type::ALGEBRAIC; - } else { - // This is the variable of integration, so skip it. - - continue; - } - - GeneratorVariablePtr stateOrVariable = GeneratorVariable::create(); - - stateOrVariable->mPimpl->populate(internalVariable->mInitialisingVariable, - internalVariable->mVariable, - type); - - if (type == GeneratorVariable::Type::STATE) { - mStates.push_back(stateOrVariable); - } else { - mVariables.push_back(stateOrVariable); - } - } - } + analyserVariable(variable)->variable()->units()); } -bool Generator::GeneratorImpl::isRelationalOperator(const GeneratorEquationAstPtr &ast) const +bool Generator::GeneratorImpl::isRelationalOperator(const AnalyserEquationAstPtr &ast) const { - return ((ast->mType == GeneratorEquationAst::Type::EQ) - && mProfile->hasEqOperator()) - || ((ast->mType == GeneratorEquationAst::Type::NEQ) - && mProfile->hasNeqOperator()) - || ((ast->mType == GeneratorEquationAst::Type::LT) - && mProfile->hasLtOperator()) - || ((ast->mType == GeneratorEquationAst::Type::LEQ) - && mProfile->hasLeqOperator()) - || ((ast->mType == GeneratorEquationAst::Type::GT) - && mProfile->hasGtOperator()) - || ((ast->mType == GeneratorEquationAst::Type::GEQ) - && mProfile->hasGeqOperator()); + return ((ast->type() == AnalyserEquationAst::Type::EQ) + && mLockedProfile->hasEqOperator()) + || ((ast->type() == AnalyserEquationAst::Type::NEQ) + && mLockedProfile->hasNeqOperator()) + || ((ast->type() == AnalyserEquationAst::Type::LT) + && mLockedProfile->hasLtOperator()) + || ((ast->type() == AnalyserEquationAst::Type::LEQ) + && mLockedProfile->hasLeqOperator()) + || ((ast->type() == AnalyserEquationAst::Type::GT) + && mLockedProfile->hasGtOperator()) + || ((ast->type() == AnalyserEquationAst::Type::GEQ) + && mLockedProfile->hasGeqOperator()); } -bool Generator::GeneratorImpl::isAndOperator(const GeneratorEquationAstPtr &ast) const +bool Generator::GeneratorImpl::isAndOperator(const AnalyserEquationAstPtr &ast) const { - return (ast->mType == GeneratorEquationAst::Type::AND) - && mProfile->hasAndOperator(); + return (ast->type() == AnalyserEquationAst::Type::AND) + && mLockedProfile->hasAndOperator(); } -bool Generator::GeneratorImpl::isOrOperator(const GeneratorEquationAstPtr &ast) const +bool Generator::GeneratorImpl::isOrOperator(const AnalyserEquationAstPtr &ast) const { - return (ast->mType == GeneratorEquationAst::Type::OR) - && mProfile->hasOrOperator(); + return (ast->type() == AnalyserEquationAst::Type::OR) + && mLockedProfile->hasOrOperator(); } -bool Generator::GeneratorImpl::isXorOperator(const GeneratorEquationAstPtr &ast) const +bool Generator::GeneratorImpl::isXorOperator(const AnalyserEquationAstPtr &ast) const { - return (ast->mType == GeneratorEquationAst::Type::XOR) - && mProfile->hasXorOperator(); + return (ast->type() == AnalyserEquationAst::Type::XOR) + && mLockedProfile->hasXorOperator(); } -bool Generator::GeneratorImpl::isLogicalOperator(const GeneratorEquationAstPtr &ast) const +bool Generator::GeneratorImpl::isLogicalOperator(const AnalyserEquationAstPtr &ast) const { - // Note: GeneratorEquationAst::Type::NOT is a unary logical operator, hence + // Note: AnalyserEquationAst::Type::NOT is a unary logical operator, hence // we don't include it here since this method is only used to // determine whether parentheses should be added around some code. return isAndOperator(ast) || isOrOperator(ast) || isXorOperator(ast); } -bool Generator::GeneratorImpl::isPlusOperator(const GeneratorEquationAstPtr &ast) const -{ - return ast->mType == GeneratorEquationAst::Type::PLUS; -} - -bool Generator::GeneratorImpl::isMinusOperator(const GeneratorEquationAstPtr &ast) const +bool Generator::GeneratorImpl::isPlusOperator(const AnalyserEquationAstPtr &ast) const { - return ast->mType == GeneratorEquationAst::Type::MINUS; + return ast->type() == AnalyserEquationAst::Type::PLUS; } -bool Generator::GeneratorImpl::isTimesOperator(const GeneratorEquationAstPtr &ast) const +bool Generator::GeneratorImpl::isMinusOperator(const AnalyserEquationAstPtr &ast) const { - return ast->mType == GeneratorEquationAst::Type::TIMES; + return ast->type() == AnalyserEquationAst::Type::MINUS; } -bool Generator::GeneratorImpl::isDivideOperator(const GeneratorEquationAstPtr &ast) const +bool Generator::GeneratorImpl::isTimesOperator(const AnalyserEquationAstPtr &ast) const { - return ast->mType == GeneratorEquationAst::Type::DIVIDE; + return ast->type() == AnalyserEquationAst::Type::TIMES; } -bool Generator::GeneratorImpl::isPowerOperator(const GeneratorEquationAstPtr &ast) const +bool Generator::GeneratorImpl::isDivideOperator(const AnalyserEquationAstPtr &ast) const { - return (ast->mType == GeneratorEquationAst::Type::POWER) - && mProfile->hasPowerOperator(); + return ast->type() == AnalyserEquationAst::Type::DIVIDE; } -bool Generator::GeneratorImpl::isRootOperator(const GeneratorEquationAstPtr &ast) const +bool Generator::GeneratorImpl::isPowerOperator(const AnalyserEquationAstPtr &ast) const { - return (ast->mType == GeneratorEquationAst::Type::ROOT) - && mProfile->hasPowerOperator(); + return (ast->type() == AnalyserEquationAst::Type::POWER) + && mLockedProfile->hasPowerOperator(); } -bool Generator::GeneratorImpl::isPiecewiseStatement(const GeneratorEquationAstPtr &ast) const +bool Generator::GeneratorImpl::isRootOperator(const AnalyserEquationAstPtr &ast) const { - return (ast->mType == GeneratorEquationAst::Type::PIECEWISE) - && mProfile->hasConditionalOperator(); + return (ast->type() == AnalyserEquationAst::Type::ROOT) + && mLockedProfile->hasPowerOperator(); } -std::string Generator::GeneratorImpl::replace(std::string string, - const std::string &from, - const std::string &to) +bool Generator::GeneratorImpl::isPiecewiseStatement(const AnalyserEquationAstPtr &ast) const { - auto index = string.find(from); - - return (index == std::string::npos) ? - string : - string.replace(index, from.length(), to); + return (ast->type() == AnalyserEquationAst::Type::PIECEWISE) + && mLockedProfile->hasConditionalOperator(); } void Generator::GeneratorImpl::updateVariableInfoSizes(size_t &componentSize, size_t &nameSize, size_t &unitsSize, - const GeneratorVariablePtr &variable) + const AnalyserVariablePtr &variable) const { auto variableComponentSize = owningComponent(variable->variable())->name().length() + 1; auto variableNameSize = variable->variable()->name().length() + 1; @@ -1780,259 +303,259 @@ bool Generator::GeneratorImpl::modifiedProfile() const { // Whether the profile requires an interface to be generated. - const std::string trueValue = "true"; - const std::string falseValue = "false"; + static const std::string TRUE_VALUE = "true"; + static const std::string FALSE_VALUE = "false"; - std::string profileContents = mProfile->hasInterface() ? - trueValue : - falseValue; + auto profileContents = mLockedProfile->hasInterface() ? + TRUE_VALUE : + FALSE_VALUE; // Assignment. - profileContents += mProfile->assignmentString(); + profileContents += mLockedProfile->assignmentString(); // Relational and logical operators. - profileContents += mProfile->eqString() - + mProfile->neqString() - + mProfile->ltString() - + mProfile->leqString() - + mProfile->gtString() - + mProfile->geqString() - + mProfile->andString() - + mProfile->orString() - + mProfile->xorString() - + mProfile->notString(); - - profileContents += (mProfile->hasEqOperator() ? - trueValue : - falseValue) - + (mProfile->hasNeqOperator() ? - trueValue : - falseValue) - + (mProfile->hasLtOperator() ? - trueValue : - falseValue) - + (mProfile->hasLeqOperator() ? - trueValue : - falseValue) - + (mProfile->hasGtOperator() ? - trueValue : - falseValue) - + (mProfile->hasGeqOperator() ? - trueValue : - falseValue) - + (mProfile->hasAndOperator() ? - trueValue : - falseValue) - + (mProfile->hasOrOperator() ? - trueValue : - falseValue) - + (mProfile->hasXorOperator() ? - trueValue : - falseValue) - + (mProfile->hasNotOperator() ? - trueValue : - falseValue); + profileContents += mLockedProfile->eqString() + + mLockedProfile->neqString() + + mLockedProfile->ltString() + + mLockedProfile->leqString() + + mLockedProfile->gtString() + + mLockedProfile->geqString() + + mLockedProfile->andString() + + mLockedProfile->orString() + + mLockedProfile->xorString() + + mLockedProfile->notString(); + + profileContents += (mLockedProfile->hasEqOperator() ? + TRUE_VALUE : + FALSE_VALUE) + + (mLockedProfile->hasNeqOperator() ? + TRUE_VALUE : + FALSE_VALUE) + + (mLockedProfile->hasLtOperator() ? + TRUE_VALUE : + FALSE_VALUE) + + (mLockedProfile->hasLeqOperator() ? + TRUE_VALUE : + FALSE_VALUE) + + (mLockedProfile->hasGtOperator() ? + TRUE_VALUE : + FALSE_VALUE) + + (mLockedProfile->hasGeqOperator() ? + TRUE_VALUE : + FALSE_VALUE) + + (mLockedProfile->hasAndOperator() ? + TRUE_VALUE : + FALSE_VALUE) + + (mLockedProfile->hasOrOperator() ? + TRUE_VALUE : + FALSE_VALUE) + + (mLockedProfile->hasXorOperator() ? + TRUE_VALUE : + FALSE_VALUE) + + (mLockedProfile->hasNotOperator() ? + TRUE_VALUE : + FALSE_VALUE); // Arithmetic operators. - profileContents += mProfile->plusString() - + mProfile->minusString() - + mProfile->timesString() - + mProfile->divideString() - + mProfile->powerString() - + mProfile->squareRootString() - + mProfile->squareString() - + mProfile->absoluteValueString() - + mProfile->exponentialString() - + mProfile->napierianLogarithmString() - + mProfile->commonLogarithmString() - + mProfile->ceilingString() - + mProfile->floorString() - + mProfile->minString() - + mProfile->maxString() - + mProfile->remString(); - - profileContents += mProfile->hasPowerOperator() ? - trueValue : - falseValue; + profileContents += mLockedProfile->plusString() + + mLockedProfile->minusString() + + mLockedProfile->timesString() + + mLockedProfile->divideString() + + mLockedProfile->powerString() + + mLockedProfile->squareRootString() + + mLockedProfile->squareString() + + mLockedProfile->absoluteValueString() + + mLockedProfile->exponentialString() + + mLockedProfile->naturalLogarithmString() + + mLockedProfile->commonLogarithmString() + + mLockedProfile->ceilingString() + + mLockedProfile->floorString() + + mLockedProfile->minString() + + mLockedProfile->maxString() + + mLockedProfile->remString(); + + profileContents += mLockedProfile->hasPowerOperator() ? + TRUE_VALUE : + FALSE_VALUE; // Trigonometric operators. - profileContents += mProfile->sinString() - + mProfile->cosString() - + mProfile->tanString() - + mProfile->secString() - + mProfile->cscString() - + mProfile->cotString() - + mProfile->sinhString() - + mProfile->coshString() - + mProfile->tanhString() - + mProfile->sechString() - + mProfile->cschString() - + mProfile->cothString() - + mProfile->asinString() - + mProfile->acosString() - + mProfile->atanString() - + mProfile->asecString() - + mProfile->acscString() - + mProfile->acotString() - + mProfile->asinhString() - + mProfile->acoshString() - + mProfile->atanhString() - + mProfile->asechString() - + mProfile->acschString() - + mProfile->acothString(); + profileContents += mLockedProfile->sinString() + + mLockedProfile->cosString() + + mLockedProfile->tanString() + + mLockedProfile->secString() + + mLockedProfile->cscString() + + mLockedProfile->cotString() + + mLockedProfile->sinhString() + + mLockedProfile->coshString() + + mLockedProfile->tanhString() + + mLockedProfile->sechString() + + mLockedProfile->cschString() + + mLockedProfile->cothString() + + mLockedProfile->asinString() + + mLockedProfile->acosString() + + mLockedProfile->atanString() + + mLockedProfile->asecString() + + mLockedProfile->acscString() + + mLockedProfile->acotString() + + mLockedProfile->asinhString() + + mLockedProfile->acoshString() + + mLockedProfile->atanhString() + + mLockedProfile->asechString() + + mLockedProfile->acschString() + + mLockedProfile->acothString(); // Piecewise statement. - profileContents += mProfile->conditionalOperatorIfString() - + mProfile->conditionalOperatorElseString() - + mProfile->piecewiseIfString() - + mProfile->piecewiseElseString(); + profileContents += mLockedProfile->conditionalOperatorIfString() + + mLockedProfile->conditionalOperatorElseString() + + mLockedProfile->piecewiseIfString() + + mLockedProfile->piecewiseElseString(); - profileContents += mProfile->hasConditionalOperator() ? - trueValue : - falseValue; + profileContents += mLockedProfile->hasConditionalOperator() ? + TRUE_VALUE : + FALSE_VALUE; // Constants. - profileContents += mProfile->trueString() - + mProfile->falseString() - + mProfile->eString() - + mProfile->piString() - + mProfile->infString() - + mProfile->nanString(); + profileContents += mLockedProfile->trueString() + + mLockedProfile->falseString() + + mLockedProfile->eString() + + mLockedProfile->piString() + + mLockedProfile->infString() + + mLockedProfile->nanString(); // Arithmetic functions. - profileContents += mProfile->eqFunctionString() - + mProfile->neqFunctionString() - + mProfile->ltFunctionString() - + mProfile->leqFunctionString() - + mProfile->gtFunctionString() - + mProfile->geqFunctionString() - + mProfile->andFunctionString() - + mProfile->orFunctionString() - + mProfile->xorFunctionString() - + mProfile->notFunctionString() - + mProfile->minFunctionString() - + mProfile->maxFunctionString(); + profileContents += mLockedProfile->eqFunctionString() + + mLockedProfile->neqFunctionString() + + mLockedProfile->ltFunctionString() + + mLockedProfile->leqFunctionString() + + mLockedProfile->gtFunctionString() + + mLockedProfile->geqFunctionString() + + mLockedProfile->andFunctionString() + + mLockedProfile->orFunctionString() + + mLockedProfile->xorFunctionString() + + mLockedProfile->notFunctionString() + + mLockedProfile->minFunctionString() + + mLockedProfile->maxFunctionString(); // Trigonometric functions. - profileContents += mProfile->secFunctionString() - + mProfile->cscFunctionString() - + mProfile->cotFunctionString() - + mProfile->sechFunctionString() - + mProfile->cschFunctionString() - + mProfile->cothFunctionString() - + mProfile->asecFunctionString() - + mProfile->acscFunctionString() - + mProfile->acotFunctionString() - + mProfile->asechFunctionString() - + mProfile->acschFunctionString() - + mProfile->acothFunctionString(); + profileContents += mLockedProfile->secFunctionString() + + mLockedProfile->cscFunctionString() + + mLockedProfile->cotFunctionString() + + mLockedProfile->sechFunctionString() + + mLockedProfile->cschFunctionString() + + mLockedProfile->cothFunctionString() + + mLockedProfile->asecFunctionString() + + mLockedProfile->acscFunctionString() + + mLockedProfile->acotFunctionString() + + mLockedProfile->asechFunctionString() + + mLockedProfile->acschFunctionString() + + mLockedProfile->acothFunctionString(); // Miscellaneous. - profileContents += mProfile->commentString() - + mProfile->originCommentString(); + profileContents += mLockedProfile->commentString() + + mLockedProfile->originCommentString(); - profileContents += mProfile->interfaceFileNameString(); + profileContents += mLockedProfile->interfaceFileNameString(); - profileContents += mProfile->interfaceHeaderString() - + mProfile->implementationHeaderString(); + profileContents += mLockedProfile->interfaceHeaderString() + + mLockedProfile->implementationHeaderString(); - profileContents += mProfile->interfaceVersionString() - + mProfile->implementationVersionString(); + profileContents += mLockedProfile->interfaceVersionString() + + mLockedProfile->implementationVersionString(); - profileContents += mProfile->interfaceLibcellmlVersionString() - + mProfile->implementationLibcellmlVersionString(); + profileContents += mLockedProfile->interfaceLibcellmlVersionString() + + mLockedProfile->implementationLibcellmlVersionString(); - profileContents += mProfile->interfaceStateCountString() - + mProfile->implementationStateCountString(); + profileContents += mLockedProfile->interfaceStateCountString() + + mLockedProfile->implementationStateCountString(); - profileContents += mProfile->interfaceVariableCountString() - + mProfile->implementationVariableCountString(); + profileContents += mLockedProfile->interfaceVariableCountString() + + mLockedProfile->implementationVariableCountString(); - profileContents += mProfile->variableTypeObjectString(); + profileContents += mLockedProfile->variableTypeObjectString(); - profileContents += mProfile->constantVariableTypeString() - + mProfile->computedConstantVariableTypeString() - + mProfile->algebraicVariableTypeString(); + profileContents += mLockedProfile->constantVariableTypeString() + + mLockedProfile->computedConstantVariableTypeString() + + mLockedProfile->algebraicVariableTypeString(); - profileContents += mProfile->variableInfoObjectString() - + mProfile->variableInfoWithTypeObjectString(); + profileContents += mLockedProfile->variableInfoObjectString() + + mLockedProfile->variableInfoWithTypeObjectString(); - profileContents += mProfile->interfaceVoiInfoString() - + mProfile->implementationVoiInfoString(); + profileContents += mLockedProfile->interfaceVoiInfoString() + + mLockedProfile->implementationVoiInfoString(); - profileContents += mProfile->interfaceStateInfoString() - + mProfile->implementationStateInfoString(); + profileContents += mLockedProfile->interfaceStateInfoString() + + mLockedProfile->implementationStateInfoString(); - profileContents += mProfile->interfaceVariableInfoString() - + mProfile->implementationVariableInfoString(); + profileContents += mLockedProfile->interfaceVariableInfoString() + + mLockedProfile->implementationVariableInfoString(); - profileContents += mProfile->variableInfoEntryString() - + mProfile->variableInfoWithTypeEntryString(); + profileContents += mLockedProfile->variableInfoEntryString() + + mLockedProfile->variableInfoWithTypeEntryString(); - profileContents += mProfile->voiString(); + profileContents += mLockedProfile->voiString(); - profileContents += mProfile->statesArrayString() - + mProfile->ratesArrayString() - + mProfile->variablesArrayString(); + profileContents += mLockedProfile->statesArrayString() + + mLockedProfile->ratesArrayString() + + mLockedProfile->variablesArrayString(); - profileContents += mProfile->interfaceCreateStatesArrayMethodString() - + mProfile->implementationCreateStatesArrayMethodString(); + profileContents += mLockedProfile->interfaceCreateStatesArrayMethodString() + + mLockedProfile->implementationCreateStatesArrayMethodString(); - profileContents += mProfile->interfaceCreateVariablesArrayMethodString() - + mProfile->implementationCreateVariablesArrayMethodString(); + profileContents += mLockedProfile->interfaceCreateVariablesArrayMethodString() + + mLockedProfile->implementationCreateVariablesArrayMethodString(); - profileContents += mProfile->interfaceDeleteArrayMethodString() - + mProfile->implementationDeleteArrayMethodString(); + profileContents += mLockedProfile->interfaceDeleteArrayMethodString() + + mLockedProfile->implementationDeleteArrayMethodString(); - profileContents += mProfile->interfaceInitializeStatesAndConstantsMethodString() - + mProfile->implementationInitializeStatesAndConstantsMethodString(); + profileContents += mLockedProfile->interfaceInitialiseStatesAndConstantsMethodString() + + mLockedProfile->implementationInitialiseStatesAndConstantsMethodString(); - profileContents += mProfile->interfaceComputeComputedConstantsMethodString() - + mProfile->implementationComputeComputedConstantsMethodString(); + profileContents += mLockedProfile->interfaceComputeComputedConstantsMethodString() + + mLockedProfile->implementationComputeComputedConstantsMethodString(); - profileContents += mProfile->interfaceComputeRatesMethodString() - + mProfile->implementationComputeRatesMethodString(); + profileContents += mLockedProfile->interfaceComputeRatesMethodString() + + mLockedProfile->implementationComputeRatesMethodString(); - profileContents += mProfile->interfaceComputeVariablesMethodString() - + mProfile->implementationComputeVariablesMethodString(); + profileContents += mLockedProfile->interfaceComputeVariablesMethodString() + + mLockedProfile->implementationComputeVariablesMethodString(); - profileContents += mProfile->emptyMethodString(); + profileContents += mLockedProfile->emptyMethodString(); - profileContents += mProfile->indentString(); + profileContents += mLockedProfile->indentString(); - profileContents += mProfile->openArrayInitializerString() - + mProfile->closeArrayInitializerString(); + profileContents += mLockedProfile->openArrayInitialiserString() + + mLockedProfile->closeArrayInitialiserString(); - profileContents += mProfile->openArrayString() - + mProfile->closeArrayString(); + profileContents += mLockedProfile->openArrayString() + + mLockedProfile->closeArrayString(); - profileContents += mProfile->arrayElementSeparatorString(); + profileContents += mLockedProfile->arrayElementSeparatorString(); - profileContents += mProfile->stringDelimiterString(); + profileContents += mLockedProfile->stringDelimiterString(); - profileContents += mProfile->commandSeparatorString(); + profileContents += mLockedProfile->commandSeparatorString(); // Compute and check the hash of our profile contents. - bool res = false; - std::string profileContentsSha1 = sha1(profileContents); + auto res = false; + auto profileContentsSha1 = sha1(profileContents); - switch (mProfile->profile()) { + switch (mLockedProfile->profile()) { case GeneratorProfile::Profile::C: - res = profileContentsSha1 != "e2aa9af2767ab84b217cf996c491c485ae876563"; + res = profileContentsSha1 != "0e79e682d28bcaf67f5ed5cbf419de670fd7373b"; break; case GeneratorProfile::Profile::PYTHON: - res = profileContentsSha1 != "1abb41ecb908526b51c2ac8c44bc9542942a9652"; + res = profileContentsSha1 != "073377e89d73541021cbea7dce4b06ee4dc88c13"; break; } @@ -2040,15 +563,15 @@ bool Generator::GeneratorImpl::modifiedProfile() const return res; } -void Generator::GeneratorImpl::addOriginCommentCode(std::string &code) +void Generator::GeneratorImpl::addOriginCommentCode() { - if (!mProfile->commentString().empty() - && !mProfile->originCommentString().empty()) { + if (!mLockedProfile->commentString().empty() + && !mLockedProfile->originCommentString().empty()) { std::string profileInformation = modifiedProfile() ? "a modified " : "the "; - switch (mProfile->profile()) { + switch (mLockedProfile->profile()) { case GeneratorProfile::Profile::C: profileInformation += "C"; @@ -2061,127 +584,121 @@ void Generator::GeneratorImpl::addOriginCommentCode(std::string &code) profileInformation += " profile of"; - std::string commentCode = replace(replace(mProfile->originCommentString(), - "", profileInformation), - "", versionString()); - - code += replace(mProfile->commentString(), - "", commentCode); + mCode += replace(mLockedProfile->commentString(), + "", replace(replace(mLockedProfile->originCommentString(), "", profileInformation), "", versionString())); } } -void Generator::GeneratorImpl::addInterfaceHeaderCode(std::string &code) const +void Generator::GeneratorImpl::addInterfaceHeaderCode() { - if (!mProfile->interfaceHeaderString().empty()) { - if (!code.empty()) { - code += "\n"; + if (!mLockedProfile->interfaceHeaderString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->interfaceHeaderString(); + mCode += mLockedProfile->interfaceHeaderString(); } } -void Generator::GeneratorImpl::addImplementationHeaderCode(std::string &code) +void Generator::GeneratorImpl::addImplementationHeaderCode() { - if (!mProfile->implementationHeaderString().empty()) { - if (!code.empty()) { - code += "\n"; + if (!mLockedProfile->implementationHeaderString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += replace(mProfile->implementationHeaderString(), - "", mProfile->interfaceFileNameString()); + mCode += replace(mLockedProfile->implementationHeaderString(), + "", mLockedProfile->interfaceFileNameString()); } } -void Generator::GeneratorImpl::addVersionAndLibcellmlVersionCode(std::string &code, - bool interface) +void Generator::GeneratorImpl::addVersionAndLibcellmlVersionCode(bool interface) { std::string versionAndLibcellmlCode; - if ((interface && !mProfile->interfaceVersionString().empty()) - || (!interface && !mProfile->implementationVersionString().empty())) { + if ((interface && !mLockedProfile->interfaceVersionString().empty()) + || (!interface && !mLockedProfile->implementationVersionString().empty())) { if (interface) { - versionAndLibcellmlCode += mProfile->interfaceVersionString(); + versionAndLibcellmlCode += mLockedProfile->interfaceVersionString(); } else { if (modifiedProfile()) { std::regex regEx("([0-9]+\\.[0-9]+\\.[0-9]+)"); - versionAndLibcellmlCode += std::regex_replace(mProfile->implementationVersionString(), regEx, "$1.post0"); + versionAndLibcellmlCode += std::regex_replace(mLockedProfile->implementationVersionString(), regEx, "$1.post0"); } else { - versionAndLibcellmlCode += mProfile->implementationVersionString(); + versionAndLibcellmlCode += mLockedProfile->implementationVersionString(); } } } - if ((interface && !mProfile->interfaceLibcellmlVersionString().empty()) - || (!interface && !mProfile->implementationLibcellmlVersionString().empty())) { + if ((interface && !mLockedProfile->interfaceLibcellmlVersionString().empty()) + || (!interface && !mLockedProfile->implementationLibcellmlVersionString().empty())) { versionAndLibcellmlCode += interface ? - mProfile->interfaceLibcellmlVersionString() : - replace(mProfile->implementationLibcellmlVersionString(), + mLockedProfile->interfaceLibcellmlVersionString() : + replace(mLockedProfile->implementationLibcellmlVersionString(), "", versionString()); } if (!versionAndLibcellmlCode.empty()) { - code += "\n"; + mCode += "\n"; } - code += versionAndLibcellmlCode; + mCode += versionAndLibcellmlCode; } -void Generator::GeneratorImpl::addStateAndVariableCountCode(std::string &code, - bool interface) +void Generator::GeneratorImpl::addStateAndVariableCountCode(bool interface) { std::string stateAndVariableCountCode; - if ((interface && !mProfile->interfaceStateCountString().empty()) - || (!interface && !mProfile->implementationStateCountString().empty())) { + if ((interface && !mLockedProfile->interfaceStateCountString().empty()) + || (!interface && !mLockedProfile->implementationStateCountString().empty())) { stateAndVariableCountCode += interface ? - mProfile->interfaceStateCountString() : - replace(mProfile->implementationStateCountString(), - "", std::to_string(mStates.size())); + mLockedProfile->interfaceStateCountString() : + replace(mLockedProfile->implementationStateCountString(), + "", std::to_string(mLockedModel->stateCount())); } - if ((interface && !mProfile->interfaceVariableCountString().empty()) - || (!interface && !mProfile->implementationVariableCountString().empty())) { + if ((interface && !mLockedProfile->interfaceVariableCountString().empty()) + || (!interface && !mLockedProfile->implementationVariableCountString().empty())) { stateAndVariableCountCode += interface ? - mProfile->interfaceVariableCountString() : - replace(mProfile->implementationVariableCountString(), - "", std::to_string(mVariables.size())); + mLockedProfile->interfaceVariableCountString() : + replace(mLockedProfile->implementationVariableCountString(), + "", std::to_string(mLockedModel->variableCount())); } if (!stateAndVariableCountCode.empty()) { - code += "\n"; + mCode += "\n"; } - code += stateAndVariableCountCode; + mCode += stateAndVariableCountCode; } -void Generator::GeneratorImpl::addVariableTypeObjectCode(std::string &code) const +void Generator::GeneratorImpl::addVariableTypeObjectCode() { - if (!mProfile->variableTypeObjectString().empty()) { - if (!code.empty()) { - code += "\n"; + if (!mLockedProfile->variableTypeObjectString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->variableTypeObjectString(); + mCode += mLockedProfile->variableTypeObjectString(); } } -std::string Generator::GeneratorImpl::generateVariableInfoObjectCode(const std::string &objectString) +std::string Generator::GeneratorImpl::generateVariableInfoObjectCode(const std::string &objectString) const { size_t componentSize = 0; size_t nameSize = 0; size_t unitsSize = 0; - if (mVoi != nullptr) { - updateVariableInfoSizes(componentSize, nameSize, unitsSize, mVoi); + if (mLockedModel->voi() != nullptr) { + updateVariableInfoSizes(componentSize, nameSize, unitsSize, mLockedModel->voi()); } - for (const auto &state : mStates) { + for (const auto &state : mLockedModel->states()) { updateVariableInfoSizes(componentSize, nameSize, unitsSize, state); } - for (const auto &variable : mVariables) { + for (const auto &variable : mLockedModel->variables()) { updateVariableInfoSizes(componentSize, nameSize, unitsSize, variable); } @@ -2191,95 +708,95 @@ std::string Generator::GeneratorImpl::generateVariableInfoObjectCode(const std:: "", std::to_string(unitsSize)); } -void Generator::GeneratorImpl::addVariableInfoObjectCode(std::string &code) +void Generator::GeneratorImpl::addVariableInfoObjectCode() { - if (!mProfile->variableInfoObjectString().empty()) { - if (!code.empty()) { - code += "\n"; + if (!mLockedProfile->variableInfoObjectString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += generateVariableInfoObjectCode(mProfile->variableInfoObjectString()); + mCode += generateVariableInfoObjectCode(mLockedProfile->variableInfoObjectString()); } } -void Generator::GeneratorImpl::addVariableInfoWithTypeObjectCode(std::string &code) +void Generator::GeneratorImpl::addVariableInfoWithTypeObjectCode() { - if (!mProfile->variableInfoWithTypeObjectString().empty()) { - if (!code.empty()) { - code += "\n"; + if (!mLockedProfile->variableInfoWithTypeObjectString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += generateVariableInfoObjectCode(mProfile->variableInfoWithTypeObjectString()); + mCode += generateVariableInfoObjectCode(mLockedProfile->variableInfoWithTypeObjectString()); } } std::string Generator::GeneratorImpl::generateVariableInfoEntryCode(const std::string &name, const std::string &units, - const std::string &component) + const std::string &component) const { - return replace(replace(replace(mProfile->variableInfoEntryString(), + return replace(replace(replace(mLockedProfile->variableInfoEntryString(), "", name), "", units), "", component); } -void Generator::GeneratorImpl::addInterfaceVoiStateAndVariableInfoCode(std::string &code) const +void Generator::GeneratorImpl::addInterfaceVoiStateAndVariableInfoCode() { std::string interfaceVoiStateAndVariableInfoCode; - if (!mProfile->interfaceVoiInfoString().empty()) { - interfaceVoiStateAndVariableInfoCode += mProfile->interfaceVoiInfoString(); + if (!mLockedProfile->interfaceVoiInfoString().empty()) { + interfaceVoiStateAndVariableInfoCode += mLockedProfile->interfaceVoiInfoString(); } - if (!mProfile->interfaceStateInfoString().empty()) { - interfaceVoiStateAndVariableInfoCode += mProfile->interfaceStateInfoString(); + if (!mLockedProfile->interfaceStateInfoString().empty()) { + interfaceVoiStateAndVariableInfoCode += mLockedProfile->interfaceStateInfoString(); } - if (!mProfile->interfaceVariableInfoString().empty()) { - interfaceVoiStateAndVariableInfoCode += mProfile->interfaceVariableInfoString(); + if (!mLockedProfile->interfaceVariableInfoString().empty()) { + interfaceVoiStateAndVariableInfoCode += mLockedProfile->interfaceVariableInfoString(); } if (!interfaceVoiStateAndVariableInfoCode.empty()) { - code += "\n"; + mCode += "\n"; } - code += interfaceVoiStateAndVariableInfoCode; + mCode += interfaceVoiStateAndVariableInfoCode; } -void Generator::GeneratorImpl::addImplementationVoiInfoCode(std::string &code) +void Generator::GeneratorImpl::addImplementationVoiInfoCode() { - if (!mProfile->implementationVoiInfoString().empty() - && !mProfile->variableInfoEntryString().empty()) { - if (!code.empty()) { - code += "\n"; + if (!mLockedProfile->implementationVoiInfoString().empty() + && !mLockedProfile->variableInfoEntryString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - std::string name = (mVoi != nullptr) ? mVoi->variable()->name() : ""; - std::string units = (mVoi != nullptr) ? mVoi->variable()->units()->name() : ""; - std::string component = (mVoi != nullptr) ? owningComponent(mVoi->variable())->name() : ""; + auto name = (mLockedModel->voi() != nullptr) ? mLockedModel->voi()->variable()->name() : ""; + auto units = (mLockedModel->voi() != nullptr) ? mLockedModel->voi()->variable()->units()->name() : ""; + auto component = (mLockedModel->voi() != nullptr) ? owningComponent(mLockedModel->voi()->variable())->name() : ""; - code += replace(mProfile->implementationVoiInfoString(), - "", generateVariableInfoEntryCode(name, units, component)); + mCode += replace(mLockedProfile->implementationVoiInfoString(), + "", generateVariableInfoEntryCode(name, units, component)); } } -void Generator::GeneratorImpl::addImplementationStateInfoCode(std::string &code) +void Generator::GeneratorImpl::addImplementationStateInfoCode() { - if (!mProfile->implementationStateInfoString().empty() - && !mProfile->variableInfoEntryString().empty() - && !mProfile->arrayElementSeparatorString().empty()) { - if (!code.empty()) { - code += "\n"; + if (!mLockedProfile->implementationStateInfoString().empty() + && !mLockedProfile->variableInfoEntryString().empty() + && !mLockedProfile->arrayElementSeparatorString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } std::string infoElementsCode; - for (const auto &state : mStates) { + for (const auto &state : mLockedModel->states()) { if (!infoElementsCode.empty()) { - infoElementsCode += mProfile->arrayElementSeparatorString() + "\n"; + infoElementsCode += mLockedProfile->arrayElementSeparatorString() + "\n"; } - infoElementsCode += mProfile->indentString() + infoElementsCode += mLockedProfile->indentString() + generateVariableInfoEntryCode(state->variable()->name(), state->variable()->units()->name(), owningComponent(state->variable())->name()); @@ -2289,42 +806,42 @@ void Generator::GeneratorImpl::addImplementationStateInfoCode(std::string &code) infoElementsCode += "\n"; } - code += replace(mProfile->implementationStateInfoString(), - "", infoElementsCode); + mCode += replace(mLockedProfile->implementationStateInfoString(), + "", infoElementsCode); } } -void Generator::GeneratorImpl::addImplementationVariableInfoCode(std::string &code) +void Generator::GeneratorImpl::addImplementationVariableInfoCode() { - if (!mProfile->implementationVariableInfoString().empty() - && !mProfile->variableInfoWithTypeEntryString().empty() - && !mProfile->arrayElementSeparatorString().empty() - && !mProfile->constantVariableTypeString().empty() - && !mProfile->computedConstantVariableTypeString().empty() - && !mProfile->algebraicVariableTypeString().empty()) { - if (!code.empty()) { - code += "\n"; + if (!mLockedProfile->implementationVariableInfoString().empty() + && !mLockedProfile->variableInfoWithTypeEntryString().empty() + && !mLockedProfile->arrayElementSeparatorString().empty() + && !mLockedProfile->constantVariableTypeString().empty() + && !mLockedProfile->computedConstantVariableTypeString().empty() + && !mLockedProfile->algebraicVariableTypeString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } std::string infoElementsCode; - for (const auto &variable : mVariables) { + for (const auto &variable : mLockedModel->variables()) { if (!infoElementsCode.empty()) { - infoElementsCode += mProfile->arrayElementSeparatorString() + "\n"; + infoElementsCode += mLockedProfile->arrayElementSeparatorString() + "\n"; } std::string variableType; - if (variable->type() == GeneratorVariable::Type::CONSTANT) { - variableType = mProfile->constantVariableTypeString(); - } else if (variable->type() == GeneratorVariable::Type::COMPUTED_CONSTANT) { - variableType = mProfile->computedConstantVariableTypeString(); - } else if (variable->type() == GeneratorVariable::Type::ALGEBRAIC) { - variableType = mProfile->algebraicVariableTypeString(); + if (variable->type() == AnalyserVariable::Type::CONSTANT) { + variableType = mLockedProfile->constantVariableTypeString(); + } else if (variable->type() == AnalyserVariable::Type::COMPUTED_CONSTANT) { + variableType = mLockedProfile->computedConstantVariableTypeString(); + } else if (variable->type() == AnalyserVariable::Type::ALGEBRAIC) { + variableType = mLockedProfile->algebraicVariableTypeString(); } - infoElementsCode += mProfile->indentString() - + replace(replace(replace(replace(mProfile->variableInfoWithTypeEntryString(), + infoElementsCode += mLockedProfile->indentString() + + replace(replace(replace(replace(mLockedProfile->variableInfoWithTypeEntryString(), "", variable->variable()->name()), "", variable->variable()->units()->name()), "", owningComponent(variable->variable())->name()), @@ -2335,305 +852,305 @@ void Generator::GeneratorImpl::addImplementationVariableInfoCode(std::string &co infoElementsCode += "\n"; } - code += replace(mProfile->implementationVariableInfoString(), - "", infoElementsCode); + mCode += replace(mLockedProfile->implementationVariableInfoString(), + "", infoElementsCode); } } -void Generator::GeneratorImpl::addArithmeticFunctionsCode(std::string &code) const +void Generator::GeneratorImpl::addArithmeticFunctionsCode() { - if (mNeedEq && !mProfile->hasEqOperator() - && !mProfile->eqFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needEqFunction() && !mLockedProfile->hasEqOperator() + && !mLockedProfile->eqFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->eqFunctionString(); + mCode += mLockedProfile->eqFunctionString(); } - if (mNeedNeq && !mProfile->hasNeqOperator() - && !mProfile->neqFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needNeqFunction() && !mLockedProfile->hasNeqOperator() + && !mLockedProfile->neqFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->neqFunctionString(); + mCode += mLockedProfile->neqFunctionString(); } - if (mNeedLt && !mProfile->hasLtOperator() - && !mProfile->ltFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needLtFunction() && !mLockedProfile->hasLtOperator() + && !mLockedProfile->ltFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->ltFunctionString(); + mCode += mLockedProfile->ltFunctionString(); } - if (mNeedLeq && !mProfile->hasLeqOperator() - && !mProfile->leqFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needLeqFunction() && !mLockedProfile->hasLeqOperator() + && !mLockedProfile->leqFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->leqFunctionString(); + mCode += mLockedProfile->leqFunctionString(); } - if (mNeedGt && !mProfile->hasGtOperator() - && !mProfile->gtFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needGtFunction() && !mLockedProfile->hasGtOperator() + && !mLockedProfile->gtFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->gtFunctionString(); + mCode += mLockedProfile->gtFunctionString(); } - if (mNeedGeq && !mProfile->hasGeqOperator() - && !mProfile->geqFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needGeqFunction() && !mLockedProfile->hasGeqOperator() + && !mLockedProfile->geqFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->geqFunctionString(); + mCode += mLockedProfile->geqFunctionString(); } - if (mNeedAnd && !mProfile->hasAndOperator() - && !mProfile->andFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needAndFunction() && !mLockedProfile->hasAndOperator() + && !mLockedProfile->andFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->andFunctionString(); + mCode += mLockedProfile->andFunctionString(); } - if (mNeedOr && !mProfile->hasOrOperator() - && !mProfile->orFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needOrFunction() && !mLockedProfile->hasOrOperator() + && !mLockedProfile->orFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->orFunctionString(); + mCode += mLockedProfile->orFunctionString(); } - if (mNeedXor && !mProfile->hasXorOperator() - && !mProfile->xorFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needXorFunction() && !mLockedProfile->hasXorOperator() + && !mLockedProfile->xorFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->xorFunctionString(); + mCode += mLockedProfile->xorFunctionString(); } - if (mNeedNot && !mProfile->hasNotOperator() - && !mProfile->notFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needNotFunction() && !mLockedProfile->hasNotOperator() + && !mLockedProfile->notFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->notFunctionString(); + mCode += mLockedProfile->notFunctionString(); } - if (mNeedMin - && !mProfile->minFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needMinFunction() + && !mLockedProfile->minFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->minFunctionString(); + mCode += mLockedProfile->minFunctionString(); } - if (mNeedMax - && !mProfile->maxFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needMaxFunction() + && !mLockedProfile->maxFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->maxFunctionString(); + mCode += mLockedProfile->maxFunctionString(); } } -void Generator::GeneratorImpl::addTrigonometricFunctionsCode(std::string &code) const +void Generator::GeneratorImpl::addTrigonometricFunctionsCode() { - if (mNeedSec - && !mProfile->secFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needSecFunction() + && !mLockedProfile->secFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->secFunctionString(); + mCode += mLockedProfile->secFunctionString(); } - if (mNeedCsc - && !mProfile->cscFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needCscFunction() + && !mLockedProfile->cscFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->cscFunctionString(); + mCode += mLockedProfile->cscFunctionString(); } - if (mNeedCot - && !mProfile->cotFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needCotFunction() + && !mLockedProfile->cotFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->cotFunctionString(); + mCode += mLockedProfile->cotFunctionString(); } - if (mNeedSech - && !mProfile->sechFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needSechFunction() + && !mLockedProfile->sechFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->sechFunctionString(); + mCode += mLockedProfile->sechFunctionString(); } - if (mNeedCsch - && !mProfile->cschFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needCschFunction() + && !mLockedProfile->cschFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->cschFunctionString(); + mCode += mLockedProfile->cschFunctionString(); } - if (mNeedCoth - && !mProfile->cothFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needCothFunction() + && !mLockedProfile->cothFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->cothFunctionString(); + mCode += mLockedProfile->cothFunctionString(); } - if (mNeedAsec - && !mProfile->asecFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needAsecFunction() + && !mLockedProfile->asecFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->asecFunctionString(); + mCode += mLockedProfile->asecFunctionString(); } - if (mNeedAcsc - && !mProfile->acscFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needAcscFunction() + && !mLockedProfile->acscFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->acscFunctionString(); + mCode += mLockedProfile->acscFunctionString(); } - if (mNeedAcot - && !mProfile->acotFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needAcotFunction() + && !mLockedProfile->acotFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->acotFunctionString(); + mCode += mLockedProfile->acotFunctionString(); } - if (mNeedAsech - && !mProfile->asechFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needAsechFunction() + && !mLockedProfile->asechFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->asechFunctionString(); + mCode += mLockedProfile->asechFunctionString(); } - if (mNeedAcsch - && !mProfile->acschFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needAcschFunction() + && !mLockedProfile->acschFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->acschFunctionString(); + mCode += mLockedProfile->acschFunctionString(); } - if (mNeedAcoth - && !mProfile->acothFunctionString().empty()) { - if (!code.empty()) { - code += "\n"; + if (mLockedModel->needAcothFunction() + && !mLockedProfile->acothFunctionString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->acothFunctionString(); + mCode += mLockedProfile->acothFunctionString(); } } -void Generator::GeneratorImpl::addInterfaceCreateDeleteArrayMethodsCode(std::string &code) const +void Generator::GeneratorImpl::addInterfaceCreateDeleteArrayMethodsCode() { std::string interfaceCreateDeleteArraysCode; - if (!mProfile->interfaceCreateStatesArrayMethodString().empty()) { - interfaceCreateDeleteArraysCode += mProfile->interfaceCreateStatesArrayMethodString(); + if (!mLockedProfile->interfaceCreateStatesArrayMethodString().empty()) { + interfaceCreateDeleteArraysCode += mLockedProfile->interfaceCreateStatesArrayMethodString(); } - if (!mProfile->interfaceCreateVariablesArrayMethodString().empty()) { - interfaceCreateDeleteArraysCode += mProfile->interfaceCreateVariablesArrayMethodString(); + if (!mLockedProfile->interfaceCreateVariablesArrayMethodString().empty()) { + interfaceCreateDeleteArraysCode += mLockedProfile->interfaceCreateVariablesArrayMethodString(); } - if (!mProfile->interfaceDeleteArrayMethodString().empty()) { - interfaceCreateDeleteArraysCode += mProfile->interfaceDeleteArrayMethodString(); + if (!mLockedProfile->interfaceDeleteArrayMethodString().empty()) { + interfaceCreateDeleteArraysCode += mLockedProfile->interfaceDeleteArrayMethodString(); } if (!interfaceCreateDeleteArraysCode.empty()) { - code += "\n"; + mCode += "\n"; } - code += interfaceCreateDeleteArraysCode; + mCode += interfaceCreateDeleteArraysCode; } -void Generator::GeneratorImpl::addImplementationCreateStatesArrayMethodCode(std::string &code) const +void Generator::GeneratorImpl::addImplementationCreateStatesArrayMethodCode() { - if (!mProfile->implementationCreateStatesArrayMethodString().empty()) { - if (!code.empty()) { - code += "\n"; + if (!mLockedProfile->implementationCreateStatesArrayMethodString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->implementationCreateStatesArrayMethodString(); + mCode += mLockedProfile->implementationCreateStatesArrayMethodString(); } } -void Generator::GeneratorImpl::addImplementationCreateVariablesArrayMethodCode(std::string &code) const +void Generator::GeneratorImpl::addImplementationCreateVariablesArrayMethodCode() { - if (!mProfile->implementationCreateVariablesArrayMethodString().empty()) { - if (!code.empty()) { - code += "\n"; + if (!mLockedProfile->implementationCreateVariablesArrayMethodString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->implementationCreateVariablesArrayMethodString(); + mCode += mLockedProfile->implementationCreateVariablesArrayMethodString(); } } -void Generator::GeneratorImpl::addImplementationDeleteArrayMethodCode(std::string &code) const +void Generator::GeneratorImpl::addImplementationDeleteArrayMethodCode() { - if (!mProfile->implementationDeleteArrayMethodString().empty()) { - if (!code.empty()) { - code += "\n"; + if (!mLockedProfile->implementationDeleteArrayMethodString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - code += mProfile->implementationDeleteArrayMethodString(); + mCode += mLockedProfile->implementationDeleteArrayMethodString(); } } std::string Generator::GeneratorImpl::generateMethodBodyCode(const std::string &methodBody) const { return methodBody.empty() ? - mProfile->emptyMethodString().empty() ? + mLockedProfile->emptyMethodString().empty() ? "" : - mProfile->indentString() + mProfile->emptyMethodString() : + mLockedProfile->indentString() + mLockedProfile->emptyMethodString() : methodBody; } -std::string Generator::GeneratorImpl::generateDoubleCode(const std::string &value) +std::string Generator::GeneratorImpl::generateDoubleCode(const std::string &value) const { if (value.find('.') != std::string::npos) { return value; } - size_t ePos = value.find('e'); + auto ePos = value.find('e'); if (ePos == std::string::npos) { return value + ".0"; @@ -2642,53 +1159,54 @@ std::string Generator::GeneratorImpl::generateDoubleCode(const std::string &valu return value.substr(0, ePos) + ".0" + value.substr(ePos); } -std::string Generator::GeneratorImpl::generateDoubleOrConstantVariableNameCode(const VariablePtr &variable) +std::string Generator::GeneratorImpl::generateDoubleOrConstantVariableNameCode(const VariablePtr &variable) const { if (isCellMLReal(variable->initialValue())) { return generateDoubleCode(variable->initialValue()); } - VariablePtr initValueVariable = owningComponent(variable)->variable(variable->initialValue()); - GeneratorInternalVariablePtr generatorInitialValueVariable = Generator::GeneratorImpl::generatorVariable(initValueVariable); + auto initValueVariable = owningComponent(variable)->variable(variable->initialValue()); + auto analyserInitialValueVariable = analyserVariable(initValueVariable); std::ostringstream index; - index << generatorInitialValueVariable->mIndex; + index << analyserInitialValueVariable->index(); - return mProfile->variablesArrayString() + mProfile->openArrayString() + index.str() + mProfile->closeArrayString(); + return mLockedProfile->variablesArrayString() + mLockedProfile->openArrayString() + index.str() + mLockedProfile->closeArrayString(); } -std::string Generator::GeneratorImpl::generateVariableNameCode(const VariablePtr &variable, const GeneratorEquationAstPtr &ast) +std::string Generator::GeneratorImpl::generateVariableNameCode(const VariablePtr &variable, + const AnalyserEquationAstPtr &ast) const { - GeneratorInternalVariablePtr generatorVariable = Generator::GeneratorImpl::generatorVariable(variable); + auto analyserVariable = Generator::GeneratorImpl::analyserVariable(variable); - if (generatorVariable->mType == GeneratorInternalVariable::Type::VARIABLE_OF_INTEGRATION) { - return mProfile->voiString(); + if (analyserVariable->type() == AnalyserVariable::Type::VARIABLE_OF_INTEGRATION) { + return mLockedProfile->voiString(); } std::string arrayName; - if (generatorVariable->mType == GeneratorInternalVariable::Type::STATE) { - arrayName = ((ast != nullptr) && (ast->mParent.lock()->mType == GeneratorEquationAst::Type::DIFF)) ? - mProfile->ratesArrayString() : - mProfile->statesArrayString(); + if (analyserVariable->type() == AnalyserVariable::Type::STATE) { + arrayName = ((ast != nullptr) && (ast->parent()->type() == AnalyserEquationAst::Type::DIFF)) ? + mLockedProfile->ratesArrayString() : + mLockedProfile->statesArrayString(); } else { - arrayName = mProfile->variablesArrayString(); + arrayName = mLockedProfile->variablesArrayString(); } std::ostringstream index; - index << generatorVariable->mIndex; + index << analyserVariable->index(); - return arrayName + mProfile->openArrayString() + index.str() + mProfile->closeArrayString(); + return arrayName + mLockedProfile->openArrayString() + index.str() + mLockedProfile->closeArrayString(); } std::string Generator::GeneratorImpl::generateOperatorCode(const std::string &op, - const GeneratorEquationAstPtr &ast) + const AnalyserEquationAstPtr &ast) const { // Generate the code for the left and right branches of the given AST. - std::string left = generateCode(ast->mLeft); - std::string right = generateCode(ast->mRight); + auto leftChild = generateCode(ast->leftChild()); + auto rightChild = generateCode(ast->rightChild()); // Determine whether parentheses should be added around the left and/or // right piece of code, and this based on the precedence of the operators @@ -2707,78 +1225,78 @@ std::string Generator::GeneratorImpl::generateOperatorCode(const std::string &op // 11. PIECEWISE (as an operator) [Right to left] if (isPlusOperator(ast)) { - if (isRelationalOperator(ast->mLeft) - || isLogicalOperator(ast->mLeft) - || isPiecewiseStatement(ast->mLeft)) { - left = "(" + left + ")"; + if (isRelationalOperator(ast->leftChild()) + || isLogicalOperator(ast->leftChild()) + || isPiecewiseStatement(ast->leftChild())) { + leftChild = "(" + leftChild + ")"; } - if (isRelationalOperator(ast->mRight) - || isLogicalOperator(ast->mRight) - || isPiecewiseStatement(ast->mRight)) { - right = "(" + right + ")"; + if (isRelationalOperator(ast->rightChild()) + || isLogicalOperator(ast->rightChild()) + || isPiecewiseStatement(ast->rightChild())) { + rightChild = "(" + rightChild + ")"; } } else if (isMinusOperator(ast)) { - if (isRelationalOperator(ast->mLeft) - || isLogicalOperator(ast->mLeft) - || isPiecewiseStatement(ast->mLeft)) { - left = "(" + left + ")"; - } - - if (isRelationalOperator(ast->mRight) - || isLogicalOperator(ast->mRight) - || isMinusOperator(ast->mRight) - || isPiecewiseStatement(ast->mRight)) { - right = "(" + right + ")"; - } else if (isPlusOperator(ast->mRight)) { - if (ast->mRight->mRight != nullptr) { - right = "(" + right + ")"; + if (isRelationalOperator(ast->leftChild()) + || isLogicalOperator(ast->leftChild()) + || isPiecewiseStatement(ast->leftChild())) { + leftChild = "(" + leftChild + ")"; + } + + if (isRelationalOperator(ast->rightChild()) + || isLogicalOperator(ast->rightChild()) + || isMinusOperator(ast->rightChild()) + || isPiecewiseStatement(ast->rightChild())) { + rightChild = "(" + rightChild + ")"; + } else if (isPlusOperator(ast->rightChild())) { + if (ast->rightChild()->rightChild() != nullptr) { + rightChild = "(" + rightChild + ")"; } } } else if (isTimesOperator(ast)) { - if (isRelationalOperator(ast->mLeft) - || isLogicalOperator(ast->mLeft) - || isPiecewiseStatement(ast->mLeft)) { - left = "(" + left + ")"; - } else if (isPlusOperator(ast->mLeft) - || isMinusOperator(ast->mLeft)) { - if (ast->mLeft->mRight != nullptr) { - left = "(" + left + ")"; + if (isRelationalOperator(ast->leftChild()) + || isLogicalOperator(ast->leftChild()) + || isPiecewiseStatement(ast->leftChild())) { + leftChild = "(" + leftChild + ")"; + } else if (isPlusOperator(ast->leftChild()) + || isMinusOperator(ast->leftChild())) { + if (ast->leftChild()->rightChild() != nullptr) { + leftChild = "(" + leftChild + ")"; } } - if (isRelationalOperator(ast->mRight) - || isLogicalOperator(ast->mRight) - || isPiecewiseStatement(ast->mRight)) { - right = "(" + right + ")"; - } else if (isPlusOperator(ast->mRight) - || isMinusOperator(ast->mRight)) { - if (ast->mRight->mRight != nullptr) { - right = "(" + right + ")"; + if (isRelationalOperator(ast->rightChild()) + || isLogicalOperator(ast->rightChild()) + || isPiecewiseStatement(ast->rightChild())) { + rightChild = "(" + rightChild + ")"; + } else if (isPlusOperator(ast->rightChild()) + || isMinusOperator(ast->rightChild())) { + if (ast->rightChild()->rightChild() != nullptr) { + rightChild = "(" + rightChild + ")"; } } } else if (isDivideOperator(ast)) { - if (isRelationalOperator(ast->mLeft) - || isLogicalOperator(ast->mLeft) - || isPiecewiseStatement(ast->mLeft)) { - left = "(" + left + ")"; - } else if (isPlusOperator(ast->mLeft) - || isMinusOperator(ast->mLeft)) { - if (ast->mLeft->mRight != nullptr) { - left = "(" + left + ")"; + if (isRelationalOperator(ast->leftChild()) + || isLogicalOperator(ast->leftChild()) + || isPiecewiseStatement(ast->leftChild())) { + leftChild = "(" + leftChild + ")"; + } else if (isPlusOperator(ast->leftChild()) + || isMinusOperator(ast->leftChild())) { + if (ast->leftChild()->rightChild() != nullptr) { + leftChild = "(" + leftChild + ")"; } } - if (isRelationalOperator(ast->mRight) - || isLogicalOperator(ast->mRight) - || isTimesOperator(ast->mRight) - || isDivideOperator(ast->mRight) - || isPiecewiseStatement(ast->mRight)) { - right = "(" + right + ")"; - } else if (isPlusOperator(ast->mRight) - || isMinusOperator(ast->mRight)) { - if (ast->mRight->mRight != nullptr) { - right = "(" + right + ")"; + if (isRelationalOperator(ast->rightChild()) + || isLogicalOperator(ast->rightChild()) + || isTimesOperator(ast->rightChild()) + || isDivideOperator(ast->rightChild()) + || isPiecewiseStatement(ast->rightChild())) { + rightChild = "(" + rightChild + ")"; + } else if (isPlusOperator(ast->rightChild()) + || isMinusOperator(ast->rightChild())) { + if (ast->rightChild()->rightChild() != nullptr) { + rightChild = "(" + rightChild + ")"; } } } else if (isAndOperator(ast)) { @@ -2787,36 +1305,36 @@ std::string Generator::GeneratorImpl::generateOperatorCode(const std::string &op // better/clearer to have some around some other operators // (agreed, this is somewhat subjective). - if (isRelationalOperator(ast->mLeft) - || isOrOperator(ast->mLeft) - || isXorOperator(ast->mLeft) - || isPiecewiseStatement(ast->mLeft)) { - left = "(" + left + ")"; - } else if (isPlusOperator(ast->mLeft) - || isMinusOperator(ast->mLeft)) { - if (ast->mLeft->mRight != nullptr) { - left = "(" + left + ")"; + if (isRelationalOperator(ast->leftChild()) + || isOrOperator(ast->leftChild()) + || isXorOperator(ast->leftChild()) + || isPiecewiseStatement(ast->leftChild())) { + leftChild = "(" + leftChild + ")"; + } else if (isPlusOperator(ast->leftChild()) + || isMinusOperator(ast->leftChild())) { + if (ast->leftChild()->rightChild() != nullptr) { + leftChild = "(" + leftChild + ")"; } - } else if (isPowerOperator(ast->mLeft)) { - left = "(" + left + ")"; - } else if (isRootOperator(ast->mLeft)) { - left = "(" + left + ")"; - } - - if (isRelationalOperator(ast->mRight) - || isOrOperator(ast->mRight) - || isXorOperator(ast->mRight) - || isPiecewiseStatement(ast->mRight)) { - right = "(" + right + ")"; - } else if (isPlusOperator(ast->mRight) - || isMinusOperator(ast->mRight)) { - if (ast->mRight->mRight != nullptr) { - right = "(" + right + ")"; + } else if (isPowerOperator(ast->leftChild())) { + leftChild = "(" + leftChild + ")"; + } else if (isRootOperator(ast->leftChild())) { + leftChild = "(" + leftChild + ")"; + } + + if (isRelationalOperator(ast->rightChild()) + || isOrOperator(ast->rightChild()) + || isXorOperator(ast->rightChild()) + || isPiecewiseStatement(ast->rightChild())) { + rightChild = "(" + rightChild + ")"; + } else if (isPlusOperator(ast->rightChild()) + || isMinusOperator(ast->rightChild())) { + if (ast->rightChild()->rightChild() != nullptr) { + rightChild = "(" + rightChild + ")"; } - } else if (isPowerOperator(ast->mRight)) { - right = "(" + right + ")"; - } else if (isRootOperator(ast->mRight)) { - right = "(" + right + ")"; + } else if (isPowerOperator(ast->rightChild())) { + rightChild = "(" + rightChild + ")"; + } else if (isRootOperator(ast->rightChild())) { + rightChild = "(" + rightChild + ")"; } } else if (isOrOperator(ast)) { // Note: according to the precedence rules above, we only need to add @@ -2824,36 +1342,36 @@ std::string Generator::GeneratorImpl::generateOperatorCode(const std::string &op // to have some around some other operators (agreed, this is // somewhat subjective). - if (isRelationalOperator(ast->mLeft) - || isAndOperator(ast->mLeft) - || isXorOperator(ast->mLeft) - || isPiecewiseStatement(ast->mLeft)) { - left = "(" + left + ")"; - } else if (isPlusOperator(ast->mLeft) - || isMinusOperator(ast->mLeft)) { - if (ast->mLeft->mRight != nullptr) { - left = "(" + left + ")"; + if (isRelationalOperator(ast->leftChild()) + || isAndOperator(ast->leftChild()) + || isXorOperator(ast->leftChild()) + || isPiecewiseStatement(ast->leftChild())) { + leftChild = "(" + leftChild + ")"; + } else if (isPlusOperator(ast->leftChild()) + || isMinusOperator(ast->leftChild())) { + if (ast->leftChild()->rightChild() != nullptr) { + leftChild = "(" + leftChild + ")"; } - } else if (isPowerOperator(ast->mLeft)) { - left = "(" + left + ")"; - } else if (isRootOperator(ast->mLeft)) { - left = "(" + left + ")"; - } - - if (isRelationalOperator(ast->mRight) - || isAndOperator(ast->mRight) - || isXorOperator(ast->mRight) - || isPiecewiseStatement(ast->mRight)) { - right = "(" + right + ")"; - } else if (isPlusOperator(ast->mRight) - || isMinusOperator(ast->mRight)) { - if (ast->mRight->mRight != nullptr) { - right = "(" + right + ")"; + } else if (isPowerOperator(ast->leftChild())) { + leftChild = "(" + leftChild + ")"; + } else if (isRootOperator(ast->leftChild())) { + leftChild = "(" + leftChild + ")"; + } + + if (isRelationalOperator(ast->rightChild()) + || isAndOperator(ast->rightChild()) + || isXorOperator(ast->rightChild()) + || isPiecewiseStatement(ast->rightChild())) { + rightChild = "(" + rightChild + ")"; + } else if (isPlusOperator(ast->rightChild()) + || isMinusOperator(ast->rightChild())) { + if (ast->rightChild()->rightChild() != nullptr) { + rightChild = "(" + rightChild + ")"; } - } else if (isPowerOperator(ast->mRight)) { - right = "(" + right + ")"; - } else if (isRootOperator(ast->mRight)) { - right = "(" + right + ")"; + } else if (isPowerOperator(ast->rightChild())) { + rightChild = "(" + rightChild + ")"; + } else if (isRootOperator(ast->rightChild())) { + rightChild = "(" + rightChild + ")"; } } else if (isXorOperator(ast)) { // Note: according to the precedence rules above, we only need to add @@ -2861,534 +1379,550 @@ std::string Generator::GeneratorImpl::generateOperatorCode(const std::string &op // better/clearer to have some around some other operators // (agreed, this is somewhat subjective). - if (isRelationalOperator(ast->mLeft) - || isAndOperator(ast->mLeft) - || isOrOperator(ast->mLeft) - || isPiecewiseStatement(ast->mLeft)) { - left = "(" + left + ")"; - } else if (isPlusOperator(ast->mLeft) - || isMinusOperator(ast->mLeft)) { - if (ast->mLeft->mRight != nullptr) { - left = "(" + left + ")"; + if (isRelationalOperator(ast->leftChild()) + || isAndOperator(ast->leftChild()) + || isOrOperator(ast->leftChild()) + || isPiecewiseStatement(ast->leftChild())) { + leftChild = "(" + leftChild + ")"; + } else if (isPlusOperator(ast->leftChild()) + || isMinusOperator(ast->leftChild())) { + if (ast->leftChild()->rightChild() != nullptr) { + leftChild = "(" + leftChild + ")"; } - } else if (isPowerOperator(ast->mLeft)) { - left = "(" + left + ")"; - } else if (isRootOperator(ast->mLeft)) { - left = "(" + left + ")"; - } - - if (isRelationalOperator(ast->mRight) - || isAndOperator(ast->mRight) - || isOrOperator(ast->mRight) - || isPiecewiseStatement(ast->mRight)) { - right = "(" + right + ")"; - } else if (isPlusOperator(ast->mRight) - || isMinusOperator(ast->mRight)) { - if (ast->mRight->mRight != nullptr) { - right = "(" + right + ")"; + } else if (isPowerOperator(ast->leftChild())) { + leftChild = "(" + leftChild + ")"; + } else if (isRootOperator(ast->leftChild())) { + leftChild = "(" + leftChild + ")"; + } + + if (isRelationalOperator(ast->rightChild()) + || isAndOperator(ast->rightChild()) + || isOrOperator(ast->rightChild()) + || isPiecewiseStatement(ast->rightChild())) { + rightChild = "(" + rightChild + ")"; + } else if (isPlusOperator(ast->rightChild()) + || isMinusOperator(ast->rightChild())) { + if (ast->rightChild()->rightChild() != nullptr) { + rightChild = "(" + rightChild + ")"; } - } else if (isPowerOperator(ast->mRight)) { - right = "(" + right + ")"; - } else if (isRootOperator(ast->mRight)) { - right = "(" + right + ")"; + } else if (isPowerOperator(ast->rightChild())) { + rightChild = "(" + rightChild + ")"; + } else if (isRootOperator(ast->rightChild())) { + rightChild = "(" + rightChild + ")"; } } else if (isPowerOperator(ast)) { - if (isRelationalOperator(ast->mLeft) - || isLogicalOperator(ast->mLeft) - || isMinusOperator(ast->mLeft) - || isTimesOperator(ast->mLeft) - || isDivideOperator(ast->mLeft) - || isPiecewiseStatement(ast->mLeft)) { - left = "(" + left + ")"; - } else if (isPlusOperator(ast->mLeft)) { - if (ast->mLeft->mRight != nullptr) { - left = "(" + left + ")"; + if (isRelationalOperator(ast->leftChild()) + || isLogicalOperator(ast->leftChild()) + || isMinusOperator(ast->leftChild()) + || isTimesOperator(ast->leftChild()) + || isDivideOperator(ast->leftChild()) + || isPiecewiseStatement(ast->leftChild())) { + leftChild = "(" + leftChild + ")"; + } else if (isPlusOperator(ast->leftChild())) { + if (ast->leftChild()->rightChild() != nullptr) { + leftChild = "(" + leftChild + ")"; } } - if (isRelationalOperator(ast->mRight) - || isLogicalOperator(ast->mRight) - || isMinusOperator(ast->mLeft) - || isTimesOperator(ast->mRight) - || isDivideOperator(ast->mRight) - || isPowerOperator(ast->mRight) - || isRootOperator(ast->mRight) - || isPiecewiseStatement(ast->mRight)) { - right = "(" + right + ")"; - } else if (isPlusOperator(ast->mRight)) { - if (ast->mRight->mRight != nullptr) { - right = "(" + right + ")"; + if (isRelationalOperator(ast->rightChild()) + || isLogicalOperator(ast->rightChild()) + || isMinusOperator(ast->leftChild()) + || isTimesOperator(ast->rightChild()) + || isDivideOperator(ast->rightChild()) + || isPowerOperator(ast->rightChild()) + || isRootOperator(ast->rightChild()) + || isPiecewiseStatement(ast->rightChild())) { + rightChild = "(" + rightChild + ")"; + } else if (isPlusOperator(ast->rightChild())) { + if (ast->rightChild()->rightChild() != nullptr) { + rightChild = "(" + rightChild + ")"; } } } else if (isRootOperator(ast)) { - if (isRelationalOperator(ast->mRight) - || isLogicalOperator(ast->mRight) - || isMinusOperator(ast->mRight) - || isTimesOperator(ast->mRight) - || isDivideOperator(ast->mRight) - || isPiecewiseStatement(ast->mRight)) { - right = "(" + right + ")"; - } else if (isPlusOperator(ast->mRight)) { - if (ast->mRight->mRight != nullptr) { - right = "(" + right + ")"; + if (isRelationalOperator(ast->rightChild()) + || isLogicalOperator(ast->rightChild()) + || isMinusOperator(ast->rightChild()) + || isTimesOperator(ast->rightChild()) + || isDivideOperator(ast->rightChild()) + || isPiecewiseStatement(ast->rightChild())) { + rightChild = "(" + rightChild + ")"; + } else if (isPlusOperator(ast->rightChild())) { + if (ast->rightChild()->rightChild() != nullptr) { + rightChild = "(" + rightChild + ")"; } } - if (isRelationalOperator(ast->mLeft) - || isLogicalOperator(ast->mLeft) - || isMinusOperator(ast->mLeft) - || isTimesOperator(ast->mLeft) - || isDivideOperator(ast->mLeft) - || isPowerOperator(ast->mLeft) - || isRootOperator(ast->mLeft) - || isPiecewiseStatement(ast->mLeft)) { - left = "(" + left + ")"; - } else if (isPlusOperator(ast->mLeft)) { - if (ast->mLeft->mRight != nullptr) { - left = "(" + left + ")"; + if (isRelationalOperator(ast->leftChild()) + || isLogicalOperator(ast->leftChild()) + || isMinusOperator(ast->leftChild()) + || isTimesOperator(ast->leftChild()) + || isDivideOperator(ast->leftChild()) + || isPowerOperator(ast->leftChild()) + || isRootOperator(ast->leftChild()) + || isPiecewiseStatement(ast->leftChild())) { + leftChild = "(" + leftChild + ")"; + } else if (isPlusOperator(ast->leftChild())) { + if (ast->leftChild()->rightChild() != nullptr) { + leftChild = "(" + leftChild + ")"; } } - return right + op + "(1.0/" + left + ")"; + return rightChild + op + "(1.0/" + leftChild + ")"; } - return left + op + right; + return leftChild + op + rightChild; } -std::string Generator::GeneratorImpl::generateMinusUnaryCode(const GeneratorEquationAstPtr &ast) +std::string Generator::GeneratorImpl::generateMinusUnaryCode(const AnalyserEquationAstPtr &ast) const { // Generate the code for the left branch of the given AST. - std::string left = generateCode(ast->mLeft); + auto left = generateCode(ast->leftChild()); // Determine whether parentheses should be added around the left code. - if (isRelationalOperator(ast->mLeft) - || isLogicalOperator(ast->mLeft) - || isPlusOperator(ast->mLeft) - || isMinusOperator(ast->mLeft) - || isPiecewiseStatement(ast->mLeft)) { + if (isRelationalOperator(ast->leftChild()) + || isLogicalOperator(ast->leftChild()) + || isPlusOperator(ast->leftChild()) + || isMinusOperator(ast->leftChild()) + || isPiecewiseStatement(ast->leftChild())) { left = "(" + left + ")"; } - return mProfile->minusString() + left; + return mLockedProfile->minusString() + left; } std::string Generator::GeneratorImpl::generateOneParameterFunctionCode(const std::string &function, - const GeneratorEquationAstPtr &ast) + const AnalyserEquationAstPtr &ast) const { - return function + "(" + generateCode(ast->mLeft) + ")"; + return function + "(" + generateCode(ast->leftChild()) + ")"; } std::string Generator::GeneratorImpl::generateTwoParameterFunctionCode(const std::string &function, - const GeneratorEquationAstPtr &ast) + const AnalyserEquationAstPtr &ast) const { - return function + "(" + generateCode(ast->mLeft) + ", " + generateCode(ast->mRight) + ")"; + return function + "(" + generateCode(ast->leftChild()) + ", " + generateCode(ast->rightChild()) + ")"; } std::string Generator::GeneratorImpl::generatePiecewiseIfCode(const std::string &condition, - const std::string &value) + const std::string &value) const { - return replace(replace(mProfile->hasConditionalOperator() ? - mProfile->conditionalOperatorIfString() : - mProfile->piecewiseIfString(), + return replace(replace(mLockedProfile->hasConditionalOperator() ? + mLockedProfile->conditionalOperatorIfString() : + mLockedProfile->piecewiseIfString(), "", condition), "", value); } -std::string Generator::GeneratorImpl::generatePiecewiseElseCode(const std::string &value) +std::string Generator::GeneratorImpl::generatePiecewiseElseCode(const std::string &value) const { - return replace(mProfile->hasConditionalOperator() ? - mProfile->conditionalOperatorElseString() : - mProfile->piecewiseElseString(), + return replace(mLockedProfile->hasConditionalOperator() ? + mLockedProfile->conditionalOperatorElseString() : + mLockedProfile->piecewiseElseString(), "", value); } -std::string Generator::GeneratorImpl::generateCode(const GeneratorEquationAstPtr &ast) +std::string Generator::GeneratorImpl::generateCode(const AnalyserEquationAstPtr &ast) const { // Generate the code for the given AST. std::string code; - switch (ast->mType) { + switch (ast->type()) { // Assignment. - case GeneratorEquationAst::Type::ASSIGNMENT: - code = generateOperatorCode(mProfile->assignmentString(), ast); + case AnalyserEquationAst::Type::ASSIGNMENT: + code = generateOperatorCode(mLockedProfile->assignmentString(), ast); break; // Relational and logical operators. - case GeneratorEquationAst::Type::EQ: - if (mProfile->hasEqOperator()) { - code = generateOperatorCode(mProfile->eqString(), ast); + case AnalyserEquationAst::Type::EQ: + if (mLockedProfile->hasEqOperator()) { + code = generateOperatorCode(mLockedProfile->eqString(), ast); } else { - code = generateTwoParameterFunctionCode(mProfile->eqString(), ast); + code = generateTwoParameterFunctionCode(mLockedProfile->eqString(), ast); } break; - case GeneratorEquationAst::Type::NEQ: - if (mProfile->hasNeqOperator()) { - code = generateOperatorCode(mProfile->neqString(), ast); + case AnalyserEquationAst::Type::NEQ: + if (mLockedProfile->hasNeqOperator()) { + code = generateOperatorCode(mLockedProfile->neqString(), ast); } else { - code = generateTwoParameterFunctionCode(mProfile->neqString(), ast); + code = generateTwoParameterFunctionCode(mLockedProfile->neqString(), ast); } break; - case GeneratorEquationAst::Type::LT: - if (mProfile->hasLtOperator()) { - code = generateOperatorCode(mProfile->ltString(), ast); + case AnalyserEquationAst::Type::LT: + if (mLockedProfile->hasLtOperator()) { + code = generateOperatorCode(mLockedProfile->ltString(), ast); } else { - code = generateTwoParameterFunctionCode(mProfile->ltString(), ast); + code = generateTwoParameterFunctionCode(mLockedProfile->ltString(), ast); } break; - case GeneratorEquationAst::Type::LEQ: - if (mProfile->hasLeqOperator()) { - code = generateOperatorCode(mProfile->leqString(), ast); + case AnalyserEquationAst::Type::LEQ: + if (mLockedProfile->hasLeqOperator()) { + code = generateOperatorCode(mLockedProfile->leqString(), ast); } else { - code = generateTwoParameterFunctionCode(mProfile->leqString(), ast); + code = generateTwoParameterFunctionCode(mLockedProfile->leqString(), ast); } break; - case GeneratorEquationAst::Type::GT: - if (mProfile->hasGtOperator()) { - code = generateOperatorCode(mProfile->gtString(), ast); + case AnalyserEquationAst::Type::GT: + if (mLockedProfile->hasGtOperator()) { + code = generateOperatorCode(mLockedProfile->gtString(), ast); } else { - code = generateTwoParameterFunctionCode(mProfile->gtString(), ast); + code = generateTwoParameterFunctionCode(mLockedProfile->gtString(), ast); } break; - case GeneratorEquationAst::Type::GEQ: - if (mProfile->hasGeqOperator()) { - code = generateOperatorCode(mProfile->geqString(), ast); + case AnalyserEquationAst::Type::GEQ: + if (mLockedProfile->hasGeqOperator()) { + code = generateOperatorCode(mLockedProfile->geqString(), ast); } else { - code = generateTwoParameterFunctionCode(mProfile->geqString(), ast); + code = generateTwoParameterFunctionCode(mLockedProfile->geqString(), ast); } break; - case GeneratorEquationAst::Type::AND: - if (mProfile->hasAndOperator()) { - code = generateOperatorCode(mProfile->andString(), ast); + case AnalyserEquationAst::Type::AND: + if (mLockedProfile->hasAndOperator()) { + code = generateOperatorCode(mLockedProfile->andString(), ast); } else { - code = generateTwoParameterFunctionCode(mProfile->andString(), ast); + code = generateTwoParameterFunctionCode(mLockedProfile->andString(), ast); } break; - case GeneratorEquationAst::Type::OR: - if (mProfile->hasOrOperator()) { - code = generateOperatorCode(mProfile->orString(), ast); + case AnalyserEquationAst::Type::OR: + if (mLockedProfile->hasOrOperator()) { + code = generateOperatorCode(mLockedProfile->orString(), ast); } else { - code = generateTwoParameterFunctionCode(mProfile->orString(), ast); + code = generateTwoParameterFunctionCode(mLockedProfile->orString(), ast); } break; - case GeneratorEquationAst::Type::XOR: - if (mProfile->hasXorOperator()) { - code = generateOperatorCode(mProfile->xorString(), ast); + case AnalyserEquationAst::Type::XOR: + if (mLockedProfile->hasXorOperator()) { + code = generateOperatorCode(mLockedProfile->xorString(), ast); } else { - code = generateTwoParameterFunctionCode(mProfile->xorString(), ast); + code = generateTwoParameterFunctionCode(mLockedProfile->xorString(), ast); } break; - case GeneratorEquationAst::Type::NOT: - if (mProfile->hasNotOperator()) { - code = mProfile->notString() + generateCode(ast->mLeft); + case AnalyserEquationAst::Type::NOT: + if (mLockedProfile->hasNotOperator()) { + code = mLockedProfile->notString() + generateCode(ast->leftChild()); } else { - code = generateOneParameterFunctionCode(mProfile->notString(), ast); + code = generateOneParameterFunctionCode(mLockedProfile->notString(), ast); } break; // Arithmetic operators. - case GeneratorEquationAst::Type::PLUS: - if (ast->mRight != nullptr) { - code = generateOperatorCode(mProfile->plusString(), ast); + case AnalyserEquationAst::Type::PLUS: + if (ast->rightChild() != nullptr) { + code = generateOperatorCode(mLockedProfile->plusString(), ast); } else { - code = generateCode(ast->mLeft); + code = generateCode(ast->leftChild()); } break; - case GeneratorEquationAst::Type::MINUS: - if (ast->mRight != nullptr) { - code = generateOperatorCode(mProfile->minusString(), ast); + case AnalyserEquationAst::Type::MINUS: + if (ast->rightChild() != nullptr) { + code = generateOperatorCode(mLockedProfile->minusString(), ast); } else { code = generateMinusUnaryCode(ast); } break; - case GeneratorEquationAst::Type::TIMES: - code = generateOperatorCode(mProfile->timesString(), ast); + case AnalyserEquationAst::Type::TIMES: + code = generateOperatorCode(mLockedProfile->timesString(), ast); break; - case GeneratorEquationAst::Type::DIVIDE: - code = generateOperatorCode(mProfile->divideString(), ast); + case AnalyserEquationAst::Type::DIVIDE: + code = generateOperatorCode(mLockedProfile->divideString(), ast); break; - case GeneratorEquationAst::Type::POWER: { - std::string stringValue = generateCode(ast->mRight); + case AnalyserEquationAst::Type::POWER: { + auto stringValue = generateCode(ast->rightChild()); double doubleValue; bool validConversion = convertToDouble(stringValue, doubleValue); if (validConversion && areEqual(doubleValue, 0.5)) { - code = generateOneParameterFunctionCode(mProfile->squareRootString(), ast); + code = generateOneParameterFunctionCode(mLockedProfile->squareRootString(), ast); } else if (validConversion && areEqual(doubleValue, 2.0) - && !mProfile->squareString().empty()) { - code = generateOneParameterFunctionCode(mProfile->squareString(), ast); + && !mLockedProfile->squareString().empty()) { + code = generateOneParameterFunctionCode(mLockedProfile->squareString(), ast); } else { - code = mProfile->hasPowerOperator() ? - generateOperatorCode(mProfile->powerString(), ast) : - mProfile->powerString() + "(" + generateCode(ast->mLeft) + ", " + stringValue + ")"; + code = mLockedProfile->hasPowerOperator() ? + generateOperatorCode(mLockedProfile->powerString(), ast) : + mLockedProfile->powerString() + "(" + generateCode(ast->leftChild()) + ", " + stringValue + ")"; } break; } - case GeneratorEquationAst::Type::ROOT: - if (ast->mRight != nullptr) { + case AnalyserEquationAst::Type::ROOT: + if (ast->rightChild() != nullptr) { double doubleValue; - if (convertToDouble(generateCode(ast->mLeft), doubleValue) + if (convertToDouble(generateCode(ast->leftChild()), doubleValue) && areEqual(doubleValue, 2.0)) { - code = mProfile->squareRootString() + "(" + generateCode(ast->mRight) + ")"; + code = mLockedProfile->squareRootString() + "(" + generateCode(ast->rightChild()) + ")"; } else { - GeneratorEquationAstPtr rootValueAst = std::make_shared(GeneratorEquationAst::Type::DIVIDE, ast); + auto rootValueAst = AnalyserEquationAst::create(); + + rootValueAst->setType(AnalyserEquationAst::Type::DIVIDE); + rootValueAst->setParent(ast); + + auto leftChild = AnalyserEquationAst::create(); + auto rightChild = AnalyserEquationAst::create(); + + leftChild->setType(AnalyserEquationAst::Type::CN); + leftChild->setValue("1.0"); + leftChild->setParent(rootValueAst); + + rightChild->setType(ast->leftChild()->type()); + rightChild->setVariable(ast->leftChild()->variable()); + rightChild->setParent(rootValueAst); + rightChild->setLeftChild(ast->leftChild()->leftChild()); + rightChild->setRightChild(ast->leftChild()->rightChild()); - rootValueAst->mLeft = std::make_shared(GeneratorEquationAst::Type::CN, "1.0", rootValueAst); - rootValueAst->mRight = std::make_shared(ast->mLeft, rootValueAst); + rootValueAst->setLeftChild(leftChild); + rootValueAst->setRightChild(rightChild); - code = mProfile->hasPowerOperator() ? - generateOperatorCode(mProfile->powerString(), ast) : - mProfile->powerString() + "(" + generateCode(ast->mRight) + ", " + generateOperatorCode(mProfile->divideString(), rootValueAst) + ")"; + code = mLockedProfile->hasPowerOperator() ? + generateOperatorCode(mLockedProfile->powerString(), ast) : + mLockedProfile->powerString() + "(" + generateCode(ast->rightChild()) + ", " + generateOperatorCode(mLockedProfile->divideString(), rootValueAst) + ")"; } } else { - code = generateOneParameterFunctionCode(mProfile->squareRootString(), ast); + code = generateOneParameterFunctionCode(mLockedProfile->squareRootString(), ast); } break; - case GeneratorEquationAst::Type::ABS: - code = generateOneParameterFunctionCode(mProfile->absoluteValueString(), ast); + case AnalyserEquationAst::Type::ABS: + code = generateOneParameterFunctionCode(mLockedProfile->absoluteValueString(), ast); break; - case GeneratorEquationAst::Type::EXP: - code = generateOneParameterFunctionCode(mProfile->exponentialString(), ast); + case AnalyserEquationAst::Type::EXP: + code = generateOneParameterFunctionCode(mLockedProfile->exponentialString(), ast); break; - case GeneratorEquationAst::Type::LN: - code = generateOneParameterFunctionCode(mProfile->napierianLogarithmString(), ast); + case AnalyserEquationAst::Type::LN: + code = generateOneParameterFunctionCode(mLockedProfile->naturalLogarithmString(), ast); break; - case GeneratorEquationAst::Type::LOG: - if (ast->mRight != nullptr) { - std::string stringValue = generateCode(ast->mLeft); + case AnalyserEquationAst::Type::LOG: + if (ast->rightChild() != nullptr) { + auto stringValue = generateCode(ast->leftChild()); double doubleValue; if (convertToDouble(stringValue, doubleValue) && areEqual(doubleValue, 10.0)) { - code = mProfile->commonLogarithmString() + "(" + generateCode(ast->mRight) + ")"; + code = mLockedProfile->commonLogarithmString() + "(" + generateCode(ast->rightChild()) + ")"; } else { - code = mProfile->napierianLogarithmString() + "(" + generateCode(ast->mRight) + ")/" + mProfile->napierianLogarithmString() + "(" + stringValue + ")"; + code = mLockedProfile->naturalLogarithmString() + "(" + generateCode(ast->rightChild()) + ")/" + mLockedProfile->naturalLogarithmString() + "(" + stringValue + ")"; } } else { - code = generateOneParameterFunctionCode(mProfile->commonLogarithmString(), ast); + code = generateOneParameterFunctionCode(mLockedProfile->commonLogarithmString(), ast); } break; - case GeneratorEquationAst::Type::CEILING: - code = generateOneParameterFunctionCode(mProfile->ceilingString(), ast); + case AnalyserEquationAst::Type::CEILING: + code = generateOneParameterFunctionCode(mLockedProfile->ceilingString(), ast); break; - case GeneratorEquationAst::Type::FLOOR: - code = generateOneParameterFunctionCode(mProfile->floorString(), ast); + case AnalyserEquationAst::Type::FLOOR: + code = generateOneParameterFunctionCode(mLockedProfile->floorString(), ast); break; - case GeneratorEquationAst::Type::MIN: - code = generateTwoParameterFunctionCode(mProfile->minString(), ast); + case AnalyserEquationAst::Type::MIN: + code = generateTwoParameterFunctionCode(mLockedProfile->minString(), ast); break; - case GeneratorEquationAst::Type::MAX: - code = generateTwoParameterFunctionCode(mProfile->maxString(), ast); + case AnalyserEquationAst::Type::MAX: + code = generateTwoParameterFunctionCode(mLockedProfile->maxString(), ast); break; - case GeneratorEquationAst::Type::REM: - code = generateTwoParameterFunctionCode(mProfile->remString(), ast); + case AnalyserEquationAst::Type::REM: + code = generateTwoParameterFunctionCode(mLockedProfile->remString(), ast); break; // Calculus elements. - case GeneratorEquationAst::Type::DIFF: - code = generateCode(ast->mRight); + case AnalyserEquationAst::Type::DIFF: + code = generateCode(ast->rightChild()); break; // Trigonometric operators. - case GeneratorEquationAst::Type::SIN: - code = generateOneParameterFunctionCode(mProfile->sinString(), ast); + case AnalyserEquationAst::Type::SIN: + code = generateOneParameterFunctionCode(mLockedProfile->sinString(), ast); break; - case GeneratorEquationAst::Type::COS: - code = generateOneParameterFunctionCode(mProfile->cosString(), ast); + case AnalyserEquationAst::Type::COS: + code = generateOneParameterFunctionCode(mLockedProfile->cosString(), ast); break; - case GeneratorEquationAst::Type::TAN: - code = generateOneParameterFunctionCode(mProfile->tanString(), ast); + case AnalyserEquationAst::Type::TAN: + code = generateOneParameterFunctionCode(mLockedProfile->tanString(), ast); break; - case GeneratorEquationAst::Type::SEC: - code = generateOneParameterFunctionCode(mProfile->secString(), ast); + case AnalyserEquationAst::Type::SEC: + code = generateOneParameterFunctionCode(mLockedProfile->secString(), ast); break; - case GeneratorEquationAst::Type::CSC: - code = generateOneParameterFunctionCode(mProfile->cscString(), ast); + case AnalyserEquationAst::Type::CSC: + code = generateOneParameterFunctionCode(mLockedProfile->cscString(), ast); break; - case GeneratorEquationAst::Type::COT: - code = generateOneParameterFunctionCode(mProfile->cotString(), ast); + case AnalyserEquationAst::Type::COT: + code = generateOneParameterFunctionCode(mLockedProfile->cotString(), ast); break; - case GeneratorEquationAst::Type::SINH: - code = generateOneParameterFunctionCode(mProfile->sinhString(), ast); + case AnalyserEquationAst::Type::SINH: + code = generateOneParameterFunctionCode(mLockedProfile->sinhString(), ast); break; - case GeneratorEquationAst::Type::COSH: - code = generateOneParameterFunctionCode(mProfile->coshString(), ast); + case AnalyserEquationAst::Type::COSH: + code = generateOneParameterFunctionCode(mLockedProfile->coshString(), ast); break; - case GeneratorEquationAst::Type::TANH: - code = generateOneParameterFunctionCode(mProfile->tanhString(), ast); + case AnalyserEquationAst::Type::TANH: + code = generateOneParameterFunctionCode(mLockedProfile->tanhString(), ast); break; - case GeneratorEquationAst::Type::SECH: - code = generateOneParameterFunctionCode(mProfile->sechString(), ast); + case AnalyserEquationAst::Type::SECH: + code = generateOneParameterFunctionCode(mLockedProfile->sechString(), ast); break; - case GeneratorEquationAst::Type::CSCH: - code = generateOneParameterFunctionCode(mProfile->cschString(), ast); + case AnalyserEquationAst::Type::CSCH: + code = generateOneParameterFunctionCode(mLockedProfile->cschString(), ast); break; - case GeneratorEquationAst::Type::COTH: - code = generateOneParameterFunctionCode(mProfile->cothString(), ast); + case AnalyserEquationAst::Type::COTH: + code = generateOneParameterFunctionCode(mLockedProfile->cothString(), ast); break; - case GeneratorEquationAst::Type::ASIN: - code = generateOneParameterFunctionCode(mProfile->asinString(), ast); + case AnalyserEquationAst::Type::ASIN: + code = generateOneParameterFunctionCode(mLockedProfile->asinString(), ast); break; - case GeneratorEquationAst::Type::ACOS: - code = generateOneParameterFunctionCode(mProfile->acosString(), ast); + case AnalyserEquationAst::Type::ACOS: + code = generateOneParameterFunctionCode(mLockedProfile->acosString(), ast); break; - case GeneratorEquationAst::Type::ATAN: - code = generateOneParameterFunctionCode(mProfile->atanString(), ast); + case AnalyserEquationAst::Type::ATAN: + code = generateOneParameterFunctionCode(mLockedProfile->atanString(), ast); break; - case GeneratorEquationAst::Type::ASEC: - code = generateOneParameterFunctionCode(mProfile->asecString(), ast); + case AnalyserEquationAst::Type::ASEC: + code = generateOneParameterFunctionCode(mLockedProfile->asecString(), ast); break; - case GeneratorEquationAst::Type::ACSC: - code = generateOneParameterFunctionCode(mProfile->acscString(), ast); + case AnalyserEquationAst::Type::ACSC: + code = generateOneParameterFunctionCode(mLockedProfile->acscString(), ast); break; - case GeneratorEquationAst::Type::ACOT: - code = generateOneParameterFunctionCode(mProfile->acotString(), ast); + case AnalyserEquationAst::Type::ACOT: + code = generateOneParameterFunctionCode(mLockedProfile->acotString(), ast); break; - case GeneratorEquationAst::Type::ASINH: - code = generateOneParameterFunctionCode(mProfile->asinhString(), ast); + case AnalyserEquationAst::Type::ASINH: + code = generateOneParameterFunctionCode(mLockedProfile->asinhString(), ast); break; - case GeneratorEquationAst::Type::ACOSH: - code = generateOneParameterFunctionCode(mProfile->acoshString(), ast); + case AnalyserEquationAst::Type::ACOSH: + code = generateOneParameterFunctionCode(mLockedProfile->acoshString(), ast); break; - case GeneratorEquationAst::Type::ATANH: - code = generateOneParameterFunctionCode(mProfile->atanhString(), ast); + case AnalyserEquationAst::Type::ATANH: + code = generateOneParameterFunctionCode(mLockedProfile->atanhString(), ast); break; - case GeneratorEquationAst::Type::ASECH: - code = generateOneParameterFunctionCode(mProfile->asechString(), ast); + case AnalyserEquationAst::Type::ASECH: + code = generateOneParameterFunctionCode(mLockedProfile->asechString(), ast); break; - case GeneratorEquationAst::Type::ACSCH: - code = generateOneParameterFunctionCode(mProfile->acschString(), ast); + case AnalyserEquationAst::Type::ACSCH: + code = generateOneParameterFunctionCode(mLockedProfile->acschString(), ast); break; - case GeneratorEquationAst::Type::ACOTH: - code = generateOneParameterFunctionCode(mProfile->acothString(), ast); + case AnalyserEquationAst::Type::ACOTH: + code = generateOneParameterFunctionCode(mLockedProfile->acothString(), ast); break; // Piecewise statement. - case GeneratorEquationAst::Type::PIECEWISE: - if (ast->mRight != nullptr) { - if (ast->mRight->mType == GeneratorEquationAst::Type::PIECE) { - code = generateCode(ast->mLeft) + generatePiecewiseElseCode(generateCode(ast->mRight) + generatePiecewiseElseCode(mProfile->nanString())); + case AnalyserEquationAst::Type::PIECEWISE: + if (ast->rightChild() != nullptr) { + if (ast->rightChild()->type() == AnalyserEquationAst::Type::PIECE) { + code = generateCode(ast->leftChild()) + generatePiecewiseElseCode(generateCode(ast->rightChild()) + generatePiecewiseElseCode(mLockedProfile->nanString())); } else { - code = generateCode(ast->mLeft) + generatePiecewiseElseCode(generateCode(ast->mRight)); + code = generateCode(ast->leftChild()) + generatePiecewiseElseCode(generateCode(ast->rightChild())); } } else { - code = generateCode(ast->mLeft) + generatePiecewiseElseCode(mProfile->nanString()); + code = generateCode(ast->leftChild()) + generatePiecewiseElseCode(mLockedProfile->nanString()); } break; - case GeneratorEquationAst::Type::PIECE: - code = generatePiecewiseIfCode(generateCode(ast->mRight), generateCode(ast->mLeft)); + case AnalyserEquationAst::Type::PIECE: + code = generatePiecewiseIfCode(generateCode(ast->rightChild()), generateCode(ast->leftChild())); break; - case GeneratorEquationAst::Type::OTHERWISE: - code = generateCode(ast->mLeft); + case AnalyserEquationAst::Type::OTHERWISE: + code = generateCode(ast->leftChild()); break; // Token elements. - case GeneratorEquationAst::Type::CI: - code = generateVariableNameCode(ast->mVariable, ast); + case AnalyserEquationAst::Type::CI: + code = generateVariableNameCode(ast->variable(), ast); break; - case GeneratorEquationAst::Type::CN: - code = generateDoubleCode(ast->mValue); + case AnalyserEquationAst::Type::CN: + code = generateDoubleCode(ast->value()); break; // Qualifier elements. - case GeneratorEquationAst::Type::DEGREE: - case GeneratorEquationAst::Type::LOGBASE: - case GeneratorEquationAst::Type::BVAR: - code = generateCode(ast->mLeft); + case AnalyserEquationAst::Type::DEGREE: + case AnalyserEquationAst::Type::LOGBASE: + case AnalyserEquationAst::Type::BVAR: + code = generateCode(ast->leftChild()); break; // Constants. - case GeneratorEquationAst::Type::TRUE: - code = mProfile->trueString(); + case AnalyserEquationAst::Type::TRUE: + code = mLockedProfile->trueString(); break; - case GeneratorEquationAst::Type::FALSE: - code = mProfile->falseString(); + case AnalyserEquationAst::Type::FALSE: + code = mLockedProfile->falseString(); break; - case GeneratorEquationAst::Type::E: - code = mProfile->eString(); + case AnalyserEquationAst::Type::E: + code = mLockedProfile->eString(); break; - case GeneratorEquationAst::Type::PI: - code = mProfile->piString(); + case AnalyserEquationAst::Type::PI: + code = mLockedProfile->piString(); break; - case GeneratorEquationAst::Type::INF: - code = mProfile->infString(); + case AnalyserEquationAst::Type::INF: + code = mLockedProfile->infString(); break; - case GeneratorEquationAst::Type::NAN: - code = mProfile->nanString(); + case AnalyserEquationAst::Type::NAN: + code = mLockedProfile->nanString(); break; } @@ -3396,167 +1930,165 @@ std::string Generator::GeneratorImpl::generateCode(const GeneratorEquationAstPtr return code; } -std::string Generator::GeneratorImpl::generateInitializationCode(const GeneratorInternalVariablePtr &variable) +std::string Generator::GeneratorImpl::generateInitializationCode(const AnalyserVariablePtr &variable) const { std::string scalingFactorCode; - double scalingFactor = Generator::GeneratorImpl::scalingFactor(variable->mInitialisingVariable); + auto scalingFactor = Generator::GeneratorImpl::scalingFactor(variable->initialisingVariable()); if (!areEqual(scalingFactor, 1.0)) { - scalingFactorCode = generateDoubleCode(convertToString(1.0 / scalingFactor)) + mProfile->timesString(); + scalingFactorCode = generateDoubleCode(convertToString(1.0 / scalingFactor)) + mLockedProfile->timesString(); } - return mProfile->indentString() + generateVariableNameCode(variable->mVariable) + " = " + scalingFactorCode + generateDoubleOrConstantVariableNameCode(variable->mInitialisingVariable) + mProfile->commandSeparatorString() + "\n"; + return mLockedProfile->indentString() + generateVariableNameCode(variable->variable()) + " = " + + scalingFactorCode + generateDoubleOrConstantVariableNameCode(variable->initialisingVariable()) + + mLockedProfile->commandSeparatorString() + "\n"; } -std::string Generator::GeneratorImpl::generateEquationCode(const GeneratorEquationPtr &equation, - std::vector &remainingEquations, - bool onlyStateRateBasedEquations) +std::string Generator::GeneratorImpl::generateEquationCode(const AnalyserEquationPtr &equation, + std::vector &remainingEquations, + bool onlyStateRateBasedEquations) const { std::string res; - for (const auto &dependency : equation->mDependencies) { - if (!onlyStateRateBasedEquations - || ((dependency->mType == GeneratorEquation::Type::ALGEBRAIC) - && dependency->mIsStateRateBased)) { - res += generateEquationCode(dependency, remainingEquations, onlyStateRateBasedEquations); + if (std::find(remainingEquations.begin(), remainingEquations.end(), equation) != remainingEquations.end()) { + if ((equation->type() == AnalyserEquation::Type::RATE) + || (equation->type() == AnalyserEquation::Type::ALGEBRAIC)) { + for (const auto &dependency : equation->dependencies()) { + if ((dependency->type() != AnalyserEquation::Type::RATE) + && (!onlyStateRateBasedEquations + || ((dependency->type() == AnalyserEquation::Type::ALGEBRAIC) + && dependency->isStateRateBased()))) { + res += generateEquationCode(dependency, remainingEquations, onlyStateRateBasedEquations); + } + } } - } - - auto equationIter = std::find(remainingEquations.begin(), remainingEquations.end(), equation); - if (equationIter != remainingEquations.end()) { - res += mProfile->indentString() + generateCode(equation->mAst) + mProfile->commandSeparatorString() + "\n"; + res += mLockedProfile->indentString() + generateCode(equation->ast()) + mLockedProfile->commandSeparatorString() + "\n"; - remainingEquations.erase(equationIter); + remainingEquations.erase(std::find(remainingEquations.begin(), remainingEquations.end(), equation)); } return res; } -void Generator::GeneratorImpl::addInterfaceComputeModelMethodsCode(std::string &code) const +void Generator::GeneratorImpl::addInterfaceComputeModelMethodsCode() { std::string interfaceComputeModelMethodsCode; - if (!mProfile->interfaceInitializeStatesAndConstantsMethodString().empty()) { - interfaceComputeModelMethodsCode += mProfile->interfaceInitializeStatesAndConstantsMethodString(); + if (!mLockedProfile->interfaceInitialiseStatesAndConstantsMethodString().empty()) { + interfaceComputeModelMethodsCode += mLockedProfile->interfaceInitialiseStatesAndConstantsMethodString(); } - if (!mProfile->interfaceComputeComputedConstantsMethodString().empty()) { - interfaceComputeModelMethodsCode += mProfile->interfaceComputeComputedConstantsMethodString(); + if (!mLockedProfile->interfaceComputeComputedConstantsMethodString().empty()) { + interfaceComputeModelMethodsCode += mLockedProfile->interfaceComputeComputedConstantsMethodString(); } - if (!mProfile->interfaceComputeRatesMethodString().empty()) { - interfaceComputeModelMethodsCode += mProfile->interfaceComputeRatesMethodString(); + if (!mLockedProfile->interfaceComputeRatesMethodString().empty()) { + interfaceComputeModelMethodsCode += mLockedProfile->interfaceComputeRatesMethodString(); } - if (!mProfile->interfaceComputeVariablesMethodString().empty()) { - interfaceComputeModelMethodsCode += mProfile->interfaceComputeVariablesMethodString(); + if (!mLockedProfile->interfaceComputeVariablesMethodString().empty()) { + interfaceComputeModelMethodsCode += mLockedProfile->interfaceComputeVariablesMethodString(); } if (!interfaceComputeModelMethodsCode.empty()) { - code += "\n"; + mCode += "\n"; } - code += interfaceComputeModelMethodsCode; + mCode += interfaceComputeModelMethodsCode; } -void Generator::GeneratorImpl::addImplementationInitializeStatesAndConstantsMethodCode(std::string &code, - std::vector &remainingEquations) +void Generator::GeneratorImpl::addImplementationInitialiseStatesAndConstantsMethodCode(std::vector &remainingEquations) { - if (!mProfile->implementationInitializeStatesAndConstantsMethodString().empty()) { - if (!code.empty()) { - code += "\n"; + if (!mLockedProfile->implementationInitialiseStatesAndConstantsMethodString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } std::string methodBody; - for (const auto &internalVariable : mInternalVariables) { - if (internalVariable->mType == GeneratorInternalVariable::Type::CONSTANT) { - methodBody += generateInitializationCode(internalVariable); + for (const auto &variable : mLockedModel->variables()) { + if (variable->type() == AnalyserVariable::Type::CONSTANT) { + methodBody += generateInitializationCode(variable); } } - for (const auto &equation : mEquations) { - if (equation->mType == GeneratorEquation::Type::TRUE_CONSTANT) { + for (const auto &equation : mLockedModel->equations()) { + if (equation->type() == AnalyserEquation::Type::TRUE_CONSTANT) { methodBody += generateEquationCode(equation, remainingEquations); } } - for (const auto &internalVariable : mInternalVariables) { - if (internalVariable->mType == GeneratorInternalVariable::Type::STATE) { - methodBody += generateInitializationCode(internalVariable); - } + for (const auto &state : mLockedModel->states()) { + methodBody += generateInitializationCode(state); } - code += replace(mProfile->implementationInitializeStatesAndConstantsMethodString(), - "", generateMethodBodyCode(methodBody)); + mCode += replace(mLockedProfile->implementationInitialiseStatesAndConstantsMethodString(), + "", generateMethodBodyCode(methodBody)); } } -void Generator::GeneratorImpl::addImplementationComputeComputedConstantsMethodCode(std::string &code, - std::vector &remainingEquations) +void Generator::GeneratorImpl::addImplementationComputeComputedConstantsMethodCode(std::vector &remainingEquations) { - if (!mProfile->implementationComputeComputedConstantsMethodString().empty()) { - if (!code.empty()) { - code += "\n"; + if (!mLockedProfile->implementationComputeComputedConstantsMethodString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } std::string methodBody; - for (const auto &equation : mEquations) { - if (equation->mType == GeneratorEquation::Type::VARIABLE_BASED_CONSTANT) { + for (const auto &equation : mLockedModel->equations()) { + if (equation->type() == AnalyserEquation::Type::VARIABLE_BASED_CONSTANT) { methodBody += generateEquationCode(equation, remainingEquations); } } - code += replace(mProfile->implementationComputeComputedConstantsMethodString(), - "", generateMethodBodyCode(methodBody)); + mCode += replace(mLockedProfile->implementationComputeComputedConstantsMethodString(), + "", generateMethodBodyCode(methodBody)); } } -void Generator::GeneratorImpl::addImplementationComputeRatesMethodCode(std::string &code, - std::vector &remainingEquations) +void Generator::GeneratorImpl::addImplementationComputeRatesMethodCode(std::vector &remainingEquations) { - if (!mProfile->implementationComputeRatesMethodString().empty()) { - if (!code.empty()) { - code += "\n"; + if (!mLockedProfile->implementationComputeRatesMethodString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } std::string methodBody; - for (const auto &equation : mEquations) { - if (equation->mType == GeneratorEquation::Type::RATE) { + for (const auto &equation : mLockedModel->equations()) { + if (equation->type() == AnalyserEquation::Type::RATE) { methodBody += generateEquationCode(equation, remainingEquations); } } - code += replace(mProfile->implementationComputeRatesMethodString(), - "", generateMethodBodyCode(methodBody)); + mCode += replace(mLockedProfile->implementationComputeRatesMethodString(), + "", generateMethodBodyCode(methodBody)); } } -void Generator::GeneratorImpl::addImplementationComputeVariablesMethodCode(std::string &code, - std::vector &remainingEquations) +void Generator::GeneratorImpl::addImplementationComputeVariablesMethodCode(std::vector &remainingEquations) { - if (!mProfile->implementationComputeVariablesMethodString().empty()) { - if (!code.empty()) { - code += "\n"; + if (!mLockedProfile->implementationComputeVariablesMethodString().empty()) { + if (!mCode.empty()) { + mCode += "\n"; } - std::vector newRemainingEquations {std::begin(mEquations), std::end(mEquations)}; - std::string methodBody; + auto equations = mLockedModel->equations(); + std::vector newRemainingEquations {std::begin(equations), std::end(equations)}; - for (const auto &equation : mEquations) { + for (const auto &equation : equations) { if ((std::find(remainingEquations.begin(), remainingEquations.end(), equation) != remainingEquations.end()) - || ((equation->mType == GeneratorEquation::Type::ALGEBRAIC) - && equation->mIsStateRateBased)) { + || ((equation->type() == AnalyserEquation::Type::ALGEBRAIC) + && equation->isStateRateBased())) { methodBody += generateEquationCode(equation, newRemainingEquations, true); } } - code += replace(mProfile->implementationComputeVariablesMethodString(), - "", generateMethodBodyCode(methodBody)); + mCode += replace(mLockedProfile->implementationComputeVariablesMethodString(), + "", generateMethodBodyCode(methodBody)); } } @@ -3578,203 +2110,152 @@ GeneratorPtr Generator::create() noexcept GeneratorProfilePtr Generator::profile() { - return mPimpl->mProfile; -} - -void Generator::setProfile(const GeneratorProfilePtr &profile) -{ - mPimpl->mProfile = profile; -} - -void Generator::processModel(const ModelPtr &model) -{ - // Make sure that the model is valid before processing it. - - /*TODO: enable the below code once validation is known to work fine. - ValidatorPtr validator = Validator::create(); - - validator->validateModel(model); - - if (validator->issueCount() > 0) { - // The model is not valid, so retrieve the validation issues and make - // them our own. - - for (size_t i = 0; i < validator->issueCount(); ++i) { - addIssue(validator->issue(i)); - } - - return; - } -*/ - - // Process the model. - - mPimpl->processModel(model); -} - -Generator::ModelType Generator::modelType() const -{ - return mPimpl->mModelType; -} - -size_t Generator::stateCount() const -{ - if (!mPimpl->hasValidModel()) { - return 0; + if (mPimpl->mOwnedProfile != nullptr) { + return mPimpl->mOwnedProfile; } - return mPimpl->mStates.size(); + return mPimpl->mProfile.lock(); } -size_t Generator::variableCount() const +void Generator::setProfile(const GeneratorProfilePtr &profile) { - if (!mPimpl->hasValidModel()) { - return 0; - } - - return mPimpl->mVariables.size(); + mPimpl->mOwnedProfile = nullptr; + mPimpl->mProfile = profile; } -GeneratorVariablePtr Generator::voi() const +AnalyserModelPtr Generator::model() { - if (!mPimpl->hasValidModel()) { - return {}; - } - - return mPimpl->mVoi; + return mPimpl->mModel.lock(); } -GeneratorVariablePtr Generator::state(size_t index) const +void Generator::setModel(const AnalyserModelPtr &model) { - if (!mPimpl->hasValidModel() || (index >= mPimpl->mStates.size())) { - return {}; - } - - return mPimpl->mStates[index]; + mPimpl->mModel = model; } -GeneratorVariablePtr Generator::variable(size_t index) const +std::string Generator::interfaceCode() const { - if (!mPimpl->hasValidModel() || (index >= mPimpl->mVariables.size())) { - return {}; - } + mPimpl->retrieveLockedModelAndProfile(); - return mPimpl->mVariables[index]; -} + if (!mPimpl->retrieveLockedModelAndProfile() + || !mPimpl->mLockedModel->isValid() + || !mPimpl->mLockedProfile->hasInterface()) { + mPimpl->resetLockedModelAndProfile(); -std::string Generator::interfaceCode() const -{ - if (!mPimpl->hasValidModel() || !mPimpl->mProfile->hasInterface()) { return {}; } // Add code for the origin comment. - std::string res; + mPimpl->mCode = {}; - mPimpl->addOriginCommentCode(res); + mPimpl->addOriginCommentCode(); // Add code for the header. - mPimpl->addInterfaceHeaderCode(res); + mPimpl->addInterfaceHeaderCode(); // Add code for the interface of the version of the profile and libCellML. - mPimpl->addVersionAndLibcellmlVersionCode(res, true); + mPimpl->addVersionAndLibcellmlVersionCode(true); // Add code for the interface of the number of states and variables. - mPimpl->addStateAndVariableCountCode(res, true); + mPimpl->addStateAndVariableCountCode(true); // Add code for the variable information related objects. - if (mPimpl->mProfile->hasInterface()) { - mPimpl->addVariableTypeObjectCode(res); - mPimpl->addVariableInfoObjectCode(res); - mPimpl->addVariableInfoWithTypeObjectCode(res); - } + mPimpl->addVariableTypeObjectCode(); + mPimpl->addVariableInfoObjectCode(); + mPimpl->addVariableInfoWithTypeObjectCode(); // Add code for the interface of the information about the variable of // integration, states and (other) variables. - mPimpl->addInterfaceVoiStateAndVariableInfoCode(res); + mPimpl->addInterfaceVoiStateAndVariableInfoCode(); // Add code for the interface to create and delete arrays. - mPimpl->addInterfaceCreateDeleteArrayMethodsCode(res); + mPimpl->addInterfaceCreateDeleteArrayMethodsCode(); // Add code for the interface to compute the model. - mPimpl->addInterfaceComputeModelMethodsCode(res); + mPimpl->addInterfaceComputeModelMethodsCode(); - return res; + mPimpl->resetLockedModelAndProfile(); + + return mPimpl->mCode; } std::string Generator::implementationCode() const { - if (!mPimpl->hasValidModel()) { + if (!mPimpl->retrieveLockedModelAndProfile() + || !mPimpl->mLockedModel->isValid()) { + mPimpl->resetLockedModelAndProfile(); + return {}; } - std::string res; - // Add code for the origin comment. - mPimpl->addOriginCommentCode(res); + mPimpl->mCode = {}; + + mPimpl->addOriginCommentCode(); // Add code for the header. - mPimpl->addImplementationHeaderCode(res); + mPimpl->addImplementationHeaderCode(); // Add code for the implementation of the version of the profile and // libCellML. - mPimpl->addVersionAndLibcellmlVersionCode(res); + mPimpl->addVersionAndLibcellmlVersionCode(); // Add code for the implementation of the number of states and variables. - mPimpl->addStateAndVariableCountCode(res); + mPimpl->addStateAndVariableCountCode(); // Add code for the variable information related objects. - if (!mPimpl->mProfile->hasInterface()) { - mPimpl->addVariableTypeObjectCode(res); - mPimpl->addVariableInfoObjectCode(res); - mPimpl->addVariableInfoWithTypeObjectCode(res); + if (!mPimpl->mLockedProfile->hasInterface()) { + mPimpl->addVariableTypeObjectCode(); + mPimpl->addVariableInfoObjectCode(); + mPimpl->addVariableInfoWithTypeObjectCode(); } // Add code for the implementation of the information about the variable of // integration, states and (other) variables. - mPimpl->addImplementationVoiInfoCode(res); - mPimpl->addImplementationStateInfoCode(res); - mPimpl->addImplementationVariableInfoCode(res); + mPimpl->addImplementationVoiInfoCode(); + mPimpl->addImplementationStateInfoCode(); + mPimpl->addImplementationVariableInfoCode(); // Add code for the arithmetic and trigonometric functions. - mPimpl->addArithmeticFunctionsCode(res); - mPimpl->addTrigonometricFunctionsCode(res); + mPimpl->addArithmeticFunctionsCode(); + mPimpl->addTrigonometricFunctionsCode(); // Add code for the implementation to create and delete arrays. - mPimpl->addImplementationCreateStatesArrayMethodCode(res); - mPimpl->addImplementationCreateVariablesArrayMethodCode(res); - mPimpl->addImplementationDeleteArrayMethodCode(res); + mPimpl->addImplementationCreateStatesArrayMethodCode(); + mPimpl->addImplementationCreateVariablesArrayMethodCode(); + mPimpl->addImplementationDeleteArrayMethodCode(); // Add code for the implementation to initialise our states and constants. - std::vector remainingEquations {std::begin(mPimpl->mEquations), std::end(mPimpl->mEquations)}; + auto equations = mPimpl->mLockedModel->equations(); + std::vector remainingEquations {std::begin(equations), std::end(equations)}; - mPimpl->addImplementationInitializeStatesAndConstantsMethodCode(res, remainingEquations); + mPimpl->addImplementationInitialiseStatesAndConstantsMethodCode(remainingEquations); // Add code for the implementation to compute our computed constants. - mPimpl->addImplementationComputeComputedConstantsMethodCode(res, remainingEquations); + mPimpl->addImplementationComputeComputedConstantsMethodCode(remainingEquations); // Add code for the implementation to compute our rates (and any variables // on which they depend). - mPimpl->addImplementationComputeRatesMethodCode(res, remainingEquations); + mPimpl->addImplementationComputeRatesMethodCode(remainingEquations); // Add code for the implementation to compute our variables. // Note: this method computes the remaining variables, i.e. the ones not @@ -3784,9 +2265,11 @@ std::string Generator::implementationCode() const // variables that rely on the value of some states/rates are up to // date. - mPimpl->addImplementationComputeVariablesMethodCode(res, remainingEquations); + mPimpl->addImplementationComputeVariablesMethodCode(remainingEquations); - return res; + mPimpl->resetLockedModelAndProfile(); + + return mPimpl->mCode; } } // namespace libcellml diff --git a/src/generatorequationast.h b/src/generatorequationast.h deleted file mode 100644 index 586f374b11..0000000000 --- a/src/generatorequationast.h +++ /dev/null @@ -1,153 +0,0 @@ -/* -Copyright libCellML Contributors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -#pragma once - -#include "libcellml/variable.h" - -#undef NAN - -#ifdef __linux__ -# undef TRUE -# undef FALSE -#endif - -namespace libcellml { - -struct GeneratorEquationAst; - -using GeneratorEquationAstPtr = std::shared_ptr; -using GeneratorEquationAstWeakPtr = std::weak_ptr; - -struct GeneratorEquationAst -{ - enum struct Type - { - // Assignment. - - ASSIGNMENT, - - // Relational and logical operators. - - EQ, - NEQ, - LT, - LEQ, - GT, - GEQ, - AND, - OR, - XOR, - NOT, - - // Arithmetic operators. - - PLUS, - MINUS, - TIMES, - DIVIDE, - POWER, - ROOT, - ABS, - EXP, - LN, - LOG, - CEILING, - FLOOR, - MIN, - MAX, - REM, - - // Calculus elements. - - DIFF, - - // Trigonometric operators. - - SIN, - COS, - TAN, - SEC, - CSC, - COT, - SINH, - COSH, - TANH, - SECH, - CSCH, - COTH, - ASIN, - ACOS, - ATAN, - ASEC, - ACSC, - ACOT, - ASINH, - ACOSH, - ATANH, - ASECH, - ACSCH, - ACOTH, - - // Piecewise statement. - - PIECEWISE, - PIECE, - OTHERWISE, - - // Token elements. - - CI, - CN, - - // Qualifier elements. - - DEGREE, - LOGBASE, - BVAR, - - // Constants. - - TRUE, - FALSE, - E, - PI, - INF, - NAN - }; - - Type mType = Type::ASSIGNMENT; - - std::string mValue; - VariablePtr mVariable = nullptr; - - GeneratorEquationAstWeakPtr mParent; - - GeneratorEquationAstPtr mLeft = nullptr; - GeneratorEquationAstPtr mRight = nullptr; - - explicit GeneratorEquationAst(); - explicit GeneratorEquationAst(Type type, - const GeneratorEquationAstPtr &parent); - explicit GeneratorEquationAst(Type type, const std::string &value, - const GeneratorEquationAstPtr &parent); - explicit GeneratorEquationAst(Type type, const VariablePtr &variable, - const GeneratorEquationAstPtr &parent); - explicit GeneratorEquationAst(const GeneratorEquationAstPtr &ast, - const GeneratorEquationAstPtr &parent); -}; - -} // namespace libcellml diff --git a/src/generatorprofile.cpp b/src/generatorprofile.cpp index 9b117724ad..5471a0f4c4 100644 --- a/src/generatorprofile.cpp +++ b/src/generatorprofile.cpp @@ -21,7 +21,6 @@ limitations under the License. #include "libcellml/generatorprofile.h" #include -#include #include "utilities.h" @@ -81,7 +80,7 @@ struct GeneratorProfile::GeneratorProfileImpl std::string mSquareString; std::string mAbsoluteValueString; std::string mExponentialString; - std::string mNapierianLogarithmString; + std::string mNaturalLogarithmString; std::string mCommonLogarithmString; std::string mCeilingString; std::string mFloorString; @@ -224,8 +223,8 @@ struct GeneratorProfile::GeneratorProfileImpl std::string mInterfaceDeleteArrayMethodString; std::string mImplementationDeleteArrayMethodString; - std::string mInterfaceInitializeStatesAndConstantsMethodString; - std::string mImplementationInitializeStatesAndConstantsMethodString; + std::string mInterfaceInitialiseStatesAndConstantsMethodString; + std::string mImplementationInitialiseStatesAndConstantsMethodString; std::string mInterfaceComputeComputedConstantsMethodString; std::string mImplementationComputeComputedConstantsMethodString; @@ -240,8 +239,8 @@ struct GeneratorProfile::GeneratorProfileImpl std::string mIndentString; - std::string mOpenArrayInitializerString; - std::string mCloseArrayInitializerString; + std::string mOpenArrayInitialiserString; + std::string mCloseArrayInitialiserString; std::string mOpenArrayString; std::string mCloseArrayString; @@ -303,7 +302,7 @@ void GeneratorProfile::GeneratorProfileImpl::loadProfile(GeneratorProfile::Profi mSquareString = ""; mAbsoluteValueString = "fabs"; mExponentialString = "exp"; - mNapierianLogarithmString = "log"; + mNaturalLogarithmString = "log"; mCommonLogarithmString = "log10"; mCeilingString = "ceil"; mFloorString = "floor"; @@ -526,8 +525,8 @@ void GeneratorProfile::GeneratorProfileImpl::loadProfile(GeneratorProfile::Profi " free(array);\n" "}\n"; - mInterfaceInitializeStatesAndConstantsMethodString = "void initializeStatesAndConstants(double *states, double *variables);\n"; - mImplementationInitializeStatesAndConstantsMethodString = "void initializeStatesAndConstants(double *states, double *variables)\n" + mInterfaceInitialiseStatesAndConstantsMethodString = "void initialiseStatesAndConstants(double *states, double *variables);\n"; + mImplementationInitialiseStatesAndConstantsMethodString = "void initialiseStatesAndConstants(double *states, double *variables)\n" "{\n" "" "}\n"; @@ -553,8 +552,8 @@ void GeneratorProfile::GeneratorProfileImpl::loadProfile(GeneratorProfile::Profi mIndentString = " "; - mOpenArrayInitializerString = "{"; - mCloseArrayInitializerString = "}"; + mOpenArrayInitialiserString = "{"; + mCloseArrayInitialiserString = "}"; mOpenArrayString = "["; mCloseArrayString = "]"; @@ -608,7 +607,7 @@ void GeneratorProfile::GeneratorProfileImpl::loadProfile(GeneratorProfile::Profi mSquareString = ""; mAbsoluteValueString = "fabs"; mExponentialString = "exp"; - mNapierianLogarithmString = "log"; + mNaturalLogarithmString = "log"; mCommonLogarithmString = "log10"; mCeilingString = "ceil"; mFloorString = "floor"; @@ -818,9 +817,9 @@ void GeneratorProfile::GeneratorProfileImpl::loadProfile(GeneratorProfile::Profi mInterfaceDeleteArrayMethodString = ""; mImplementationDeleteArrayMethodString = ""; - mInterfaceInitializeStatesAndConstantsMethodString = ""; - mImplementationInitializeStatesAndConstantsMethodString = "\n" - "def initialize_states_and_constants(states, variables):\n" + mInterfaceInitialiseStatesAndConstantsMethodString = ""; + mImplementationInitialiseStatesAndConstantsMethodString = "\n" + "def initialise_states_and_constants(states, variables):\n" ""; mInterfaceComputeComputedConstantsMethodString = ""; @@ -842,8 +841,8 @@ void GeneratorProfile::GeneratorProfileImpl::loadProfile(GeneratorProfile::Profi mIndentString = " "; - mOpenArrayInitializerString = "["; - mCloseArrayInitializerString = "]"; + mOpenArrayInitialiserString = "["; + mCloseArrayInitialiserString = "]"; mOpenArrayString = "["; mCloseArrayString = "]"; @@ -1192,14 +1191,14 @@ void GeneratorProfile::setExponentialString(const std::string &exponentialString mPimpl->mExponentialString = exponentialString; } -std::string GeneratorProfile::napierianLogarithmString() const +std::string GeneratorProfile::naturalLogarithmString() const { - return mPimpl->mNapierianLogarithmString; + return mPimpl->mNaturalLogarithmString; } -void GeneratorProfile::setNapierianLogarithmString(const std::string &napierianLogarithmString) +void GeneratorProfile::setNaturalLogarithmString(const std::string &naturalLogarithmString) { - mPimpl->mNapierianLogarithmString = napierianLogarithmString; + mPimpl->mNaturalLogarithmString = naturalLogarithmString; } std::string GeneratorProfile::commonLogarithmString() const @@ -2232,24 +2231,24 @@ void GeneratorProfile::setImplementationDeleteArrayMethodString(const std::strin mPimpl->mImplementationDeleteArrayMethodString = implementationDeleteArrayMethodString; } -std::string GeneratorProfile::interfaceInitializeStatesAndConstantsMethodString() const +std::string GeneratorProfile::interfaceInitialiseStatesAndConstantsMethodString() const { - return mPimpl->mInterfaceInitializeStatesAndConstantsMethodString; + return mPimpl->mInterfaceInitialiseStatesAndConstantsMethodString; } -void GeneratorProfile::setInterfaceInitializeStatesAndConstantsMethodString(const std::string &interfaceInitializeStatesAndConstantsMethodString) +void GeneratorProfile::setInterfaceInitialiseStatesAndConstantsMethodString(const std::string &interfaceInitialiseStatesAndConstantsMethodString) { - mPimpl->mInterfaceInitializeStatesAndConstantsMethodString = interfaceInitializeStatesAndConstantsMethodString; + mPimpl->mInterfaceInitialiseStatesAndConstantsMethodString = interfaceInitialiseStatesAndConstantsMethodString; } -std::string GeneratorProfile::implementationInitializeStatesAndConstantsMethodString() const +std::string GeneratorProfile::implementationInitialiseStatesAndConstantsMethodString() const { - return mPimpl->mImplementationInitializeStatesAndConstantsMethodString; + return mPimpl->mImplementationInitialiseStatesAndConstantsMethodString; } -void GeneratorProfile::setImplementationInitializeStatesAndConstantsMethodString(const std::string &implementationInitializeStatesAndConstantsMethodString) +void GeneratorProfile::setImplementationInitialiseStatesAndConstantsMethodString(const std::string &implementationInitialiseStatesAndConstantsMethodString) { - mPimpl->mImplementationInitializeStatesAndConstantsMethodString = implementationInitializeStatesAndConstantsMethodString; + mPimpl->mImplementationInitialiseStatesAndConstantsMethodString = implementationInitialiseStatesAndConstantsMethodString; } std::string GeneratorProfile::interfaceComputeComputedConstantsMethodString() const @@ -2332,24 +2331,24 @@ void GeneratorProfile::setIndentString(const std::string &indentString) mPimpl->mIndentString = indentString; } -std::string GeneratorProfile::openArrayInitializerString() const +std::string GeneratorProfile::openArrayInitialiserString() const { - return mPimpl->mOpenArrayInitializerString; + return mPimpl->mOpenArrayInitialiserString; } -void GeneratorProfile::setOpenArrayInitializerString(const std::string &openArrayInitializerString) +void GeneratorProfile::setOpenArrayInitialiserString(const std::string &openArrayInitialiserString) { - mPimpl->mOpenArrayInitializerString = openArrayInitializerString; + mPimpl->mOpenArrayInitialiserString = openArrayInitialiserString; } -std::string GeneratorProfile::closeArrayInitializerString() const +std::string GeneratorProfile::closeArrayInitialiserString() const { - return mPimpl->mCloseArrayInitializerString; + return mPimpl->mCloseArrayInitialiserString; } -void GeneratorProfile::setCloseArrayInitializerString(const std::string &closeArrayInitializerString) +void GeneratorProfile::setCloseArrayInitialiserString(const std::string &closeArrayInitialiserString) { - mPimpl->mCloseArrayInitializerString = closeArrayInitializerString; + mPimpl->mCloseArrayInitialiserString = closeArrayInitialiserString; } std::string GeneratorProfile::openArrayString() const diff --git a/src/utilities.cpp b/src/utilities.cpp index 01f4ce6caa..5872ca701e 100644 --- a/src/utilities.cpp +++ b/src/utilities.cpp @@ -468,6 +468,12 @@ size_t getVariableIndexInComponent(const ComponentPtr &component, const Variable return index; } +bool isSameOrEquivalentVariable(const VariablePtr &variable1, + const VariablePtr &variable2) +{ + return (variable1 == variable2) || variable1->hasEquivalentVariable(variable2, true); +} + bool isEntityChildOf(const EntityPtr &entity1, const EntityPtr &entity2) { return entity1->parent() == entity2; @@ -1049,4 +1055,13 @@ std::string makeUniqueId(IdList &idList) return id; } +std::string replace(std::string string, const std::string &from, const std::string &to) +{ + auto index = string.find(from); + + return (index == std::string::npos) ? + string : + string.replace(index, from.length(), to); +} + } // namespace libcellml diff --git a/src/utilities.h b/src/utilities.h index 5306398867..a1f12240a0 100644 --- a/src/utilities.h +++ b/src/utilities.h @@ -450,6 +450,25 @@ bool isStandardPrefixName(const std::string &name); */ size_t getVariableIndexInComponent(const ComponentPtr &component, const VariablePtr &variable); +/** + * @brief Test to determine if @p variable1 and @p variable2 are the same or + * (directly or indirectly) equivalent. + * + * Test to see if @p variable1 is the same or (directly or indirectly) + * equivalent to @p variable2. Returns @c true if @p variable1 is the same or + * (directly or indirectly) equivalent to @p variable2 and @c false otherwise. + * + * @param variable1 The @c Variable to test if it is the same or (directly or + * indirectly) equivalent to @p variable2. + * @param variable2 The @c Variable that is potentially the same or (directly or + * indirectly) equivalent to @p variable1. + * + * @return @c true if @p variable1 is the same or (directly or indirectly) + * equivalent to @p variable2 and @c false otherwise. + */ +bool isSameOrEquivalentVariable(const VariablePtr &variable1, + const VariablePtr &variable2); + /** * @brief Test to determine if @p entity1 is a child of @p entity2. * @@ -588,5 +607,6 @@ EquivalenceMap rebaseEquivalenceMap(const EquivalenceMap &map, const IndexStack std::vector unitsUsed(const ModelPtr &model, const ComponentPtr &component); ComponentNameMap createComponentNamesMap(const ComponentPtr &component); void findAndReplaceComponentsCnUnitsNames(const ComponentPtr &component, const StringStringMap &replaceMap); +std::string replace(std::string string, const std::string &from, const std::string &to); } // namespace libcellml diff --git a/src/xmldoc.cpp b/src/xmldoc.cpp index 7e2681662a..b9e90cd553 100644 --- a/src/xmldoc.cpp +++ b/src/xmldoc.cpp @@ -89,18 +89,15 @@ void XmlDoc::parse(const std::string &input) xmlCleanupGlobals(); } -void XmlDoc::parseMathML(const std::string &input, bool validate) +void XmlDoc::parseMathML(const std::string &input) { xmlInitParser(); - std::string mathmlString = input; - if (validate) { - mathmlString = "" + mathmlString; - } + std::string mathmlString = "" + input; xmlParserCtxtPtr context = xmlNewParserCtxt(); context->_private = reinterpret_cast(this); xmlSetStructuredErrorFunc(context, structuredErrorCallback); mPimpl->mXmlDocPtr = xmlCtxtReadDoc(context, reinterpret_cast(mathmlString.c_str()), "/", nullptr, - validate ? XML_PARSE_DTDVALID : 0); + XML_PARSE_DTDVALID); xmlFreeParserCtxt(context); xmlSetStructuredErrorFunc(nullptr, nullptr); xmlCleanupParser(); diff --git a/src/xmldoc.h b/src/xmldoc.h index c29140d972..f1b9bf84ce 100644 --- a/src/xmldoc.h +++ b/src/xmldoc.h @@ -53,10 +53,8 @@ class XmlDoc * Parses the @p input @c std::string as a MathML string. * * @param input The @c std::string to parse. - * @param validate Optional parameter to determine whether validation - * against the MathML DTD should be done. */ - void parseMathML(const std::string &input, bool validate = true); + void parseMathML(const std::string &input); /** * @brief Convert this @c XmlDoc content into a pretty-print @c std::string. diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 79bc3444fd..c6fa6f9c68 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -27,6 +27,7 @@ mark_as_advanced(gtest_force_shared_crt) # to the LIBCELLML_TESTS list. Any source files for the # test must be set to _SRCS, likewise for # header files _HDRS. +include(analyser/tests.cmake) include(clone/tests.cmake) include(component/tests.cmake) include(connection/tests.cmake) diff --git a/tests/analyser/analyser.cpp b/tests/analyser/analyser.cpp new file mode 100644 index 0000000000..e98d3532db --- /dev/null +++ b/tests/analyser/analyser.cpp @@ -0,0 +1,407 @@ +/* +Copyright libCellML Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "test_utils.h" + +#include "gtest/gtest.h" + +#include + +TEST(Analyser, initialisedVariableOfIntegration) +{ + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("analyser/initialised_variable_of_integration.cellml")); + + EXPECT_EQ(size_t(0), parser->issueCount()); + + const std::vector expectedIssues = { + "Variable 'time' in component 'my_component' cannot be both a variable of integration and initialised.", + }; + const std::vector expectedCauses = { + libcellml::Issue::Cause::VARIABLE, + }; + const std::vector expectedLevels = { + libcellml::Issue::Level::ERROR, + }; + + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ_ISSUES_CAUSES_LEVELS(expectedIssues, expectedCauses, expectedLevels, analyser); + + EXPECT_EQ(libcellml::AnalyserModel::Type::INVALID, analyser->model()->type()); +} + +TEST(Analyser, initialisedVariableOfIntegrationInNonFirstComponent) +{ + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("analyser/initialised_variable_of_integration_in_non_first_component.cellml")); + + EXPECT_EQ(size_t(0), parser->issueCount()); + + const std::vector expectedIssues = { + "Variable 'time' in component 'environment' cannot be both a variable of integration and initialised.", + }; + const std::vector expectedCauses = { + libcellml::Issue::Cause::VARIABLE, + }; + const std::vector expectedLevels = { + libcellml::Issue::Level::ERROR, + }; + + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ_ISSUES_CAUSES_LEVELS(expectedIssues, expectedCauses, expectedLevels, analyser); + + EXPECT_EQ(libcellml::AnalyserModel::Type::INVALID, analyser->model()->type()); +} + +TEST(Analyser, twoVariablesOfIntegration) +{ + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("analyser/two_variables_of_integration.cellml")); + + EXPECT_EQ(size_t(0), parser->issueCount()); + + const std::vector expectedIssues = { + "Variable 'time' in component 'main' and variable 'other_time' in component 'sub_sub_sub' cannot both be the variable of integration.", + }; + const std::vector expectedCauses = { + libcellml::Issue::Cause::VARIABLE, + }; + const std::vector expectedLevels = { + libcellml::Issue::Level::ERROR, + }; + + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ_ISSUES_CAUSES_LEVELS(expectedIssues, expectedCauses, expectedLevels, analyser); + + EXPECT_EQ(libcellml::AnalyserModel::Type::INVALID, analyser->model()->type()); +} + +TEST(Analyser, nonFirstOrderOdes) +{ + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("analyser/non_first_order_odes.cellml")); + + EXPECT_EQ(size_t(0), parser->issueCount()); + + const std::vector expectedIssues = { + "The differential equation for variable 'x' in component 'main' must be of the first order.", + "The differential equation for variable 'y' in component 'sub' must be of the first order.", + "The differential equation for variable 'z' in component 'sub_sub' must be of the first order.", + }; + const std::vector expectedCauses = { + libcellml::Issue::Cause::MATHML, + libcellml::Issue::Cause::MATHML, + libcellml::Issue::Cause::MATHML, + }; + const std::vector expectedLevels = { + libcellml::Issue::Level::ERROR, + libcellml::Issue::Level::ERROR, + libcellml::Issue::Level::ERROR, + }; + + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ_ISSUES_CAUSES_LEVELS(expectedIssues, expectedCauses, expectedLevels, analyser); + + EXPECT_EQ(libcellml::AnalyserModel::Type::INVALID, analyser->model()->type()); +} + +TEST(Analyser, undefinedVariables) +{ + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("analyser/undefined_variables.cellml")); + + EXPECT_EQ(size_t(0), parser->issueCount()); + + const std::vector expectedIssues = { + "MathML ci element has the child text 'a' which does not correspond with any variable names present in component 'my_component'.", + "MathML ci element has the child text 'b' which does not correspond with any variable names present in component 'my_component'.", + }; + const std::vector expectedCauses = { + libcellml::Issue::Cause::MATHML, + libcellml::Issue::Cause::MATHML, + }; + const std::vector expectedLevels = { + libcellml::Issue::Level::ERROR, + libcellml::Issue::Level::ERROR, + }; + + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ_ISSUES_CAUSES_LEVELS(expectedIssues, expectedCauses, expectedLevels, analyser); + + EXPECT_EQ(libcellml::AnalyserModel::Type::INVALID, analyser->model()->type()); +} + +TEST(Analyser, variableInitialisedTwice) +{ + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("analyser/variable_initialised_twice.cellml")); + + EXPECT_EQ(size_t(0), parser->issueCount()); + + const std::vector expectedIssues = { + "Variable 'x' in component 'sub' and variable 'x' in component 'main' are equivalent and cannot therefore both be initialised.", + }; + const std::vector expectedCauses = { + libcellml::Issue::Cause::VARIABLE, + }; + const std::vector expectedLevels = { + libcellml::Issue::Level::ERROR, + }; + + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ_ISSUES_CAUSES_LEVELS(expectedIssues, expectedCauses, expectedLevels, analyser); + + EXPECT_EQ(libcellml::AnalyserModel::Type::INVALID, analyser->model()->type()); +} + +TEST(Analyser, nonConstantInitialisingVariable) +{ + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("analyser/non_constant_initialising_variable.cellml")); + + EXPECT_EQ(size_t(0), parser->issueCount()); + + const std::vector expectedIssues = { + "Variable 'x' in component 'main' is initialised using variable 'k2', but it is not a constant.", + }; + const std::vector expectedCauses = { + libcellml::Issue::Cause::VARIABLE, + }; + const std::vector expectedLevels = { + libcellml::Issue::Level::ERROR, + }; + + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ_ISSUES_CAUSES_LEVELS(expectedIssues, expectedCauses, expectedLevels, analyser); + + EXPECT_EQ(libcellml::AnalyserModel::Type::INVALID, analyser->model()->type()); +} + +TEST(Analyser, nonExistingInitialisingVariable) +{ + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("analyser/non_existing_initialising_variable.cellml")); + + EXPECT_EQ(size_t(0), parser->issueCount()); + + const std::vector expectedIssues = { + "Variable 'x' has an invalid initial value 'k'. Initial values must be a real number string or a variable reference.", + }; + const std::vector expectedCauses = { + libcellml::Issue::Cause::VARIABLE, + }; + const std::vector expectedLevels = { + libcellml::Issue::Level::ERROR, + }; + + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ_ISSUES_CAUSES_LEVELS(expectedIssues, expectedCauses, expectedLevels, analyser); + + EXPECT_EQ(libcellml::AnalyserModel::Type::INVALID, analyser->model()->type()); +} + +TEST(Analyser, nonInitialisedState) +{ + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("analyser/non_initialised_state.cellml")); + + EXPECT_EQ(size_t(0), parser->issueCount()); + + const std::vector expectedIssues = { + "Variable 'x' in component 'my_component' is used in an ODE, but it is not initialised.", + }; + const std::vector expectedCauses = { + libcellml::Issue::Cause::VARIABLE, + }; + const std::vector expectedLevels = { + libcellml::Issue::Level::ERROR, + }; + const std::string expectedVariableName = "x"; + + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ_ISSUES_CAUSES_LEVELS(expectedIssues, expectedCauses, expectedLevels, analyser); + EXPECT_EQ(expectedVariableName, analyser->issue(0)->variable()->name()); + + EXPECT_EQ(libcellml::AnalyserModel::Type::UNDERCONSTRAINED, analyser->model()->type()); +} + +TEST(Analyser, underconstrained) +{ + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("analyser/underconstrained.cellml")); + + EXPECT_EQ(size_t(0), parser->issueCount()); + + const std::vector expectedIssues = { + "Variable 'x' in component 'my_component' is not computed.", + }; + const std::vector expectedCauses = { + libcellml::Issue::Cause::VARIABLE, + }; + const std::vector expectedLevels = { + libcellml::Issue::Level::ERROR, + }; + + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ_ISSUES_CAUSES_LEVELS(expectedIssues, expectedCauses, expectedLevels, analyser); + + EXPECT_EQ(libcellml::AnalyserModel::Type::UNDERCONSTRAINED, analyser->model()->type()); +} + +TEST(Analyser, overconstrained) +{ + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("analyser/overconstrained.cellml")); + + EXPECT_EQ(size_t(0), parser->issueCount()); + + const std::vector expectedIssues = { + "Variable 'x' in component 'my_component' is computed more than once.", + }; + const std::vector expectedCauses = { + libcellml::Issue::Cause::VARIABLE, + }; + const std::vector expectedLevels = { + libcellml::Issue::Level::ERROR, + }; + + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ_ISSUES_CAUSES_LEVELS(expectedIssues, expectedCauses, expectedLevels, analyser); + + EXPECT_EQ(libcellml::AnalyserModel::Type::OVERCONSTRAINED, analyser->model()->type()); +} + +TEST(Analyser, unsuitablyConstrained) +{ + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("analyser/unsuitably_constrained.cellml")); + + EXPECT_EQ(size_t(0), parser->issueCount()); + + const std::vector expectedIssues = { + "Variable 'x' in component 'my_component' is not computed.", + "Variable 'y' in component 'my_component' is computed more than once.", + }; + const std::vector expectedCauses = { + libcellml::Issue::Cause::VARIABLE, + libcellml::Issue::Cause::VARIABLE, + }; + const std::vector expectedLevels = { + libcellml::Issue::Level::ERROR, + libcellml::Issue::Level::ERROR, + }; + + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ_ISSUES_CAUSES_LEVELS(expectedIssues, expectedCauses, expectedLevels, analyser); + + EXPECT_EQ(libcellml::AnalyserModel::Type::UNSUITABLY_CONSTRAINED, analyser->model()->type()); +} + +TEST(Analyser, coverage) +{ + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(nullptr); + + EXPECT_EQ(size_t(0), analyser->issueCount()); + + auto analyserModel = analyser->model(); + + EXPECT_FALSE(analyserModel->isValid()); + + EXPECT_EQ(libcellml::AnalyserModel::Type::UNKNOWN, analyserModel->type()); + + EXPECT_EQ(nullptr, analyserModel->voi()); + + EXPECT_EQ(size_t(0), analyserModel->stateCount()); + EXPECT_EQ(size_t(0), analyserModel->states().size()); + + EXPECT_EQ(size_t(0), analyserModel->variableCount()); + EXPECT_EQ(size_t(0), analyserModel->variables().size()); + + EXPECT_EQ(size_t(0), analyserModel->equationCount()); + EXPECT_EQ(size_t(0), analyserModel->equations().size()); + + EXPECT_FALSE(analyserModel->needEqFunction()); + EXPECT_FALSE(analyserModel->needNeqFunction()); + EXPECT_FALSE(analyserModel->needLtFunction()); + EXPECT_FALSE(analyserModel->needLeqFunction()); + EXPECT_FALSE(analyserModel->needGtFunction()); + EXPECT_FALSE(analyserModel->needGeqFunction()); + EXPECT_FALSE(analyserModel->needAndFunction()); + EXPECT_FALSE(analyserModel->needOrFunction()); + EXPECT_FALSE(analyserModel->needXorFunction()); + EXPECT_FALSE(analyserModel->needNotFunction()); + EXPECT_FALSE(analyserModel->needMinFunction()); + EXPECT_FALSE(analyserModel->needMaxFunction()); + EXPECT_FALSE(analyserModel->needSecFunction()); + EXPECT_FALSE(analyserModel->needCscFunction()); + EXPECT_FALSE(analyserModel->needCotFunction()); + EXPECT_FALSE(analyserModel->needSechFunction()); + EXPECT_FALSE(analyserModel->needCschFunction()); + EXPECT_FALSE(analyserModel->needCothFunction()); + EXPECT_FALSE(analyserModel->needAsecFunction()); + EXPECT_FALSE(analyserModel->needAcscFunction()); + EXPECT_FALSE(analyserModel->needAcotFunction()); + EXPECT_FALSE(analyserModel->needAsechFunction()); + EXPECT_FALSE(analyserModel->needAcschFunction()); + EXPECT_FALSE(analyserModel->needAcothFunction()); + + auto ast = libcellml::AnalyserEquationAst::create(); + + EXPECT_NE(nullptr, ast); + + ast->setType(libcellml::AnalyserEquationAst::Type::ASSIGNMENT); + ast->setValue({}); + ast->setVariable(libcellml::Variable::create()); + ast->setParent(libcellml::AnalyserEquationAst::create()); +} diff --git a/tests/analyser/tests.cmake b/tests/analyser/tests.cmake new file mode 100644 index 0000000000..01e5314b65 --- /dev/null +++ b/tests/analyser/tests.cmake @@ -0,0 +1,8 @@ +set(CURRENT_TEST analyser) +set(${CURRENT_TEST}_CATEGORY utils) + +list(APPEND LIBCELLML_TESTS ${CURRENT_TEST}) + +set(${CURRENT_TEST}_SRCS + ${CMAKE_CURRENT_LIST_DIR}/analyser.cpp +) diff --git a/tests/bindings/python/CMakeLists.txt b/tests/bindings/python/CMakeLists.txt index e54329103b..44ca72674c 100644 --- a/tests/bindings/python/CMakeLists.txt +++ b/tests/bindings/python/CMakeLists.txt @@ -13,6 +13,8 @@ # limitations under the License.cmake_minimum_required (VERSION 3.1) set(TEST_SRCS + test_analyser.py + test_analyser_equation_ast.py test_component.py test_docstrings.py test_entity.py diff --git a/tests/bindings/python/runner.py b/tests/bindings/python/runner.py index f5ca0e4550..25346fb807 100644 --- a/tests/bindings/python/runner.py +++ b/tests/bindings/python/runner.py @@ -1,18 +1,19 @@ -import coverage import os import sys import unittest +import coverage + args = sys.argv[:] -args.pop(0) # Remove program name. +args.pop(0) # Remove program name. configuration = "" if len(args): - configuration = args.pop(0) + configuration = args.pop(0) arg1 = "" if len(args): - arg1 = args.pop(0) + arg1 = args.pop(0) suite = unittest.TestLoader().discover(".") @@ -29,6 +30,6 @@ cov.save() if arg1 == "html": - cov.html_report(directory='coverage_html_report') + cov.html_report(directory='coverage_html_report') else: - cov.report() + cov.report() diff --git a/tests/bindings/python/test_analyser.py b/tests/bindings/python/test_analyser.py new file mode 100644 index 0000000000..53abf0104f --- /dev/null +++ b/tests/bindings/python/test_analyser.py @@ -0,0 +1,161 @@ +# +# Tests the Analyser class bindings +# +import unittest + + +class AnalyserTestCase(unittest.TestCase): + VALUE = 'value' + + def test_create_destroy(self): + from libcellml import Analyser + + x = Analyser() + del x + + def test_inheritance(self): + import libcellml + from libcellml import Analyser + + x = Analyser() + self.assertIsInstance(x, libcellml.logger.Logger) + + # Test access to inherited methods. + self.assertIsNone(x.issue(0)) + self.assertIsNone(x.issue(-1)) + self.assertEqual(x.issueCount(), 0) + x.addIssue(libcellml.Issue()) + self.assertEqual(x.issueCount(), 1) + + def test_analyse_model(self): + from libcellml import Analyser + from libcellml import AnalyserModel + from libcellml import Model + + # Analyse an empty model and make sure that we get no errors and an + # UNKNOWN type for the analyser model. + + m = Model('my_model') + a = Analyser() + + a.analyseModel(m) + + self.assertEqual(0, a.errorCount()) + self.assertEqual(AnalyserModel.Type.UNKNOWN, a.model().type()) + + def test_coverage(self): + from libcellml import Analyser + from libcellml import AnalyserEquation + from libcellml import AnalyserEquationAst + from libcellml import AnalyserModel + from libcellml import AnalyserVariable + from libcellml import Parser + from test_resources import file_contents + + # Try to create an analyser equation/model/variable, something that is not allowed. + + self.assertRaises(AttributeError, AnalyserEquation) + self.assertRaises(AttributeError, AnalyserModel) + self.assertRaises(AttributeError, AnalyserVariable) + + # Analyse a model, so we can then do some coverage. + + p = Parser() + m = p.parseModel(file_contents('generator/noble_model_1962/model.cellml')) + + a = Analyser() + a.analyseModel(m) + + # Ensure coverage for AnalyserModel. + + am = a.model() + + self.assertTrue(am.isValid()) + + self.assertIsNotNone(am.voi()) + + self.assertEqual(4, am.stateCount()) + self.assertIsNotNone(am.states()) + self.assertIsNotNone(am.state(3)) + + self.assertEqual(17, am.variableCount()) + self.assertIsNotNone(am.variables()) + self.assertIsNotNone(am.variable(3)) + + self.assertEqual(16, am.equationCount()) + self.assertIsNotNone(am.equations()) + self.assertIsNotNone(am.equation(3)) + + self.assertFalse(am.needEqFunction()) + self.assertFalse(am.needNeqFunction()) + self.assertFalse(am.needLtFunction()) + self.assertFalse(am.needLeqFunction()) + self.assertFalse(am.needGtFunction()) + self.assertFalse(am.needGeqFunction()) + self.assertFalse(am.needAndFunction()) + self.assertFalse(am.needOrFunction()) + self.assertFalse(am.needXorFunction()) + self.assertFalse(am.needNotFunction()) + self.assertFalse(am.needMinFunction()) + self.assertFalse(am.needMaxFunction()) + self.assertFalse(am.needSecFunction()) + self.assertFalse(am.needCscFunction()) + self.assertFalse(am.needCotFunction()) + self.assertFalse(am.needSechFunction()) + self.assertFalse(am.needCschFunction()) + self.assertFalse(am.needCothFunction()) + self.assertFalse(am.needAsecFunction()) + self.assertFalse(am.needAcscFunction()) + self.assertFalse(am.needAcotFunction()) + self.assertFalse(am.needAsechFunction()) + self.assertFalse(am.needAcschFunction()) + self.assertFalse(am.needAcothFunction()) + + # Ensure coverage for AnalyserVariable. + + av = am.variable(3) + + self.assertEqual(AnalyserVariable.Type.CONSTANT, av.type()) + self.assertEqual(3, av.index()) + self.assertIsNotNone(av.initialisingVariable()) + self.assertIsNotNone(av.variable()) + self.assertIsNotNone(av.equation()) + + # Ensure coverage for AnalyserEquation. + + ae = am.equation(3) + + self.assertEqual(AnalyserEquation.Type.RATE, ae.type()) + self.assertIsNotNone(ae.ast()) + self.assertIsNotNone(ae.dependencies()) + self.assertTrue(ae.isStateRateBased()) + self.assertIsNotNone(ae.variable()) + + # Ensure coverage for AnalyserEquationAst. + + aea = ae.ast() + + self.assertEqual(AnalyserEquationAst.Type.ASSIGNMENT, aea.type()) + self.assertEqual('', aea.value()) + self.assertIsNone(aea.variable()) + self.assertIsNone(aea.parent()) + self.assertIsNotNone(aea.leftChild()) + self.assertIsNotNone(aea.rightChild()) + + aea.setType(AnalyserEquationAst.Type.EQ) + aea.setValue(AnalyserTestCase.VALUE) + aea.setVariable(av.variable()) + aea.setParent(aea) + aea.setLeftChild(None) + aea.setRightChild(None) + + self.assertEqual(AnalyserEquationAst.Type.EQ, aea.type()) + self.assertEqual(AnalyserTestCase.VALUE, aea.value()) + self.assertIsNotNone(aea.variable()) + self.assertIsNotNone(aea.parent()) + self.assertIsNone(aea.leftChild()) + self.assertIsNone(aea.rightChild()) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/bindings/python/test_analyser_equation_ast.py b/tests/bindings/python/test_analyser_equation_ast.py new file mode 100644 index 0000000000..6c766a65ff --- /dev/null +++ b/tests/bindings/python/test_analyser_equation_ast.py @@ -0,0 +1,29 @@ +# +# Tests the AnalyserEquationAst class bindings +# +import unittest + + +class AnalyserEquationAstTestCase(unittest.TestCase): + + def test_create_destroy(self): + from libcellml import AnalyserEquationAst + + x = AnalyserEquationAst() + del x + + def test_analyser_equation_ast(self): + from libcellml import AnalyserEquationAst + + # Create an equation AST and check its default settings. + ast = AnalyserEquationAst() + self.assertEqual(AnalyserEquationAst.Type.ASSIGNMENT, ast.type()) + self.assertEqual('', ast.value()) + self.assertIsNone(ast.variable()) + self.assertIsNone(ast.parent()) + self.assertIsNone(ast.leftChild()) + self.assertIsNone(ast.rightChild()) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/bindings/python/test_component.py b/tests/bindings/python/test_component.py index 6f3235ac73..f989b79f61 100644 --- a/tests/bindings/python/test_component.py +++ b/tests/bindings/python/test_component.py @@ -11,7 +11,7 @@ def test_create_destroy(self): # Test create/copy/destroy x = Component() - del(x) + del x y = Component("c3") self.assertEqual("c3", y.name()) @@ -109,7 +109,7 @@ def test_has_variable(self): c.addVariable(v) self.assertTrue(c.hasVariable(v)) self.assertFalse(c.hasVariable(Variable())) - del(c, v) + del [c, v] # bool hasVariable(const std::string &name) c = Component() @@ -128,7 +128,7 @@ def test_has_variable(self): vTaken = c.takeVariable(0) self.assertEqual('orange', vTaken.name()) self.assertTrue(c.variableCount() == 1) - del(c, v1, v2, vTaken, name) + del [c, v1, v2, vTaken, name] def test_remove_variable(self): from libcellml import Component, Variable @@ -143,7 +143,7 @@ def test_remove_variable(self): self.assertFalse(c.removeVariable(1)) self.assertTrue(c.removeVariable(0)) self.assertFalse(c.removeVariable(0)) - del(c) + del c # bool removeVariable(const std::string &name) c = Component() @@ -158,7 +158,7 @@ def test_remove_variable(self): c.addVariable(v1) self.assertTrue(c.removeVariable(name)) self.assertFalse(c.removeVariable(name)) - del(c, v1, name) + del [c, v1, name] # bool removeVariable(const VariablePtr &variable) c = Component() @@ -201,7 +201,7 @@ def test_variable(self): self.assertIsNone(c.variable(-1)) self.assertIsNotNone(c.variable(0)) self.assertEqual(c.variable(0).name(), name) - del(c, v, name) + del [c, v, name] # VariablePtr variable(const std::string &name) c = Component() diff --git a/tests/bindings/python/test_docstrings.py b/tests/bindings/python/test_docstrings.py index eb142aeb33..a3b63037d5 100644 --- a/tests/bindings/python/test_docstrings.py +++ b/tests/bindings/python/test_docstrings.py @@ -1,8 +1,8 @@ # # Tests if all CellML bindings have docstrings set. # -import unittest import types +import unittest class DocstringTestCase(unittest.TestCase): diff --git a/tests/bindings/python/test_entity.py b/tests/bindings/python/test_entity.py index b310a03847..bb6beb49f3 100644 --- a/tests/bindings/python/test_entity.py +++ b/tests/bindings/python/test_entity.py @@ -92,7 +92,6 @@ def test_create(self): self.assertRaises(AttributeError, Logger) - def test_issue_types(self): from libcellml import Parser, Issue diff --git a/tests/bindings/python/test_generator.py b/tests/bindings/python/test_generator.py index d57ebdd3a7..688fb1e68a 100644 --- a/tests/bindings/python/test_generator.py +++ b/tests/bindings/python/test_generator.py @@ -1,18 +1,8 @@ # -# Tests the Parser class bindings +# Tests the Generator class bindings # import unittest -from test_resources import file_contents - -class GeneratorVariableTestCase(unittest.TestCase): - - def test_create_destroy(self): - from libcellml import GeneratorVariable - - x = GeneratorVariable() - del(x) - class GeneratorTestCase(unittest.TestCase): @@ -20,87 +10,46 @@ def test_create_destroy(self): from libcellml import Generator x = Generator() - del(x) - - def test_inheritance(self): - import libcellml - from libcellml import Generator - - x = Generator() - self.assertIsInstance(x, libcellml.logger.Logger) - - # Test access to inherited methods - self.assertIsNone(x.issue(0)) - self.assertIsNone(x.issue(-1)) - self.assertEqual(x.issueCount(), 0) - x.addIssue(libcellml.Issue()) - self.assertEqual(x.issueCount(), 1) - - def test_process_model(self): - from libcellml import Generator - from libcellml import Model - - m = Model() - g = Generator() - - g.processModel(m) - - self.assertEqual(0, g.errorCount()) - self.assertEqual(Generator.ModelType.UNKNOWN, g.modelType()) + del x def test_algebraic_eqn_computed_var_on_rhs(self): - from libcellml import Parser + from libcellml import Analyser + from libcellml import AnalyserModel from libcellml import Generator from libcellml import GeneratorProfile + from libcellml import Parser + from test_resources import file_contents p = Parser() m = p.parseModel(file_contents('generator/algebraic_eqn_computed_var_on_rhs/model.cellml')) - g = Generator() + a = Analyser() + a.analyseModel(m) - g.processModel(m) + am = a.model() - self.assertEqual(Generator.ModelType.ALGEBRAIC, g.modelType()) - - self.assertEqual(file_contents("generator/algebraic_eqn_computed_var_on_rhs/model.py"), g.implementationCode()) - - profile = GeneratorProfile(GeneratorProfile.Profile.C) - g.setProfile(profile) - - self.assertEqual(file_contents("generator/algebraic_eqn_computed_var_on_rhs/model.h"), g.interfaceCode()) - self.assertEqual(file_contents("generator/algebraic_eqn_computed_var_on_rhs/model.c"), g.implementationCode()) - - self.assertEqual(GeneratorProfile.Profile.C, g.profile().profile()) - - def test_getters(self): - from libcellml import Parser - from libcellml import Generator - from libcellml import GeneratorProfile - from libcellml import GeneratorVariable - - p = Parser() - m = p.parseModel(file_contents('generator/garny_kohl_hunter_boyett_noble_rabbit_san_model_2003/model.cellml')) + self.assertEqual(AnalyserModel.Type.ALGEBRAIC, am.type()) g = Generator() - g.processModel(m) + self.assertIsNone(g.model()) - self.assertEqual(Generator.ModelType.ODE, g.modelType()) + g.setModel(am) - self.assertEqual(185, g.variableCount()) + self.assertIsNotNone(g.model()) - v = g.variable(1) + self.assertEqual(file_contents("generator/algebraic_eqn_computed_var_on_rhs/model.h"), g.interfaceCode()) + self.assertEqual(file_contents("generator/algebraic_eqn_computed_var_on_rhs/model.c"), g.implementationCode()) - self.assertEqual(GeneratorVariable.Type.CONSTANT, v.type()) - self.assertEqual("g_Ca_L_Centre_0DCapable", v.variable().name()) + self.assertEqual(GeneratorProfile.Profile.C, g.profile().profile()) - voi = g.voi() + profile = GeneratorProfile(GeneratorProfile.Profile.PYTHON) + g.setProfile(profile) - self.assertEqual("time", voi.variable().name()) + self.assertEqual("", g.interfaceCode()) + self.assertEqual(file_contents("generator/algebraic_eqn_computed_var_on_rhs/model.py"), g.implementationCode()) - self.assertEqual(15, g.stateCount()) - self.assertEqual("P_af", g.state(9).variable().name()) - self.assertEqual("V", g.state(14).initialisingVariable().name()) + self.assertEqual(GeneratorProfile.Profile.PYTHON, g.profile().profile()) if __name__ == '__main__': diff --git a/tests/bindings/python/test_generator_profile.py b/tests/bindings/python/test_generator_profile.py index edae9e410e..c918e0fcb8 100644 --- a/tests/bindings/python/test_generator_profile.py +++ b/tests/bindings/python/test_generator_profile.py @@ -1,1477 +1,1511 @@ # -# Tests the Parser class bindings +# Tests the GeneratorProfile class bindings # import unittest class GeneratorProfileTestCase(unittest.TestCase): + VALUE = 'value' def test_create_destroy(self): from libcellml import GeneratorProfile x = GeneratorProfile() - del(x) + del x - def test_profile(self): + def test_generator_profile(self): from libcellml import GeneratorProfile + # Create a default, i.e. C, profile. p = GeneratorProfile() self.assertEqual(GeneratorProfile.Profile.C, p.profile()) + # Make the profile a Python profile. p.setProfile(GeneratorProfile.Profile.PYTHON) self.assertEqual(GeneratorProfile.Profile.PYTHON, p.profile()) - def test_has_interface(self): + # Create a Python profile. + pp = GeneratorProfile(GeneratorProfile.Profile.PYTHON) + self.assertEqual(GeneratorProfile.Profile.PYTHON, pp.profile()) + + @unittest.skip('Create tests script') + def test_create_tests(self): + import re from libcellml import GeneratorProfile p = GeneratorProfile() - self.assertTrue(p.hasInterface()) + seen = {} - p.setHasInterface(False) - self.assertFalse(p.hasInterface()) + def working_name(entry): + name = re.sub('([A-Z]{1})', r'_\1', entry).lower() - @unittest.skip("Create tests script") - def test_create_tests(self): - import re - from libcellml import GeneratorProfile - - p = GeneratorProfile() - - seen = {} - def working_name(entry): - name = re.sub('([A-Z]{1})', r'_\1', entry).lower() - if name.startswith("set"): - name = name[4:] - - return name - - def ignore(entry): - if entry.startswith("_") or entry in ["Profile", "profile", "this", "thisown"]: - return True - - return False - - def visited(entry): - result = entry in seen - - return entry in seen - if entry not in seen: - seen[entry] = True - return False - - return True - - def getSetNames(entry): - if entry.startswith("set"): - getter = entry[3:] - getter = getter[0].lower() + getter[1:] - return [getter, entry] - else: - setter = entry - setter = "set" + setter[0].upper() + setter[1:] - return[entry, setter] - - def printStringMethod(entry): - - [getter, setter] = getSetNames(entry) - content = getattr(p, getter)() - content = content.replace("\n", "\\n") - print(" from libcellml import GeneratorProfile") - print(" ") - print(" g = GeneratorProfile()") - print(" ") - print(f" self.assertEqual(\"{content}\", g.{getter}())") - print(f" g.{setter}(\"Some text content.\")") - print(f" self.assertEqual(\"Some text content.\", g.{getter}())") - print(" ") - - def printHasMethod(entry): - print(" from libcellml import GeneratorProfile") - print(" ") - print(" g = GeneratorProfile()") - print(" ") - print(" self.assertFalse(g.{0}())".format(entry)) - print(" ") - - def isStringMethod(name): - return name.endswith("string") - - def isHasMethod(name): - return name.startswith("has") - - - for entry in dir(p): - name = working_name(entry) - if not ignore(entry) and not name in seen: - seen[name] = True - print(" def test_{0}(self):".format(name)) - if isStringMethod(name): - printStringMethod(entry) - elif isHasMethod(name): - printHasMethod(entry) - else: - print(" # Yikes missing this method: " + entry) + if name.startswith('set'): + name = name[4:] + + return name + + def ignore(entry): + if entry.startswith('_') or entry in ['Profile', 'profile', 'this', 'thisown']: + return True + + return False + + def get_set_names(entry): + if entry.startswith('set'): + getter = entry[3:] + getter = getter[0].lower() + getter[1:] + + return [getter, entry] + else: + setter = entry + setter = 'set' + setter[0].upper() + setter[1:] + + return [entry, setter] + + def print_string_method(entry): + [getter, setter] = get_set_names(entry) + content = getattr(p, getter)() + content = content.replace('\n', '\\n') + + print(' from libcellml import GeneratorProfile') + print(' ') + print(' g = GeneratorProfile()') + print(' ') + print(' self.assertEqual("{content}", g.{getter}())') + print(' g.{setter}("Some text content.")') + print(' self.assertEqual("Some text content.", g.{getter}())') + print(' ') + + def print_has_method(entry): + print(' from libcellml import GeneratorProfile') + print(' ') + print(' g = GeneratorProfile()') + print(' ') + print(' self.assertFalse(g.{0}())'.format(entry)) + print(' ') + + def is_string_method(name): + return name.endswith('string') + + def is_has_method(name): + return name.startswith('has') + for entry in dir(p): + name = working_name(entry) + + if not ignore(entry) and not name in seen: + seen[name] = True + + print(' def test_{0}(self):'.format(name)) + + if is_string_method(name): + print_string_method(entry) + elif is_has_method(name): + print_has_method(entry) + else: + print(' # Yikes missing this method: ' + entry) def test_absolute_value_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("fabs", g.absoluteValueString()) - g.setAbsoluteValueString("Some text content.") - self.assertEqual("Some text content.", g.absoluteValueString()) - + + self.assertEqual('fabs', g.absoluteValueString()) + g.setAbsoluteValueString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.absoluteValueString()) + def test_acos_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("acos", g.acosString()) - g.setAcosString("Some text content.") - self.assertEqual("Some text content.", g.acosString()) - + + self.assertEqual('acos', g.acosString()) + g.setAcosString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.acosString()) + def test_acosh_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("acosh", g.acoshString()) - g.setAcoshString("Some text content.") - self.assertEqual("Some text content.", g.acoshString()) - + + self.assertEqual('acosh', g.acoshString()) + g.setAcoshString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.acoshString()) + def test_acot_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("double acot(double x)\n{\n return atan(1.0/x);\n}\n", g.acotFunctionString()) - g.setAcotFunctionString("Some text content.") - self.assertEqual("Some text content.", g.acotFunctionString()) - + + self.assertEqual('double acot(double x)\n{\n return atan(1.0/x);\n}\n', g.acotFunctionString()) + g.setAcotFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.acotFunctionString()) + def test_acot_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("acot", g.acotString()) - g.setAcotString("Some text content.") - self.assertEqual("Some text content.", g.acotString()) - + + self.assertEqual('acot', g.acotString()) + g.setAcotString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.acotString()) + def test_acoth_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("double acoth(double x)\n{\n double oneOverX = 1.0/x;\n\n return 0.5*log((1.0+oneOverX)/(1.0-oneOverX));\n}\n", g.acothFunctionString()) - g.setAcothFunctionString("Some text content.") - self.assertEqual("Some text content.", g.acothFunctionString()) - + + self.assertEqual( + 'double acoth(double x)\n{\n double oneOverX = 1.0/x;\n\n return 0.5*log((1.0+oneOverX)/(1.0-oneOverX));\n}\n', + g.acothFunctionString()) + g.setAcothFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.acothFunctionString()) + def test_acoth_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("acoth", g.acothString()) - g.setAcothString("Some text content.") - self.assertEqual("Some text content.", g.acothString()) - + + self.assertEqual('acoth', g.acothString()) + g.setAcothString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.acothString()) + def test_acsc_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("double acsc(double x)\n{\n return asin(1.0/x);\n}\n", g.acscFunctionString()) - g.setAcscFunctionString("Some text content.") - self.assertEqual("Some text content.", g.acscFunctionString()) - + + self.assertEqual('double acsc(double x)\n{\n return asin(1.0/x);\n}\n', g.acscFunctionString()) + g.setAcscFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.acscFunctionString()) + def test_acsc_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("acsc", g.acscString()) - g.setAcscString("Some text content.") - self.assertEqual("Some text content.", g.acscString()) - + + self.assertEqual('acsc', g.acscString()) + g.setAcscString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.acscString()) + def test_acsch_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("double acsch(double x)\n{\n double oneOverX = 1.0/x;\n\n return log(oneOverX+sqrt(oneOverX*oneOverX+1.0));\n}\n", g.acschFunctionString()) - g.setAcschFunctionString("Some text content.") - self.assertEqual("Some text content.", g.acschFunctionString()) - + + self.assertEqual( + 'double acsch(double x)\n{\n double oneOverX = 1.0/x;\n\n return log(oneOverX+sqrt(oneOverX*oneOverX+1.0));\n}\n', + g.acschFunctionString()) + g.setAcschFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.acschFunctionString()) + def test_acsch_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("acsch", g.acschString()) - g.setAcschString("Some text content.") - self.assertEqual("Some text content.", g.acschString()) - + + self.assertEqual('acsch', g.acschString()) + g.setAcschString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.acschString()) + def test_algebraic_variable_type_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("ALGEBRAIC", g.algebraicVariableTypeString()) - g.setAlgebraicVariableTypeString("Some text content.") - self.assertEqual("Some text content.", g.algebraicVariableTypeString()) - + + self.assertEqual('ALGEBRAIC', g.algebraicVariableTypeString()) + g.setAlgebraicVariableTypeString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.algebraicVariableTypeString()) + def test_and_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("", g.andFunctionString()) - g.setAndFunctionString("Some text content.") - self.assertEqual("Some text content.", g.andFunctionString()) - + + self.assertEqual('', g.andFunctionString()) + g.setAndFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.andFunctionString()) + def test_and_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual(" && ", g.andString()) - g.setAndString("Some text content.") - self.assertEqual("Some text content.", g.andString()) - + + self.assertEqual(' && ', g.andString()) + g.setAndString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.andString()) + def test_array_element_separator_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual(",", g.arrayElementSeparatorString()) - g.setArrayElementSeparatorString("Some text content.") - self.assertEqual("Some text content.", g.arrayElementSeparatorString()) - + + self.assertEqual(',', g.arrayElementSeparatorString()) + g.setArrayElementSeparatorString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.arrayElementSeparatorString()) + def test_asec_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("double asec(double x)\n{\n return acos(1.0/x);\n}\n", g.asecFunctionString()) - g.setAsecFunctionString("Some text content.") - self.assertEqual("Some text content.", g.asecFunctionString()) - + + self.assertEqual('double asec(double x)\n{\n return acos(1.0/x);\n}\n', g.asecFunctionString()) + g.setAsecFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.asecFunctionString()) + def test_asec_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("asec", g.asecString()) - g.setAsecString("Some text content.") - self.assertEqual("Some text content.", g.asecString()) - + + self.assertEqual('asec', g.asecString()) + g.setAsecString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.asecString()) + def test_asech_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("double asech(double x)\n{\n double oneOverX = 1.0/x;\n\n return log(oneOverX+sqrt(oneOverX*oneOverX-1.0));\n}\n", g.asechFunctionString()) - g.setAsechFunctionString("Some text content.") - self.assertEqual("Some text content.", g.asechFunctionString()) - + + self.assertEqual( + 'double asech(double x)\n{\n double oneOverX = 1.0/x;\n\n return log(oneOverX+sqrt(oneOverX*oneOverX-1.0));\n}\n', + g.asechFunctionString()) + g.setAsechFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.asechFunctionString()) + def test_asech_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("asech", g.asechString()) - g.setAsechString("Some text content.") - self.assertEqual("Some text content.", g.asechString()) - + + self.assertEqual('asech', g.asechString()) + g.setAsechString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.asechString()) + def test_asin_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("asin", g.asinString()) - g.setAsinString("Some text content.") - self.assertEqual("Some text content.", g.asinString()) - + + self.assertEqual('asin', g.asinString()) + g.setAsinString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.asinString()) + def test_asinh_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("asinh", g.asinhString()) - g.setAsinhString("Some text content.") - self.assertEqual("Some text content.", g.asinhString()) - + + self.assertEqual('asinh', g.asinhString()) + g.setAsinhString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.asinhString()) + def test_assignment_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual(" = ", g.assignmentString()) - g.setAssignmentString("Some text content.") - self.assertEqual("Some text content.", g.assignmentString()) - + + self.assertEqual(' = ', g.assignmentString()) + g.setAssignmentString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.assignmentString()) + def test_atan_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("atan", g.atanString()) - g.setAtanString("Some text content.") - self.assertEqual("Some text content.", g.atanString()) - + + self.assertEqual('atan', g.atanString()) + g.setAtanString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.atanString()) + def test_atanh_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("atanh", g.atanhString()) - g.setAtanhString("Some text content.") - self.assertEqual("Some text content.", g.atanhString()) - + + self.assertEqual('atanh', g.atanhString()) + g.setAtanhString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.atanhString()) + def test_ceiling_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("ceil", g.ceilingString()) - g.setCeilingString("Some text content.") - self.assertEqual("Some text content.", g.ceilingString()) - - def test_close_array_initializer_string(self): + + self.assertEqual('ceil', g.ceilingString()) + g.setCeilingString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.ceilingString()) + + def test_close_array_initialiser_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("}", g.closeArrayInitializerString()) - g.setCloseArrayInitializerString("Some text content.") - self.assertEqual("Some text content.", g.closeArrayInitializerString()) - + + self.assertEqual('}', g.closeArrayInitialiserString()) + g.setCloseArrayInitialiserString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.closeArrayInitialiserString()) + def test_close_array_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("]", g.closeArrayString()) - g.setCloseArrayString("Some text content.") - self.assertEqual("Some text content.", g.closeArrayString()) - + + self.assertEqual(']', g.closeArrayString()) + g.setCloseArrayString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.closeArrayString()) + def test_command_separator_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual(";", g.commandSeparatorString()) - g.setCommandSeparatorString("Some text content.") - self.assertEqual("Some text content.", g.commandSeparatorString()) - + + self.assertEqual(';', g.commandSeparatorString()) + g.setCommandSeparatorString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.commandSeparatorString()) + def test_comment_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("/* */\n", g.commentString()) - g.setCommentString("Some text content.") - self.assertEqual("Some text content.", g.commentString()) - + + self.assertEqual('/* */\n', g.commentString()) + g.setCommentString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.commentString()) + def test_common_logarithm_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("log10", g.commonLogarithmString()) - g.setCommonLogarithmString("Some text content.") - self.assertEqual("Some text content.", g.commonLogarithmString()) - + + self.assertEqual('log10', g.commonLogarithmString()) + g.setCommonLogarithmString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.commonLogarithmString()) + def test_computed_constant_variable_type_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("COMPUTED_CONSTANT", g.computedConstantVariableTypeString()) - g.setComputedConstantVariableTypeString("Some text content.") - self.assertEqual("Some text content.", g.computedConstantVariableTypeString()) - + + self.assertEqual('COMPUTED_CONSTANT', g.computedConstantVariableTypeString()) + g.setComputedConstantVariableTypeString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.computedConstantVariableTypeString()) + def test_conditional_operator_else_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual(":", g.conditionalOperatorElseString()) - g.setConditionalOperatorElseString("Some text content.") - self.assertEqual("Some text content.", g.conditionalOperatorElseString()) - + + self.assertEqual(':', g.conditionalOperatorElseString()) + g.setConditionalOperatorElseString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.conditionalOperatorElseString()) + def test_conditional_operator_if_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("()?", g.conditionalOperatorIfString()) - g.setConditionalOperatorIfString("Some text content.") - self.assertEqual("Some text content.", g.conditionalOperatorIfString()) - + + self.assertEqual('()?', g.conditionalOperatorIfString()) + g.setConditionalOperatorIfString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.conditionalOperatorIfString()) + def test_constant_variable_type_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("CONSTANT", g.constantVariableTypeString()) - g.setConstantVariableTypeString("Some text content.") - self.assertEqual("Some text content.", g.constantVariableTypeString()) - + + self.assertEqual('CONSTANT', g.constantVariableTypeString()) + g.setConstantVariableTypeString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.constantVariableTypeString()) + def test_cos_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("cos", g.cosString()) - g.setCosString("Some text content.") - self.assertEqual("Some text content.", g.cosString()) - + + self.assertEqual('cos', g.cosString()) + g.setCosString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.cosString()) + def test_cosh_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("cosh", g.coshString()) - g.setCoshString("Some text content.") - self.assertEqual("Some text content.", g.coshString()) - + + self.assertEqual('cosh', g.coshString()) + g.setCoshString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.coshString()) + def test_cot_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("double cot(double x)\n{\n return 1.0/tan(x);\n}\n", g.cotFunctionString()) - g.setCotFunctionString("Some text content.") - self.assertEqual("Some text content.", g.cotFunctionString()) - + + self.assertEqual('double cot(double x)\n{\n return 1.0/tan(x);\n}\n', g.cotFunctionString()) + g.setCotFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.cotFunctionString()) + def test_cot_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("cot", g.cotString()) - g.setCotString("Some text content.") - self.assertEqual("Some text content.", g.cotString()) - + + self.assertEqual('cot', g.cotString()) + g.setCotString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.cotString()) + def test_coth_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("double coth(double x)\n{\n return 1.0/tanh(x);\n}\n", g.cothFunctionString()) - g.setCothFunctionString("Some text content.") - self.assertEqual("Some text content.", g.cothFunctionString()) - + + self.assertEqual('double coth(double x)\n{\n return 1.0/tanh(x);\n}\n', g.cothFunctionString()) + g.setCothFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.cothFunctionString()) + def test_coth_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("coth", g.cothString()) - g.setCothString("Some text content.") - self.assertEqual("Some text content.", g.cothString()) - + + self.assertEqual('coth', g.cothString()) + g.setCothString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.cothString()) + def test_csc_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("double csc(double x)\n{\n return 1.0/sin(x);\n}\n", g.cscFunctionString()) - g.setCscFunctionString("Some text content.") - self.assertEqual("Some text content.", g.cscFunctionString()) - + + self.assertEqual('double csc(double x)\n{\n return 1.0/sin(x);\n}\n', g.cscFunctionString()) + g.setCscFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.cscFunctionString()) + def test_csc_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("csc", g.cscString()) - g.setCscString("Some text content.") - self.assertEqual("Some text content.", g.cscString()) - + + self.assertEqual('csc', g.cscString()) + g.setCscString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.cscString()) + def test_csch_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("double csch(double x)\n{\n return 1.0/sinh(x);\n}\n", g.cschFunctionString()) - g.setCschFunctionString("Some text content.") - self.assertEqual("Some text content.", g.cschFunctionString()) - + + self.assertEqual('double csch(double x)\n{\n return 1.0/sinh(x);\n}\n', g.cschFunctionString()) + g.setCschFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.cschFunctionString()) + def test_csch_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("csch", g.cschString()) - g.setCschString("Some text content.") - self.assertEqual("Some text content.", g.cschString()) - + + self.assertEqual('csch', g.cschString()) + g.setCschString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.cschString()) + def test_divide_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("/", g.divideString()) - g.setDivideString("Some text content.") - self.assertEqual("Some text content.", g.divideString()) - + + self.assertEqual('/', g.divideString()) + g.setDivideString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.divideString()) + def test_e_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("2.71828182845905", g.eString()) - g.setEString("Some text content.") - self.assertEqual("Some text content.", g.eString()) - + + self.assertEqual('2.71828182845905', g.eString()) + g.setEString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.eString()) + def test_empty_method_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("", g.emptyMethodString()) - g.setEmptyMethodString("Some text content.") - self.assertEqual("Some text content.", g.emptyMethodString()) - + + self.assertEqual('', g.emptyMethodString()) + g.setEmptyMethodString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.emptyMethodString()) + def test_eq_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("", g.eqFunctionString()) - g.setEqFunctionString("Some text content.") - self.assertEqual("Some text content.", g.eqFunctionString()) - + + self.assertEqual('', g.eqFunctionString()) + g.setEqFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.eqFunctionString()) + def test_eq_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual(" == ", g.eqString()) - g.setEqString("Some text content.") - self.assertEqual("Some text content.", g.eqString()) - + + self.assertEqual(' == ', g.eqString()) + g.setEqString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.eqString()) + def test_exponential_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("exp", g.exponentialString()) - g.setExponentialString("Some text content.") - self.assertEqual("Some text content.", g.exponentialString()) - + + self.assertEqual('exp', g.exponentialString()) + g.setExponentialString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.exponentialString()) + def test_false_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("0.0", g.falseString()) - g.setFalseString("Some text content.") - self.assertEqual("Some text content.", g.falseString()) - + + self.assertEqual('0.0', g.falseString()) + g.setFalseString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.falseString()) + def test_floor_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("floor", g.floorString()) - g.setFloorString("Some text content.") - self.assertEqual("Some text content.", g.floorString()) - + + self.assertEqual('floor', g.floorString()) + g.setFloorString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.floorString()) + def test_geq_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("", g.geqFunctionString()) - g.setGeqFunctionString("Some text content.") - self.assertEqual("Some text content.", g.geqFunctionString()) - + + self.assertEqual('', g.geqFunctionString()) + g.setGeqFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.geqFunctionString()) + def test_geq_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual(" >= ", g.geqString()) - g.setGeqString("Some text content.") - self.assertEqual("Some text content.", g.geqString()) - + + self.assertEqual(' >= ', g.geqString()) + g.setGeqString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.geqString()) + def test_gt_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("", g.gtFunctionString()) - g.setGtFunctionString("Some text content.") - self.assertEqual("Some text content.", g.gtFunctionString()) - + + self.assertEqual('', g.gtFunctionString()) + g.setGtFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.gtFunctionString()) + def test_gt_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual(" > ", g.gtString()) - g.setGtString("Some text content.") - self.assertEqual("Some text content.", g.gtString()) - + + self.assertEqual(' > ', g.gtString()) + g.setGtString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.gtString()) + def test_has_and_operator(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - + self.assertTrue(g.hasAndOperator()) g.setHasAndOperator(False) self.assertFalse(g.hasAndOperator()) - + def test_has_conditional_operator(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - + self.assertTrue(g.hasConditionalOperator()) g.setHasConditionalOperator(False) self.assertFalse(g.hasConditionalOperator()) def test_has_eq_operator(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - + self.assertTrue(g.hasEqOperator()) g.setHasEqOperator(False) self.assertFalse(g.hasEqOperator()) def test_has_geq_operator(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - + self.assertTrue(g.hasGeqOperator()) g.setHasGeqOperator(False) self.assertFalse(g.hasGeqOperator()) def test_has_gt_operator(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - + self.assertTrue(g.hasGtOperator()) g.setHasGtOperator(False) self.assertFalse(g.hasGtOperator()) def test_has_leq_operator(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - + self.assertTrue(g.hasLeqOperator()) g.setHasLeqOperator(False) self.assertFalse(g.hasLeqOperator()) def test_has_lt_operator(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - + self.assertTrue(g.hasLtOperator()) g.setHasLtOperator(False) self.assertFalse(g.hasLtOperator()) def test_has_neq_operator(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - + self.assertTrue(g.hasNeqOperator()) g.setHasNeqOperator(False) self.assertFalse(g.hasNeqOperator()) def test_has_not_operator(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - + self.assertTrue(g.hasNotOperator()) g.setHasNotOperator(False) self.assertFalse(g.hasNotOperator()) def test_has_or_operator(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - + self.assertTrue(g.hasOrOperator()) g.setHasOrOperator(False) self.assertFalse(g.hasOrOperator()) def test_has_power_operator(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - + self.assertFalse(g.hasPowerOperator()) g.setHasPowerOperator(True) self.assertTrue(g.hasPowerOperator()) def test_has_xor_operator(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - + self.assertFalse(g.hasXorOperator()) g.setHasXorOperator(True) self.assertTrue(g.hasXorOperator()) def test_implementation_compute_computed_constants_method_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("void computeComputedConstants(double *variables)\n{\n}\n", g.implementationComputeComputedConstantsMethodString()) - g.setImplementationComputeComputedConstantsMethodString("Some text content.") - self.assertEqual("Some text content.", g.implementationComputeComputedConstantsMethodString()) - + + self.assertEqual('void computeComputedConstants(double *variables)\n{\n}\n', + g.implementationComputeComputedConstantsMethodString()) + g.setImplementationComputeComputedConstantsMethodString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.implementationComputeComputedConstantsMethodString()) + def test_implementation_compute_rates_method_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("void computeRates(double voi, double *states, double *rates, double *variables)\n{\n}\n", g.implementationComputeRatesMethodString()) - g.setImplementationComputeRatesMethodString("Some text content.") - self.assertEqual("Some text content.", g.implementationComputeRatesMethodString()) - + + self.assertEqual( + 'void computeRates(double voi, double *states, double *rates, double *variables)\n{\n}\n', + g.implementationComputeRatesMethodString()) + g.setImplementationComputeRatesMethodString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.implementationComputeRatesMethodString()) + def test_implementation_compute_variables_method_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("void computeVariables(double voi, double *states, double *rates, double *variables)\n{\n}\n", g.implementationComputeVariablesMethodString()) - g.setImplementationComputeVariablesMethodString("Some text content.") - self.assertEqual("Some text content.", g.implementationComputeVariablesMethodString()) - + + self.assertEqual( + 'void computeVariables(double voi, double *states, double *rates, double *variables)\n{\n}\n', + g.implementationComputeVariablesMethodString()) + g.setImplementationComputeVariablesMethodString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.implementationComputeVariablesMethodString()) + def test_implementation_create_states_array_method_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("double * createStatesArray()\n{\n return (double *) malloc(STATE_COUNT*sizeof(double));\n}\n", g.implementationCreateStatesArrayMethodString()) - g.setImplementationCreateStatesArrayMethodString("Some text content.") - self.assertEqual("Some text content.", g.implementationCreateStatesArrayMethodString()) - + + self.assertEqual( + 'double * createStatesArray()\n{\n return (double *) malloc(STATE_COUNT*sizeof(double));\n}\n', + g.implementationCreateStatesArrayMethodString()) + g.setImplementationCreateStatesArrayMethodString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.implementationCreateStatesArrayMethodString()) + def test_implementation_create_variables_array_method_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("double * createVariablesArray()\n{\n return (double *) malloc(VARIABLE_COUNT*sizeof(double));\n}\n", g.implementationCreateVariablesArrayMethodString()) - g.setImplementationCreateVariablesArrayMethodString("Some text content.") - self.assertEqual("Some text content.", g.implementationCreateVariablesArrayMethodString()) - + + self.assertEqual( + 'double * createVariablesArray()\n{\n return (double *) malloc(VARIABLE_COUNT*sizeof(double));\n}\n', + g.implementationCreateVariablesArrayMethodString()) + g.setImplementationCreateVariablesArrayMethodString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.implementationCreateVariablesArrayMethodString()) + def test_implementation_delete_array_method_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("void deleteArray(double *array)\n{\n free(array);\n}\n", g.implementationDeleteArrayMethodString()) - g.setImplementationDeleteArrayMethodString("Some text content.") - self.assertEqual("Some text content.", g.implementationDeleteArrayMethodString()) - + + self.assertEqual('void deleteArray(double *array)\n{\n free(array);\n}\n', + g.implementationDeleteArrayMethodString()) + g.setImplementationDeleteArrayMethodString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.implementationDeleteArrayMethodString()) + def test_implementation_header_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("#include \"\"\n\n#include \n#include \n", g.implementationHeaderString()) - g.setImplementationHeaderString("Some text content.") - self.assertEqual("Some text content.", g.implementationHeaderString()) - - def test_implementation_initialize_states_and_constants_method_string(self): + + self.assertEqual('#include ""\n\n#include \n#include \n', + g.implementationHeaderString()) + g.setImplementationHeaderString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.implementationHeaderString()) + + def test_implementation_initialise_states_and_constants_method_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("void initializeStatesAndConstants(double *states, double *variables)\n{\n}\n", g.implementationInitializeStatesAndConstantsMethodString()) - g.setImplementationInitializeStatesAndConstantsMethodString("Some text content.") - self.assertEqual("Some text content.", g.implementationInitializeStatesAndConstantsMethodString()) - + + self.assertEqual('void initialiseStatesAndConstants(double *states, double *variables)\n{\n}\n', + g.implementationInitialiseStatesAndConstantsMethodString()) + g.setImplementationInitialiseStatesAndConstantsMethodString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.implementationInitialiseStatesAndConstantsMethodString()) + def test_implementation_libcellml_version_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("const char LIBCELLML_VERSION[] = \"\";\n", g.implementationLibcellmlVersionString()) - g.setImplementationLibcellmlVersionString("Some text content.") - self.assertEqual("Some text content.", g.implementationLibcellmlVersionString()) - + + self.assertEqual('const char LIBCELLML_VERSION[] = "";\n', + g.implementationLibcellmlVersionString()) + g.setImplementationLibcellmlVersionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.implementationLibcellmlVersionString()) + def test_implementation_state_count_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("const size_t STATE_COUNT = ;\n", g.implementationStateCountString()) - g.setImplementationStateCountString("Some text content.") - self.assertEqual("Some text content.", g.implementationStateCountString()) - + + self.assertEqual('const size_t STATE_COUNT = ;\n', g.implementationStateCountString()) + g.setImplementationStateCountString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.implementationStateCountString()) + def test_implementation_state_info_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("const VariableInfo STATE_INFO[] = {\n};\n", g.implementationStateInfoString()) - g.setImplementationStateInfoString("Some text content.") - self.assertEqual("Some text content.", g.implementationStateInfoString()) - + + self.assertEqual('const VariableInfo STATE_INFO[] = {\n};\n', g.implementationStateInfoString()) + g.setImplementationStateInfoString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.implementationStateInfoString()) + def test_implementation_variable_count_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("const size_t VARIABLE_COUNT = ;\n", g.implementationVariableCountString()) - g.setImplementationVariableCountString("Some text content.") - self.assertEqual("Some text content.", g.implementationVariableCountString()) - + + self.assertEqual('const size_t VARIABLE_COUNT = ;\n', g.implementationVariableCountString()) + g.setImplementationVariableCountString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.implementationVariableCountString()) + def test_implementation_variable_info_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("const VariableInfoWithType VARIABLE_INFO[] = {\n};\n", g.implementationVariableInfoString()) - g.setImplementationVariableInfoString("Some text content.") - self.assertEqual("Some text content.", g.implementationVariableInfoString()) - + + self.assertEqual('const VariableInfoWithType VARIABLE_INFO[] = {\n};\n', + g.implementationVariableInfoString()) + g.setImplementationVariableInfoString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.implementationVariableInfoString()) + def test_implementation_version_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("const char VERSION[] = \"0.1.0\";\n", g.implementationVersionString()) - g.setImplementationVersionString("Some text content.") - self.assertEqual("Some text content.", g.implementationVersionString()) - + + self.assertEqual('const char VERSION[] = "0.1.0";\n', g.implementationVersionString()) + g.setImplementationVersionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.implementationVersionString()) + def test_implementation_voi_info_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("const VariableInfo VOI_INFO = ;\n", g.implementationVoiInfoString()) - g.setImplementationVoiInfoString("Some text content.") - self.assertEqual("Some text content.", g.implementationVoiInfoString()) - + + self.assertEqual('const VariableInfo VOI_INFO = ;\n', g.implementationVoiInfoString()) + g.setImplementationVoiInfoString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.implementationVoiInfoString()) + def test_indent_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual(" ", g.indentString()) - g.setIndentString("Some text content.") - self.assertEqual("Some text content.", g.indentString()) - + + self.assertEqual(' ', g.indentString()) + g.setIndentString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.indentString()) + def test_inf_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("INFINITY", g.infString()) - g.setInfString("Some text content.") - self.assertEqual("Some text content.", g.infString()) - + + self.assertEqual('INFINITY', g.infString()) + g.setInfString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.infString()) + def test_interface_compute_computed_constants_method_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("void computeComputedConstants(double *variables);\n", g.interfaceComputeComputedConstantsMethodString()) - g.setInterfaceComputeComputedConstantsMethodString("Some text content.") - self.assertEqual("Some text content.", g.interfaceComputeComputedConstantsMethodString()) - + + self.assertEqual('void computeComputedConstants(double *variables);\n', + g.interfaceComputeComputedConstantsMethodString()) + g.setInterfaceComputeComputedConstantsMethodString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.interfaceComputeComputedConstantsMethodString()) + def test_interface_compute_rates_method_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("void computeRates(double voi, double *states, double *rates, double *variables);\n", g.interfaceComputeRatesMethodString()) - g.setInterfaceComputeRatesMethodString("Some text content.") - self.assertEqual("Some text content.", g.interfaceComputeRatesMethodString()) - + + self.assertEqual('void computeRates(double voi, double *states, double *rates, double *variables);\n', + g.interfaceComputeRatesMethodString()) + g.setInterfaceComputeRatesMethodString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.interfaceComputeRatesMethodString()) + def test_interface_compute_variables_method_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("void computeVariables(double voi, double *states, double *rates, double *variables);\n", g.interfaceComputeVariablesMethodString()) - g.setInterfaceComputeVariablesMethodString("Some text content.") - self.assertEqual("Some text content.", g.interfaceComputeVariablesMethodString()) - + + self.assertEqual('void computeVariables(double voi, double *states, double *rates, double *variables);\n', + g.interfaceComputeVariablesMethodString()) + g.setInterfaceComputeVariablesMethodString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.interfaceComputeVariablesMethodString()) + def test_interface_create_states_array_method_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("double * createStatesArray();\n", g.interfaceCreateStatesArrayMethodString()) - g.setInterfaceCreateStatesArrayMethodString("Some text content.") - self.assertEqual("Some text content.", g.interfaceCreateStatesArrayMethodString()) - + + self.assertEqual('double * createStatesArray();\n', g.interfaceCreateStatesArrayMethodString()) + g.setInterfaceCreateStatesArrayMethodString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.interfaceCreateStatesArrayMethodString()) + def test_interface_create_variables_array_method_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("double * createVariablesArray();\n", g.interfaceCreateVariablesArrayMethodString()) - g.setInterfaceCreateVariablesArrayMethodString("Some text content.") - self.assertEqual("Some text content.", g.interfaceCreateVariablesArrayMethodString()) - + + self.assertEqual('double * createVariablesArray();\n', g.interfaceCreateVariablesArrayMethodString()) + g.setInterfaceCreateVariablesArrayMethodString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.interfaceCreateVariablesArrayMethodString()) + def test_interface_delete_array_method_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("void deleteArray(double *array);\n", g.interfaceDeleteArrayMethodString()) - g.setInterfaceDeleteArrayMethodString("Some text content.") - self.assertEqual("Some text content.", g.interfaceDeleteArrayMethodString()) - + + self.assertEqual('void deleteArray(double *array);\n', g.interfaceDeleteArrayMethodString()) + g.setInterfaceDeleteArrayMethodString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.interfaceDeleteArrayMethodString()) + def test_interface_file_name_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("model.h", g.interfaceFileNameString()) - g.setInterfaceFileNameString("Some text content.") - self.assertEqual("Some text content.", g.interfaceFileNameString()) - + + self.assertEqual('model.h', g.interfaceFileNameString()) + g.setInterfaceFileNameString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.interfaceFileNameString()) + def test_interface_header_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("#pragma once\n\n#include \n", g.interfaceHeaderString()) - g.setInterfaceHeaderString("Some text content.") - self.assertEqual("Some text content.", g.interfaceHeaderString()) - - def test_interface_initialize_states_and_constants_method_string(self): + + self.assertEqual('#pragma once\n\n#include \n', g.interfaceHeaderString()) + g.setInterfaceHeaderString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.interfaceHeaderString()) + + def test_interface_initialise_states_and_constants_method_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("void initializeStatesAndConstants(double *states, double *variables);\n", g.interfaceInitializeStatesAndConstantsMethodString()) - g.setInterfaceInitializeStatesAndConstantsMethodString("Some text content.") - self.assertEqual("Some text content.", g.interfaceInitializeStatesAndConstantsMethodString()) - + + self.assertEqual('void initialiseStatesAndConstants(double *states, double *variables);\n', + g.interfaceInitialiseStatesAndConstantsMethodString()) + g.setInterfaceInitialiseStatesAndConstantsMethodString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.interfaceInitialiseStatesAndConstantsMethodString()) + def test_interface_libcellml_version_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("extern const char LIBCELLML_VERSION[];\n", g.interfaceLibcellmlVersionString()) - g.setInterfaceLibcellmlVersionString("Some text content.") - self.assertEqual("Some text content.", g.interfaceLibcellmlVersionString()) - + + self.assertEqual('extern const char LIBCELLML_VERSION[];\n', g.interfaceLibcellmlVersionString()) + g.setInterfaceLibcellmlVersionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.interfaceLibcellmlVersionString()) + def test_interface_state_count_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("extern const size_t STATE_COUNT;\n", g.interfaceStateCountString()) - g.setInterfaceStateCountString("Some text content.") - self.assertEqual("Some text content.", g.interfaceStateCountString()) - + + self.assertEqual('extern const size_t STATE_COUNT;\n', g.interfaceStateCountString()) + g.setInterfaceStateCountString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.interfaceStateCountString()) + def test_interface_state_info_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("extern const VariableInfo STATE_INFO[];\n", g.interfaceStateInfoString()) - g.setInterfaceStateInfoString("Some text content.") - self.assertEqual("Some text content.", g.interfaceStateInfoString()) - + + self.assertEqual('extern const VariableInfo STATE_INFO[];\n', g.interfaceStateInfoString()) + g.setInterfaceStateInfoString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.interfaceStateInfoString()) + def test_interface_variable_count_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("extern const size_t VARIABLE_COUNT;\n", g.interfaceVariableCountString()) - g.setInterfaceVariableCountString("Some text content.") - self.assertEqual("Some text content.", g.interfaceVariableCountString()) - + + self.assertEqual('extern const size_t VARIABLE_COUNT;\n', g.interfaceVariableCountString()) + g.setInterfaceVariableCountString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.interfaceVariableCountString()) + def test_interface_variable_info_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("extern const VariableInfoWithType VARIABLE_INFO[];\n", g.interfaceVariableInfoString()) - g.setInterfaceVariableInfoString("Some text content.") - self.assertEqual("Some text content.", g.interfaceVariableInfoString()) - + + self.assertEqual('extern const VariableInfoWithType VARIABLE_INFO[];\n', g.interfaceVariableInfoString()) + g.setInterfaceVariableInfoString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.interfaceVariableInfoString()) + def test_interface_version_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("extern const char VERSION[];\n", g.interfaceVersionString()) - g.setInterfaceVersionString("Some text content.") - self.assertEqual("Some text content.", g.interfaceVersionString()) - + + self.assertEqual('extern const char VERSION[];\n', g.interfaceVersionString()) + g.setInterfaceVersionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.interfaceVersionString()) + def test_interface_voi_info_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("extern const VariableInfo VOI_INFO;\n", g.interfaceVoiInfoString()) - g.setInterfaceVoiInfoString("Some text content.") - self.assertEqual("Some text content.", g.interfaceVoiInfoString()) - + + self.assertEqual('extern const VariableInfo VOI_INFO;\n', g.interfaceVoiInfoString()) + g.setInterfaceVoiInfoString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.interfaceVoiInfoString()) + def test_leq_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("", g.leqFunctionString()) - g.setLeqFunctionString("Some text content.") - self.assertEqual("Some text content.", g.leqFunctionString()) - + + self.assertEqual('', g.leqFunctionString()) + g.setLeqFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.leqFunctionString()) + def test_leq_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual(" <= ", g.leqString()) - g.setLeqString("Some text content.") - self.assertEqual("Some text content.", g.leqString()) - + + self.assertEqual(' <= ', g.leqString()) + g.setLeqString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.leqString()) + def test_lt_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("", g.ltFunctionString()) - g.setLtFunctionString("Some text content.") - self.assertEqual("Some text content.", g.ltFunctionString()) - + + self.assertEqual('', g.ltFunctionString()) + g.setLtFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.ltFunctionString()) + def test_lt_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual(" < ", g.ltString()) - g.setLtString("Some text content.") - self.assertEqual("Some text content.", g.ltString()) - + + self.assertEqual(' < ', g.ltString()) + g.setLtString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.ltString()) + def test_max_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("double max(double x, double y)\n{\n return (x > y)?x:y;\n}\n", g.maxFunctionString()) - g.setMaxFunctionString("Some text content.") - self.assertEqual("Some text content.", g.maxFunctionString()) - + + self.assertEqual('double max(double x, double y)\n{\n return (x > y)?x:y;\n}\n', g.maxFunctionString()) + g.setMaxFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.maxFunctionString()) + def test_max_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("max", g.maxString()) - g.setMaxString("Some text content.") - self.assertEqual("Some text content.", g.maxString()) - + + self.assertEqual('max', g.maxString()) + g.setMaxString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.maxString()) + def test_min_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("double min(double x, double y)\n{\n return (x < y)?x:y;\n}\n", g.minFunctionString()) - g.setMinFunctionString("Some text content.") - self.assertEqual("Some text content.", g.minFunctionString()) - + + self.assertEqual('double min(double x, double y)\n{\n return (x < y)?x:y;\n}\n', g.minFunctionString()) + g.setMinFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.minFunctionString()) + def test_min_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("min", g.minString()) - g.setMinString("Some text content.") - self.assertEqual("Some text content.", g.minString()) - + + self.assertEqual('min', g.minString()) + g.setMinString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.minString()) + def test_minus_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("-", g.minusString()) - g.setMinusString("Some text content.") - self.assertEqual("Some text content.", g.minusString()) - + + self.assertEqual('-', g.minusString()) + g.setMinusString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.minusString()) + def test_nan_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("NAN", g.nanString()) - g.setNanString("Some text content.") - self.assertEqual("Some text content.", g.nanString()) - - def test_napierian_logarithm_string(self): + + self.assertEqual('NAN', g.nanString()) + g.setNanString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.nanString()) + + def test_natural_logarithm_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("log", g.napierianLogarithmString()) - g.setNapierianLogarithmString("Some text content.") - self.assertEqual("Some text content.", g.napierianLogarithmString()) - + + self.assertEqual('log', g.naturalLogarithmString()) + g.setNaturalLogarithmString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.naturalLogarithmString()) + def test_neq_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("", g.neqFunctionString()) - g.setNeqFunctionString("Some text content.") - self.assertEqual("Some text content.", g.neqFunctionString()) - + + self.assertEqual('', g.neqFunctionString()) + g.setNeqFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.neqFunctionString()) + def test_neq_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual(" != ", g.neqString()) - g.setNeqString("Some text content.") - self.assertEqual("Some text content.", g.neqString()) - + + self.assertEqual(' != ', g.neqString()) + g.setNeqString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.neqString()) + def test_not_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("", g.notFunctionString()) - g.setNotFunctionString("Some text content.") - self.assertEqual("Some text content.", g.notFunctionString()) - + + self.assertEqual('', g.notFunctionString()) + g.setNotFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.notFunctionString()) + def test_not_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("!", g.notString()) - g.setNotString("Some text content.") - self.assertEqual("Some text content.", g.notString()) - - def test_open_array_initializer_string(self): + + self.assertEqual('!', g.notString()) + g.setNotString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.notString()) + + def test_open_array_initialiser_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("{", g.openArrayInitializerString()) - g.setOpenArrayInitializerString("Some text content.") - self.assertEqual("Some text content.", g.openArrayInitializerString()) - + + self.assertEqual('{', g.openArrayInitialiserString()) + g.setOpenArrayInitialiserString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.openArrayInitialiserString()) + def test_open_array_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("[", g.openArrayString()) - g.setOpenArrayString("Some text content.") - self.assertEqual("Some text content.", g.openArrayString()) - + + self.assertEqual('[', g.openArrayString()) + g.setOpenArrayString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.openArrayString()) + def test_or_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("", g.orFunctionString()) - g.setOrFunctionString("Some text content.") - self.assertEqual("Some text content.", g.orFunctionString()) - + + self.assertEqual('', g.orFunctionString()) + g.setOrFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.orFunctionString()) + def test_or_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual(" || ", g.orString()) - g.setOrString("Some text content.") - self.assertEqual("Some text content.", g.orString()) - + + self.assertEqual(' || ', g.orString()) + g.setOrString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.orString()) + def test_origin_comment_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("The content of this file was generated using libCellML .", g.originCommentString()) - g.setOriginCommentString("Some text content.") - self.assertEqual("Some text content.", g.originCommentString()) - + + self.assertEqual( + 'The content of this file was generated using libCellML .', + g.originCommentString()) + g.setOriginCommentString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.originCommentString()) + def test_pi_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("3.14159265358979", g.piString()) - g.setPiString("Some text content.") - self.assertEqual("Some text content.", g.piString()) - + + self.assertEqual('3.14159265358979', g.piString()) + g.setPiString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.piString()) + def test_piecewise_else_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("", g.piecewiseElseString()) - g.setPiecewiseElseString("Some text content.") - self.assertEqual("Some text content.", g.piecewiseElseString()) - + + self.assertEqual('', g.piecewiseElseString()) + g.setPiecewiseElseString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.piecewiseElseString()) + def test_piecewise_if_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("", g.piecewiseIfString()) - g.setPiecewiseIfString("Some text content.") - self.assertEqual("Some text content.", g.piecewiseIfString()) - + + self.assertEqual('', g.piecewiseIfString()) + g.setPiecewiseIfString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.piecewiseIfString()) + def test_plus_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("+", g.plusString()) - g.setPlusString("Some text content.") - self.assertEqual("Some text content.", g.plusString()) - + + self.assertEqual('+', g.plusString()) + g.setPlusString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.plusString()) + def test_power_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("pow", g.powerString()) - g.setPowerString("Some text content.") - self.assertEqual("Some text content.", g.powerString()) - + + self.assertEqual('pow', g.powerString()) + g.setPowerString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.powerString()) + def test_rates_array_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("rates", g.ratesArrayString()) - g.setRatesArrayString("Some text content.") - self.assertEqual("Some text content.", g.ratesArrayString()) - + + self.assertEqual('rates', g.ratesArrayString()) + g.setRatesArrayString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.ratesArrayString()) + def test_rem_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("fmod", g.remString()) - g.setRemString("Some text content.") - self.assertEqual("Some text content.", g.remString()) - + + self.assertEqual('fmod', g.remString()) + g.setRemString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.remString()) + def test_sec_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("double sec(double x)\n{\n return 1.0/cos(x);\n}\n", g.secFunctionString()) - g.setSecFunctionString("Some text content.") - self.assertEqual("Some text content.", g.secFunctionString()) - + + self.assertEqual('double sec(double x)\n{\n return 1.0/cos(x);\n}\n', g.secFunctionString()) + g.setSecFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.secFunctionString()) + def test_sec_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("sec", g.secString()) - g.setSecString("Some text content.") - self.assertEqual("Some text content.", g.secString()) - + + self.assertEqual('sec', g.secString()) + g.setSecString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.secString()) + def test_sech_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("double sech(double x)\n{\n return 1.0/cosh(x);\n}\n", g.sechFunctionString()) - g.setSechFunctionString("Some text content.") - self.assertEqual("Some text content.", g.sechFunctionString()) - + + self.assertEqual('double sech(double x)\n{\n return 1.0/cosh(x);\n}\n', g.sechFunctionString()) + g.setSechFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.sechFunctionString()) + def test_sech_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("sech", g.sechString()) - g.setSechString("Some text content.") - self.assertEqual("Some text content.", g.sechString()) - + + self.assertEqual('sech', g.sechString()) + g.setSechString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.sechString()) + def test_sin_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("sin", g.sinString()) - g.setSinString("Some text content.") - self.assertEqual("Some text content.", g.sinString()) - + + self.assertEqual('sin', g.sinString()) + g.setSinString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.sinString()) + def test_sinh_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("sinh", g.sinhString()) - g.setSinhString("Some text content.") - self.assertEqual("Some text content.", g.sinhString()) - + + self.assertEqual('sinh', g.sinhString()) + g.setSinhString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.sinhString()) + def test_square_root_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("sqrt", g.squareRootString()) - g.setSquareRootString("Some text content.") - self.assertEqual("Some text content.", g.squareRootString()) - + + self.assertEqual('sqrt', g.squareRootString()) + g.setSquareRootString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.squareRootString()) + def test_square_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("", g.squareString()) - g.setSquareString("Some text content.") - self.assertEqual("Some text content.", g.squareString()) - + + self.assertEqual('', g.squareString()) + g.setSquareString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.squareString()) + def test_states_array_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("states", g.statesArrayString()) - g.setStatesArrayString("Some text content.") - self.assertEqual("Some text content.", g.statesArrayString()) - + + self.assertEqual('states', g.statesArrayString()) + g.setStatesArrayString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.statesArrayString()) + def test_string_delimiter_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("\"", g.stringDelimiterString()) - g.setStringDelimiterString("Some text content.") - self.assertEqual("Some text content.", g.stringDelimiterString()) - + + self.assertEqual('"', g.stringDelimiterString()) + g.setStringDelimiterString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.stringDelimiterString()) + def test_tan_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("tan", g.tanString()) - g.setTanString("Some text content.") - self.assertEqual("Some text content.", g.tanString()) - + + self.assertEqual('tan', g.tanString()) + g.setTanString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.tanString()) + def test_tanh_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("tanh", g.tanhString()) - g.setTanhString("Some text content.") - self.assertEqual("Some text content.", g.tanhString()) - + + self.assertEqual('tanh', g.tanhString()) + g.setTanhString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.tanhString()) + def test_times_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("*", g.timesString()) - g.setTimesString("Some text content.") - self.assertEqual("Some text content.", g.timesString()) - + + self.assertEqual('*', g.timesString()) + g.setTimesString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.timesString()) + def test_true_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("1.0", g.trueString()) - g.setTrueString("Some text content.") - self.assertEqual("Some text content.", g.trueString()) - + + self.assertEqual('1.0', g.trueString()) + g.setTrueString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.trueString()) + def test_variable_info_entry_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("{\"\", \"\", \"\"}", g.variableInfoEntryString()) - g.setVariableInfoEntryString("Some text content.") - self.assertEqual("Some text content.", g.variableInfoEntryString()) - + + self.assertEqual('{"", "", ""}', g.variableInfoEntryString()) + g.setVariableInfoEntryString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.variableInfoEntryString()) + def test_variable_info_object_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("typedef struct {\n char name[];\n char units[];\n char component[];\n} VariableInfo;\n", g.variableInfoObjectString()) - g.setVariableInfoObjectString("Some text content.") - self.assertEqual("Some text content.", g.variableInfoObjectString()) - + + self.assertEqual( + 'typedef struct {\n char name[];\n char units[];\n char component[];\n} VariableInfo;\n', + g.variableInfoObjectString()) + g.setVariableInfoObjectString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.variableInfoObjectString()) + def test_variable_info_with_type_entry_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("{\"\", \"\", \"\", }", g.variableInfoWithTypeEntryString()) - g.setVariableInfoWithTypeEntryString("Some text content.") - self.assertEqual("Some text content.", g.variableInfoWithTypeEntryString()) - + + self.assertEqual('{"", "", "", }', g.variableInfoWithTypeEntryString()) + g.setVariableInfoWithTypeEntryString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.variableInfoWithTypeEntryString()) + def test_variable_info_with_type_object_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("typedef struct {\n char name[];\n char units[];\n char component[];\n VariableType type;\n} VariableInfoWithType;\n", g.variableInfoWithTypeObjectString()) - g.setVariableInfoWithTypeObjectString("Some text content.") - self.assertEqual("Some text content.", g.variableInfoWithTypeObjectString()) - + + self.assertEqual( + 'typedef struct {\n char name[];\n char units[];\n char component[];\n VariableType type;\n} VariableInfoWithType;\n', + g.variableInfoWithTypeObjectString()) + g.setVariableInfoWithTypeObjectString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.variableInfoWithTypeObjectString()) + def test_variable_type_object_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("typedef enum {\n CONSTANT,\n COMPUTED_CONSTANT,\n ALGEBRAIC\n} VariableType;\n", g.variableTypeObjectString()) - g.setVariableTypeObjectString("Some text content.") - self.assertEqual("Some text content.", g.variableTypeObjectString()) - + + self.assertEqual('typedef enum {\n CONSTANT,\n COMPUTED_CONSTANT,\n ALGEBRAIC\n} VariableType;\n', + g.variableTypeObjectString()) + g.setVariableTypeObjectString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.variableTypeObjectString()) + def test_variables_array_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("variables", g.variablesArrayString()) - g.setVariablesArrayString("Some text content.") - self.assertEqual("Some text content.", g.variablesArrayString()) - + + self.assertEqual('variables', g.variablesArrayString()) + g.setVariablesArrayString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.variablesArrayString()) + def test_voi_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("voi", g.voiString()) - g.setVoiString("Some text content.") - self.assertEqual("Some text content.", g.voiString()) - + + self.assertEqual('voi', g.voiString()) + g.setVoiString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.voiString()) + def test_xor_function_string(self): from libcellml import GeneratorProfile - + g = GeneratorProfile() - - self.assertEqual("double xor(double x, double y)\n{\n return (x != 0.0) ^ (y != 0.0);\n}\n", g.xorFunctionString()) - g.setXorFunctionString("Some text content.") - self.assertEqual("Some text content.", g.xorFunctionString()) - + + self.assertEqual('double xor(double x, double y)\n{\n return (x != 0.0) ^ (y != 0.0);\n}\n', + g.xorFunctionString()) + g.setXorFunctionString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.xorFunctionString()) + def test_xor_string(self): from libcellml import GeneratorProfile - + + g = GeneratorProfile() + + self.assertEqual('xor', g.xorString()) + g.setXorString(GeneratorProfileTestCase.VALUE) + self.assertEqual(GeneratorProfileTestCase.VALUE, g.xorString()) + + def test_has_interface(self): + from libcellml import GeneratorProfile + g = GeneratorProfile() - - self.assertEqual("xor", g.xorString()) - g.setXorString("Some text content.") - self.assertEqual("Some text content.", g.xorString()) - + + self.assertTrue(g.hasInterface()) + g.setHasInterface(False) + self.assertFalse(g.hasInterface()) + + if __name__ == '__main__': unittest.main() diff --git a/tests/bindings/python/test_import_source.py b/tests/bindings/python/test_import_source.py index 1a52aff544..8574ca14ca 100644 --- a/tests/bindings/python/test_import_source.py +++ b/tests/bindings/python/test_import_source.py @@ -10,7 +10,7 @@ def test_create(self): from libcellml import ImportSource x = ImportSource() - del(x) + del x def test_inheritance(self): import libcellml @@ -65,7 +65,6 @@ def test_clone(self): xCloned = x.clone() self.assertEqual(xCloned.url(), sourceUrl) - def test_component(self): from libcellml import ImportSource, Component @@ -89,7 +88,6 @@ def test_component(self): self.assertEqual(0, x.componentCount()) - def test_units(self): from libcellml import ImportSource, Units @@ -114,6 +112,5 @@ def test_units(self): self.assertEqual(0, x.unitsCount()) - if __name__ == '__main__': unittest.main() diff --git a/tests/bindings/python/test_importer.py b/tests/bindings/python/test_importer.py index 75e58ade2f..a721e2e70a 100644 --- a/tests/bindings/python/test_importer.py +++ b/tests/bindings/python/test_importer.py @@ -68,7 +68,6 @@ def test_importer(self): self.assertEqual(file_contents("importer/diamond_left.cellml"), printer.printModel(left)) - def test_add_model(self): from libcellml import Component, Importer, Model, Parser diff --git a/tests/bindings/python/test_issue.py b/tests/bindings/python/test_issue.py index 963b825e11..ccedcd44c9 100644 --- a/tests/bindings/python/test_issue.py +++ b/tests/bindings/python/test_issue.py @@ -16,31 +16,31 @@ def test_create_destroy(self): from libcellml import Variable e1 = Issue() - del(e1) + del e1 c = Component() e2 = Issue(c) - del(e2) + del e2 i = ImportSource() e3 = Issue(i) - del(e3) + del e3 m = Model() e4 = Issue(m) - del(e4) + del e4 r = Reset() e5 = Issue(r) - del(e5) + del e5 u = Units() e6 = Issue(u) - del(e6) + del e6 v = Variable() e7 = Issue(v) - del(e7) + del e7 def test_cause_enum(self): from libcellml import Issue @@ -159,7 +159,7 @@ def test_reference_rule_enum(self): Issue.ReferenceRule.UNDEFINED - 1) self.assertRaises(RuntimeError, e.setReferenceRule, Issue.ReferenceRule.MAP_VARIABLES_IDENTICAL_UNIT_REDUCTION + 1) - del(e) + del e def test_set_description(self): from libcellml import Issue @@ -178,7 +178,7 @@ def test_description(self): self.assertEqual(e.description(), '') e.setDescription(d) self.assertEqual(e.description(), d) - del(d, e) + del [d, e] def test_set_cause(self): from libcellml import Issue diff --git a/tests/bindings/python/test_model.py b/tests/bindings/python/test_model.py index da2110286d..fd903f0a5f 100644 --- a/tests/bindings/python/test_model.py +++ b/tests/bindings/python/test_model.py @@ -11,7 +11,7 @@ def test_create_destroy(self): from libcellml import Model x = Model() - del(x) + del x y = Model('bob') self.assertEqual('bob', y.name()) @@ -57,7 +57,7 @@ def test_remove_units(self): self.assertFalse(m.removeUnits(-1)) self.assertTrue(m.removeUnits(0)) self.assertFalse(m.removeUnits(0)) - del(m, u) + del [m, u] # bool removeUnits(const std::string &name) name = 'bert' @@ -68,7 +68,7 @@ def test_remove_units(self): m.addUnits(u) self.assertFalse(m.removeUnits('ernie')) self.assertTrue(m.removeUnits(name)) - del(m, u, name) + del [m, u, name] # bool removeUnits(const UnitsPtr &units) m = Model() @@ -78,7 +78,7 @@ def test_remove_units(self): m.addUnits(u1) self.assertFalse(m.removeUnits(u2)) self.assertFalse(m.removeUnits(u1)) - del(m, u1, u2) + del [m, u1, u2] def test_remove_all_units(self): from libcellml import Model, Units @@ -92,7 +92,7 @@ def test_remove_all_units(self): m.removeAllUnits() self.assertFalse(m.removeUnits(u1)) self.assertFalse(m.removeUnits(u2)) - del(m, u1, u2) + del [m, u1, u2] def test_has_units(self): from libcellml import Model, Units @@ -127,7 +127,7 @@ def test_units(self): self.assertIsNone(m.units(-1)) self.assertIsNotNone(m.units(0)) self.assertEqual(m.units(0).name(), name) - del(m, u, name) + del [m, u, name] # UnitsPtr units(const std::string &name) name = 'kermit' @@ -138,7 +138,7 @@ def test_units(self): m.addUnits(u) self.assertIsNotNone(m.units(name)) self.assertEqual(m.units(name).name(), name) - del(m, u, name) + del [m, u, name] def test_take_units(self): from libcellml import Model, Units @@ -159,7 +159,7 @@ def test_take_units(self): m.addUnits(Units()) m.addUnits(u) self.assertEqual(m.takeUnits(1).name(), name) - del(m, u) + del [m, u] # UnitsPtr takeUnits(const std::string &name) name = 'aloha' @@ -170,7 +170,7 @@ def test_take_units(self): m.addUnits(u) self.assertEqual(m.takeUnits(name).name(), name) self.assertIsNone(m.takeUnits(name)) - del(m, u, name) + del [m, u, name] def test_replace_units(self): from libcellml import Model, Units @@ -186,7 +186,7 @@ def test_replace_units(self): self.assertFalse(m.replaceUnits(1, u1)) self.assertFalse(m.replaceUnits(-1, u1)) self.assertEqual(m.units(0).name(), 'b') - del(m, u1, u2) + del [m, u1, u2] # bool replaceUnits(const std::string &name, const UnitsPtr &units) m = Model() @@ -199,7 +199,7 @@ def test_replace_units(self): self.assertTrue(m.replaceUnits('a', b)) self.assertTrue(m.replaceUnits('b', a)) self.assertFalse(m.replaceUnits('b', a)) - del(m, a, b) + del [m, a, b] # bool replaceUnits(const UnitsPtr &oldUnits, const UnitsPtr &newUnits) m = Model() @@ -209,7 +209,7 @@ def test_replace_units(self): self.assertFalse(m.replaceUnits(b, a)) self.assertFalse(m.replaceUnits(a, b)) self.assertFalse(m.replaceUnits(b, a)) - del(m, a, b) + del [m, a, b] def test_units_count(self): from libcellml import Model, Units @@ -223,7 +223,7 @@ def test_units_count(self): self.assertEqual(m.unitsCount(), 2) m.removeAllUnits() self.assertEqual(m.unitsCount(), 0) - del(m) + del m def test_has_unresolved_imports(self): from libcellml import Model, Component, ImportSource @@ -304,7 +304,6 @@ def test_clone(self): self.assertEqual(1, mCloned.component(0).variableCount()) self.assertEqual("apple", mCloned.component(0).variable(0).units().name()) - def test_link_units(self): from libcellml import Component, Model, Units, Variable @@ -348,7 +347,6 @@ def test_variable_interfaces(self): self.assertEqual("public", v1.interfaceType()) self.assertEqual("public", v2.interfaceType()) - def test_imports(self): from libcellml import Model, ImportSource, Units @@ -382,7 +380,5 @@ def test_imports(self): self.assertEqual(0, m.importSourceCount()) - - if __name__ == '__main__': unittest.main() diff --git a/tests/bindings/python/test_parser.py b/tests/bindings/python/test_parser.py index 8b521b70ea..0d5d6cc8ca 100644 --- a/tests/bindings/python/test_parser.py +++ b/tests/bindings/python/test_parser.py @@ -10,7 +10,7 @@ def test_create_destroy(self): from libcellml import Parser x = Parser() - del(x) + del x def test_inheritance(self): import libcellml diff --git a/tests/bindings/python/test_printer.py b/tests/bindings/python/test_printer.py index 14226ecd48..1ea81de5cf 100644 --- a/tests/bindings/python/test_printer.py +++ b/tests/bindings/python/test_printer.py @@ -10,7 +10,7 @@ def test_create_destroy(self): from libcellml import Printer x = Printer() - del(x) + del x def test_print_model(self): from libcellml import Printer, Model diff --git a/tests/bindings/python/test_reset.py b/tests/bindings/python/test_reset.py index fa1b8ab213..58477adcce 100644 --- a/tests/bindings/python/test_reset.py +++ b/tests/bindings/python/test_reset.py @@ -10,7 +10,7 @@ def test_create_destroy(self): from libcellml import Reset x = Reset() - del(x) + del x def test_set_get_variable(self): from libcellml import Reset @@ -128,4 +128,3 @@ def test_clone(self): if __name__ == '__main__': unittest.main() - diff --git a/tests/bindings/python/test_resources.in.py b/tests/bindings/python/test_resources.in.py index 6836f33aa7..829a83de84 100644 --- a/tests/bindings/python/test_resources.in.py +++ b/tests/bindings/python/test_resources.in.py @@ -1,16 +1,13 @@ - import os TESTS_RESOURCE_LOCATION = "${TESTS_RESOURCE_LOCATION}" def resource_path(relative_path=''): - return TESTS_RESOURCE_LOCATION + '/' + relative_path def file_contents(file_name): - with open(os.path.join(TESTS_RESOURCE_LOCATION, file_name)) as f: content = f.read() diff --git a/tests/bindings/python/test_units.py b/tests/bindings/python/test_units.py index 05347f30c6..4440964bb3 100644 --- a/tests/bindings/python/test_units.py +++ b/tests/bindings/python/test_units.py @@ -10,7 +10,7 @@ def test_create_destroy(self): from libcellml import Units x = Units() - del(x) + del x y = Units("mine") self.assertEqual("mine", y.name()) @@ -98,7 +98,7 @@ def test_add_unit(self): u.addUnit('a', 'b', 0) u.addUnit('a', 'b', 3, 3) u.addUnit('a', 'b', 0.1, -1.2) - del(u) + del u # void addUnit(const std::string &reference, int prefix, # double exponent, double multiplier=1.0) @@ -114,20 +114,20 @@ def test_add_unit(self): u.addUnit('a', -1, -1, 3) u.addUnit('a', -1, -1, 2.3) u.addUnit('a', -1, 1.2, 3.4) - del(u) + del u # void addUnit(const std::string &reference, double exponent) u = Units() u.addUnit('a', 1.0) # TODO Ints get converted to Prefix enum, not to double! # u.addUnit('a', -1) - del(u) + del u # void addUnit(const std::string &reference) u = Units() u.addUnit('') u.addUnit('a') - del(u) + del u # void addUnit(StandardUnit standardRef, const std::string &prefix, # double exponent=1.0, double multiplier=1.0) @@ -138,7 +138,7 @@ def test_add_unit(self): u.addUnit(Units.StandardUnit.KATAL, 'pico', 1.0, 2.0) u.addUnit(Units.StandardUnit.KATAL, 'pico', 1, 2.0) u.addUnit(Units.StandardUnit.KATAL, 'pico', -1, 2) - del(u) + del u # void addUnit(StandardUnit standardRef, int prefix, # double exponent, double multiplier=1.0) @@ -147,7 +147,7 @@ def test_add_unit(self): u.addUnit(Units.StandardUnit.KATAL, -1, -1.0) u.addUnit(Units.StandardUnit.KATAL, 1, 1.0, 1.0) u.addUnit(Units.StandardUnit.KATAL, -1, -1.0, 1.0, 'id') - del(u) + del u # void addUnit(StandardUnit standardRef, double exponent) # Hidden to avoid confusion with addUnit(StandardUnit, Prefix, double, @@ -156,7 +156,7 @@ def test_add_unit(self): # void addUnit(StandardUnit standardRef) u = Units() u.addUnit(Units.StandardUnit.KATAL) - del(u) + del u def test_unit_attributes(self): from libcellml import Units @@ -174,7 +174,7 @@ def test_unit_attributes(self): x = u.unitAttributes(1) self.assertIsInstance(x, list) self.assertEqual(x, ['', '', 1.0, 1.0, '']) - del(u, x) + del [u, x] # void unitAttributes(const std::string &reference, # std::string &prefix, double &exponent, double &multiplier) const; @@ -189,7 +189,7 @@ def test_unit_attributes(self): x = u.unitAttributes('few') self.assertIsInstance(x, list) self.assertEqual(x, ['few', 'bars', 4.3, 2.1, 'job']) - del(u, x) + del [u, x] # This method conflicts with unitAttributes(size_t, ...) # void unitAttributes(StandardUnit standardRef, std::string &prefix, @@ -208,7 +208,7 @@ def test_remove_unit(self): self.assertFalse(u.removeUnit(-1)) self.assertTrue(u.removeUnit(0)) self.assertFalse(u.removeUnit(0)) - del(u) + del [u] # bool removeUnit(const std::string &reference) u = Units() @@ -217,7 +217,7 @@ def test_remove_unit(self): self.assertFalse(u.removeUnit('hi')) self.assertTrue(u.removeUnit('hello')) self.assertFalse(u.removeUnit('hello')) - del(u) + del [u] # This method conflicts with removeUnit(size_t) # bool removeUnit(StandardUnit standardRef) diff --git a/tests/bindings/python/test_validator.py b/tests/bindings/python/test_validator.py index b808c1feed..3e91f12d09 100644 --- a/tests/bindings/python/test_validator.py +++ b/tests/bindings/python/test_validator.py @@ -10,7 +10,7 @@ def test_create_destroy(self): from libcellml import Validator x = Validator() - del(x) + del x def test_inheritance(self): import libcellml diff --git a/tests/bindings/python/test_variable.py b/tests/bindings/python/test_variable.py index 724882c510..a68af2916a 100644 --- a/tests/bindings/python/test_variable.py +++ b/tests/bindings/python/test_variable.py @@ -10,7 +10,7 @@ def test_create_destroy(self): from libcellml import Variable x = Variable() - del(x) + del x y = Variable("nice") self.assertEqual("nice", y.name()) @@ -33,7 +33,8 @@ def test_inheritance(self): def test_id(self): from libcellml import Variable - from libcellml.variable import Variable_setEquivalenceMappingId, Variable_setEquivalenceConnectionId, Variable_equivalenceMappingId, Variable_equivalenceConnectionId + from libcellml.variable import Variable_setEquivalenceMappingId, Variable_setEquivalenceConnectionId, \ + Variable_equivalenceMappingId, Variable_equivalenceConnectionId from libcellml.variable import Variable_removeEquivalenceMappingId, Variable_removeEquivalenceConnectionId v1 = Variable("v1") @@ -224,7 +225,7 @@ def test_set_units(self): v.setUnits('') v.setUnits('Hello') v.setUnits('') - del(v) + del v # void setUnits(const UnitsPtr &units) name = 'tiger' @@ -288,11 +289,11 @@ def test_interface_type(self): self.assertNotEqual( Variable.InterfaceType.NONE, Variable.InterfaceType.PRIVATE, - ) + ) self.assertNotEqual( Variable.InterfaceType.PUBLIC, Variable.InterfaceType.PUBLIC_AND_PRIVATE, - ) + ) def test_set_interface_type(self): from libcellml import Variable @@ -316,12 +317,12 @@ def test_set_interface_type(self): self.assertRaises( RuntimeError, v.setInterfaceType, Variable.InterfaceType.PUBLIC_AND_PRIVATE + 1) - del(v) + del v # void setInterfaceType(const std::string &interfaceType) v = Variable() v.setInterfaceType('not an interface type') - del(v) + del v def test_interface_type(self): from libcellml import Variable @@ -403,7 +404,5 @@ def test_clone(self): self.assertEqual("kg_per_ml", vCloned.units().name()) - - if __name__ == '__main__': unittest.main() diff --git a/tests/clone/clone.cpp b/tests/clone/clone.cpp index eb2d78de8a..a0c60b1ad4 100644 --- a/tests/clone/clone.cpp +++ b/tests/clone/clone.cpp @@ -491,13 +491,18 @@ TEST(Clone, generateFromClonedModel) EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); - auto clonedModel = model->clone(); compareModel(model, clonedModel); - generator->processModel(clonedModel); + libcellml::AnalyserPtr analyser = libcellml::Analyser::create(); + + analyser->analyseModel(clonedModel); + + libcellml::GeneratorPtr generator = libcellml::Generator::create(); + + generator->setModel(analyser->model()); + EXPECT_EQ(fileContents("generator/hodgkin_huxley_squid_axon_model_1952/model.c"), generator->implementationCode()); libcellml::PrinterPtr p = libcellml::Printer::create(); diff --git a/tests/generator/generator.cpp b/tests/generator/generator.cpp index 79b2946cc1..aef7c96d5a 100644 --- a/tests/generator/generator.cpp +++ b/tests/generator/generator.cpp @@ -24,437 +24,58 @@ static const std::string EMPTY_STRING; TEST(Generator, emptyModel) { - libcellml::ModelPtr model = libcellml::Model::create(); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + libcellml::ModelPtr model = libcellml::Model::create("empty_model"); + libcellml::AnalyserPtr analyser = libcellml::Analyser::create(); - generator->processModel(model); + analyser->analyseModel(model); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(size_t(0), analyser->errorCount()); - EXPECT_EQ(libcellml::Generator::ModelType::UNKNOWN, generator->modelType()); + auto analyserModel = analyser->model(); + auto generator = libcellml::Generator::create(); - EXPECT_EQ(size_t(0), generator->stateCount()); - EXPECT_EQ(size_t(0), generator->variableCount()); - - EXPECT_EQ(nullptr, generator->voi()); - EXPECT_EQ(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->variable(0)); - - EXPECT_EQ(EMPTY_STRING, generator->interfaceCode()); - EXPECT_EQ(EMPTY_STRING, generator->implementationCode()); -} - -TEST(Generator, initializedVariableOfIntegration) -{ - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/initialized_variable_of_integration.cellml")); - - EXPECT_EQ(size_t(0), parser->issueCount()); - - const std::vector expectedIssues = { - "Variable 'time' in component 'my_component' of model 'initialized_variable_of_integration' cannot be both a variable of integration and initialised.", - }; - const std::vector expectedCauses = { - libcellml::Issue::Cause::GENERATOR, - }; - - libcellml::GeneratorPtr generator = libcellml::Generator::create(); - - generator->processModel(model); - - EXPECT_EQ_ISSUES_CAUSES(expectedIssues, expectedCauses, generator); - - EXPECT_EQ(libcellml::Generator::ModelType::INVALID, generator->modelType()); - - EXPECT_EQ(size_t(0), generator->stateCount()); - EXPECT_EQ(size_t(0), generator->variableCount()); - - EXPECT_EQ(nullptr, generator->voi()); - EXPECT_EQ(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->variable(0)); - - EXPECT_EQ(EMPTY_STRING, generator->interfaceCode()); - EXPECT_EQ(EMPTY_STRING, generator->implementationCode()); -} - -TEST(Generator, initializedVariableOfIntegrationInNonFirstComponent) -{ - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/initialized_variable_of_integration_in_non_first_component.cellml")); - - EXPECT_EQ(size_t(0), parser->issueCount()); - - const std::vector expectedIssues = { - "Variable 'time' in component 'environment' of model 'initialized_variable_of_integration_in_non_first_component' cannot be both a variable of integration and initialised.", - }; - const std::vector expectedCauses = { - libcellml::Issue::Cause::GENERATOR, - }; - - libcellml::GeneratorPtr generator = libcellml::Generator::create(); - - generator->processModel(model); - - EXPECT_EQ_ISSUES_CAUSES(expectedIssues, expectedCauses, generator); - - EXPECT_EQ(libcellml::Generator::ModelType::INVALID, generator->modelType()); - - EXPECT_EQ(size_t(0), generator->stateCount()); - EXPECT_EQ(size_t(0), generator->variableCount()); - - EXPECT_EQ(nullptr, generator->voi()); - EXPECT_EQ(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->variable(0)); - - EXPECT_EQ(EMPTY_STRING, generator->interfaceCode()); - EXPECT_EQ(EMPTY_STRING, generator->implementationCode()); -} - -TEST(Generator, twoVariablesOfIntegration) -{ - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/two_variables_of_integration.cellml")); - - EXPECT_EQ(size_t(0), parser->issueCount()); - - const std::vector expectedIssues = { - "Variable 'time' in component 'main' of model 'two_variables_of_integration' and variable 'other_time' in component 'sub_sub_sub' of model 'two_variables_of_integration' cannot both be the variable of integration.", - }; - const std::vector expectedCauses = { - libcellml::Issue::Cause::GENERATOR, - }; - - libcellml::GeneratorPtr generator = libcellml::Generator::create(); - - generator->processModel(model); - - EXPECT_EQ_ISSUES_CAUSES(expectedIssues, expectedCauses, generator); - - EXPECT_EQ(libcellml::Generator::ModelType::INVALID, generator->modelType()); - - EXPECT_EQ(size_t(0), generator->stateCount()); - EXPECT_EQ(size_t(0), generator->variableCount()); - - EXPECT_EQ(nullptr, generator->voi()); - EXPECT_EQ(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->variable(0)); - - EXPECT_EQ(EMPTY_STRING, generator->interfaceCode()); - EXPECT_EQ(EMPTY_STRING, generator->implementationCode()); -} - -TEST(Generator, nonFirstOrderOdes) -{ - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/non_first_order_odes.cellml")); - - EXPECT_EQ(size_t(0), parser->issueCount()); - - const std::vector expectedIssues = { - "The differential equation for variable 'x' in component 'main' of model 'non_first_order_odes' must be of the first order.", - "The differential equation for variable 'y' in component 'sub' of model 'non_first_order_odes' must be of the first order.", - "The differential equation for variable 'z' in component 'sub_sub' of model 'non_first_order_odes' must be of the first order.", - }; - const std::vector expectedCauses = { - libcellml::Issue::Cause::GENERATOR, - libcellml::Issue::Cause::GENERATOR, - libcellml::Issue::Cause::GENERATOR, - }; - - libcellml::GeneratorPtr generator = libcellml::Generator::create(); - - generator->processModel(model); - - EXPECT_EQ_ISSUES_CAUSES(expectedIssues, expectedCauses, generator); - - EXPECT_EQ(libcellml::Generator::ModelType::INVALID, generator->modelType()); - - EXPECT_EQ(size_t(0), generator->stateCount()); - EXPECT_EQ(size_t(0), generator->variableCount()); - - EXPECT_EQ(nullptr, generator->voi()); - EXPECT_EQ(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->variable(0)); - - EXPECT_EQ(EMPTY_STRING, generator->interfaceCode()); - EXPECT_EQ(EMPTY_STRING, generator->implementationCode()); -} - -TEST(Generator, undefinedVariables) -{ - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/undefined_variables.cellml")); - - EXPECT_EQ(size_t(0), parser->issueCount()); - - const std::vector expectedIssues = { - "Variable 'a' in component 'my_component' of model 'undefined_variables' is referenced in an equation, but it is not defined anywhere.", - "Variable 'b' in component 'my_component' of model 'undefined_variables' is referenced in an equation, but it is not defined anywhere.", - }; - - libcellml::GeneratorPtr generator = libcellml::Generator::create(); - - generator->processModel(model); - - EXPECT_EQ_ISSUES(expectedIssues, generator); - - EXPECT_EQ(libcellml::Generator::ModelType::INVALID, generator->modelType()); - - EXPECT_EQ(size_t(0), generator->stateCount()); - EXPECT_EQ(size_t(0), generator->variableCount()); - - EXPECT_EQ(nullptr, generator->voi()); - EXPECT_EQ(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->variable(0)); - - EXPECT_EQ(EMPTY_STRING, generator->interfaceCode()); - EXPECT_EQ(EMPTY_STRING, generator->implementationCode()); -} - -TEST(Generator, variableInitializedTwice) -{ - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/variable_initialized_twice.cellml")); - - EXPECT_EQ(size_t(0), parser->issueCount()); - - const std::vector expectedIssues = { - "Variable 'x' in component 'sub' of model 'variable_initialized_twice' and variable 'x' in component 'main' of model 'variable_initialized_twice' are equivalent and cannot therefore both be initialised.", - }; - - libcellml::GeneratorPtr generator = libcellml::Generator::create(); - - generator->processModel(model); - - EXPECT_EQ_ISSUES(expectedIssues, generator); - - EXPECT_EQ(libcellml::Generator::ModelType::INVALID, generator->modelType()); - - EXPECT_EQ(size_t(0), generator->stateCount()); - EXPECT_EQ(size_t(0), generator->variableCount()); - - EXPECT_EQ(nullptr, generator->voi()); - EXPECT_EQ(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->variable(0)); - - EXPECT_EQ(EMPTY_STRING, generator->interfaceCode()); - EXPECT_EQ(EMPTY_STRING, generator->implementationCode()); -} - -TEST(Generator, nonConstantInitialisingVariable) -{ - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/non_constant_initialising_variable.cellml")); - - EXPECT_EQ(size_t(0), parser->issueCount()); - - const std::vector expectedIssues = { - "Variable 'x' in component 'main' of model 'my_model' is initialised using variable 'k2', but it is not a constant.", - }; - const std::vector expectedCauses = { - libcellml::Issue::Cause::GENERATOR, - }; - - libcellml::GeneratorPtr generator = libcellml::Generator::create(); - - generator->processModel(model); - - EXPECT_EQ_ISSUES_CAUSES(expectedIssues, expectedCauses, generator); - - EXPECT_EQ(libcellml::Generator::ModelType::INVALID, generator->modelType()); - - EXPECT_EQ(size_t(0), generator->stateCount()); - EXPECT_EQ(size_t(0), generator->variableCount()); - - EXPECT_EQ(nullptr, generator->voi()); - EXPECT_EQ(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->variable(0)); - - EXPECT_EQ(EMPTY_STRING, generator->interfaceCode()); - EXPECT_EQ(EMPTY_STRING, generator->implementationCode()); -} - -TEST(Generator, nonExistingInitialisingVariable) -{ - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/non_existing_initialising_variable.cellml")); - - EXPECT_EQ(size_t(0), parser->issueCount()); - - const std::vector expectedIssues = { - "Variable 'x' in component 'main' of model 'my_model' is initialised using variable 'k', but it is not defined anywhere.", - }; - const std::vector expectedCauses = { - libcellml::Issue::Cause::GENERATOR, - }; - - libcellml::GeneratorPtr generator = libcellml::Generator::create(); - - generator->processModel(model); - - EXPECT_EQ_ISSUES_CAUSES(expectedIssues, expectedCauses, generator); - - EXPECT_EQ(libcellml::Generator::ModelType::INVALID, generator->modelType()); - - EXPECT_EQ(size_t(0), generator->stateCount()); - EXPECT_EQ(size_t(0), generator->variableCount()); - - EXPECT_EQ(nullptr, generator->voi()); - EXPECT_EQ(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->variable(0)); - - EXPECT_EQ(EMPTY_STRING, generator->interfaceCode()); - EXPECT_EQ(EMPTY_STRING, generator->implementationCode()); -} - -TEST(Generator, nonInitializedState) -{ - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/non_initialized_state.cellml")); - - EXPECT_EQ(size_t(0), parser->issueCount()); - - const std::vector expectedIssues = { - "Variable 'x' in component 'my_component' of model 'non_initialized_state' is used in an ODE, but it is not initialised.", - }; - - libcellml::GeneratorPtr generator = libcellml::Generator::create(); - - generator->processModel(model); - - EXPECT_EQ_ISSUES(expectedIssues, generator); - - EXPECT_EQ(libcellml::Generator::ModelType::UNDERCONSTRAINED, generator->modelType()); - - EXPECT_EQ(size_t(0), generator->stateCount()); - EXPECT_EQ(size_t(0), generator->variableCount()); - - EXPECT_EQ(nullptr, generator->voi()); - EXPECT_EQ(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->variable(0)); - - EXPECT_EQ(EMPTY_STRING, generator->interfaceCode()); - EXPECT_EQ(EMPTY_STRING, generator->implementationCode()); -} - -TEST(Generator, underconstrained) -{ - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/underconstrained.cellml")); - - EXPECT_EQ(size_t(0), parser->issueCount()); - - const std::vector expectedIssues = { - "Variable 'x' in component 'my_component' of model 'my_model' is not computed.", - }; - - libcellml::GeneratorPtr generator = libcellml::Generator::create(); - - generator->processModel(model); - - EXPECT_EQ_ISSUES(expectedIssues, generator); - - EXPECT_EQ(libcellml::Generator::ModelType::UNDERCONSTRAINED, generator->modelType()); - - EXPECT_EQ(size_t(0), generator->stateCount()); - EXPECT_EQ(size_t(0), generator->variableCount()); - - EXPECT_EQ(nullptr, generator->voi()); - EXPECT_EQ(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->variable(0)); + generator->setModel(analyserModel); EXPECT_EQ(EMPTY_STRING, generator->interfaceCode()); EXPECT_EQ(EMPTY_STRING, generator->implementationCode()); } -TEST(Generator, overconstrained) -{ - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/overconstrained.cellml")); - - EXPECT_EQ(size_t(0), parser->issueCount()); - - const std::vector expectedIssues = { - "Variable 'x' in component 'my_component' of model 'my_model' is computed more than once.", - }; - - libcellml::GeneratorPtr generator = libcellml::Generator::create(); - - generator->processModel(model); - - EXPECT_EQ_ISSUES(expectedIssues, generator); - - EXPECT_EQ(libcellml::Generator::ModelType::OVERCONSTRAINED, generator->modelType()); - - EXPECT_EQ(size_t(0), generator->stateCount()); - EXPECT_EQ(size_t(0), generator->variableCount()); - - EXPECT_EQ(nullptr, generator->voi()); - EXPECT_EQ(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->variable(0)); - - EXPECT_EQ(EMPTY_STRING, generator->interfaceCode()); - EXPECT_EQ(EMPTY_STRING, generator->implementationCode()); -} - -TEST(Generator, unsuitablyConstrained) +TEST(Generator, algebraicEqnComputedVarOnRhs) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/unsuitably_constrained.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/algebraic_eqn_computed_var_on_rhs/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - const std::vector expectedIssues = { - "Variable 'x' in component 'my_component' of model 'my_model' is not computed.", - "Variable 'y' in component 'my_component' of model 'my_model' is computed more than once.", - }; + auto analyser = libcellml::Analyser::create(); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + analyser->analyseModel(model); - generator->processModel(model); + EXPECT_EQ(size_t(0), analyser->errorCount()); - EXPECT_EQ_ISSUES(expectedIssues, generator); + auto analyserModel = analyser->model(); - EXPECT_EQ(libcellml::Generator::ModelType::UNSUITABLY_CONSTRAINED, generator->modelType()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ALGEBRAIC, analyserModel->type()); - EXPECT_EQ(size_t(0), generator->stateCount()); - EXPECT_EQ(size_t(0), generator->variableCount()); + EXPECT_EQ(size_t(0), analyserModel->stateCount()); + EXPECT_EQ(size_t(2), analyserModel->variableCount()); + EXPECT_EQ(size_t(2), analyserModel->equationCount()); - EXPECT_EQ(nullptr, generator->voi()); - EXPECT_EQ(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->variable(0)); + EXPECT_EQ(nullptr, analyserModel->voi()); + EXPECT_EQ(nullptr, analyserModel->state(0)); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); - EXPECT_EQ(EMPTY_STRING, generator->interfaceCode()); - EXPECT_EQ(EMPTY_STRING, generator->implementationCode()); -} + auto generator = libcellml::Generator::create(); -TEST(Generator, algebraicEqnComputedVarOnRhs) -{ - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/algebraic_eqn_computed_var_on_rhs/model.cellml")); - - EXPECT_EQ(size_t(0), parser->issueCount()); - - libcellml::GeneratorPtr generator = libcellml::Generator::create(); - - generator->processModel(model); - - EXPECT_EQ(size_t(0), generator->issueCount()); - - EXPECT_EQ(libcellml::Generator::ModelType::ALGEBRAIC, generator->modelType()); - - EXPECT_EQ(size_t(0), generator->stateCount()); - EXPECT_EQ(size_t(2), generator->variableCount()); - - EXPECT_EQ(nullptr, generator->voi()); - EXPECT_EQ(nullptr, generator->state(0)); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/algebraic_eqn_computed_var_on_rhs/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/algebraic_eqn_computed_var_on_rhs/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -464,31 +85,40 @@ TEST(Generator, algebraicEqnComputedVarOnRhs) TEST(Generator, algebraicEqnConstVarOnRhs) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/algebraic_eqn_const_var_on_rhs/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/algebraic_eqn_const_var_on_rhs/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->errorCount()); - generator->processModel(model); + auto analyserModel = analyser->model(); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ALGEBRAIC, analyserModel->type()); - EXPECT_EQ(libcellml::Generator::ModelType::ALGEBRAIC, generator->modelType()); + EXPECT_EQ(size_t(0), analyserModel->stateCount()); + EXPECT_EQ(size_t(2), analyserModel->variableCount()); + EXPECT_EQ(size_t(1), analyserModel->equationCount()); - EXPECT_EQ(size_t(0), generator->stateCount()); - EXPECT_EQ(size_t(2), generator->variableCount()); + EXPECT_EQ(nullptr, analyserModel->voi()); + EXPECT_EQ(nullptr, analyserModel->state(0)); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); - EXPECT_EQ(nullptr, generator->voi()); - EXPECT_EQ(nullptr, generator->state(0)); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/algebraic_eqn_const_var_on_rhs/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/algebraic_eqn_const_var_on_rhs/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -498,31 +128,40 @@ TEST(Generator, algebraicEqnConstVarOnRhs) TEST(Generator, algebraicEqnConstantOnRhs) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/algebraic_eqn_constant_on_rhs/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/algebraic_eqn_constant_on_rhs/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->errorCount()); + + auto analyserModel = analyser->model(); - generator->processModel(model); + EXPECT_EQ(libcellml::AnalyserModel::Type::ALGEBRAIC, analyserModel->type()); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(size_t(0), analyserModel->stateCount()); + EXPECT_EQ(size_t(1), analyserModel->variableCount()); + EXPECT_EQ(size_t(1), analyserModel->equationCount()); - EXPECT_EQ(libcellml::Generator::ModelType::ALGEBRAIC, generator->modelType()); + EXPECT_EQ(nullptr, analyserModel->voi()); + EXPECT_EQ(nullptr, analyserModel->state(0)); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); - EXPECT_EQ(size_t(0), generator->stateCount()); - EXPECT_EQ(size_t(1), generator->variableCount()); + auto generator = libcellml::Generator::create(); - EXPECT_EQ(nullptr, generator->voi()); - EXPECT_EQ(nullptr, generator->state(0)); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/algebraic_eqn_constant_on_rhs/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/algebraic_eqn_constant_on_rhs/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -532,32 +171,41 @@ TEST(Generator, algebraicEqnConstantOnRhs) TEST(Generator, algebraicEqnDerivativeOnRhs) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/algebraic_eqn_derivative_on_rhs/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/algebraic_eqn_derivative_on_rhs/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); - generator->processModel(model); + analyser->analyseModel(model); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(size_t(0), analyser->errorCount()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + auto analyserModel = analyser->model(); - EXPECT_EQ(size_t(1), generator->stateCount()); - EXPECT_EQ(size_t(2), generator->variableCount()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + EXPECT_EQ(size_t(1), analyserModel->stateCount()); + EXPECT_EQ(size_t(2), analyserModel->variableCount()); + EXPECT_EQ(size_t(3), analyserModel->equationCount()); + + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); + + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/algebraic_eqn_derivative_on_rhs/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/algebraic_eqn_derivative_on_rhs/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -567,32 +215,41 @@ TEST(Generator, algebraicEqnDerivativeOnRhs) TEST(Generator, algebraicEqnDerivativeOnRhsOneComponent) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/algebraic_eqn_derivative_on_rhs_one_component/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/algebraic_eqn_derivative_on_rhs_one_component/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); - generator->processModel(model); + EXPECT_EQ(size_t(0), analyser->errorCount()); - EXPECT_EQ(size_t(0), generator->issueCount()); + auto analyserModel = analyser->model(); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_EQ(size_t(1), generator->stateCount()); - EXPECT_EQ(size_t(2), generator->variableCount()); + EXPECT_EQ(size_t(1), analyserModel->stateCount()); + EXPECT_EQ(size_t(2), analyserModel->variableCount()); + EXPECT_EQ(size_t(3), analyserModel->equationCount()); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); + + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/algebraic_eqn_derivative_on_rhs_one_component/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/algebraic_eqn_derivative_on_rhs_one_component/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -602,32 +259,41 @@ TEST(Generator, algebraicEqnDerivativeOnRhsOneComponent) TEST(Generator, algebraicEqnStateVarOnRhs) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/algebraic_eqn_state_var_on_rhs/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/algebraic_eqn_state_var_on_rhs/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->errorCount()); + + auto analyserModel = analyser->model(); - generator->processModel(model); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(size_t(1), analyserModel->stateCount()); + EXPECT_EQ(size_t(2), analyserModel->variableCount()); + EXPECT_EQ(size_t(3), analyserModel->equationCount()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); - EXPECT_EQ(size_t(1), generator->stateCount()); - EXPECT_EQ(size_t(2), generator->variableCount()); + auto generator = libcellml::Generator::create(); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/algebraic_eqn_state_var_on_rhs/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/algebraic_eqn_state_var_on_rhs/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -637,32 +303,41 @@ TEST(Generator, algebraicEqnStateVarOnRhs) TEST(Generator, algebraicEqnStateVarOnRhsOneComponent) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/algebraic_eqn_state_var_on_rhs_one_component/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/algebraic_eqn_state_var_on_rhs_one_component/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); - generator->processModel(model); + analyser->analyseModel(model); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(size_t(0), analyser->errorCount()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + auto analyserModel = analyser->model(); - EXPECT_EQ(size_t(1), generator->stateCount()); - EXPECT_EQ(size_t(2), generator->variableCount()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + EXPECT_EQ(size_t(1), analyserModel->stateCount()); + EXPECT_EQ(size_t(2), analyserModel->variableCount()); + EXPECT_EQ(size_t(3), analyserModel->equationCount()); + + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); + + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/algebraic_eqn_state_var_on_rhs_one_component/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/algebraic_eqn_state_var_on_rhs_one_component/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -672,32 +347,41 @@ TEST(Generator, algebraicEqnStateVarOnRhsOneComponent) TEST(Generator, odeComputedVarOnRhs) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/ode_computed_var_on_rhs/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/ode_computed_var_on_rhs/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); - generator->processModel(model); + EXPECT_EQ(size_t(0), analyser->errorCount()); - EXPECT_EQ(size_t(0), generator->issueCount()); + auto analyserModel = analyser->model(); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_EQ(size_t(1), generator->stateCount()); - EXPECT_EQ(size_t(1), generator->variableCount()); + EXPECT_EQ(size_t(1), analyserModel->stateCount()); + EXPECT_EQ(size_t(1), analyserModel->variableCount()); + EXPECT_EQ(size_t(2), analyserModel->equationCount()); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); + + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/ode_computed_var_on_rhs/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/ode_computed_var_on_rhs/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -707,32 +391,41 @@ TEST(Generator, odeComputedVarOnRhs) TEST(Generator, odeComputedVarOnRhsOneComponent) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/ode_computed_var_on_rhs_one_component/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/ode_computed_var_on_rhs_one_component/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->errorCount()); - generator->processModel(model); + auto analyserModel = analyser->model(); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + EXPECT_EQ(size_t(1), analyserModel->stateCount()); + EXPECT_EQ(size_t(1), analyserModel->variableCount()); + EXPECT_EQ(size_t(2), analyserModel->equationCount()); - EXPECT_EQ(size_t(1), generator->stateCount()); - EXPECT_EQ(size_t(1), generator->variableCount()); + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/ode_computed_var_on_rhs_one_component/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/ode_computed_var_on_rhs_one_component/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -742,32 +435,41 @@ TEST(Generator, odeComputedVarOnRhsOneComponent) TEST(Generator, odeConstVarOnRhs) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/ode_const_var_on_rhs/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/ode_const_var_on_rhs/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->errorCount()); + + auto analyserModel = analyser->model(); - generator->processModel(model); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(size_t(1), analyserModel->stateCount()); + EXPECT_EQ(size_t(1), analyserModel->variableCount()); + EXPECT_EQ(size_t(1), analyserModel->equationCount()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); - EXPECT_EQ(size_t(1), generator->stateCount()); - EXPECT_EQ(size_t(1), generator->variableCount()); + auto generator = libcellml::Generator::create(); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/ode_const_var_on_rhs/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/ode_const_var_on_rhs/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -777,32 +479,41 @@ TEST(Generator, odeConstVarOnRhs) TEST(Generator, odeConstVarOnRhsOneComponent) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/ode_const_var_on_rhs_one_component/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/ode_const_var_on_rhs_one_component/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); - generator->processModel(model); + analyser->analyseModel(model); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(size_t(0), analyser->errorCount()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + auto analyserModel = analyser->model(); - EXPECT_EQ(size_t(1), generator->stateCount()); - EXPECT_EQ(size_t(1), generator->variableCount()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + EXPECT_EQ(size_t(1), analyserModel->stateCount()); + EXPECT_EQ(size_t(1), analyserModel->variableCount()); + EXPECT_EQ(size_t(1), analyserModel->equationCount()); + + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); + + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/ode_const_var_on_rhs_one_component/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/ode_const_var_on_rhs_one_component/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -812,31 +523,40 @@ TEST(Generator, odeConstVarOnRhsOneComponent) TEST(Generator, odeConstantOnRhs) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/ode_constant_on_rhs/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/ode_constant_on_rhs/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->errorCount()); - generator->processModel(model); + auto analyserModel = analyser->model(); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + EXPECT_EQ(size_t(1), analyserModel->stateCount()); + EXPECT_EQ(size_t(0), analyserModel->variableCount()); + EXPECT_EQ(size_t(1), analyserModel->equationCount()); - EXPECT_EQ(size_t(1), generator->stateCount()); - EXPECT_EQ(size_t(0), generator->variableCount()); + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_EQ(nullptr, analyserModel->variable(0)); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_EQ(nullptr, generator->variable(0)); + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/ode_constant_on_rhs/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/ode_constant_on_rhs/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -846,31 +566,40 @@ TEST(Generator, odeConstantOnRhs) TEST(Generator, odeConstantOnRhsOneComponent) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/ode_constant_on_rhs_one_component/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/ode_constant_on_rhs_one_component/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->errorCount()); + + auto analyserModel = analyser->model(); - generator->processModel(model); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(size_t(1), analyserModel->stateCount()); + EXPECT_EQ(size_t(0), analyserModel->variableCount()); + EXPECT_EQ(size_t(1), analyserModel->equationCount()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_EQ(nullptr, analyserModel->variable(0)); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); - EXPECT_EQ(size_t(1), generator->stateCount()); - EXPECT_EQ(size_t(0), generator->variableCount()); + auto generator = libcellml::Generator::create(); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_EQ(nullptr, generator->variable(0)); + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/ode_constant_on_rhs_one_component/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/ode_constant_on_rhs_one_component/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -880,32 +609,41 @@ TEST(Generator, odeConstantOnRhsOneComponent) TEST(Generator, odeMultipleDependentOdes) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/ode_multiple_dependent_odes/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/ode_multiple_dependent_odes/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); - generator->processModel(model); + analyser->analyseModel(model); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(size_t(0), analyser->errorCount()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + auto analyserModel = analyser->model(); - EXPECT_EQ(size_t(2), generator->stateCount()); - EXPECT_EQ(size_t(1), generator->variableCount()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + EXPECT_EQ(size_t(2), analyserModel->stateCount()); + EXPECT_EQ(size_t(1), analyserModel->variableCount()); + EXPECT_EQ(size_t(2), analyserModel->equationCount()); + + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); + + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/ode_multiple_dependent_odes/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/ode_multiple_dependent_odes/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -915,32 +653,41 @@ TEST(Generator, odeMultipleDependentOdes) TEST(Generator, odeMultipleDependentOdesOneComponent) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/ode_multiple_dependent_odes_one_component/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/ode_multiple_dependent_odes_one_component/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->errorCount()); - generator->processModel(model); + auto analyserModel = analyser->model(); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + EXPECT_EQ(size_t(2), analyserModel->stateCount()); + EXPECT_EQ(size_t(1), analyserModel->variableCount()); + EXPECT_EQ(size_t(2), analyserModel->equationCount()); - EXPECT_EQ(size_t(2), generator->stateCount()); - EXPECT_EQ(size_t(1), generator->variableCount()); + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/ode_multiple_dependent_odes_one_component/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/ode_multiple_dependent_odes_one_component/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -950,32 +697,41 @@ TEST(Generator, odeMultipleDependentOdesOneComponent) TEST(Generator, odeMultipleOdesWithSameName) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/ode_multiple_odes_with_same_name/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/ode_multiple_odes_with_same_name/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->errorCount()); + + auto analyserModel = analyser->model(); - generator->processModel(model); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(size_t(2), analyserModel->stateCount()); + EXPECT_EQ(size_t(1), analyserModel->variableCount()); + EXPECT_EQ(size_t(2), analyserModel->equationCount()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); - EXPECT_EQ(size_t(2), generator->stateCount()); - EXPECT_EQ(size_t(1), generator->variableCount()); + auto generator = libcellml::Generator::create(); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/ode_multiple_odes_with_same_name/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/ode_multiple_odes_with_same_name/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -985,32 +741,41 @@ TEST(Generator, odeMultipleOdesWithSameName) TEST(Generator, cellmlMappingsAndEncapsulations) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/cellml_mappings_and_encapsulations/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/cellml_mappings_and_encapsulations/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); - generator->processModel(model); + analyser->analyseModel(model); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(size_t(0), analyser->errorCount()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + auto analyserModel = analyser->model(); - EXPECT_EQ(size_t(2), generator->stateCount()); - EXPECT_EQ(size_t(2), generator->variableCount()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + EXPECT_EQ(size_t(2), analyserModel->stateCount()); + EXPECT_EQ(size_t(2), analyserModel->variableCount()); + EXPECT_EQ(size_t(4), analyserModel->equationCount()); + + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); + + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/cellml_mappings_and_encapsulations/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/cellml_mappings_and_encapsulations/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -1020,32 +785,41 @@ TEST(Generator, cellmlMappingsAndEncapsulations) TEST(Generator, cellmlStateInitialisedUsingVariable) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/cellml_state_initialised_using_variable/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/cellml_state_initialised_using_variable/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->errorCount()); - generator->processModel(model); + auto analyserModel = analyser->model(); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + EXPECT_EQ(size_t(1), analyserModel->stateCount()); + EXPECT_EQ(size_t(1), analyserModel->variableCount()); + EXPECT_EQ(size_t(1), analyserModel->equationCount()); - EXPECT_EQ(size_t(1), generator->stateCount()); - EXPECT_EQ(size_t(1), generator->variableCount()); + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/cellml_state_initialised_using_variable/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/cellml_state_initialised_using_variable/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -1055,32 +829,41 @@ TEST(Generator, cellmlStateInitialisedUsingVariable) TEST(Generator, cellmlUnitScalingVoiIndirect) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/cellml_unit_scaling_voi_indirect/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/cellml_unit_scaling_voi_indirect/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->errorCount()); + + auto analyserModel = analyser->model(); - generator->processModel(model); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(size_t(2), analyserModel->stateCount()); + EXPECT_EQ(size_t(0), analyserModel->variableCount()); + EXPECT_EQ(size_t(2), analyserModel->equationCount()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_EQ(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); - EXPECT_EQ(size_t(2), generator->stateCount()); - EXPECT_EQ(size_t(0), generator->variableCount()); + auto generator = libcellml::Generator::create(); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_EQ(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/cellml_unit_scaling_voi_indirect/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/cellml_unit_scaling_voi_indirect/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -1090,32 +873,41 @@ TEST(Generator, cellmlUnitScalingVoiIndirect) TEST(Generator, cellmlUnitScalingVoiDirect) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/cellml_unit_scaling_voi_direct/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/cellml_unit_scaling_voi_direct/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); - generator->processModel(model); + analyser->analyseModel(model); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(size_t(0), analyser->errorCount()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + auto analyserModel = analyser->model(); - EXPECT_EQ(size_t(2), generator->stateCount()); - EXPECT_EQ(size_t(0), generator->variableCount()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_EQ(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + EXPECT_EQ(size_t(2), analyserModel->stateCount()); + EXPECT_EQ(size_t(0), analyserModel->variableCount()); + EXPECT_EQ(size_t(2), analyserModel->equationCount()); + + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_EQ(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); + + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/cellml_unit_scaling_voi_direct/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/cellml_unit_scaling_voi_direct/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -1125,32 +917,41 @@ TEST(Generator, cellmlUnitScalingVoiDirect) TEST(Generator, cellmlUnitScalingConstant) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/cellml_unit_scaling_constant/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/cellml_unit_scaling_constant/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); - generator->processModel(model); + EXPECT_EQ(size_t(0), analyser->errorCount()); - EXPECT_EQ(size_t(0), generator->issueCount()); + auto analyserModel = analyser->model(); - EXPECT_EQ(libcellml::Generator::ModelType::ALGEBRAIC, generator->modelType()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ALGEBRAIC, analyserModel->type()); - EXPECT_EQ(size_t(0), generator->stateCount()); - EXPECT_EQ(size_t(3), generator->variableCount()); + EXPECT_EQ(size_t(0), analyserModel->stateCount()); + EXPECT_EQ(size_t(3), analyserModel->variableCount()); + EXPECT_EQ(size_t(2), analyserModel->equationCount()); - EXPECT_EQ(nullptr, generator->voi()); - EXPECT_EQ(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + EXPECT_EQ(nullptr, analyserModel->voi()); + EXPECT_EQ(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); + + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/cellml_unit_scaling_constant/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/cellml_unit_scaling_constant/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -1160,32 +961,41 @@ TEST(Generator, cellmlUnitScalingConstant) TEST(Generator, cellmlUnitScalingState) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/cellml_unit_scaling_state/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/cellml_unit_scaling_state/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->errorCount()); - generator->processModel(model); + auto analyserModel = analyser->model(); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + EXPECT_EQ(size_t(1), analyserModel->stateCount()); + EXPECT_EQ(size_t(2), analyserModel->variableCount()); + EXPECT_EQ(size_t(3), analyserModel->equationCount()); - EXPECT_EQ(size_t(1), generator->stateCount()); - EXPECT_EQ(size_t(2), generator->variableCount()); + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/cellml_unit_scaling_state/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/cellml_unit_scaling_state/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -1195,32 +1005,41 @@ TEST(Generator, cellmlUnitScalingState) TEST(Generator, cellmlUnitScalingStateInitialisedUsingConstant) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/cellml_unit_scaling_state_initialised_using_constant/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/cellml_unit_scaling_state_initialised_using_constant/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->errorCount()); - generator->processModel(model); + auto analyserModel = analyser->model(); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + EXPECT_EQ(size_t(2), analyserModel->stateCount()); + EXPECT_EQ(size_t(0), analyserModel->variableCount()); + EXPECT_EQ(size_t(2), analyserModel->equationCount()); - EXPECT_EQ(size_t(2), generator->stateCount()); - EXPECT_EQ(size_t(0), generator->variableCount()); + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_EQ(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_EQ(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/cellml_unit_scaling_state_initialised_using_constant/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/cellml_unit_scaling_state_initialised_using_constant/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -1230,32 +1049,41 @@ TEST(Generator, cellmlUnitScalingStateInitialisedUsingConstant) TEST(Generator, cellmlUnitScalingStateInitialisedUsingVariable) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/cellml_unit_scaling_state_initialised_using_variable/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/cellml_unit_scaling_state_initialised_using_variable/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); - generator->processModel(model); + EXPECT_EQ(size_t(0), analyser->errorCount()); - EXPECT_EQ(size_t(0), generator->issueCount()); + auto analyserModel = analyser->model(); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_EQ(size_t(2), generator->stateCount()); - EXPECT_EQ(size_t(2), generator->variableCount()); + EXPECT_EQ(size_t(2), analyserModel->stateCount()); + EXPECT_EQ(size_t(2), analyserModel->variableCount()); + EXPECT_EQ(size_t(2), analyserModel->equationCount()); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); + + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/cellml_unit_scaling_state_initialised_using_variable/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/cellml_unit_scaling_state_initialised_using_variable/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -1265,32 +1093,41 @@ TEST(Generator, cellmlUnitScalingStateInitialisedUsingVariable) TEST(Generator, cellmlUnitScalingRate) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/cellml_unit_scaling_rate/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/cellml_unit_scaling_rate/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->errorCount()); - generator->processModel(model); + auto analyserModel = analyser->model(); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + EXPECT_EQ(size_t(1), analyserModel->stateCount()); + EXPECT_EQ(size_t(2), analyserModel->variableCount()); + EXPECT_EQ(size_t(3), analyserModel->equationCount()); - EXPECT_EQ(size_t(1), generator->stateCount()); - EXPECT_EQ(size_t(2), generator->variableCount()); + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/cellml_unit_scaling_rate/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/cellml_unit_scaling_rate/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -1300,32 +1137,41 @@ TEST(Generator, cellmlUnitScalingRate) TEST(Generator, dependentEqns) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/dependent_eqns/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/dependent_eqns/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->errorCount()); + + auto analyserModel = analyser->model(); - generator->processModel(model); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(size_t(1), analyserModel->stateCount()); + EXPECT_EQ(size_t(2), analyserModel->variableCount()); + EXPECT_EQ(size_t(3), analyserModel->equationCount()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); - EXPECT_EQ(size_t(1), generator->stateCount()); - EXPECT_EQ(size_t(2), generator->variableCount()); + auto generator = libcellml::Generator::create(); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/dependent_eqns/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/dependent_eqns/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -1335,32 +1181,41 @@ TEST(Generator, dependentEqns) TEST(Generator, fabbriFantiniWildersSeveriHumanSanModel2017) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/fabbri_fantini_wilders_severi_human_san_model_2017/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/fabbri_fantini_wilders_severi_human_san_model_2017/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); - generator->processModel(model); + analyser->analyseModel(model); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(size_t(0), analyser->errorCount()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + auto analyserModel = analyser->model(); - EXPECT_EQ(size_t(33), generator->stateCount()); - EXPECT_EQ(size_t(217), generator->variableCount()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + EXPECT_EQ(size_t(33), analyserModel->stateCount()); + EXPECT_EQ(size_t(217), analyserModel->variableCount()); + EXPECT_EQ(size_t(159), analyserModel->equationCount()); + + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); + + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/fabbri_fantini_wilders_severi_human_san_model_2017/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/fabbri_fantini_wilders_severi_human_san_model_2017/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -1370,32 +1225,41 @@ TEST(Generator, fabbriFantiniWildersSeveriHumanSanModel2017) TEST(Generator, garnyKohlHunterBoyettNobleRabbitSanModel2003) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/garny_kohl_hunter_boyett_noble_rabbit_san_model_2003/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/garny_kohl_hunter_boyett_noble_rabbit_san_model_2003/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); - generator->processModel(model); + EXPECT_EQ(size_t(0), analyser->errorCount()); - EXPECT_EQ(size_t(0), generator->issueCount()); + auto analyserModel = analyser->model(); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_EQ(size_t(15), generator->stateCount()); - EXPECT_EQ(size_t(185), generator->variableCount()); + EXPECT_EQ(size_t(15), analyserModel->stateCount()); + EXPECT_EQ(size_t(185), analyserModel->variableCount()); + EXPECT_EQ(size_t(90), analyserModel->equationCount()); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); + + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/garny_kohl_hunter_boyett_noble_rabbit_san_model_2003/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/garny_kohl_hunter_boyett_noble_rabbit_san_model_2003/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -1405,32 +1269,41 @@ TEST(Generator, garnyKohlHunterBoyettNobleRabbitSanModel2003) TEST(Generator, hodgkinHuxleySquidAxonModel1952) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/hodgkin_huxley_squid_axon_model_1952/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/hodgkin_huxley_squid_axon_model_1952/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->errorCount()); + + auto analyserModel = analyser->model(); - generator->processModel(model); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(size_t(4), analyserModel->stateCount()); + EXPECT_EQ(size_t(18), analyserModel->variableCount()); + EXPECT_EQ(size_t(17), analyserModel->equationCount()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); - EXPECT_EQ(size_t(4), generator->stateCount()); - EXPECT_EQ(size_t(18), generator->variableCount()); + auto generator = libcellml::Generator::create(); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/hodgkin_huxley_squid_axon_model_1952/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/hodgkin_huxley_squid_axon_model_1952/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -1440,32 +1313,41 @@ TEST(Generator, hodgkinHuxleySquidAxonModel1952) TEST(Generator, nobleModel1962) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/noble_model_1962/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/noble_model_1962/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); - generator->processModel(model); + analyser->analyseModel(model); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(size_t(0), analyser->errorCount()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + auto analyserModel = analyser->model(); - EXPECT_EQ(size_t(4), generator->stateCount()); - EXPECT_EQ(size_t(17), generator->variableCount()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + EXPECT_EQ(size_t(4), analyserModel->stateCount()); + EXPECT_EQ(size_t(17), analyserModel->variableCount()); + EXPECT_EQ(size_t(16), analyserModel->equationCount()); + + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); + + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/noble_model_1962/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/noble_model_1962/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -1475,8 +1357,8 @@ TEST(Generator, nobleModel1962) TEST(Generator, sineImports) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("sine_approximations_import.xml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("sine_approximations_import.xml")); auto importer = libcellml::Importer::create(); EXPECT_EQ(size_t(0), parser->issueCount()); @@ -1488,27 +1370,36 @@ TEST(Generator, sineImports) model = importer->flattenModel(model); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); - generator->processModel(model); + EXPECT_EQ(size_t(0), analyser->errorCount()); - EXPECT_EQ(size_t(0), generator->issueCount()); + auto analyserModel = analyser->model(); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_EQ(size_t(1), generator->stateCount()); - EXPECT_EQ(size_t(10), generator->variableCount()); + EXPECT_EQ(size_t(1), analyserModel->stateCount()); + EXPECT_EQ(size_t(10), analyserModel->variableCount()); + EXPECT_EQ(size_t(9), analyserModel->equationCount()); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); + + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); EXPECT_EQ(fileContents("generator/sine_model_imports/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/sine_model_imports/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); @@ -1518,42 +1409,59 @@ TEST(Generator, sineImports) TEST(Generator, coverage) { - libcellml::ParserPtr parser = libcellml::Parser::create(); - libcellml::ModelPtr model = parser->parseModel(fileContents("generator/coverage/model.cellml")); + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/coverage/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); - libcellml::GeneratorPtr generator = libcellml::Generator::create(); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ(size_t(0), analyser->errorCount()); - generator->processModel(model); + auto analyserModel = analyser->model(); - EXPECT_EQ(size_t(0), generator->issueCount()); + EXPECT_EQ(libcellml::AnalyserModel::Type::ODE, analyserModel->type()); - EXPECT_EQ(libcellml::Generator::ModelType::ODE, generator->modelType()); + EXPECT_EQ(size_t(1), analyserModel->stateCount()); + EXPECT_EQ(size_t(186), analyserModel->variableCount()); + EXPECT_EQ(size_t(180), analyserModel->equationCount()); - EXPECT_EQ(size_t(1), generator->stateCount()); - EXPECT_EQ(size_t(186), generator->variableCount()); + EXPECT_NE(nullptr, analyserModel->voi()); + EXPECT_EQ(nullptr, analyserModel->voi()->equation()); + EXPECT_NE(nullptr, analyserModel->state(0)); + EXPECT_NE(nullptr, analyserModel->state(0)->equation()); + EXPECT_EQ(nullptr, analyserModel->state(analyserModel->stateCount())); + EXPECT_NE(nullptr, analyserModel->variable(0)); + EXPECT_EQ(nullptr, analyserModel->variable(analyserModel->variableCount())); + EXPECT_NE(nullptr, analyserModel->equation(0)); + EXPECT_NE(nullptr, analyserModel->equation(0)->variable()); + EXPECT_EQ(nullptr, analyserModel->equation(analyserModel->equationCount())); - EXPECT_NE(nullptr, generator->voi()); - EXPECT_NE(nullptr, generator->state(0)); - EXPECT_EQ(nullptr, generator->state(generator->stateCount())); - EXPECT_NE(nullptr, generator->variable(0)); - EXPECT_EQ(nullptr, generator->variable(generator->variableCount())); + auto generator = libcellml::Generator::create(); - EXPECT_EQ(nullptr, generator->voi()->initialisingVariable()); + EXPECT_EQ(nullptr, analyserModel->voi()->initialisingVariable()); - for (size_t i = 0; i < generator->stateCount(); ++i) { - EXPECT_NE(nullptr, generator->state(i)->initialisingVariable()); + for (size_t i = 0; i < analyserModel->stateCount(); ++i) { + EXPECT_NE(nullptr, analyserModel->state(i)->initialisingVariable()); } - for (size_t i = 0; i < generator->variableCount(); ++i) { - EXPECT_EQ(i < 7, generator->variable(i)->initialisingVariable() != nullptr); + for (size_t i = 0; i < analyserModel->variableCount(); ++i) { + EXPECT_EQ(i < 7, analyserModel->variable(i)->initialisingVariable() != nullptr); } + EXPECT_EQ(nullptr, generator->model()); + EXPECT_EQ(EMPTY_STRING, generator->interfaceCode()); + EXPECT_EQ(EMPTY_STRING, generator->implementationCode()); + + generator->setModel(analyserModel); + + EXPECT_EQ(analyserModel, generator->model()); EXPECT_EQ(fileContents("generator/coverage/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/coverage/model.c"), generator->implementationCode()); - libcellml::GeneratorProfilePtr profile = generator->profile(); + auto profile = generator->profile(); profile->setInterfaceCreateStatesArrayMethodString("double * createStatesVector();\n"); profile->setImplementationCreateStatesArrayMethodString("double * createStatesVector()\n" @@ -1617,9 +1525,8 @@ TEST(Generator, coverage) profile->setImplementationDeleteArrayMethodString(""); - profile->setImplementationComputeVariablesMethodString("// We should have computeVariables() here, but we replaced it with this comment\n" - "// and no code template that can be replaced so that our replace() method can\n" - "// is forced to return an empty string, ensuring 100% coverage using llvm-cov...\n"); + profile->setImplementationComputeVariablesMethodString("// The x's below are to ensure that we get 100% coverage in our SHA-1 utility.\n" + "// xxxxxxxxxxxxxxxxxxxxxxx\n"); EXPECT_EQ(EMPTY_STRING, generator->interfaceCode()); EXPECT_EQ(fileContents("generator/coverage/model.out"), generator->implementationCode()); diff --git a/tests/generator/generatorprofile.cpp b/tests/generator/generatorprofile.cpp index 86f8907e52..5d9e8a5383 100644 --- a/tests/generator/generatorprofile.cpp +++ b/tests/generator/generatorprofile.cpp @@ -83,7 +83,7 @@ TEST(GeneratorProfile, defaultArithmeticOperatorValues) EXPECT_EQ("", generatorProfile->squareString()); EXPECT_EQ("fabs", generatorProfile->absoluteValueString()); EXPECT_EQ("exp", generatorProfile->exponentialString()); - EXPECT_EQ("log", generatorProfile->napierianLogarithmString()); + EXPECT_EQ("log", generatorProfile->naturalLogarithmString()); EXPECT_EQ("log10", generatorProfile->commonLogarithmString()); EXPECT_EQ("ceil", generatorProfile->ceilingString()); EXPECT_EQ("floor", generatorProfile->floorString()); @@ -354,13 +354,13 @@ TEST(GeneratorProfile, defaultMiscellaneousValues) "}\n", generatorProfile->implementationDeleteArrayMethodString()); - EXPECT_EQ("void initializeStatesAndConstants(double *states, double *variables);\n", - generatorProfile->interfaceInitializeStatesAndConstantsMethodString()); - EXPECT_EQ("void initializeStatesAndConstants(double *states, double *variables)\n" + EXPECT_EQ("void initialiseStatesAndConstants(double *states, double *variables);\n", + generatorProfile->interfaceInitialiseStatesAndConstantsMethodString()); + EXPECT_EQ("void initialiseStatesAndConstants(double *states, double *variables)\n" "{\n" "" "}\n", - generatorProfile->implementationInitializeStatesAndConstantsMethodString()); + generatorProfile->implementationInitialiseStatesAndConstantsMethodString()); EXPECT_EQ("void computeComputedConstants(double *variables);\n", generatorProfile->interfaceComputeComputedConstantsMethodString()); @@ -390,8 +390,8 @@ TEST(GeneratorProfile, defaultMiscellaneousValues) EXPECT_EQ(" ", generatorProfile->indentString()); - EXPECT_EQ("{", generatorProfile->openArrayInitializerString()); - EXPECT_EQ("}", generatorProfile->closeArrayInitializerString()); + EXPECT_EQ("{", generatorProfile->openArrayInitialiserString()); + EXPECT_EQ("}", generatorProfile->closeArrayInitialiserString()); EXPECT_EQ("[", generatorProfile->openArrayString()); EXPECT_EQ("]", generatorProfile->closeArrayString()); @@ -490,7 +490,7 @@ TEST(GeneratorProfile, arithmeticOperators) generatorProfile->setSquareString(value); generatorProfile->setAbsoluteValueString(value); generatorProfile->setExponentialString(value); - generatorProfile->setNapierianLogarithmString(value); + generatorProfile->setNaturalLogarithmString(value); generatorProfile->setCommonLogarithmString(value); generatorProfile->setCeilingString(value); generatorProfile->setFloorString(value); @@ -509,7 +509,7 @@ TEST(GeneratorProfile, arithmeticOperators) EXPECT_EQ(value, generatorProfile->squareString()); EXPECT_EQ(value, generatorProfile->absoluteValueString()); EXPECT_EQ(value, generatorProfile->exponentialString()); - EXPECT_EQ(value, generatorProfile->napierianLogarithmString()); + EXPECT_EQ(value, generatorProfile->naturalLogarithmString()); EXPECT_EQ(value, generatorProfile->commonLogarithmString()); EXPECT_EQ(value, generatorProfile->ceilingString()); EXPECT_EQ(value, generatorProfile->floorString()); @@ -748,8 +748,8 @@ TEST(GeneratorProfile, miscellaneous) generatorProfile->setInterfaceDeleteArrayMethodString(value); generatorProfile->setImplementationDeleteArrayMethodString(value); - generatorProfile->setInterfaceInitializeStatesAndConstantsMethodString(value); - generatorProfile->setImplementationInitializeStatesAndConstantsMethodString(value); + generatorProfile->setInterfaceInitialiseStatesAndConstantsMethodString(value); + generatorProfile->setImplementationInitialiseStatesAndConstantsMethodString(value); generatorProfile->setInterfaceComputeComputedConstantsMethodString(value); generatorProfile->setImplementationComputeComputedConstantsMethodString(value); @@ -764,8 +764,8 @@ TEST(GeneratorProfile, miscellaneous) generatorProfile->setIndentString(value); - generatorProfile->setOpenArrayInitializerString(value); - generatorProfile->setCloseArrayInitializerString(value); + generatorProfile->setOpenArrayInitialiserString(value); + generatorProfile->setCloseArrayInitialiserString(value); generatorProfile->setOpenArrayString(value); generatorProfile->setCloseArrayString(value); @@ -832,8 +832,8 @@ TEST(GeneratorProfile, miscellaneous) EXPECT_EQ(value, generatorProfile->interfaceDeleteArrayMethodString()); EXPECT_EQ(value, generatorProfile->implementationDeleteArrayMethodString()); - EXPECT_EQ(value, generatorProfile->interfaceInitializeStatesAndConstantsMethodString()); - EXPECT_EQ(value, generatorProfile->implementationInitializeStatesAndConstantsMethodString()); + EXPECT_EQ(value, generatorProfile->interfaceInitialiseStatesAndConstantsMethodString()); + EXPECT_EQ(value, generatorProfile->implementationInitialiseStatesAndConstantsMethodString()); EXPECT_EQ(value, generatorProfile->interfaceComputeComputedConstantsMethodString()); EXPECT_EQ(value, generatorProfile->implementationComputeComputedConstantsMethodString()); @@ -848,8 +848,8 @@ TEST(GeneratorProfile, miscellaneous) EXPECT_EQ(value, generatorProfile->indentString()); - EXPECT_EQ(value, generatorProfile->openArrayInitializerString()); - EXPECT_EQ(value, generatorProfile->closeArrayInitializerString()); + EXPECT_EQ(value, generatorProfile->openArrayInitialiserString()); + EXPECT_EQ(value, generatorProfile->closeArrayInitialiserString()); EXPECT_EQ(value, generatorProfile->openArrayString()); EXPECT_EQ(value, generatorProfile->closeArrayString()); diff --git a/tests/importer/model_flattening.cpp b/tests/importer/model_flattening.cpp index e6acee68f8..976d074580 100644 --- a/tests/importer/model_flattening.cpp +++ b/tests/importer/model_flattening.cpp @@ -719,9 +719,13 @@ TEST(ModelFlattening, hodgkinHuxleyDefinedUsingImports) auto e = printer->printModel(modelNonImportVersion); EXPECT_EQ(e, a); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + auto generator = libcellml::Generator::create(); - generator->processModel(model); + generator->setModel(analyser->model()); EXPECT_EQ(fileContents("generator/hodgkin_huxley_squid_axon_model_1952/model.h"), generator->interfaceCode()); EXPECT_EQ(fileContents("generator/hodgkin_huxley_squid_axon_model_1952/model.c"), generator->implementationCode()); diff --git a/tests/isolated/generator.cpp b/tests/isolated/generator.cpp index f36dad72bd..6767739dd6 100644 --- a/tests/isolated/generator.cpp +++ b/tests/isolated/generator.cpp @@ -89,7 +89,7 @@ TEST(Generator, isolatedFirstOrderModel) // 2.b Add the maths to the component. Note that there is only one maths // string stored, so parts which are appended must create a viable - // MathML string when concantenated. To clear any string, which is + // MathML string when concatenated. To clear any string, which is // already stored, simply call setMath("") with an empty string. component->setMath(mathHeader); component->appendMath(equation1); @@ -200,14 +200,11 @@ TEST(Generator, isolatedFirstOrderModel) validator->validateModel(model); EXPECT_EQ(size_t(0), validator->issueCount()); - // 5.a Create a Generator instance. By default the options set in the - // generator constructor are: - // - profile() return "C" (cf "PYTHON"); and - // - modelType() returns "ODE". + // 5.a Create an Analyser instance and analyse the model. - libcellml::GeneratorPtr generator = libcellml::Generator::create(); - generator->processModel(model); + libcellml::AnalyserPtr analyser = libcellml::Analyser::create(); + analyser->analyseModel(model); - // 5.b Check whether the generator has encountered any issues. - EXPECT_EQ(size_t(0), generator->issueCount()); + // 5.b Check whether the analyser has encountered any issues. + EXPECT_EQ(size_t(0), analyser->issueCount()); } diff --git a/tests/parser/file_parser.cpp b/tests/parser/file_parser.cpp index 8d501e44ce..b2ca9a3046 100644 --- a/tests/parser/file_parser.cpp +++ b/tests/parser/file_parser.cpp @@ -148,7 +148,7 @@ TEST(Parser, simpleGeneratorModel) "\n"; libcellml::ParserPtr p = libcellml::Parser::create(); - libcellml::ModelPtr model = p->parseModel(fileContents("generator/initialized_variable_of_integration.cellml")); + libcellml::ModelPtr model = p->parseModel(fileContents("analyser/initialised_variable_of_integration.cellml")); EXPECT_EQ(size_t(0), p->issueCount()); diff --git a/tests/parser/parser.cpp b/tests/parser/parser.cpp index c43bf997c8..f164f1f58e 100644 --- a/tests/parser/parser.cpp +++ b/tests/parser/parser.cpp @@ -1450,7 +1450,6 @@ TEST(Parser, invalidModelWithAllCausesOfIssues) case libcellml::Issue::Cause::RESET: case libcellml::Issue::Cause::UNDEFINED: case libcellml::Issue::Cause::XML: - case libcellml::Issue::Cause::GENERATOR: break; } } diff --git a/tests/printer/printer.cpp b/tests/printer/printer.cpp index 1ce4fcc315..39bec81391 100644 --- a/tests/printer/printer.cpp +++ b/tests/printer/printer.cpp @@ -216,7 +216,7 @@ TEST(Printer, printModelWithImports) { const std::string e_model = "\n" - "\n" + "\n" " \n" " \n" " \n" @@ -226,12 +226,12 @@ TEST(Printer, printModelWithImports) " \n" " \n" " \n" - " \n" - " \n" - " \n" - " \n" - " \n" - " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" " \n" " \n" " \n" diff --git a/tests/resources/generator/initialized_variable_of_integration.cellml b/tests/resources/analyser/initialised_variable_of_integration.cellml similarity index 76% rename from tests/resources/generator/initialized_variable_of_integration.cellml rename to tests/resources/analyser/initialised_variable_of_integration.cellml index 7a2c3c2142..f2bb81346c 100644 --- a/tests/resources/generator/initialized_variable_of_integration.cellml +++ b/tests/resources/analyser/initialised_variable_of_integration.cellml @@ -1,11 +1,11 @@ - + - - + + diff --git a/tests/resources/generator/initialized_variable_of_integration_in_non_first_component.cellml b/tests/resources/analyser/initialised_variable_of_integration_in_non_first_component.cellml similarity index 75% rename from tests/resources/generator/initialized_variable_of_integration_in_non_first_component.cellml rename to tests/resources/analyser/initialised_variable_of_integration_in_non_first_component.cellml index 2cbb359f05..479100d1ac 100644 --- a/tests/resources/generator/initialized_variable_of_integration_in_non_first_component.cellml +++ b/tests/resources/analyser/initialised_variable_of_integration_in_non_first_component.cellml @@ -1,11 +1,11 @@ - + - - + + @@ -21,7 +21,7 @@ - + diff --git a/tests/resources/generator/non_constant_initialising_variable.cellml b/tests/resources/analyser/non_constant_initialising_variable.cellml similarity index 100% rename from tests/resources/generator/non_constant_initialising_variable.cellml rename to tests/resources/analyser/non_constant_initialising_variable.cellml diff --git a/tests/resources/generator/non_existing_initialising_variable.cellml b/tests/resources/analyser/non_existing_initialising_variable.cellml similarity index 100% rename from tests/resources/generator/non_existing_initialising_variable.cellml rename to tests/resources/analyser/non_existing_initialising_variable.cellml diff --git a/tests/resources/generator/non_first_order_odes.cellml b/tests/resources/analyser/non_first_order_odes.cellml similarity index 85% rename from tests/resources/generator/non_first_order_odes.cellml rename to tests/resources/analyser/non_first_order_odes.cellml index 5995fe59b5..650dc49353 100644 --- a/tests/resources/generator/non_first_order_odes.cellml +++ b/tests/resources/analyser/non_first_order_odes.cellml @@ -4,8 +4,8 @@ - - + + @@ -24,8 +24,8 @@ - - + + @@ -44,8 +44,8 @@ - - + + diff --git a/tests/resources/generator/non_initialized_state.cellml b/tests/resources/analyser/non_initialised_state.cellml similarity index 92% rename from tests/resources/generator/non_initialized_state.cellml rename to tests/resources/analyser/non_initialised_state.cellml index 5174931529..db6fdb9590 100644 --- a/tests/resources/generator/non_initialized_state.cellml +++ b/tests/resources/analyser/non_initialised_state.cellml @@ -1,5 +1,5 @@ - + diff --git a/tests/resources/generator/overconstrained.cellml b/tests/resources/analyser/overconstrained.cellml similarity index 100% rename from tests/resources/generator/overconstrained.cellml rename to tests/resources/analyser/overconstrained.cellml diff --git a/tests/resources/generator/two_variables_of_integration.cellml b/tests/resources/analyser/two_variables_of_integration.cellml similarity index 84% rename from tests/resources/generator/two_variables_of_integration.cellml rename to tests/resources/analyser/two_variables_of_integration.cellml index 6931dd5f5d..6f0c6c1a0e 100644 --- a/tests/resources/generator/two_variables_of_integration.cellml +++ b/tests/resources/analyser/two_variables_of_integration.cellml @@ -4,8 +4,8 @@ - - + + @@ -21,8 +21,8 @@ - - + + @@ -38,8 +38,8 @@ - - + + @@ -56,7 +56,7 @@ - + diff --git a/tests/resources/generator/undefined_variables.cellml b/tests/resources/analyser/undefined_variables.cellml similarity index 100% rename from tests/resources/generator/undefined_variables.cellml rename to tests/resources/analyser/undefined_variables.cellml diff --git a/tests/resources/generator/underconstrained.cellml b/tests/resources/analyser/underconstrained.cellml similarity index 100% rename from tests/resources/generator/underconstrained.cellml rename to tests/resources/analyser/underconstrained.cellml diff --git a/tests/resources/generator/unsuitably_constrained.cellml b/tests/resources/analyser/unsuitably_constrained.cellml similarity index 100% rename from tests/resources/generator/unsuitably_constrained.cellml rename to tests/resources/analyser/unsuitably_constrained.cellml diff --git a/tests/resources/generator/variable_initialized_twice.cellml b/tests/resources/analyser/variable_initialised_twice.cellml similarity index 65% rename from tests/resources/generator/variable_initialized_twice.cellml rename to tests/resources/analyser/variable_initialised_twice.cellml index 653501b93c..fe915eb284 100644 --- a/tests/resources/generator/variable_initialized_twice.cellml +++ b/tests/resources/analyser/variable_initialised_twice.cellml @@ -1,8 +1,8 @@ - + - - + + @@ -12,8 +12,8 @@ - - + + diff --git a/tests/resources/deriv_approx_sin.xml b/tests/resources/deriv_approx_sin.xml index 692de9cb00..2e2f7141a9 100644 --- a/tests/resources/deriv_approx_sin.xml +++ b/tests/resources/deriv_approx_sin.xml @@ -1,9 +1,9 @@ - + - - - + + + diff --git a/tests/resources/generator/algebraic_eqn_computed_var_on_rhs/model.c b/tests/resources/generator/algebraic_eqn_computed_var_on_rhs/model.c index a0e8e504f7..d3e7d0a60b 100644 --- a/tests/resources/generator/algebraic_eqn_computed_var_on_rhs/model.c +++ b/tests/resources/generator/algebraic_eqn_computed_var_on_rhs/model.c @@ -36,7 +36,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 1.0; } diff --git a/tests/resources/generator/algebraic_eqn_computed_var_on_rhs/model.h b/tests/resources/generator/algebraic_eqn_computed_var_on_rhs/model.h index eab3841fde..7dc7f39c26 100644 --- a/tests/resources/generator/algebraic_eqn_computed_var_on_rhs/model.h +++ b/tests/resources/generator/algebraic_eqn_computed_var_on_rhs/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/algebraic_eqn_computed_var_on_rhs/model.py b/tests/resources/generator/algebraic_eqn_computed_var_on_rhs/model.py index 0223e656bc..398912e7cb 100644 --- a/tests/resources/generator/algebraic_eqn_computed_var_on_rhs/model.py +++ b/tests/resources/generator/algebraic_eqn_computed_var_on_rhs/model.py @@ -36,7 +36,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 1.0 diff --git a/tests/resources/generator/algebraic_eqn_const_var_on_rhs/model.c b/tests/resources/generator/algebraic_eqn_const_var_on_rhs/model.c index 8c68351da5..431dd4ca9a 100644 --- a/tests/resources/generator/algebraic_eqn_const_var_on_rhs/model.c +++ b/tests/resources/generator/algebraic_eqn_const_var_on_rhs/model.c @@ -36,7 +36,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 1.0; } diff --git a/tests/resources/generator/algebraic_eqn_const_var_on_rhs/model.h b/tests/resources/generator/algebraic_eqn_const_var_on_rhs/model.h index eab3841fde..7dc7f39c26 100644 --- a/tests/resources/generator/algebraic_eqn_const_var_on_rhs/model.h +++ b/tests/resources/generator/algebraic_eqn_const_var_on_rhs/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/algebraic_eqn_const_var_on_rhs/model.py b/tests/resources/generator/algebraic_eqn_const_var_on_rhs/model.py index c67b528935..9ed6cdddba 100644 --- a/tests/resources/generator/algebraic_eqn_const_var_on_rhs/model.py +++ b/tests/resources/generator/algebraic_eqn_const_var_on_rhs/model.py @@ -36,7 +36,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 1.0 diff --git a/tests/resources/generator/algebraic_eqn_constant_on_rhs/model.c b/tests/resources/generator/algebraic_eqn_constant_on_rhs/model.c index 880893d064..b339c76c41 100644 --- a/tests/resources/generator/algebraic_eqn_constant_on_rhs/model.c +++ b/tests/resources/generator/algebraic_eqn_constant_on_rhs/model.c @@ -35,7 +35,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 1.0; } diff --git a/tests/resources/generator/algebraic_eqn_constant_on_rhs/model.h b/tests/resources/generator/algebraic_eqn_constant_on_rhs/model.h index d00734f89c..96cde6e7d0 100644 --- a/tests/resources/generator/algebraic_eqn_constant_on_rhs/model.h +++ b/tests/resources/generator/algebraic_eqn_constant_on_rhs/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/algebraic_eqn_constant_on_rhs/model.py b/tests/resources/generator/algebraic_eqn_constant_on_rhs/model.py index abd58603b4..0dc3428388 100644 --- a/tests/resources/generator/algebraic_eqn_constant_on_rhs/model.py +++ b/tests/resources/generator/algebraic_eqn_constant_on_rhs/model.py @@ -35,7 +35,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 1.0 diff --git a/tests/resources/generator/algebraic_eqn_derivative_on_rhs/model.c b/tests/resources/generator/algebraic_eqn_derivative_on_rhs/model.c index 4b554a7ba4..72340ec0d7 100644 --- a/tests/resources/generator/algebraic_eqn_derivative_on_rhs/model.c +++ b/tests/resources/generator/algebraic_eqn_derivative_on_rhs/model.c @@ -37,7 +37,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 1.0; states[0] = 1.0; diff --git a/tests/resources/generator/algebraic_eqn_derivative_on_rhs/model.h b/tests/resources/generator/algebraic_eqn_derivative_on_rhs/model.h index eab3841fde..7dc7f39c26 100644 --- a/tests/resources/generator/algebraic_eqn_derivative_on_rhs/model.h +++ b/tests/resources/generator/algebraic_eqn_derivative_on_rhs/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/algebraic_eqn_derivative_on_rhs/model.py b/tests/resources/generator/algebraic_eqn_derivative_on_rhs/model.py index badaf1f9a9..bc746ae294 100644 --- a/tests/resources/generator/algebraic_eqn_derivative_on_rhs/model.py +++ b/tests/resources/generator/algebraic_eqn_derivative_on_rhs/model.py @@ -37,7 +37,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 1.0 states[0] = 1.0 diff --git a/tests/resources/generator/algebraic_eqn_derivative_on_rhs_one_component/model.c b/tests/resources/generator/algebraic_eqn_derivative_on_rhs_one_component/model.c index 36468fba55..d65c4bfb42 100644 --- a/tests/resources/generator/algebraic_eqn_derivative_on_rhs_one_component/model.c +++ b/tests/resources/generator/algebraic_eqn_derivative_on_rhs_one_component/model.c @@ -37,7 +37,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 1.0; states[0] = 1.0; diff --git a/tests/resources/generator/algebraic_eqn_derivative_on_rhs_one_component/model.h b/tests/resources/generator/algebraic_eqn_derivative_on_rhs_one_component/model.h index d00734f89c..96cde6e7d0 100644 --- a/tests/resources/generator/algebraic_eqn_derivative_on_rhs_one_component/model.h +++ b/tests/resources/generator/algebraic_eqn_derivative_on_rhs_one_component/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/algebraic_eqn_derivative_on_rhs_one_component/model.py b/tests/resources/generator/algebraic_eqn_derivative_on_rhs_one_component/model.py index 11a3a6603d..7c3693e153 100644 --- a/tests/resources/generator/algebraic_eqn_derivative_on_rhs_one_component/model.py +++ b/tests/resources/generator/algebraic_eqn_derivative_on_rhs_one_component/model.py @@ -37,7 +37,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 1.0 states[0] = 1.0 diff --git a/tests/resources/generator/algebraic_eqn_state_var_on_rhs/model.c b/tests/resources/generator/algebraic_eqn_state_var_on_rhs/model.c index a4f8a04648..ef3ecd3099 100644 --- a/tests/resources/generator/algebraic_eqn_state_var_on_rhs/model.c +++ b/tests/resources/generator/algebraic_eqn_state_var_on_rhs/model.c @@ -37,7 +37,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 1.0; states[0] = 1.0; diff --git a/tests/resources/generator/algebraic_eqn_state_var_on_rhs/model.h b/tests/resources/generator/algebraic_eqn_state_var_on_rhs/model.h index d5ea9958d8..b488e68b1b 100644 --- a/tests/resources/generator/algebraic_eqn_state_var_on_rhs/model.h +++ b/tests/resources/generator/algebraic_eqn_state_var_on_rhs/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/algebraic_eqn_state_var_on_rhs/model.py b/tests/resources/generator/algebraic_eqn_state_var_on_rhs/model.py index 08bcb322c1..67c76638f5 100644 --- a/tests/resources/generator/algebraic_eqn_state_var_on_rhs/model.py +++ b/tests/resources/generator/algebraic_eqn_state_var_on_rhs/model.py @@ -37,7 +37,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 1.0 states[0] = 1.0 diff --git a/tests/resources/generator/algebraic_eqn_state_var_on_rhs_one_component/model.c b/tests/resources/generator/algebraic_eqn_state_var_on_rhs_one_component/model.c index 7ea45659d5..d50bf68c1a 100644 --- a/tests/resources/generator/algebraic_eqn_state_var_on_rhs_one_component/model.c +++ b/tests/resources/generator/algebraic_eqn_state_var_on_rhs_one_component/model.c @@ -37,7 +37,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 1.0; states[0] = 1.0; diff --git a/tests/resources/generator/algebraic_eqn_state_var_on_rhs_one_component/model.h b/tests/resources/generator/algebraic_eqn_state_var_on_rhs_one_component/model.h index 4468b38993..11035b6d84 100644 --- a/tests/resources/generator/algebraic_eqn_state_var_on_rhs_one_component/model.h +++ b/tests/resources/generator/algebraic_eqn_state_var_on_rhs_one_component/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/algebraic_eqn_state_var_on_rhs_one_component/model.py b/tests/resources/generator/algebraic_eqn_state_var_on_rhs_one_component/model.py index 47f3f24857..c04a426475 100644 --- a/tests/resources/generator/algebraic_eqn_state_var_on_rhs_one_component/model.py +++ b/tests/resources/generator/algebraic_eqn_state_var_on_rhs_one_component/model.py @@ -37,7 +37,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 1.0 states[0] = 1.0 diff --git a/tests/resources/generator/cellml_mappings_and_encapsulations/model.c b/tests/resources/generator/cellml_mappings_and_encapsulations/model.c index b7fec7c49b..0005a5e28d 100644 --- a/tests/resources/generator/cellml_mappings_and_encapsulations/model.c +++ b/tests/resources/generator/cellml_mappings_and_encapsulations/model.c @@ -38,7 +38,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { states[0] = 0.0; states[1] = 1.0; diff --git a/tests/resources/generator/cellml_mappings_and_encapsulations/model.cellml b/tests/resources/generator/cellml_mappings_and_encapsulations/model.cellml index cc26bb95cd..a4abc31716 100644 --- a/tests/resources/generator/cellml_mappings_and_encapsulations/model.cellml +++ b/tests/resources/generator/cellml_mappings_and_encapsulations/model.cellml @@ -25,6 +25,9 @@ + + + diff --git a/tests/resources/generator/cellml_mappings_and_encapsulations/model.h b/tests/resources/generator/cellml_mappings_and_encapsulations/model.h index ed588b8f72..3f0bd19628 100644 --- a/tests/resources/generator/cellml_mappings_and_encapsulations/model.h +++ b/tests/resources/generator/cellml_mappings_and_encapsulations/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/cellml_mappings_and_encapsulations/model.py b/tests/resources/generator/cellml_mappings_and_encapsulations/model.py index b334dc9947..20cf1ab10c 100644 --- a/tests/resources/generator/cellml_mappings_and_encapsulations/model.py +++ b/tests/resources/generator/cellml_mappings_and_encapsulations/model.py @@ -38,7 +38,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): states[0] = 0.0 states[1] = 1.0 diff --git a/tests/resources/generator/cellml_state_initialised_using_variable/model.c b/tests/resources/generator/cellml_state_initialised_using_variable/model.c index 9eda5783f4..75ecd29a3f 100644 --- a/tests/resources/generator/cellml_state_initialised_using_variable/model.c +++ b/tests/resources/generator/cellml_state_initialised_using_variable/model.c @@ -36,7 +36,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 123.0; states[0] = variables[0]; diff --git a/tests/resources/generator/cellml_state_initialised_using_variable/model.h b/tests/resources/generator/cellml_state_initialised_using_variable/model.h index 53073b04dc..f94c7c1345 100644 --- a/tests/resources/generator/cellml_state_initialised_using_variable/model.h +++ b/tests/resources/generator/cellml_state_initialised_using_variable/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/cellml_state_initialised_using_variable/model.py b/tests/resources/generator/cellml_state_initialised_using_variable/model.py index cfb2005603..a07d0d4606 100644 --- a/tests/resources/generator/cellml_state_initialised_using_variable/model.py +++ b/tests/resources/generator/cellml_state_initialised_using_variable/model.py @@ -36,7 +36,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 123.0 states[0] = variables[0] diff --git a/tests/resources/generator/cellml_unit_scaling_constant/model.c b/tests/resources/generator/cellml_unit_scaling_constant/model.c index 1e61905954..99b8e55b5e 100644 --- a/tests/resources/generator/cellml_unit_scaling_constant/model.c +++ b/tests/resources/generator/cellml_unit_scaling_constant/model.c @@ -37,7 +37,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 123.0; } diff --git a/tests/resources/generator/cellml_unit_scaling_constant/model.h b/tests/resources/generator/cellml_unit_scaling_constant/model.h index a73d1b7986..b017d1afab 100644 --- a/tests/resources/generator/cellml_unit_scaling_constant/model.h +++ b/tests/resources/generator/cellml_unit_scaling_constant/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/cellml_unit_scaling_constant/model.py b/tests/resources/generator/cellml_unit_scaling_constant/model.py index 7405e98d9c..3fcff9a4f0 100644 --- a/tests/resources/generator/cellml_unit_scaling_constant/model.py +++ b/tests/resources/generator/cellml_unit_scaling_constant/model.py @@ -37,7 +37,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 123.0 diff --git a/tests/resources/generator/cellml_unit_scaling_rate/model.c b/tests/resources/generator/cellml_unit_scaling_rate/model.c index 33d83d9d52..2db08b5ba9 100644 --- a/tests/resources/generator/cellml_unit_scaling_rate/model.c +++ b/tests/resources/generator/cellml_unit_scaling_rate/model.c @@ -37,7 +37,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { states[0] = 123.0; } diff --git a/tests/resources/generator/cellml_unit_scaling_rate/model.h b/tests/resources/generator/cellml_unit_scaling_rate/model.h index 53073b04dc..f94c7c1345 100644 --- a/tests/resources/generator/cellml_unit_scaling_rate/model.h +++ b/tests/resources/generator/cellml_unit_scaling_rate/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/cellml_unit_scaling_rate/model.py b/tests/resources/generator/cellml_unit_scaling_rate/model.py index 84d5590953..04af7a224c 100644 --- a/tests/resources/generator/cellml_unit_scaling_rate/model.py +++ b/tests/resources/generator/cellml_unit_scaling_rate/model.py @@ -37,7 +37,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): states[0] = 123.0 diff --git a/tests/resources/generator/cellml_unit_scaling_state/model.c b/tests/resources/generator/cellml_unit_scaling_state/model.c index 3586ba5099..36758eece8 100644 --- a/tests/resources/generator/cellml_unit_scaling_state/model.c +++ b/tests/resources/generator/cellml_unit_scaling_state/model.c @@ -37,7 +37,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { states[0] = 123.0; } diff --git a/tests/resources/generator/cellml_unit_scaling_state/model.h b/tests/resources/generator/cellml_unit_scaling_state/model.h index 53073b04dc..f94c7c1345 100644 --- a/tests/resources/generator/cellml_unit_scaling_state/model.h +++ b/tests/resources/generator/cellml_unit_scaling_state/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/cellml_unit_scaling_state/model.py b/tests/resources/generator/cellml_unit_scaling_state/model.py index 987bb59947..946b708e78 100644 --- a/tests/resources/generator/cellml_unit_scaling_state/model.py +++ b/tests/resources/generator/cellml_unit_scaling_state/model.py @@ -37,7 +37,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): states[0] = 123.0 diff --git a/tests/resources/generator/cellml_unit_scaling_state_initialised_using_constant/model.c b/tests/resources/generator/cellml_unit_scaling_state_initialised_using_constant/model.c index 5a885b09e7..7ca0f89588 100644 --- a/tests/resources/generator/cellml_unit_scaling_state_initialised_using_constant/model.c +++ b/tests/resources/generator/cellml_unit_scaling_state_initialised_using_constant/model.c @@ -36,7 +36,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { states[0] = 123.0; states[1] = 0.001*789.0; diff --git a/tests/resources/generator/cellml_unit_scaling_state_initialised_using_constant/model.h b/tests/resources/generator/cellml_unit_scaling_state_initialised_using_constant/model.h index c02ecbbdef..068871f78c 100644 --- a/tests/resources/generator/cellml_unit_scaling_state_initialised_using_constant/model.h +++ b/tests/resources/generator/cellml_unit_scaling_state_initialised_using_constant/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/cellml_unit_scaling_state_initialised_using_constant/model.py b/tests/resources/generator/cellml_unit_scaling_state_initialised_using_constant/model.py index b0dd51691f..ccb7196032 100644 --- a/tests/resources/generator/cellml_unit_scaling_state_initialised_using_constant/model.py +++ b/tests/resources/generator/cellml_unit_scaling_state_initialised_using_constant/model.py @@ -36,7 +36,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): states[0] = 123.0 states[1] = 0.001*789.0 diff --git a/tests/resources/generator/cellml_unit_scaling_state_initialised_using_variable/model.c b/tests/resources/generator/cellml_unit_scaling_state_initialised_using_variable/model.c index e3fcd89556..2917cbbbf7 100644 --- a/tests/resources/generator/cellml_unit_scaling_state_initialised_using_variable/model.c +++ b/tests/resources/generator/cellml_unit_scaling_state_initialised_using_variable/model.c @@ -38,7 +38,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 123.0; variables[1] = 789.0; diff --git a/tests/resources/generator/cellml_unit_scaling_state_initialised_using_variable/model.h b/tests/resources/generator/cellml_unit_scaling_state_initialised_using_variable/model.h index f768eda650..aa3ff8f887 100644 --- a/tests/resources/generator/cellml_unit_scaling_state_initialised_using_variable/model.h +++ b/tests/resources/generator/cellml_unit_scaling_state_initialised_using_variable/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/cellml_unit_scaling_state_initialised_using_variable/model.py b/tests/resources/generator/cellml_unit_scaling_state_initialised_using_variable/model.py index c2ad065f33..5e974903df 100644 --- a/tests/resources/generator/cellml_unit_scaling_state_initialised_using_variable/model.py +++ b/tests/resources/generator/cellml_unit_scaling_state_initialised_using_variable/model.py @@ -38,7 +38,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 123.0 variables[1] = 789.0 states[0] = variables[0] diff --git a/tests/resources/generator/cellml_unit_scaling_voi_direct/model.c b/tests/resources/generator/cellml_unit_scaling_voi_direct/model.c index d76d35d7cf..1e62c29a4d 100644 --- a/tests/resources/generator/cellml_unit_scaling_voi_direct/model.c +++ b/tests/resources/generator/cellml_unit_scaling_voi_direct/model.c @@ -36,7 +36,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { states[0] = 3.0; states[1] = 5.0; diff --git a/tests/resources/generator/cellml_unit_scaling_voi_direct/model.h b/tests/resources/generator/cellml_unit_scaling_voi_direct/model.h index 4f9cdf30e9..ae985fe4c8 100644 --- a/tests/resources/generator/cellml_unit_scaling_voi_direct/model.h +++ b/tests/resources/generator/cellml_unit_scaling_voi_direct/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/cellml_unit_scaling_voi_direct/model.py b/tests/resources/generator/cellml_unit_scaling_voi_direct/model.py index fc3409e992..fac14d7615 100644 --- a/tests/resources/generator/cellml_unit_scaling_voi_direct/model.py +++ b/tests/resources/generator/cellml_unit_scaling_voi_direct/model.py @@ -36,7 +36,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): states[0] = 3.0 states[1] = 5.0 diff --git a/tests/resources/generator/cellml_unit_scaling_voi_indirect/model.c b/tests/resources/generator/cellml_unit_scaling_voi_indirect/model.c index b38bd63947..777eaec0c4 100644 --- a/tests/resources/generator/cellml_unit_scaling_voi_indirect/model.c +++ b/tests/resources/generator/cellml_unit_scaling_voi_indirect/model.c @@ -36,7 +36,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { states[0] = 3.0; states[1] = 7.0; diff --git a/tests/resources/generator/cellml_unit_scaling_voi_indirect/model.h b/tests/resources/generator/cellml_unit_scaling_voi_indirect/model.h index 53073b04dc..f94c7c1345 100644 --- a/tests/resources/generator/cellml_unit_scaling_voi_indirect/model.h +++ b/tests/resources/generator/cellml_unit_scaling_voi_indirect/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/cellml_unit_scaling_voi_indirect/model.py b/tests/resources/generator/cellml_unit_scaling_voi_indirect/model.py index f1ba71b1ee..3c4b1fd901 100644 --- a/tests/resources/generator/cellml_unit_scaling_voi_indirect/model.py +++ b/tests/resources/generator/cellml_unit_scaling_voi_indirect/model.py @@ -36,7 +36,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): states[0] = 3.0 states[1] = 7.0 diff --git a/tests/resources/generator/coverage/model.c b/tests/resources/generator/coverage/model.c index 973a0fa439..680c5fe29b 100644 --- a/tests/resources/generator/coverage/model.c +++ b/tests/resources/generator/coverage/model.c @@ -302,7 +302,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 1.0; variables[1] = 2.0; diff --git a/tests/resources/generator/coverage/model.cellml b/tests/resources/generator/coverage/model.cellml index 0996fc60f2..047e3d6514 100644 --- a/tests/resources/generator/coverage/model.cellml +++ b/tests/resources/generator/coverage/model.cellml @@ -211,6 +211,8 @@ 1 + + eqnEq @@ -233,6 +235,8 @@ + + eqnNeq @@ -255,6 +259,8 @@ + + eqnLt @@ -264,6 +270,8 @@ n + + eqnLeq @@ -273,6 +281,8 @@ n + + eqnGt @@ -282,6 +292,8 @@ n + + eqnGeq @@ -291,6 +303,8 @@ n + + eqnAnd @@ -527,6 +541,8 @@ + + eqnOr @@ -763,6 +779,8 @@ + + eqnXor @@ -999,6 +1017,8 @@ + + eqnNot @@ -1007,6 +1027,8 @@ m + + eqnPlus @@ -1051,6 +1073,8 @@ m + + eqnMinus @@ -1130,6 +1154,8 @@ + + eqnTimes @@ -1298,6 +1324,8 @@ + + eqnDivide @@ -1490,6 +1518,8 @@ + + eqnPowerSqrt @@ -1777,6 +1807,8 @@ + + eqnRootSqrt @@ -2069,6 +2101,8 @@ + + eqnAbs @@ -2077,6 +2111,8 @@ m + + eqnExp @@ -2085,6 +2121,8 @@ m + + eqnLn @@ -2093,6 +2131,8 @@ m + + eqnLog @@ -2134,6 +2174,8 @@ m + + eqnCeiling @@ -2142,6 +2184,8 @@ m + + eqnFloor @@ -2150,6 +2194,8 @@ m + + eqnMin @@ -2169,6 +2215,8 @@ o + + eqnMax @@ -2188,6 +2236,8 @@ o + + eqnRem @@ -2197,6 +2247,8 @@ n + + eqnSin @@ -2205,6 +2257,8 @@ m + + eqnCos @@ -2213,6 +2267,8 @@ m + + eqnTan @@ -2221,6 +2277,8 @@ m + + eqnSec @@ -2229,6 +2287,8 @@ m + + eqnCsc @@ -2237,6 +2297,8 @@ m + + eqnCot @@ -2245,6 +2307,8 @@ m + + eqnSinh @@ -2253,6 +2317,8 @@ m + + eqnCosh @@ -2261,6 +2327,8 @@ m + + eqnTanh @@ -2269,6 +2337,8 @@ m + + eqnSech @@ -2277,6 +2347,8 @@ m + + eqnCsch @@ -2285,6 +2357,8 @@ m + + eqnCoth @@ -2293,6 +2367,8 @@ m + + eqnArcsin @@ -2301,6 +2377,8 @@ m + + eqnArccos @@ -2309,6 +2387,8 @@ m + + eqnArctan @@ -2317,6 +2397,8 @@ m + + eqnArcsec @@ -2325,6 +2407,8 @@ m + + eqnArccsc @@ -2333,6 +2417,8 @@ m + + eqnArccot @@ -2341,6 +2427,8 @@ m + + eqnArcsinh @@ -2349,6 +2437,8 @@ m + + eqnArccosh @@ -2357,6 +2447,8 @@ m + + eqnArctanh @@ -2369,6 +2461,8 @@ + + eqnArcsech @@ -2377,6 +2471,8 @@ m + + eqnArccsch @@ -2385,6 +2481,8 @@ m + + eqnArccoth @@ -2397,6 +2495,8 @@ + + eqnPiecewisePiece @@ -2491,6 +2591,8 @@ + + eqnWithPiecewise @@ -2509,6 +2611,8 @@ + + eqnCnInteger @@ -2541,6 +2645,8 @@ 99 + + eqnCi @@ -2548,31 +2654,43 @@ m + + eqnTrue + + eqnFalse + + eqnExponentiale + + eqnPi + + eqnInfinity + + eqnNotanumber diff --git a/tests/resources/generator/coverage/model.h b/tests/resources/generator/coverage/model.h index 8e7a53ae53..721b5487e1 100644 --- a/tests/resources/generator/coverage/model.h +++ b/tests/resources/generator/coverage/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/coverage/model.implementation.out b/tests/resources/generator/coverage/model.implementation.out index 33a8e1f323..9998d28983 100644 --- a/tests/resources/generator/coverage/model.implementation.out +++ b/tests/resources/generator/coverage/model.implementation.out @@ -96,7 +96,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 1.0; variables[1] = 2.0; diff --git a/tests/resources/generator/coverage/model.interface.out b/tests/resources/generator/coverage/model.interface.out index aafad2c638..4c053483bd 100644 --- a/tests/resources/generator/coverage/model.interface.out +++ b/tests/resources/generator/coverage/model.interface.out @@ -8,7 +8,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/coverage/model.modified.profile.c b/tests/resources/generator/coverage/model.modified.profile.c index 0d11f0db8a..f298af5547 100644 --- a/tests/resources/generator/coverage/model.modified.profile.c +++ b/tests/resources/generator/coverage/model.modified.profile.c @@ -302,7 +302,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 1.0; variables[1] = 2.0; diff --git a/tests/resources/generator/coverage/model.modified.profile.h b/tests/resources/generator/coverage/model.modified.profile.h index e8469e7bf0..a824e3e5af 100644 --- a/tests/resources/generator/coverage/model.modified.profile.h +++ b/tests/resources/generator/coverage/model.modified.profile.h @@ -37,7 +37,7 @@ double * createStatesVector(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/coverage/model.modified.profile.py b/tests/resources/generator/coverage/model.modified.profile.py index c9fe14c208..90fe4192c4 100644 --- a/tests/resources/generator/coverage/model.modified.profile.py +++ b/tests/resources/generator/coverage/model.modified.profile.py @@ -323,7 +323,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 1.0 variables[1] = 2.0 variables[2] = 3.0 diff --git a/tests/resources/generator/coverage/model.out b/tests/resources/generator/coverage/model.out index 4390d74ee5..824ab5cfa3 100644 --- a/tests/resources/generator/coverage/model.out +++ b/tests/resources/generator/coverage/model.out @@ -78,7 +78,7 @@ double acoth(double x) return 0.5*log((1.0+oneOverX)/(1.0-oneOverX)); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 1.0; variables[1] = 2.0; @@ -278,6 +278,5 @@ void computeRates(double voi, double *states, double *rates, double *variables) rates[0] = 1.0; } -// We should have computeVariables() here, but we replaced it with this comment -// and no code template that can be replaced so that our replace() method can -// is forced to return an empty string, ensuring 100% coverage using llvm-cov... +// The x's below are to ensure that we get 100% coverage in our SHA-1 utility. +// xxxxxxxxxxxxxxxxxxxxxxx diff --git a/tests/resources/generator/coverage/model.py b/tests/resources/generator/coverage/model.py index ff30fa026d..d840db2a78 100644 --- a/tests/resources/generator/coverage/model.py +++ b/tests/resources/generator/coverage/model.py @@ -323,7 +323,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 1.0 variables[1] = 2.0 variables[2] = 3.0 diff --git a/tests/resources/generator/dependent_eqns/model.c b/tests/resources/generator/dependent_eqns/model.c index cc56f0af9d..4564bf923f 100644 --- a/tests/resources/generator/dependent_eqns/model.c +++ b/tests/resources/generator/dependent_eqns/model.c @@ -37,7 +37,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { states[0] = 0.0; } diff --git a/tests/resources/generator/dependent_eqns/model.h b/tests/resources/generator/dependent_eqns/model.h index 0795d7d993..9151856930 100644 --- a/tests/resources/generator/dependent_eqns/model.h +++ b/tests/resources/generator/dependent_eqns/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/dependent_eqns/model.py b/tests/resources/generator/dependent_eqns/model.py index 613869ddce..ee89e6cc28 100644 --- a/tests/resources/generator/dependent_eqns/model.py +++ b/tests/resources/generator/dependent_eqns/model.py @@ -37,7 +37,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): states[0] = 0.0 diff --git a/tests/resources/generator/fabbri_fantini_wilders_severi_human_san_model_2017/model.c b/tests/resources/generator/fabbri_fantini_wilders_severi_human_san_model_2017/model.c index 74301f0f28..ab11edfc83 100644 --- a/tests/resources/generator/fabbri_fantini_wilders_severi_human_san_model_2017/model.c +++ b/tests/resources/generator/fabbri_fantini_wilders_severi_human_san_model_2017/model.c @@ -284,7 +284,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 0.45; variables[1] = 2.5; diff --git a/tests/resources/generator/fabbri_fantini_wilders_severi_human_san_model_2017/model.h b/tests/resources/generator/fabbri_fantini_wilders_severi_human_san_model_2017/model.h index 00fad045ae..6c12e7e435 100644 --- a/tests/resources/generator/fabbri_fantini_wilders_severi_human_san_model_2017/model.h +++ b/tests/resources/generator/fabbri_fantini_wilders_severi_human_san_model_2017/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/fabbri_fantini_wilders_severi_human_san_model_2017/model.py b/tests/resources/generator/fabbri_fantini_wilders_severi_human_san_model_2017/model.py index 4ee89c6b09..5e39074256 100644 --- a/tests/resources/generator/fabbri_fantini_wilders_severi_human_san_model_2017/model.py +++ b/tests/resources/generator/fabbri_fantini_wilders_severi_human_san_model_2017/model.py @@ -304,7 +304,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 0.45 variables[1] = 2.5 variables[2] = 15.0 diff --git a/tests/resources/generator/garny_kohl_hunter_boyett_noble_rabbit_san_model_2003/model.c b/tests/resources/generator/garny_kohl_hunter_boyett_noble_rabbit_san_model_2003/model.c index 1fc35e8b09..ade48a9f22 100644 --- a/tests/resources/generator/garny_kohl_hunter_boyett_noble_rabbit_san_model_2003/model.c +++ b/tests/resources/generator/garny_kohl_hunter_boyett_noble_rabbit_san_model_2003/model.c @@ -234,7 +234,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 46.4; variables[1] = 0.0057938; diff --git a/tests/resources/generator/garny_kohl_hunter_boyett_noble_rabbit_san_model_2003/model.h b/tests/resources/generator/garny_kohl_hunter_boyett_noble_rabbit_san_model_2003/model.h index 758710f3f1..086f9d369b 100644 --- a/tests/resources/generator/garny_kohl_hunter_boyett_noble_rabbit_san_model_2003/model.h +++ b/tests/resources/generator/garny_kohl_hunter_boyett_noble_rabbit_san_model_2003/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/garny_kohl_hunter_boyett_noble_rabbit_san_model_2003/model.py b/tests/resources/generator/garny_kohl_hunter_boyett_noble_rabbit_san_model_2003/model.py index f7f75d1352..936366a950 100644 --- a/tests/resources/generator/garny_kohl_hunter_boyett_noble_rabbit_san_model_2003/model.py +++ b/tests/resources/generator/garny_kohl_hunter_boyett_noble_rabbit_san_model_2003/model.py @@ -242,7 +242,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 46.4 variables[1] = 0.0057938 variables[2] = 0.0082 diff --git a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.c b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.c index 03bcc745fe..198040546e 100644 --- a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.c +++ b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.c @@ -56,7 +56,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 0.3; variables[1] = 1.0; diff --git a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.h b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.h index 04eeaeb84a..9c7689370d 100644 --- a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.h +++ b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.py b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.py index 7809e93748..b6f0b87fab 100644 --- a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.py +++ b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.py @@ -68,7 +68,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 0.3 variables[1] = 1.0 variables[2] = 0.0 diff --git a/tests/resources/generator/noble_model_1962/model.c b/tests/resources/generator/noble_model_1962/model.c index 26e79f60ba..6564521a42 100644 --- a/tests/resources/generator/noble_model_1962/model.c +++ b/tests/resources/generator/noble_model_1962/model.c @@ -55,7 +55,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = -60.0; variables[1] = 0.075; diff --git a/tests/resources/generator/noble_model_1962/model.h b/tests/resources/generator/noble_model_1962/model.h index b8ff6333cd..9702bce587 100644 --- a/tests/resources/generator/noble_model_1962/model.h +++ b/tests/resources/generator/noble_model_1962/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/noble_model_1962/model.py b/tests/resources/generator/noble_model_1962/model.py index 4ddea5a4c8..6f28e2465c 100644 --- a/tests/resources/generator/noble_model_1962/model.py +++ b/tests/resources/generator/noble_model_1962/model.py @@ -55,7 +55,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = -60.0 variables[1] = 0.075 variables[2] = 12.0 diff --git a/tests/resources/generator/ode_computed_var_on_rhs/model.c b/tests/resources/generator/ode_computed_var_on_rhs/model.c index e185a357b2..0806d95685 100644 --- a/tests/resources/generator/ode_computed_var_on_rhs/model.c +++ b/tests/resources/generator/ode_computed_var_on_rhs/model.c @@ -36,7 +36,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 1.0; states[0] = 1.0; diff --git a/tests/resources/generator/ode_computed_var_on_rhs/model.h b/tests/resources/generator/ode_computed_var_on_rhs/model.h index 4f9cdf30e9..ae985fe4c8 100644 --- a/tests/resources/generator/ode_computed_var_on_rhs/model.h +++ b/tests/resources/generator/ode_computed_var_on_rhs/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/ode_computed_var_on_rhs/model.py b/tests/resources/generator/ode_computed_var_on_rhs/model.py index 365011fee7..b72469196e 100644 --- a/tests/resources/generator/ode_computed_var_on_rhs/model.py +++ b/tests/resources/generator/ode_computed_var_on_rhs/model.py @@ -36,7 +36,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 1.0 states[0] = 1.0 diff --git a/tests/resources/generator/ode_computed_var_on_rhs_one_component/model.c b/tests/resources/generator/ode_computed_var_on_rhs_one_component/model.c index 120d6a791a..2627c07c2d 100644 --- a/tests/resources/generator/ode_computed_var_on_rhs_one_component/model.c +++ b/tests/resources/generator/ode_computed_var_on_rhs_one_component/model.c @@ -36,7 +36,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 1.0; states[0] = 1.0; diff --git a/tests/resources/generator/ode_computed_var_on_rhs_one_component/model.h b/tests/resources/generator/ode_computed_var_on_rhs_one_component/model.h index d00734f89c..96cde6e7d0 100644 --- a/tests/resources/generator/ode_computed_var_on_rhs_one_component/model.h +++ b/tests/resources/generator/ode_computed_var_on_rhs_one_component/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/ode_computed_var_on_rhs_one_component/model.py b/tests/resources/generator/ode_computed_var_on_rhs_one_component/model.py index 894d0c0126..429f32ebf2 100644 --- a/tests/resources/generator/ode_computed_var_on_rhs_one_component/model.py +++ b/tests/resources/generator/ode_computed_var_on_rhs_one_component/model.py @@ -36,7 +36,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 1.0 states[0] = 1.0 diff --git a/tests/resources/generator/ode_const_var_on_rhs/model.c b/tests/resources/generator/ode_const_var_on_rhs/model.c index 9871ff2c52..c01a502dff 100644 --- a/tests/resources/generator/ode_const_var_on_rhs/model.c +++ b/tests/resources/generator/ode_const_var_on_rhs/model.c @@ -36,7 +36,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 1.0; states[0] = 1.0; diff --git a/tests/resources/generator/ode_const_var_on_rhs/model.h b/tests/resources/generator/ode_const_var_on_rhs/model.h index 4f9cdf30e9..ae985fe4c8 100644 --- a/tests/resources/generator/ode_const_var_on_rhs/model.h +++ b/tests/resources/generator/ode_const_var_on_rhs/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/ode_const_var_on_rhs/model.py b/tests/resources/generator/ode_const_var_on_rhs/model.py index a26724ea33..737ca0ca68 100644 --- a/tests/resources/generator/ode_const_var_on_rhs/model.py +++ b/tests/resources/generator/ode_const_var_on_rhs/model.py @@ -36,7 +36,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 1.0 states[0] = 1.0 diff --git a/tests/resources/generator/ode_const_var_on_rhs_one_component/model.c b/tests/resources/generator/ode_const_var_on_rhs_one_component/model.c index 4c8ecd0d0c..346df65c2e 100644 --- a/tests/resources/generator/ode_const_var_on_rhs_one_component/model.c +++ b/tests/resources/generator/ode_const_var_on_rhs_one_component/model.c @@ -36,7 +36,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 1.0; states[0] = 1.0; diff --git a/tests/resources/generator/ode_const_var_on_rhs_one_component/model.h b/tests/resources/generator/ode_const_var_on_rhs_one_component/model.h index d00734f89c..96cde6e7d0 100644 --- a/tests/resources/generator/ode_const_var_on_rhs_one_component/model.h +++ b/tests/resources/generator/ode_const_var_on_rhs_one_component/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/ode_const_var_on_rhs_one_component/model.py b/tests/resources/generator/ode_const_var_on_rhs_one_component/model.py index 4f586a5445..665efcd4a4 100644 --- a/tests/resources/generator/ode_const_var_on_rhs_one_component/model.py +++ b/tests/resources/generator/ode_const_var_on_rhs_one_component/model.py @@ -36,7 +36,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 1.0 states[0] = 1.0 diff --git a/tests/resources/generator/ode_constant_on_rhs/model.c b/tests/resources/generator/ode_constant_on_rhs/model.c index aa538bd074..39426bd201 100644 --- a/tests/resources/generator/ode_constant_on_rhs/model.c +++ b/tests/resources/generator/ode_constant_on_rhs/model.c @@ -35,7 +35,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { states[0] = 1.0; } diff --git a/tests/resources/generator/ode_constant_on_rhs/model.h b/tests/resources/generator/ode_constant_on_rhs/model.h index 4f9cdf30e9..ae985fe4c8 100644 --- a/tests/resources/generator/ode_constant_on_rhs/model.h +++ b/tests/resources/generator/ode_constant_on_rhs/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/ode_constant_on_rhs/model.py b/tests/resources/generator/ode_constant_on_rhs/model.py index 509bd3ef5c..d082e032c1 100644 --- a/tests/resources/generator/ode_constant_on_rhs/model.py +++ b/tests/resources/generator/ode_constant_on_rhs/model.py @@ -35,7 +35,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): states[0] = 1.0 diff --git a/tests/resources/generator/ode_constant_on_rhs_one_component/model.c b/tests/resources/generator/ode_constant_on_rhs_one_component/model.c index 8494164773..370e9a0ba6 100644 --- a/tests/resources/generator/ode_constant_on_rhs_one_component/model.c +++ b/tests/resources/generator/ode_constant_on_rhs_one_component/model.c @@ -35,7 +35,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { states[0] = 1.0; } diff --git a/tests/resources/generator/ode_constant_on_rhs_one_component/model.h b/tests/resources/generator/ode_constant_on_rhs_one_component/model.h index d00734f89c..96cde6e7d0 100644 --- a/tests/resources/generator/ode_constant_on_rhs_one_component/model.h +++ b/tests/resources/generator/ode_constant_on_rhs_one_component/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/ode_constant_on_rhs_one_component/model.py b/tests/resources/generator/ode_constant_on_rhs_one_component/model.py index 527f37da27..ac4273f890 100644 --- a/tests/resources/generator/ode_constant_on_rhs_one_component/model.py +++ b/tests/resources/generator/ode_constant_on_rhs_one_component/model.py @@ -35,7 +35,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): states[0] = 1.0 diff --git a/tests/resources/generator/ode_multiple_dependent_odes/model.c b/tests/resources/generator/ode_multiple_dependent_odes/model.c index 8de57852b9..fc6feaca5a 100644 --- a/tests/resources/generator/ode_multiple_dependent_odes/model.c +++ b/tests/resources/generator/ode_multiple_dependent_odes/model.c @@ -37,7 +37,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 1.0; states[0] = -2.0; diff --git a/tests/resources/generator/ode_multiple_dependent_odes/model.h b/tests/resources/generator/ode_multiple_dependent_odes/model.h index 1773f18091..55ef2829f2 100644 --- a/tests/resources/generator/ode_multiple_dependent_odes/model.h +++ b/tests/resources/generator/ode_multiple_dependent_odes/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/ode_multiple_dependent_odes/model.py b/tests/resources/generator/ode_multiple_dependent_odes/model.py index 82f360c4c4..8586a4494a 100644 --- a/tests/resources/generator/ode_multiple_dependent_odes/model.py +++ b/tests/resources/generator/ode_multiple_dependent_odes/model.py @@ -37,7 +37,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 1.0 states[0] = -2.0 states[1] = 0.0 diff --git a/tests/resources/generator/ode_multiple_dependent_odes_one_component/model.c b/tests/resources/generator/ode_multiple_dependent_odes_one_component/model.c index dd8247a485..f442e01669 100644 --- a/tests/resources/generator/ode_multiple_dependent_odes_one_component/model.c +++ b/tests/resources/generator/ode_multiple_dependent_odes_one_component/model.c @@ -37,7 +37,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 1.0; states[0] = -2.0; diff --git a/tests/resources/generator/ode_multiple_dependent_odes_one_component/model.h b/tests/resources/generator/ode_multiple_dependent_odes_one_component/model.h index cb4b1f5454..d5d0a0ded3 100644 --- a/tests/resources/generator/ode_multiple_dependent_odes_one_component/model.h +++ b/tests/resources/generator/ode_multiple_dependent_odes_one_component/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/ode_multiple_dependent_odes_one_component/model.py b/tests/resources/generator/ode_multiple_dependent_odes_one_component/model.py index 48b170b024..e1fffe3071 100644 --- a/tests/resources/generator/ode_multiple_dependent_odes_one_component/model.py +++ b/tests/resources/generator/ode_multiple_dependent_odes_one_component/model.py @@ -37,7 +37,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 1.0 states[0] = -2.0 states[1] = 0.0 diff --git a/tests/resources/generator/ode_multiple_odes_with_same_name/model.c b/tests/resources/generator/ode_multiple_odes_with_same_name/model.c index 259cd48b82..c1c5aa7d27 100644 --- a/tests/resources/generator/ode_multiple_odes_with_same_name/model.c +++ b/tests/resources/generator/ode_multiple_odes_with_same_name/model.c @@ -37,7 +37,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 1.0; states[0] = 1.0; diff --git a/tests/resources/generator/ode_multiple_odes_with_same_name/model.h b/tests/resources/generator/ode_multiple_odes_with_same_name/model.h index d9f18555d9..26a987a22d 100644 --- a/tests/resources/generator/ode_multiple_odes_with_same_name/model.h +++ b/tests/resources/generator/ode_multiple_odes_with_same_name/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/ode_multiple_odes_with_same_name/model.py b/tests/resources/generator/ode_multiple_odes_with_same_name/model.py index 5b0a1f6c5d..9f530d6f75 100644 --- a/tests/resources/generator/ode_multiple_odes_with_same_name/model.py +++ b/tests/resources/generator/ode_multiple_odes_with_same_name/model.py @@ -37,7 +37,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 1.0 states[0] = 1.0 states[1] = 1.0 diff --git a/tests/resources/generator/sine_model_imports/model.c b/tests/resources/generator/sine_model_imports/model.c index 83d43828cd..dfa66c2427 100644 --- a/tests/resources/generator/sine_model_imports/model.c +++ b/tests/resources/generator/sine_model_imports/model.c @@ -45,7 +45,7 @@ void deleteArray(double *array) free(array); } -void initializeStatesAndConstants(double *states, double *variables) +void initialiseStatesAndConstants(double *states, double *variables) { variables[0] = 0.75; variables[1] = 0.0; diff --git a/tests/resources/generator/sine_model_imports/model.h b/tests/resources/generator/sine_model_imports/model.h index 28568f919a..530bee375b 100644 --- a/tests/resources/generator/sine_model_imports/model.h +++ b/tests/resources/generator/sine_model_imports/model.h @@ -37,7 +37,7 @@ double * createStatesArray(); double * createVariablesArray(); void deleteArray(double *array); -void initializeStatesAndConstants(double *states, double *variables); +void initialiseStatesAndConstants(double *states, double *variables); void computeComputedConstants(double *variables); void computeRates(double voi, double *states, double *rates, double *variables); void computeVariables(double voi, double *states, double *rates, double *variables); diff --git a/tests/resources/generator/sine_model_imports/model.py b/tests/resources/generator/sine_model_imports/model.py index 309cc7b09c..9a2281775b 100644 --- a/tests/resources/generator/sine_model_imports/model.py +++ b/tests/resources/generator/sine_model_imports/model.py @@ -49,7 +49,7 @@ def create_variables_array(): return [nan]*VARIABLE_COUNT -def initialize_states_and_constants(states, variables): +def initialise_states_and_constants(states, variables): variables[0] = 0.75 variables[1] = 0.0 variables[3] = 2.0/3.14159265358979 diff --git a/tests/resources/parabolic_approx_sin.xml b/tests/resources/parabolic_approx_sin.xml index 713d0e631b..58a7131517 100644 --- a/tests/resources/parabolic_approx_sin.xml +++ b/tests/resources/parabolic_approx_sin.xml @@ -1,9 +1,9 @@ - + - - - + + + @@ -12,32 +12,32 @@ - + k2_oPi 2.0 - + k2Pi 2.0 - + kPi_2 2.0 - + kPi - + kPi_32 @@ -48,7 +48,7 @@ - + z @@ -111,7 +111,7 @@ - + sin diff --git a/tests/resources/requires_imports.cellml b/tests/resources/requires_imports.cellml index e59fb1d0ab..3231abb296 100644 --- a/tests/resources/requires_imports.cellml +++ b/tests/resources/requires_imports.cellml @@ -6,7 +6,7 @@ - diff --git a/tests/resources/sin.xml b/tests/resources/sin.xml index ca5721418b..c6b8edb467 100644 --- a/tests/resources/sin.xml +++ b/tests/resources/sin.xml @@ -1,11 +1,11 @@ - + - + - + - + sin x diff --git a/tests/resources/sine_approximations_import.xml b/tests/resources/sine_approximations_import.xml index e37be8bd13..3a29143cf8 100644 --- a/tests/resources/sine_approximations_import.xml +++ b/tests/resources/sine_approximations_import.xml @@ -1,4 +1,4 @@ - + @@ -12,12 +12,12 @@ - - - - - - + + + + + + diff --git a/tests/test_utils.cpp b/tests/test_utils.cpp index a381acd094..94f9c5370e 100644 --- a/tests/test_utils.cpp +++ b/tests/test_utils.cpp @@ -195,15 +195,18 @@ void expectEqualIssuesSpecificationHeadings(const std::vector &issu } } -void expectEqualIssuesCauses(const std::vector &issues, - const std::vector &causes, - const libcellml::LoggerPtr &logger) +void expectEqualIssuesCausesLevels(const std::vector &issues, + const std::vector &causes, + const std::vector &levels, + const libcellml::LoggerPtr &logger) { EXPECT_EQ(issues.size(), logger->issueCount()); EXPECT_EQ(causes.size(), logger->issueCount()); + EXPECT_EQ(levels.size(), logger->issueCount()); for (size_t i = 0; i < logger->issueCount() && i < issues.size(); ++i) { EXPECT_EQ(issues.at(i), logger->issue(i)->description()); EXPECT_EQ(causes.at(i), logger->issue(i)->cause()); + EXPECT_EQ(levels.at(i), logger->issue(i)->level()); } } diff --git a/tests/test_utils.h b/tests/test_utils.h index fce86ea367..8776707fd1 100644 --- a/tests/test_utils.h +++ b/tests/test_utils.h @@ -84,9 +84,10 @@ void TEST_EXPORT expectEqualIssues(const std::vector &issues, const void TEST_EXPORT expectEqualIssuesSpecificationHeadings(const std::vector &issues, const std::vector &specificationHeadings, const libcellml::LoggerPtr &logger); -void TEST_EXPORT expectEqualIssuesCauses(const std::vector &issues, - const std::vector &causes, - const libcellml::LoggerPtr &logger); +void TEST_EXPORT expectEqualIssuesCausesLevels(const std::vector &issues, + const std::vector &causes, + const std::vector &levels, + const libcellml::LoggerPtr &logger); libcellml::ModelPtr TEST_EXPORT createModel(const std::string &name = ""); libcellml::ModelPtr TEST_EXPORT createModelWithComponent(const std::string &modelName = "", const std::string &componentName = ""); @@ -107,6 +108,6 @@ void TEST_EXPORT compareModel(const libcellml::ModelPtr &m1, const libcellml::Mo SCOPED_TRACE("Issue occured here."); \ expectEqualIssuesSpecificationHeadings(issues, specificationHeadings, logger) -#define EXPECT_EQ_ISSUES_CAUSES(issues, causes, logger) \ +#define EXPECT_EQ_ISSUES_CAUSES_LEVELS(issues, causes, levels, logger) \ SCOPED_TRACE("Issue occured here."); \ - expectEqualIssuesCauses(issues, causes, logger) + expectEqualIssuesCausesLevels(issues, causes, levels, logger)