From e1bf70b1856874adcb40ff642d08024679dec87b Mon Sep 17 00:00:00 2001 From: NikitaZotov Date: Fri, 6 Dec 2024 02:28:50 +0300 Subject: [PATCH] [memory][scs][tests] Don't allow belonging nodes to connector types and connectors to node types --- .../include/sc-memory/scs/scs_parser.hpp | 2 +- .../include/sc-memory/scs/scs_types.hpp | 15 ++-- sc-memory/sc-memory/src/sc_scs_helper.cpp | 2 +- sc-memory/sc-memory/src/scs/scs_parser.cpp | 31 ++++--- sc-memory/sc-memory/src/scs/scs_types.cpp | 86 ++++++++++++------- .../units/scs-helper/test_scs_helper.cpp | 19 ++-- 6 files changed, 100 insertions(+), 55 deletions(-) diff --git a/sc-memory/sc-memory/include/sc-memory/scs/scs_parser.hpp b/sc-memory/sc-memory/include/sc-memory/scs/scs_parser.hpp index 3210b238e..6506ad3b1 100644 --- a/sc-memory/sc-memory/include/sc-memory/scs/scs_parser.hpp +++ b/sc-memory/sc-memory/include/sc-memory/scs/scs_parser.hpp @@ -185,7 +185,7 @@ class Parser IdtfToParsedElementMap m_idtfToParsedElement; AliasHandles m_aliasHandles; std::unordered_set m_elementTypeOutgoingBaseArcs; - std::multimap m_elementTypeNotOutgoingBaseArcsToElementTypes; + std::multimap m_elementTypeNotOutgoingBaseArcsToSCsElementTypes; std::string m_lastError; diff --git a/sc-memory/sc-memory/include/sc-memory/scs/scs_types.hpp b/sc-memory/sc-memory/include/sc-memory/scs/scs_types.hpp index fd9267d43..69d09c8bb 100644 --- a/sc-memory/sc-memory/include/sc-memory/scs/scs_types.hpp +++ b/sc-memory/sc-memory/include/sc-memory/scs/scs_types.hpp @@ -22,12 +22,14 @@ class TypeResolver final static std::string GetSCsElementKeynode(ScType const & type); static ScType const & GetConnectorType(std::string const & connectorAlias); - static ScType const & GetKeynodeType(std::string const & keynodeAlias); + static ScType GetTypeBySCsElementType(std::string const & keynodeAlias); static bool IsConnectorReversed(std::string const & connectorAlias); static bool IsConst(std::string const & idtf); static bool IsConnectorAttrConst(std::string const & attr); - static bool IsKeynodeType(std::string const & alias); + static bool IsElementType(std::string const & alias); + static bool IsNodeType(std::string const & alias); + static bool IsConnectorType(std::string const & alias); static bool IsUnnamed(std::string const & alias); protected: @@ -44,10 +46,13 @@ class TypeResolver final static ScTypesToSCsDesignations ms_typesToConnectors; static ScTypesToSCsDesignations ms_typesToReverseConnectors; - static SCsDesignationsToScTypes ms_keynodesToTypes; - static SCsDesignationsToScTypes ms_deprecatedKeynodesToTypes; + static SCsDesignationsToScTypes ms_scsNodeTypesToTypes; + static SCsDesignationsToScTypes ms_deprecatedSCsNodeTypesToTypes; - static ScTypesToSCsDesignations ms_typesToKeynodes; + static SCsDesignationsToScTypes ms_scsConnectorTypesToTypes; + static SCsDesignationsToScTypes ms_deprecatedSCsConnectorTypesToTypes; + + static ScTypesToSCsDesignations ms_typesToSCsElementTypes; static SCsConnectorDesignations ms_reversedConnectors; static SCsConnectorDesignations ms_deprecatedReversedConnectors; diff --git a/sc-memory/sc-memory/src/sc_scs_helper.cpp b/sc-memory/sc-memory/src/sc_scs_helper.cpp index 0d9909ac1..600fc8d32 100644 --- a/sc-memory/sc-memory/src/sc_scs_helper.cpp +++ b/sc-memory/sc-memory/src/sc_scs_helper.cpp @@ -166,7 +166,7 @@ class StructGenerator // TODO(NikitaZotov): Throw exception if this sc-link is a sc-link with system identifier of sc-element // denoting sc-elements type, and type of sc-element, for which this sc-link is specified as a system // identifier, can't be extended to ScType::ConstNodeClass. See - // SCsHelperTest.GenerateBySCs_ContourWithExplicitlySpecifiedElementTypeSystemIdentifier. + // SCsHelperTest.GenerateBySCs_ContourWithExplicitlySpecifiedSCsElementTypesystemIdentifier. resultAddr = m_ctx.GenerateLink(type); SetupLinkContent(resultAddr, el); } diff --git a/sc-memory/sc-memory/src/scs/scs_parser.cpp b/sc-memory/sc-memory/src/scs/scs_parser.cpp index 866144eb4..707e7fcb4 100644 --- a/sc-memory/sc-memory/src/scs/scs_parser.cpp +++ b/sc-memory/sc-memory/src/scs/scs_parser.cpp @@ -124,7 +124,7 @@ ParsedElement::ParsedElement( , m_value(value) , m_isURL(isURL) { - m_isElementType = scs::TypeResolver::IsKeynodeType(m_idtf); + m_isElementType = scs::TypeResolver::IsElementType(m_idtf); if (!m_value.empty()) m_visibility = Visibility::Local; @@ -458,7 +458,7 @@ ElementHandle Parser::ProcessIdentifier(std::string const & name) ElementHandle Parser::ProcessIdentifierLevel1(std::string const & scsType, std::string const & name) { - ScType type = scs::TypeResolver::GetKeynodeType(scsType); + ScType type = scs::TypeResolver::GetTypeBySCsElementType(scsType); type |= scs::TypeResolver::IsConst(name) ? ScType::Const : ScType::Var; return AppendElement(name, type); } @@ -479,15 +479,22 @@ void Parser::ProcessTriple( if (source.IsElementType() && (connector.GetType() == ScType::ConstPermPosArc)) { - if (target.m_type.IsConnector()) + if (TypeResolver::IsNodeType(source.GetIdtf()) && target.m_type.IsConnector()) SC_THROW_EXCEPTION( utils::ExceptionParseError, "Connector with type `" << std::string(target.m_type) - << "` can't belong to sc-element denoting type of sc-elements `" << source.GetIdtf() + << "` can't belong to sc-element denoting type of sc-nodes `" << source.GetIdtf() + << "`."); + + if (TypeResolver::IsConnectorType(source.GetIdtf()) && target.m_type.IsNode()) + SC_THROW_EXCEPTION( + utils::ExceptionParseError, + "Node with type `" << std::string(target.m_type) + << "` can't belong to sc-element denoting type of sc-connectors `" << source.GetIdtf() << "`."); std::string const & sourceIdtf = source.GetIdtf(); - ScType const newType = target.m_type | scs::TypeResolver::GetKeynodeType(sourceIdtf); + ScType const newType = target.m_type | scs::TypeResolver::GetTypeBySCsElementType(sourceIdtf); if (target.IsElementType() && !newType.CanExtendTo(ScType::ConstNodeClass)) SC_THROW_EXCEPTION( @@ -514,15 +521,15 @@ void Parser::ProcessTriple( m_elementTypeOutgoingBaseArcs.insert(connector.GetIdtf()); if (target.IsElementType()) - m_elementTypeNotOutgoingBaseArcsToElementTypes.insert({connector.GetIdtf(), targetHdl}); + m_elementTypeNotOutgoingBaseArcsToSCsElementTypes.insert({connector.GetIdtf(), targetHdl}); } else if (source.IsElementType() || target.IsElementType()) { if (source.IsElementType()) - m_elementTypeNotOutgoingBaseArcsToElementTypes.insert({connector.GetIdtf(), sourceHdl}); + m_elementTypeNotOutgoingBaseArcsToSCsElementTypes.insert({connector.GetIdtf(), sourceHdl}); if (target.IsElementType()) - m_elementTypeNotOutgoingBaseArcsToElementTypes.insert({connector.GetIdtf(), targetHdl}); + m_elementTypeNotOutgoingBaseArcsToSCsElementTypes.insert({connector.GetIdtf(), targetHdl}); } else { @@ -670,21 +677,21 @@ void Parser::ProcessContourEnd(ElementHandle const & contourHandle) newElements.insert(t.m_target); } - std::unordered_set addedElementTypesIntoStructure; + std::unordered_set addedSCsElementTypesIntoStructure; for (auto const & elementHandle : newElements) { auto const & element = GetParsedElement(elementHandle); // Add sc-arc from structure to element type if element type has not only outgoing base sc-arcs - auto const & range = m_elementTypeNotOutgoingBaseArcsToElementTypes.equal_range(element.GetIdtf()); + auto const & range = m_elementTypeNotOutgoingBaseArcsToSCsElementTypes.equal_range(element.GetIdtf()); for (auto it = range.first; it != range.second; ++it) { - if (addedElementTypesIntoStructure.count(*it->second)) + if (addedSCsElementTypesIntoStructure.count(*it->second)) continue; ElementHandle const connectorHandle = ProcessConnector("->"); ProcessTriple(contourHandle, connectorHandle, it->second); - addedElementTypesIntoStructure.insert(*it->second); + addedSCsElementTypesIntoStructure.insert(*it->second); } if (elementHandle.IsElementType() || IsElementTypeOutgoingBaseArc(element)) diff --git a/sc-memory/sc-memory/src/scs/scs_types.cpp b/sc-memory/sc-memory/src/scs/scs_types.cpp index 0ba7e5c01..f8b9d466c 100644 --- a/sc-memory/sc-memory/src/scs/scs_types.cpp +++ b/sc-memory/sc-memory/src/scs/scs_types.cpp @@ -292,12 +292,7 @@ TypeResolver::ScTypesToSCsDesignations TypeResolver::ms_typesToReverseConnectors {ScType::VarInactualTempNegArc, "<|%_"} }; -TypeResolver::SCsDesignationsToScTypes TypeResolver::ms_keynodesToTypes = { - {"sc_common_edge", ScType::CommonEdge}, - {"sc_common_arc", ScType::CommonArc}, - {"sc_membership_arc", ScType::MembershipArc}, - {"sc_main_arc", ScType::ConstPermPosArc}, - +TypeResolver::SCsDesignationsToScTypes TypeResolver::ms_scsNodeTypesToTypes = { {"sc_node", ScType::Node}, {"sc_link", ScType::NodeLink}, {"sc_link_class", ScType::NodeLinkClass}, @@ -310,7 +305,21 @@ TypeResolver::SCsDesignationsToScTypes TypeResolver::ms_keynodesToTypes = { {"sc_node_material", ScType::NodeMaterial}, }; -TypeResolver::SCsDesignationsToScTypes TypeResolver::ms_deprecatedKeynodesToTypes = { +TypeResolver::SCsDesignationsToScTypes TypeResolver::ms_scsConnectorTypesToTypes = { + {"sc_common_edge", ScType::CommonEdge}, + {"sc_common_arc", ScType::CommonArc}, + {"sc_membership_arc", ScType::MembershipArc}, + {"sc_main_arc", ScType::ConstPermPosArc}, +}; + +TypeResolver::SCsDesignationsToScTypes TypeResolver::ms_deprecatedSCsNodeTypesToTypes = { + {"sc_node_not_binary_tuple", ScType::NodeTuple}, + {"sc_node_struct", ScType::NodeStructure}, + {"sc_node_not_relation", ScType::NodeClass}, + {"sc_node_norole_relation", ScType::NodeNonRole}, +}; + +TypeResolver::SCsDesignationsToScTypes TypeResolver::ms_deprecatedSCsConnectorTypesToTypes = { {"sc_edge", ScType::CommonEdge}, {"sc_edge_ucommon", ScType::CommonEdge}, @@ -322,14 +331,9 @@ TypeResolver::SCsDesignationsToScTypes TypeResolver::ms_deprecatedKeynodesToType {"sc_arc_access", ScType::MembershipArc}, {"sc_edge_access", ScType::MembershipArc}, - - {"sc_node_not_binary_tuple", ScType::NodeTuple}, - {"sc_node_struct", ScType::NodeStructure}, - {"sc_node_not_relation", ScType::NodeClass}, - {"sc_node_norole_relation", ScType::NodeNonRole}, }; -TypeResolver::ScTypesToSCsDesignations TypeResolver::ms_typesToKeynodes = { +TypeResolver::ScTypesToSCsDesignations TypeResolver::ms_typesToSCsElementTypes = { {ScType::CommonEdge, "sc_common_edge"}, {ScType::CommonArc, "sc_common_arc"}, {ScType::MembershipArc, "sc_membership_arc"}, @@ -379,8 +383,8 @@ std::string TypeResolver::GetReverseSCsConnector(ScType const & type) std::string TypeResolver::GetSCsElementKeynode(ScType const & type) { - auto const it = ms_typesToKeynodes.find(type); - if (it == ms_typesToKeynodes.cend()) + auto const it = ms_typesToSCsElementTypes.find(type); + if (it == ms_typesToSCsElementTypes.cend()) return ""; return it->second; @@ -412,22 +416,33 @@ ScType const & TypeResolver::GetConnectorType(std::string const & connectorAlias return it->second; } -ScType const & TypeResolver::GetKeynodeType(std::string const & keynodeAlias) +ScType TypeResolver::GetTypeBySCsElementType(std::string const & keynodeAlias) { - auto const it = ms_keynodesToTypes.find(keynodeAlias); - if (it == ms_keynodesToTypes.cend()) - { - auto const deprecatedIt = ms_deprecatedKeynodesToTypes.find(keynodeAlias); - if (deprecatedIt == ms_deprecatedKeynodesToTypes.cend()) - return ScType::Unknown; + auto const _GetTypeBySCsElementType = [&]( + SCsDesignationsToScTypes const & scsElementTypesToTypes, + SCsDesignationsToScTypes const & deprecatedSCsElementTypesToTypes + ) -> ScType { + auto const it = scsElementTypesToTypes.find(keynodeAlias); + if (it == scsElementTypesToTypes.cend()) + { + auto const deprecatedIt = deprecatedSCsElementTypesToTypes.find(keynodeAlias); + if (deprecatedIt == deprecatedSCsElementTypesToTypes.cend()) + return ScType::Unknown; - SC_LOG_WARNING("Specified sc-type class `" << keynodeAlias << "` is deprecated in SCs-code, " - << "use `" << ms_typesToKeynodes[deprecatedIt->second] << "` instead."); + SC_LOG_WARNING("Specified sc-type class `" << keynodeAlias << "` is deprecated in SCs-code, " + << "use `" << ms_typesToSCsElementTypes[deprecatedIt->second] << "` instead."); - return deprecatedIt->second; - } + return deprecatedIt->second; + } - return it->second; + return it->second; + }; + + ScType type = _GetTypeBySCsElementType(ms_scsNodeTypesToTypes, ms_deprecatedSCsNodeTypesToTypes); + if (type.IsUnknown()) + type = _GetTypeBySCsElementType(ms_scsConnectorTypesToTypes, ms_deprecatedSCsConnectorTypesToTypes); + + return type; } bool TypeResolver::IsConnectorReversed(std::string const & connectorAlias) @@ -454,10 +469,21 @@ bool TypeResolver::IsConnectorAttrConst(std::string const & attr) return attr == ":"; } -bool TypeResolver::IsKeynodeType(std::string const & alias) +bool TypeResolver::IsElementType(std::string const & alias) +{ + return IsNodeType(alias) || IsConnectorType(alias); +} + +bool TypeResolver::IsNodeType(std::string const & alias) +{ + return ms_scsNodeTypesToTypes.find(alias) != ms_scsNodeTypesToTypes.cend() + || ms_deprecatedSCsNodeTypesToTypes.find(alias) != ms_deprecatedSCsNodeTypesToTypes.cend(); +} + +bool TypeResolver::IsConnectorType(std::string const & alias) { - return ms_keynodesToTypes.find(alias) != ms_keynodesToTypes.cend() - || ms_deprecatedKeynodesToTypes.find(alias) != ms_deprecatedKeynodesToTypes.cend(); + return ms_scsConnectorTypesToTypes.find(alias) != ms_scsConnectorTypesToTypes.cend() + || ms_deprecatedSCsConnectorTypesToTypes.find(alias) != ms_deprecatedSCsConnectorTypesToTypes.cend(); } bool TypeResolver::IsUnnamed(std::string const & alias) diff --git a/sc-memory/sc-memory/tests/sc-memory/units/scs-helper/test_scs_helper.cpp b/sc-memory/sc-memory/tests/sc-memory/units/scs-helper/test_scs_helper.cpp index 0c0fbbd9f..af0d9c91d 100644 --- a/sc-memory/sc-memory/tests/sc-memory/units/scs-helper/test_scs_helper.cpp +++ b/sc-memory/sc-memory/tests/sc-memory/units/scs-helper/test_scs_helper.cpp @@ -310,7 +310,7 @@ TEST_F(SCsHelperTest, GenerateBySCs_ArcToElementTypeWithinStructure) EXPECT_TRUE(m_ctx->CheckConnector(structureAddr, nodeClassAddr, ScType::ConstPermPosArc)); } -TEST_F(SCsHelperTest, GenerateBySCs_BaseArcBetweenElementTypesWithinStructure) +TEST_F(SCsHelperTest, GenerateBySCs_BaseArcBetweenSCsElementTypesWithinStructure) { SCsHelper helper(*m_ctx, std::make_shared()); std::string const scsData = "structure = [* sc_node -> sc_node_class;; *];;"; @@ -327,21 +327,21 @@ TEST_F(SCsHelperTest, GenerateBySCs_BaseArcBetweenElementTypesWithinStructure) EXPECT_TRUE(m_ctx->CheckConnector(structureAddr, nodeClassAddr, ScType::ConstPermPosArc)); } -TEST_F(SCsHelperTest, GenerateBySCs_ArcToElementTypeFromIncomtableElementTypesWithinStructure) +TEST_F(SCsHelperTest, GenerateBySCs_ArcToElementTypeFromIncomtableSCsElementTypesWithinStructure) { SCsHelper helper(*m_ctx, std::make_shared()); std::string const scsData = "structure = [* sc_node_tuple -> sc_node_class;; *];;"; EXPECT_FALSE(helper.GenerateBySCsText(scsData)); } -TEST_F(SCsHelperTest, GenerateBySCs_ContourWithImplicitlySpecifiedElementTypeSystemIdentifier) +TEST_F(SCsHelperTest, GenerateBySCs_ContourWithImplicitlySpecifiedSCsElementTypesystemIdentifier) { SCsHelper helper(*m_ctx, std::make_shared()); std::string const scsData = "sc_node_class = [* sc_node -> sc_node_class;; *];;"; EXPECT_FALSE(helper.GenerateBySCsText(scsData)); } -TEST_F(SCsHelperTest, DISABLED_GenerateBySCs_ContourWithExplicitlySpecifiedElementTypeSystemIdentifier) +TEST_F(SCsHelperTest, DISABLED_GenerateBySCs_ContourWithExplicitlySpecifiedSCsElementTypesystemIdentifier) { SCsHelper helper(*m_ctx, std::make_shared()); std::string const scsData = @@ -350,14 +350,21 @@ TEST_F(SCsHelperTest, DISABLED_GenerateBySCs_ContourWithExplicitlySpecifiedEleme EXPECT_FALSE(helper.GenerateBySCsText(scsData)); } -TEST_F(SCsHelperTest, GenerateBySCs_ConnectorBelongsToElementType) +TEST_F(SCsHelperTest, GenerateBySCs_ConnectorBelongsToNodeType) { SCsHelper helper(*m_ctx, std::make_shared()); std::string const scsData = "..contour = [* sc_node_tuple -> (sc_node_class => sc_node_tuple);; *];;"; EXPECT_FALSE(helper.GenerateBySCsText(scsData)); } -TEST_F(SCsHelperTest, GenerateBySCs_NotBaseArcBetweenElementTypesWithinStructure) +TEST_F(SCsHelperTest, GenerateBySCs_NodeBelongsToConnectorsType) +{ + SCsHelper helper(*m_ctx, std::make_shared()); + std::string const scsData = "..contour = [* sc_main_arc -> ..node;; *];;"; + EXPECT_FALSE(helper.GenerateBySCsText(scsData)); +} + +TEST_F(SCsHelperTest, GenerateBySCs_NotBaseArcBetweenSCsElementTypesWithinStructure) { SCsHelper helper(*m_ctx, std::make_shared()); std::string const scsData = "structure = [* sc_node_tuple -|> sc_node_class;; *];;";