Skip to content

Commit

Permalink
[memory][scs][tests] Don't allow belonging nodes to connector types a…
Browse files Browse the repository at this point in the history
…nd connectors to node types
  • Loading branch information
NikitaZotov committed Dec 5, 2024
1 parent 416e8cc commit e1bf70b
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 55 deletions.
2 changes: 1 addition & 1 deletion sc-memory/sc-memory/include/sc-memory/scs/scs_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ class Parser
IdtfToParsedElementMap m_idtfToParsedElement;
AliasHandles m_aliasHandles;
std::unordered_set<std::string> m_elementTypeOutgoingBaseArcs;
std::multimap<std::string, ElementHandle> m_elementTypeNotOutgoingBaseArcsToElementTypes;
std::multimap<std::string, ElementHandle> m_elementTypeNotOutgoingBaseArcsToSCsElementTypes;

std::string m_lastError;

Expand Down
15 changes: 10 additions & 5 deletions sc-memory/sc-memory/include/sc-memory/scs/scs_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion sc-memory/sc-memory/src/sc_scs_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
31 changes: 19 additions & 12 deletions sc-memory/sc-memory/src/scs/scs_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand All @@ -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(
Expand All @@ -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
{
Expand Down Expand Up @@ -670,21 +677,21 @@ void Parser::ProcessContourEnd(ElementHandle const & contourHandle)
newElements.insert(t.m_target);
}

std::unordered_set<ElementID> addedElementTypesIntoStructure;
std::unordered_set<ElementID> 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))
Expand Down
86 changes: 56 additions & 30 deletions sc-memory/sc-memory/src/scs/scs_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand All @@ -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},

Expand All @@ -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"},
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<DummyFileInterface>());
std::string const scsData = "structure = [* sc_node -> sc_node_class;; *];;";
Expand All @@ -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<DummyFileInterface>());
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<DummyFileInterface>());
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<DummyFileInterface>());
std::string const scsData =
Expand All @@ -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<DummyFileInterface>());
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<DummyFileInterface>());
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<DummyFileInterface>());
std::string const scsData = "structure = [* sc_node_tuple -|> sc_node_class;; *];;";
Expand Down

0 comments on commit e1bf70b

Please sign in to comment.