From f55ae4f5cf1c98daa62bb486019cb0cd1de25c3f Mon Sep 17 00:00:00 2001 From: Alan Garny Date: Fri, 16 Aug 2024 19:04:43 +0200 Subject: [PATCH] Analyser: put some struct/class definitions in a corresponding private header. --- src/analyser.cpp | 259 +-------------------------------------------- src/analyser_p.h | 266 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 267 insertions(+), 258 deletions(-) create mode 100644 src/analyser_p.h diff --git a/src/analyser.cpp b/src/analyser.cpp index 8670ec3928..4ce70f6f0c 100644 --- a/src/analyser.cpp +++ b/src/analyser.cpp @@ -20,89 +20,21 @@ limitations under the License. #include "libcellml/analyser.h" -#include -#include - #include "libcellml/analyserequation.h" -#include "libcellml/analyserequationast.h" #include "libcellml/analyserexternalvariable.h" -#include "libcellml/analysermodel.h" -#include "libcellml/analyservariable.h" -#include "libcellml/component.h" -#include "libcellml/generator.h" #include "libcellml/generatorprofile.h" -#include "libcellml/model.h" -#include "libcellml/units.h" #include "libcellml/validator.h" -#include "libcellml/variable.h" +#include "analyser_p.h" #include "analyserequation_p.h" #include "analyserequationast_p.h" -#include "analysermodel_p.h" #include "analyservariable_p.h" -#include "anycellmlelement_p.h" #include "commonutils.h" #include "generator_p.h" -#include "issue_p.h" -#include "logger_p.h" -#include "utilities.h" -#include "xmldoc.h" #include "xmlutils.h" -#include "libcellml/undefines.h" - namespace libcellml { -struct AnalyserInternalEquation; -struct AnalyserInternalVariable; - -using AnalyserInternalEquationWeakPtr = std::weak_ptr; -using AnalyserInternalEquationPtr = std::shared_ptr; -using AnalyserInternalVariablePtr = std::shared_ptr; - -using AnalyserInternalEquationWeakPtrs = std::vector; -using AnalyserInternalEquationPtrs = std::vector; -using AnalyserInternalVariablePtrs = std::vector; - -using AnalyserEquationPtrs = std::vector; -using AnalyserVariablePtrs = std::vector; -using AnalyserExternalVariablePtrs = std::vector; - -struct AnalyserInternalVariable -{ - enum struct Type - { - UNKNOWN, - SHOULD_BE_STATE, - INITIALISED, - VARIABLE_OF_INTEGRATION, - STATE, - CONSTANT, - COMPUTED_TRUE_CONSTANT, - COMPUTED_VARIABLE_BASED_CONSTANT, - INITIALISED_ALGEBRAIC, - ALGEBRAIC, - OVERCONSTRAINED - }; - - size_t mIndex = MAX_SIZE_T; - Type mType = Type::UNKNOWN; - bool mIsExternal = false; - - VariablePtr mInitialisingVariable; - VariablePtr mVariable; - VariablePtrs mDependencies; - - static AnalyserInternalVariablePtr create(const VariablePtr &variable); - - void setVariable(const VariablePtr &variable, - bool checkInitialValue = true); - - void makeVoi(); - void makeState(); - void makeConstant(size_t &index); -}; - AnalyserInternalVariablePtr AnalyserInternalVariable::create(const VariablePtr &variable) { auto res = AnalyserInternalVariablePtr {new AnalyserInternalVariable {}}; @@ -155,62 +87,6 @@ void AnalyserInternalVariable::makeConstant(size_t &index) mType = Type::CONSTANT; } -struct AnalyserInternalEquation -{ - enum struct Type - { - UNKNOWN, - TRUE_CONSTANT, - VARIABLE_BASED_CONSTANT, - ODE, - NLA, - ALGEBRAIC - }; - - Type mType = Type::UNKNOWN; - - VariablePtrs mDependencies; - - AnalyserEquationAstPtr mAst; - - ComponentPtr mComponent; - - AnalyserInternalVariablePtrs mVariables; - AnalyserInternalVariablePtrs mOdeVariables; - AnalyserInternalVariablePtrs mAllVariables; - AnalyserInternalVariablePtrs mUnknownVariables; - - size_t mNlaSystemIndex = MAX_SIZE_T; - AnalyserInternalEquationWeakPtrs mNlaSiblings; - - bool mComputedTrueConstant = true; - bool mComputedVariableBasedConstant = true; - - static AnalyserInternalEquationPtr create(const ComponentPtr &component); - static AnalyserInternalEquationPtr create(const AnalyserInternalVariablePtr &variable); - - 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 AnalyserInternalVariablePtrs &variables); - bool hasKnownVariables(); - - static bool isNonConstantVariable(const AnalyserInternalVariablePtr &variable); - - static bool hasNonConstantVariables(const AnalyserInternalVariablePtrs &variables); - bool hasNonConstantVariables(); - - bool variableOnLhsRhs(const AnalyserInternalVariablePtr &variable, - const AnalyserEquationAstPtr &astChild); - bool variableOnRhs(const AnalyserInternalVariablePtr &variable); - bool variableOnLhsOrRhs(const AnalyserInternalVariablePtr &variable); - - bool check(const AnalyserModelPtr &model, size_t &stateIndex, size_t &computedConstantIndex, size_t &algebraicIndex, bool checkNlaSystems); -}; - AnalyserInternalEquationPtr AnalyserInternalEquation::create(const ComponentPtr &component) { auto res = AnalyserInternalEquationPtr {new AnalyserInternalEquation {}}; @@ -497,139 +373,6 @@ bool AnalyserInternalEquation::check(const AnalyserModelPtr &model, return false; } -/** - * @brief The Analyser::AnalyserImpl class. - * - * The private implementation for the Analyser class. - */ -using UnitsMap = std::map; -using UnitsMaps = std::vector; -using UnitsMultipliers = std::vector; - -class Analyser::AnalyserImpl: public Logger::LoggerImpl -{ -public: - class PowerData - { - public: - bool mDimensionlessBase; - bool mExponentValueAvailable = true; - bool mExponentValueChangeable = false; - double mExponentValue; - AnalyserEquationAstPtr mExponentAst; - }; - - Analyser *mAnalyser = nullptr; - - AnalyserModelPtr mModel = AnalyserModel::AnalyserModelImpl::create(); - - AnalyserExternalVariablePtrs mExternalVariables; - - AnalyserInternalVariablePtrs mInternalVariables; - AnalyserInternalEquationPtrs mInternalEquations; - - GeneratorProfilePtr mGeneratorProfile = libcellml::GeneratorProfile::create(); - - std::map mStandardUnits; - std::map mCiCnUnits; - - AnalyserImpl(); - - 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 analyseComponentVariables(const ComponentPtr &component); - - void doEquivalentVariables(const VariablePtr &variable, - VariablePtrs &equivalentVariables) const; - VariablePtrs equivalentVariables(const VariablePtr &variable) const; - - void analyseEquationAst(const AnalyserEquationAstPtr &ast); - - void updateUnitsMapWithStandardUnit(const std::string &unitsName, - UnitsMap &unitsMap, - double unitsExponent); - void updateUnitsMap(const ModelPtr &model, const std::string &unitsName, - UnitsMap &unitsMap, bool userUnitsMap = false, - double unitsExponent = 1.0, - double unitsMultiplier = 0.0); - UnitsMap multiplyDivideUnitsMaps(const UnitsMap &firstUnitsMap, - const UnitsMap &secondUnitsMap, - bool multiply); - UnitsMaps multiplyDivideUnitsMaps(const UnitsMaps &firstUnitsMaps, - const UnitsMaps &secondUnitsMaps, - bool multiply = true); - UnitsMaps multiplyDivideUnitsMaps(const UnitsMaps &unitsMaps, - double factor, bool multiply); - double multiplyDivideUnitsMultipliers(double firstUnitsMultiplier, - double secondUnitsMultiplier, - bool multiply); - UnitsMultipliers multiplyDivideUnitsMultipliers(const UnitsMultipliers &firstUnitsMultipliers, - const UnitsMultipliers &secondUnitsMultipliers, - bool multiply = true); - UnitsMultipliers multiplyDivideUnitsMultipliers(double firstUnitsMultiplier, - const UnitsMultipliers &secondUnitsMultipliers, - bool multiply); - UnitsMultipliers powerRootUnitsMultipliers(const UnitsMultipliers &unitsMultipliers, - double factor, bool power); - bool areSameUnitsMaps(const UnitsMaps &firstUnitsMaps, - const UnitsMaps &secondUnitsMaps); - bool isDimensionlessUnitsMaps(const UnitsMaps &unitsMaps); - bool areSameUnitsMultipliers(const UnitsMultipliers &firstUnitsMultipliers, - const UnitsMultipliers &secondUnitsMultipliers); - void updateUnitsMultiplier(const ModelPtr &model, - const std::string &unitsName, - double &newUnitsMultiplier, - double unitsExponent = 1.0, - double unitsMultiplier = 0.0); - std::string componentName(const AnalyserEquationAstPtr &ast); - double powerValue(const AnalyserEquationAstPtr &ast, PowerData &powerData); - std::string expression(const AnalyserEquationAstPtr &ast, - bool includeHierarchy = true); - std::string expressionUnits(const UnitsMaps &unitsMaps, - const UnitsMultipliers &unitsMultipliers = {}); - std::string expressionUnits(const AnalyserEquationAstPtr &ast, - const UnitsMaps &unitsMaps, - const UnitsMaps &userUnitsMaps, - const UnitsMultipliers &unitsMultipliers); - void defaultUnitsMapsAndMultipliers(UnitsMaps &unitsMaps, - UnitsMaps &userUnitsMaps, - UnitsMultipliers &unitsMultipliers); - void analyseEquationUnits(const AnalyserEquationAstPtr &ast, - UnitsMaps &unitsMaps, UnitsMaps &userUnitsMaps, - UnitsMultipliers &unitsMultipliers, - std::string &issueDescription, PowerData &powerData); - - double scalingFactor(const VariablePtr &variable); - - void scaleAst(const AnalyserEquationAstPtr &ast, - const AnalyserEquationAstPtr &astParent, - double scalingFactor); - void scaleEquationAst(const AnalyserEquationAstPtr &ast); - - static bool isExternalVariable(const AnalyserInternalVariablePtr &variable); - - bool isStateRateBased(const AnalyserEquationPtr &equation, - AnalyserEquationPtrs &checkedEquations); - - void addInvalidVariableIssue(const AnalyserInternalVariablePtr &variable, - Issue::ReferenceRule referenceRule); - - void analyseModel(const ModelPtr &model); - - AnalyserExternalVariablePtrs::const_iterator findExternalVariable(const ModelPtr &model, - const std::string &componentName, - const std::string &variableName) const; - AnalyserExternalVariablePtrs::const_iterator findExternalVariable(const AnalyserExternalVariablePtr &externalVariable) const; -}; - Analyser::AnalyserImpl::AnalyserImpl() { // Customise our generator's profile. diff --git a/src/analyser_p.h b/src/analyser_p.h new file mode 100644 index 0000000000..138021a954 --- /dev/null +++ b/src/analyser_p.h @@ -0,0 +1,266 @@ +/* +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 "analysermodel_p.h" +#include "internaltypes.h" +#include "issue_p.h" +#include "logger_p.h" +#include "utilities.h" + +namespace libcellml { + +struct AnalyserInternalEquation; +struct AnalyserInternalVariable; + +using AnalyserInternalEquationWeakPtr = std::weak_ptr; +using AnalyserInternalEquationPtr = std::shared_ptr; +using AnalyserInternalVariablePtr = std::shared_ptr; + +using AnalyserInternalEquationWeakPtrs = std::vector; +using AnalyserInternalEquationPtrs = std::vector; +using AnalyserInternalVariablePtrs = std::vector; + +using AnalyserEquationPtrs = std::vector; +using AnalyserVariablePtrs = std::vector; +using AnalyserExternalVariablePtrs = std::vector; + +struct AnalyserInternalVariable +{ + enum struct Type + { + UNKNOWN, + SHOULD_BE_STATE, + INITIALISED, + VARIABLE_OF_INTEGRATION, + STATE, + CONSTANT, + COMPUTED_TRUE_CONSTANT, + COMPUTED_VARIABLE_BASED_CONSTANT, + INITIALISED_ALGEBRAIC, + ALGEBRAIC, + OVERCONSTRAINED + }; + + size_t mIndex = MAX_SIZE_T; + Type mType = Type::UNKNOWN; + bool mIsExternal = false; + + VariablePtr mInitialisingVariable; + VariablePtr mVariable; + VariablePtrs mDependencies; + + static AnalyserInternalVariablePtr create(const VariablePtr &variable); + + void setVariable(const VariablePtr &variable, + bool checkInitialValue = true); + + void makeVoi(); + void makeState(); + void makeConstant(size_t &index); +}; + +struct AnalyserInternalEquation +{ + enum struct Type + { + UNKNOWN, + TRUE_CONSTANT, + VARIABLE_BASED_CONSTANT, + ODE, + NLA, + ALGEBRAIC + }; + + Type mType = Type::UNKNOWN; + + VariablePtrs mDependencies; + + AnalyserEquationAstPtr mAst; + + ComponentPtr mComponent; + + AnalyserInternalVariablePtrs mVariables; + AnalyserInternalVariablePtrs mOdeVariables; + AnalyserInternalVariablePtrs mAllVariables; + AnalyserInternalVariablePtrs mUnknownVariables; + + size_t mNlaSystemIndex = MAX_SIZE_T; + AnalyserInternalEquationWeakPtrs mNlaSiblings; + + bool mComputedTrueConstant = true; + bool mComputedVariableBasedConstant = true; + + static AnalyserInternalEquationPtr create(const ComponentPtr &component); + static AnalyserInternalEquationPtr create(const AnalyserInternalVariablePtr &variable); + + 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 AnalyserInternalVariablePtrs &variables); + bool hasKnownVariables(); + + static bool isNonConstantVariable(const AnalyserInternalVariablePtr &variable); + + static bool hasNonConstantVariables(const AnalyserInternalVariablePtrs &variables); + bool hasNonConstantVariables(); + + bool variableOnLhsRhs(const AnalyserInternalVariablePtr &variable, + const AnalyserEquationAstPtr &astChild); + bool variableOnRhs(const AnalyserInternalVariablePtr &variable); + bool variableOnLhsOrRhs(const AnalyserInternalVariablePtr &variable); + + bool check(const AnalyserModelPtr &model, size_t &stateIndex, size_t &computedConstantIndex, size_t &algebraicIndex, bool checkNlaSystems); +}; + +/** + * @brief The Analyser::AnalyserImpl class. + * + * The private implementation for the Analyser class. + */ +using UnitsMap = std::map; +using UnitsMaps = std::vector; +using UnitsMultipliers = std::vector; + +class Analyser::AnalyserImpl: public Logger::LoggerImpl +{ +public: + class PowerData + { + public: + bool mDimensionlessBase; + bool mExponentValueAvailable = true; + bool mExponentValueChangeable = false; + double mExponentValue; + AnalyserEquationAstPtr mExponentAst; + }; + + Analyser *mAnalyser = nullptr; + + AnalyserModelPtr mModel = AnalyserModel::AnalyserModelImpl::create(); + + AnalyserExternalVariablePtrs mExternalVariables; + + AnalyserInternalVariablePtrs mInternalVariables; + AnalyserInternalEquationPtrs mInternalEquations; + + GeneratorProfilePtr mGeneratorProfile = libcellml::GeneratorProfile::create(); + + std::map mStandardUnits; + std::map mCiCnUnits; + + AnalyserImpl(); + + 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 analyseComponentVariables(const ComponentPtr &component); + + void doEquivalentVariables(const VariablePtr &variable, + VariablePtrs &equivalentVariables) const; + VariablePtrs equivalentVariables(const VariablePtr &variable) const; + + void analyseEquationAst(const AnalyserEquationAstPtr &ast); + + void updateUnitsMapWithStandardUnit(const std::string &unitsName, + UnitsMap &unitsMap, + double unitsExponent); + void updateUnitsMap(const ModelPtr &model, const std::string &unitsName, + UnitsMap &unitsMap, bool userUnitsMap = false, + double unitsExponent = 1.0, + double unitsMultiplier = 0.0); + UnitsMap multiplyDivideUnitsMaps(const UnitsMap &firstUnitsMap, + const UnitsMap &secondUnitsMap, + bool multiply); + UnitsMaps multiplyDivideUnitsMaps(const UnitsMaps &firstUnitsMaps, + const UnitsMaps &secondUnitsMaps, + bool multiply = true); + UnitsMaps multiplyDivideUnitsMaps(const UnitsMaps &unitsMaps, + double factor, bool multiply); + double multiplyDivideUnitsMultipliers(double firstUnitsMultiplier, + double secondUnitsMultiplier, + bool multiply); + UnitsMultipliers multiplyDivideUnitsMultipliers(const UnitsMultipliers &firstUnitsMultipliers, + const UnitsMultipliers &secondUnitsMultipliers, + bool multiply = true); + UnitsMultipliers multiplyDivideUnitsMultipliers(double firstUnitsMultiplier, + const UnitsMultipliers &secondUnitsMultipliers, + bool multiply); + UnitsMultipliers powerRootUnitsMultipliers(const UnitsMultipliers &unitsMultipliers, + double factor, bool power); + bool areSameUnitsMaps(const UnitsMaps &firstUnitsMaps, + const UnitsMaps &secondUnitsMaps); + bool isDimensionlessUnitsMaps(const UnitsMaps &unitsMaps); + bool areSameUnitsMultipliers(const UnitsMultipliers &firstUnitsMultipliers, + const UnitsMultipliers &secondUnitsMultipliers); + void updateUnitsMultiplier(const ModelPtr &model, + const std::string &unitsName, + double &newUnitsMultiplier, + double unitsExponent = 1.0, + double unitsMultiplier = 0.0); + std::string componentName(const AnalyserEquationAstPtr &ast); + double powerValue(const AnalyserEquationAstPtr &ast, PowerData &powerData); + std::string expression(const AnalyserEquationAstPtr &ast, + bool includeHierarchy = true); + std::string expressionUnits(const UnitsMaps &unitsMaps, + const UnitsMultipliers &unitsMultipliers = {}); + std::string expressionUnits(const AnalyserEquationAstPtr &ast, + const UnitsMaps &unitsMaps, + const UnitsMaps &userUnitsMaps, + const UnitsMultipliers &unitsMultipliers); + void defaultUnitsMapsAndMultipliers(UnitsMaps &unitsMaps, + UnitsMaps &userUnitsMaps, + UnitsMultipliers &unitsMultipliers); + void analyseEquationUnits(const AnalyserEquationAstPtr &ast, + UnitsMaps &unitsMaps, UnitsMaps &userUnitsMaps, + UnitsMultipliers &unitsMultipliers, + std::string &issueDescription, PowerData &powerData); + + double scalingFactor(const VariablePtr &variable); + + void scaleAst(const AnalyserEquationAstPtr &ast, + const AnalyserEquationAstPtr &astParent, + double scalingFactor); + void scaleEquationAst(const AnalyserEquationAstPtr &ast); + + static bool isExternalVariable(const AnalyserInternalVariablePtr &variable); + + bool isStateRateBased(const AnalyserEquationPtr &equation, + AnalyserEquationPtrs &checkedEquations); + + void addInvalidVariableIssue(const AnalyserInternalVariablePtr &variable, + Issue::ReferenceRule referenceRule); + + void analyseModel(const ModelPtr &model); + + AnalyserExternalVariablePtrs::const_iterator findExternalVariable(const ModelPtr &model, + const std::string &componentName, + const std::string &variableName) const; + AnalyserExternalVariablePtrs::const_iterator findExternalVariable(const AnalyserExternalVariablePtr &externalVariable) const; +}; + +} // namespace libcellml