mirror of
https://github.com/IRBorisov/ConceptCore.git
synced 2025-06-26 01:00:36 +03:00
F: Improve typechecking API for CstTypes expectations
This commit is contained in:
parent
71a5b32de7
commit
c8578447f3
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
|
@ -18,6 +18,7 @@
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"BIGPR",
|
"BIGPR",
|
||||||
"conanfile",
|
"conanfile",
|
||||||
|
"constituenta",
|
||||||
"coredll",
|
"coredll",
|
||||||
"DCMAKE",
|
"DCMAKE",
|
||||||
"debool",
|
"debool",
|
||||||
|
@ -36,6 +37,7 @@
|
||||||
"NOTEQUAL",
|
"NOTEQUAL",
|
||||||
"NOTIN",
|
"NOTIN",
|
||||||
"notsubset",
|
"notsubset",
|
||||||
|
"pbdoc",
|
||||||
"PUNC",
|
"PUNC",
|
||||||
"pybind",
|
"pybind",
|
||||||
"pyconcept",
|
"pyconcept",
|
||||||
|
|
|
@ -198,6 +198,7 @@
|
||||||
<ClCompile Include="src\semantic\rsmodel\rsValuesFacet.cpp" />
|
<ClCompile Include="src\semantic\rsmodel\rsValuesFacet.cpp" />
|
||||||
<ClCompile Include="src\semantic\schema\RSConcept.cpp" />
|
<ClCompile Include="src\semantic\schema\RSConcept.cpp" />
|
||||||
<ClCompile Include="src\semantic\schema\Schema.cpp" />
|
<ClCompile Include="src\semantic\schema\Schema.cpp" />
|
||||||
|
<ClCompile Include="src\semantic\schema\SchemaAuditor.cpp" />
|
||||||
<ClCompile Include="src\semantic\thesaurus\TextConcept.cpp" />
|
<ClCompile Include="src\semantic\thesaurus\TextConcept.cpp" />
|
||||||
<ClCompile Include="src\semantic\thesaurus\Thesaurus.cpp" />
|
<ClCompile Include="src\semantic\thesaurus\Thesaurus.cpp" />
|
||||||
<ClCompile Include="src\tools\CstNameGenerator.cpp" />
|
<ClCompile Include="src\tools\CstNameGenerator.cpp" />
|
||||||
|
@ -235,6 +236,7 @@
|
||||||
<ClInclude Include="include\ccl\semantic\rsOperationFacet.h" />
|
<ClInclude Include="include\ccl\semantic\rsOperationFacet.h" />
|
||||||
<ClInclude Include="include\ccl\semantic\rsValuesFacet.h" />
|
<ClInclude Include="include\ccl\semantic\rsValuesFacet.h" />
|
||||||
<ClInclude Include="include\ccl\semantic\Schema.h" />
|
<ClInclude Include="include\ccl\semantic\Schema.h" />
|
||||||
|
<ClInclude Include="include\ccl\semantic\SchemaAuditor.h" />
|
||||||
<ClInclude Include="include\ccl\semantic\TextConcept.h" />
|
<ClInclude Include="include\ccl\semantic\TextConcept.h" />
|
||||||
<ClInclude Include="include\ccl\semantic\TextData.hpp" />
|
<ClInclude Include="include\ccl\semantic\TextData.hpp" />
|
||||||
<ClInclude Include="include\ccl\semantic\Thesaurus.h" />
|
<ClInclude Include="include\ccl\semantic\Thesaurus.h" />
|
||||||
|
|
|
@ -129,6 +129,9 @@
|
||||||
<ClCompile Include="src\api\RSFormJA.cpp">
|
<ClCompile Include="src\api\RSFormJA.cpp">
|
||||||
<Filter>06 API</Filter>
|
<Filter>06 API</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\semantic\schema\SchemaAuditor.cpp">
|
||||||
|
<Filter>03 semantic\01 Schema</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="include\ccl\env\SourceManager.hpp">
|
<ClInclude Include="include\ccl\env\SourceManager.hpp">
|
||||||
|
@ -248,5 +251,8 @@
|
||||||
<ClInclude Include="include\ccl\api\RSFormJA.h">
|
<ClInclude Include="include\ccl\api\RSFormJA.h">
|
||||||
<Filter>06 API</Filter>
|
<Filter>06 API</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\ccl\semantic\SchemaAuditor.h">
|
||||||
|
<Filter>03 semantic\01 Schema</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -25,6 +25,8 @@ public:
|
||||||
[[nodiscard]] std::string ToMinimalJSON() const;
|
[[nodiscard]] std::string ToMinimalJSON() const;
|
||||||
|
|
||||||
[[nodiscard]] std::string CheckExpression(const std::string& text, rslang::Syntax syntaxHint = rslang::Syntax::UNDEF) const;
|
[[nodiscard]] std::string CheckExpression(const std::string& text, rslang::Syntax syntaxHint = rslang::Syntax::UNDEF) const;
|
||||||
|
[[nodiscard]] std::string CheckConstituenta(const std::string& alias, const std::string& definition, semantic::CstType targetType) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ccl::api
|
} // namespace ccl::api
|
||||||
|
|
|
@ -89,7 +89,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Pict* Access(PictID pid);
|
Pict* Access(PictID pid);
|
||||||
void InsertInternal(const Pict& pict, GridPosition pos,
|
void InsertInternal(Pict&& pict, GridPosition pos,
|
||||||
const src::Handle& srcHandle,
|
const src::Handle& srcHandle,
|
||||||
std::unique_ptr<OperationHandle> opHandle);
|
std::unique_ptr<OperationHandle> opHandle);
|
||||||
|
|
||||||
|
|
|
@ -97,4 +97,14 @@ constexpr bool IsStatement(const CstType type) noexcept {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr bool IsLogical(const CstType type) noexcept {
|
||||||
|
switch (type) {
|
||||||
|
default: return false;
|
||||||
|
case CstType::axiom:
|
||||||
|
case CstType::theorem:
|
||||||
|
case CstType::predicate:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ccl::semantic
|
} // namespace ccl::semantic
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ccl/rslang/Auditor.h"
|
|
||||||
#include "ccl/rslang/SyntaxTree.h"
|
#include "ccl/rslang/SyntaxTree.h"
|
||||||
|
#include "ccl/semantic/SchemaAuditor.h"
|
||||||
#include "ccl/semantic/RSConcept.h"
|
#include "ccl/semantic/RSConcept.h"
|
||||||
#include "ccl/graph/CGraph.h"
|
#include "ccl/graph/CGraph.h"
|
||||||
|
|
||||||
|
@ -50,8 +50,8 @@ class Schema final : public rslang::TypeContext {
|
||||||
mutable graph::UpdatableGraph graph;
|
mutable graph::UpdatableGraph graph;
|
||||||
|
|
||||||
// Note: Auditor should be created last because it needs context references
|
// Note: Auditor should be created last because it needs context references
|
||||||
using RSAuditor = std::unique_ptr<rslang::Auditor>;
|
using RSAuditor = std::unique_ptr<SchemaAuditor>;
|
||||||
mutable RSAuditor auditor{ std::make_unique<rslang::Auditor>(*this, VCContext(), ASTContext()) };
|
mutable RSAuditor auditor{ std::make_unique<SchemaAuditor>(*this, VCContext(), ASTContext()) };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~Schema() noexcept final = default;
|
~Schema() noexcept final = default;
|
||||||
|
@ -85,8 +85,13 @@ public:
|
||||||
[[nodiscard]] rslang::SyntaxTreeContext ASTContext() const;
|
[[nodiscard]] rslang::SyntaxTreeContext ASTContext() const;
|
||||||
[[nodiscard]] rslang::ValueClassContext VCContext() const;
|
[[nodiscard]] rslang::ValueClassContext VCContext() const;
|
||||||
|
|
||||||
bool Emplace(EntityUID newID, std::string newAlias, CstType type,
|
bool Emplace(
|
||||||
std::string definition = {}, std::string convention = {});
|
EntityUID newID,
|
||||||
|
std::string newAlias,
|
||||||
|
CstType type,
|
||||||
|
std::string definition = {},
|
||||||
|
std::string convention = {}
|
||||||
|
);
|
||||||
bool InsertCopy(const RSConcept& cst);
|
bool InsertCopy(const RSConcept& cst);
|
||||||
bool Insert(RSConcept&& cst);
|
bool Insert(RSConcept&& cst);
|
||||||
void Load(RSConcept&& cst);
|
void Load(RSConcept&& cst);
|
||||||
|
@ -101,11 +106,9 @@ public:
|
||||||
void Translate(EntityUID target, const StrTranslator& old2New);
|
void Translate(EntityUID target, const StrTranslator& old2New);
|
||||||
void TranslateAll(const StrTranslator& old2New);
|
void TranslateAll(const StrTranslator& old2New);
|
||||||
|
|
||||||
[[nodiscard]] static bool CheckTypeConstistency(const rslang::ExpressionType& type, CstType cstType) noexcept;
|
[[nodiscard]] std::unique_ptr<SchemaAuditor> MakeAuditor() const;
|
||||||
[[nodiscard]] std::optional<rslang::ExpressionType> Evaluate(const std::string& input) const;
|
[[nodiscard]] std::optional<rslang::ExpressionType> Evaluate(const std::string& input) const;
|
||||||
|
|
||||||
[[nodiscard]] std::unique_ptr<rslang::Auditor> MakeAuditor() const;
|
|
||||||
|
|
||||||
void UpdateState();
|
void UpdateState();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
56
ccl/core/include/ccl/semantic/SchemaAuditor.h
Normal file
56
ccl/core/include/ccl/semantic/SchemaAuditor.h
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ccl/semantic/CstType.hpp"
|
||||||
|
#include "ccl/rslang/Auditor.h"
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
namespace ccl::semantic {
|
||||||
|
|
||||||
|
//! CstType semantic errors enumeration
|
||||||
|
enum class CstTypeEID : uint32_t {
|
||||||
|
cstNonemptyBase = 0x8860, // Áàçèñíîå èëè êîíñòàíòíîå ìíîæåñòâî íå ïóñòî
|
||||||
|
cstEmptyDerived = 0x8861, // Îïðåäåëåíèå ïîíÿòèÿ ïóñòî
|
||||||
|
cstCallableNoArgs = 0x8862, // Ïàðàìåòðèçîâàííîå âûðàæåíèå áåç àðãóìåíòîâ
|
||||||
|
cstNonCallableHasArgs = 0x8863, // Íåïàðàìåòðèçîâàííîå âûðàæåíèå ñ àðãóìåíòàìè
|
||||||
|
cstExpectedLogical = 0x8864, // Îæèäàëîñü ëîãè÷åñêîå âûðàæåíèå
|
||||||
|
cstExpectedTyped = 0x8865, // Îæèäàëîñü òåîðåòèêî-ìíîæåñòâåííîå âûðàæåíèå
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Auditor for Schema - wrapper around rsLang::Auditor
|
||||||
|
class SchemaAuditor {
|
||||||
|
public:
|
||||||
|
StrPos prefixLen;
|
||||||
|
|
||||||
|
private:
|
||||||
|
rslang::Auditor auditor;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SchemaAuditor(
|
||||||
|
const rslang::TypeContext& types,
|
||||||
|
rslang::ValueClassContext globalClass,
|
||||||
|
rslang::SyntaxTreeContext globalAST
|
||||||
|
);
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool CheckConstituenta(const std::string& alias, const std::string& definition, CstType targetType);
|
||||||
|
bool CheckExpression(const std::string& expr, rslang::Syntax syntax = rslang::Syntax::MATH);
|
||||||
|
bool CheckValue();
|
||||||
|
|
||||||
|
[[nodiscard]] bool IsParsed() const noexcept;
|
||||||
|
[[nodiscard]] bool IsTypeCorrect() const noexcept;
|
||||||
|
[[nodiscard]] bool IsValueCorrect() const noexcept;
|
||||||
|
|
||||||
|
[[nodiscard]] const rslang::Syntax& GetSyntax() const noexcept;
|
||||||
|
[[nodiscard]] const rslang::SyntaxTree& AST() const noexcept;
|
||||||
|
[[nodiscard]] const rslang::ErrorLogger& Errors() const noexcept;
|
||||||
|
[[nodiscard]] const rslang::FunctionArguments& GetDeclarationArgs() const noexcept;
|
||||||
|
[[nodiscard]] const rslang::ExpressionType& GetType() const noexcept;
|
||||||
|
[[nodiscard]] rslang::ValueClass GetValueClass() const noexcept;
|
||||||
|
[[nodiscard]] meta::UniqueCPPtr<rslang::SyntaxTree> ExtractAST() noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void OnError(CstTypeEID errorID);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ccl::semantic
|
|
@ -46,7 +46,7 @@ void LoadPicts(const JSON& data, ccl::oss::OSSchema& oss) {
|
||||||
}
|
}
|
||||||
if (it->contains("attachedOperation")) {
|
if (it->contains("attachedOperation")) {
|
||||||
opHandle = std::make_unique<OperationHandle>();
|
opHandle = std::make_unique<OperationHandle>();
|
||||||
it->at("attachedOperation").get_to(*opHandle.get());
|
it->at("attachedOperation").get_to(*opHandle);
|
||||||
}
|
}
|
||||||
oss.LoadPict(std::move(pict), position, srcHandle, std::move(opHandle));
|
oss.LoadPict(std::move(pict), position, srcHandle, std::move(opHandle));
|
||||||
}
|
}
|
||||||
|
@ -220,7 +220,6 @@ void to_json(JSON& object, const RSCore& core) {
|
||||||
for (const auto uid : core.List()) {
|
for (const auto uid : core.List()) {
|
||||||
const auto& parse = core.GetParse(uid);
|
const auto& parse = core.GetParse(uid);
|
||||||
const auto* typification = parse.Typification();
|
const auto* typification = parse.Typification();
|
||||||
const auto typeStr = typification != nullptr ? typification->ToString() : std::string{};
|
|
||||||
const auto* exprTree = core.RSLang().ASTContext()(core.GetRS(uid).alias);
|
const auto* exprTree = core.RSLang().ASTContext()(core.GetRS(uid).alias);
|
||||||
JSON cstJSON(core.AsRecord(uid));
|
JSON cstJSON(core.AsRecord(uid));
|
||||||
cstJSON["parse"] = {
|
cstJSON["parse"] = {
|
||||||
|
@ -309,7 +308,7 @@ void from_json(const JSON& object, TrackingFlags& mods) {
|
||||||
object.at("editConvention").get_to(mods.convention);
|
object.at("editConvention").get_to(mods.convention);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ccl::semantic
|
} // namespace semantic
|
||||||
|
|
||||||
|
|
||||||
namespace rslang {
|
namespace rslang {
|
||||||
|
@ -379,7 +378,7 @@ void to_json(JSON& object, const Error& error) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ccl::rslang
|
} // namespace rslang
|
||||||
|
|
||||||
|
|
||||||
namespace lang {
|
namespace lang {
|
||||||
|
@ -422,7 +421,7 @@ void from_json(const JSON& object, ManagedText& text) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ccl::lang
|
} // namespace lang
|
||||||
|
|
||||||
|
|
||||||
namespace src {
|
namespace src {
|
||||||
|
@ -532,12 +531,12 @@ void from_json(const JSON& object, OperationHandle& operation) {
|
||||||
object.at("isOutdated").get_to(operation.outdated);
|
object.at("isOutdated").get_to(operation.outdated);
|
||||||
if (object.contains("options")) {
|
if (object.contains("options")) {
|
||||||
auto opts = std::make_unique<ops::EquationOptions>();
|
auto opts = std::make_unique<ops::EquationOptions>();
|
||||||
object.at("options").at("data").get_to(*opts.get());
|
object.at("options").at("data").get_to(*opts);
|
||||||
operation.options = meta::UniqueCPPtr<ops::Options>{ std::move(opts) };
|
operation.options = meta::UniqueCPPtr<ops::Options>{ std::move(opts) };
|
||||||
}
|
}
|
||||||
if (object.contains("translations")) {
|
if (object.contains("translations")) {
|
||||||
operation.translations = std::make_unique<ops::TranslationData>();
|
operation.translations = std::make_unique<ops::TranslationData>();
|
||||||
object.at("translations").get_to(*operation.translations.get());
|
object.at("translations").get_to(*operation.translations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,7 +567,7 @@ void from_json(const JSON& object, GridPosition& position) {
|
||||||
object.at("column").get_to(position.column);
|
object.at("column").get_to(position.column);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ccl::oss
|
} // namespace oss
|
||||||
|
|
||||||
|
|
||||||
namespace ops {
|
namespace ops {
|
||||||
|
@ -614,7 +613,7 @@ void from_json(const JSON& object, Equation& equation) {
|
||||||
object.at("newTerm").get_to(equation.arg);
|
object.at("newTerm").get_to(equation.arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ccl::ops
|
} // namespace ops
|
||||||
|
|
||||||
void to_json(JSON& object, const EntityTranslation& translation) {
|
void to_json(JSON& object, const EntityTranslation& translation) {
|
||||||
object = JSON::array();
|
object = JSON::array();
|
||||||
|
|
|
@ -31,11 +31,11 @@ std::string ParseExpression(const std::string& expression, const rslang::Syntax
|
||||||
}
|
}
|
||||||
|
|
||||||
const semantic::RSForm& RSFormJA::data() const noexcept {
|
const semantic::RSForm& RSFormJA::data() const noexcept {
|
||||||
return *schema.get();
|
return *schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
semantic::RSForm& RSFormJA::data() noexcept {
|
semantic::RSForm& RSFormJA::data() noexcept {
|
||||||
return *schema.get();
|
return *schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
RSFormJA RSFormJA::FromData(semantic::RSForm&& data) {
|
RSFormJA RSFormJA::FromData(semantic::RSForm&& data) {
|
||||||
|
@ -74,11 +74,12 @@ std::string RSFormJA::CheckExpression(const std::string& text, const rslang::Syn
|
||||||
JSON result{};
|
JSON result{};
|
||||||
|
|
||||||
auto analyser = schema->Core().RSLang().MakeAuditor();
|
auto analyser = schema->Core().RSLang().MakeAuditor();
|
||||||
const auto typeOK = analyser->CheckType(text, syntaxHint);
|
const auto typeOK = analyser->CheckExpression(text, syntaxHint);
|
||||||
const auto valueOK = typeOK && analyser->CheckValue();
|
const auto valueOK = typeOK && analyser->CheckValue();
|
||||||
|
|
||||||
result["parseResult"] = typeOK;
|
result["parseResult"] = typeOK;
|
||||||
result["syntax"] = analyser->parser.syntax;
|
result["syntax"] = analyser->GetSyntax();
|
||||||
|
result["prefixLen"] = 0;
|
||||||
if (typeOK) {
|
if (typeOK) {
|
||||||
result["typification"] = analyser->GetType();
|
result["typification"] = analyser->GetType();
|
||||||
} else {
|
} else {
|
||||||
|
@ -96,9 +97,9 @@ std::string RSFormJA::CheckExpression(const std::string& text, const rslang::Syn
|
||||||
result["errors"] += error;
|
result["errors"] += error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (analyser->isParsed) {
|
if (analyser->IsParsed()) {
|
||||||
result["astText"] = rslang::AST2String::Apply(analyser->parser.AST());
|
result["astText"] = rslang::AST2String::Apply(analyser->AST());
|
||||||
result["ast"] = analyser->parser.AST();
|
result["ast"] = analyser->AST();
|
||||||
} else {
|
} else {
|
||||||
result["astText"] = "";
|
result["astText"] = "";
|
||||||
result["ast"] = JSON::array();
|
result["ast"] = JSON::array();
|
||||||
|
@ -107,4 +108,49 @@ std::string RSFormJA::CheckExpression(const std::string& text, const rslang::Syn
|
||||||
return result.dump(JSON_IDENT);
|
return result.dump(JSON_IDENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string RSFormJA::CheckConstituenta(
|
||||||
|
const std::string& alias,
|
||||||
|
const std::string& definition,
|
||||||
|
semantic::CstType targetType
|
||||||
|
) const {
|
||||||
|
JSON result{};
|
||||||
|
|
||||||
|
auto analyser = schema->Core().RSLang().MakeAuditor();
|
||||||
|
const auto typeOK = analyser->CheckConstituenta(alias, definition, targetType);
|
||||||
|
const auto valueOK = typeOK && analyser->CheckValue();
|
||||||
|
|
||||||
|
result["parseResult"] = typeOK;
|
||||||
|
result["syntax"] = analyser->GetSyntax();
|
||||||
|
result["prefixLen"] = analyser->prefixLen;
|
||||||
|
if (typeOK) {
|
||||||
|
result["typification"] = analyser->GetType();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result["typification"] = "N/A";
|
||||||
|
}
|
||||||
|
if (valueOK) {
|
||||||
|
result["valueClass"] = analyser->GetValueClass();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result["valueClass"] = ccl::rslang::ValueClass::invalid;
|
||||||
|
}
|
||||||
|
result["args"] = analyser->GetDeclarationArgs();
|
||||||
|
|
||||||
|
result["errors"] = JSON::array();
|
||||||
|
for (const auto& error : analyser->Errors().All()) {
|
||||||
|
result["errors"] += error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeOK) {
|
||||||
|
result["astText"] = rslang::AST2String::Apply(analyser->AST());
|
||||||
|
result["ast"] = analyser->AST();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result["astText"] = "";
|
||||||
|
result["ast"] = JSON::array();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.dump(JSON_IDENT);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ccl::api
|
} // namespace ccl::api
|
||||||
|
|
|
@ -139,7 +139,7 @@ const Pict& OSSchema::LoadPict(
|
||||||
pict.uid = idGen.NewUID();
|
pict.uid = idGen.NewUID();
|
||||||
}
|
}
|
||||||
const auto pid = pict.uid;
|
const auto pid = pict.uid;
|
||||||
InsertInternal(pict, pos, handle, std::move(params));
|
InsertInternal(std::move(pict), pos, handle, std::move(params));
|
||||||
return storage.at(pid);
|
return storage.at(pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,15 +175,14 @@ PictPtr OSSchema::InsertBase() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSSchema::InsertInternal(
|
void OSSchema::InsertInternal(
|
||||||
const Pict& pict,
|
Pict&& pict,
|
||||||
GridPosition pos,
|
GridPosition pos,
|
||||||
const src::Handle& srcHandle,
|
const src::Handle& srcHandle,
|
||||||
std::unique_ptr<OperationHandle> opHandle
|
std::unique_ptr<OperationHandle> opHandle
|
||||||
) {
|
) {
|
||||||
const auto pid = pict.uid;
|
const auto pid = pict.uid;
|
||||||
|
|
||||||
idGen.AddUID(pid);
|
idGen.AddUID(pid);
|
||||||
storage.emplace(pid, pict);
|
storage.emplace(pid, std::move(pict));
|
||||||
Grid().SetPosFor(pid, pos);
|
Grid().SetPosFor(pid, pos);
|
||||||
Src().sources.emplace(pid, srcHandle);
|
Src().sources.emplace(pid, srcHandle);
|
||||||
if (opHandle != nullptr) {
|
if (opHandle != nullptr) {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include "ccl/semantic/Schema.h"
|
#include "ccl/semantic/Schema.h"
|
||||||
|
|
||||||
#include "ccl/semantic/RSCore.h"
|
#include "ccl/semantic/RSCore.h"
|
||||||
#include "ccl/rslang/RSGenerator.h"
|
|
||||||
|
|
||||||
namespace ccl::semantic {
|
namespace ccl::semantic {
|
||||||
|
|
||||||
|
@ -243,8 +242,13 @@ void Schema::TranslateAll(const StrTranslator& old2New) {
|
||||||
UpdateState();
|
UpdateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Schema::Emplace(const EntityUID newID, std::string newAlias, const CstType type,
|
bool Schema::Emplace(
|
||||||
std::string definition, std::string convention) {
|
const EntityUID newID,
|
||||||
|
std::string newAlias,
|
||||||
|
const CstType type,
|
||||||
|
std::string definition,
|
||||||
|
std::string convention
|
||||||
|
) {
|
||||||
if (info.emplace(std::pair{ newID, ParsingInfo{} }).second) {
|
if (info.emplace(std::pair{ newID, ParsingInfo{} }).second) {
|
||||||
storage.emplace(std::pair{ newID,
|
storage.emplace(std::pair{ newID,
|
||||||
RSConcept{ newID, std::move(newAlias), type, std::move(definition), std::move(convention) } });
|
RSConcept{ newID, std::move(newAlias), type, std::move(definition), std::move(convention) } });
|
||||||
|
@ -357,16 +361,15 @@ rslang::ValueClassContext Schema::VCContext() const {
|
||||||
|
|
||||||
std::optional<rslang::ExpressionType>
|
std::optional<rslang::ExpressionType>
|
||||||
Schema::Evaluate(const std::string& input) const {
|
Schema::Evaluate(const std::string& input) const {
|
||||||
if (!auditor->CheckType(input, rslang::Syntax::MATH)) {
|
if (!auditor->CheckExpression(input)) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
} else {
|
} else {
|
||||||
return auditor->GetType();
|
return auditor->GetType();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::unique_ptr<rslang::Auditor>
|
[[nodiscard]] std::unique_ptr<SchemaAuditor> Schema::MakeAuditor() const {
|
||||||
Schema::MakeAuditor() const {
|
return std::make_unique<SchemaAuditor>(*this, VCContext(), ASTContext());
|
||||||
return std::make_unique<rslang::Auditor>(*this, VCContext(), ASTContext());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Schema::TriggerParse(const EntityUID target) {
|
void Schema::TriggerParse(const EntityUID target) {
|
||||||
|
@ -381,14 +384,8 @@ void Schema::TriggerParse(const EntityUID target) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Schema::ParseCst(const EntityUID target) {
|
void Schema::ParseCst(const EntityUID target) {
|
||||||
using rslang::Generator;
|
|
||||||
const auto& cst = At(target);
|
const auto& cst = At(target);
|
||||||
const auto expr = Generator::GlobalDefinition(cst.alias, cst.definition, cst.type == CstType::structured);
|
const auto isValid = auditor->CheckConstituenta(cst.alias, cst.definition, cst.type);
|
||||||
const auto isValid =
|
|
||||||
auditor->CheckType(expr, rslang::Syntax::MATH)
|
|
||||||
&& CheckTypeConstistency(auditor->GetType(), cst.type)
|
|
||||||
&& (IsBaseSet(cst.type) == std::empty(cst.definition));
|
|
||||||
|
|
||||||
info.at(target).Reset();
|
info.at(target).Reset();
|
||||||
info.at(target).status = isValid ? ParsingStatus::VERIFIED : ParsingStatus::INCORRECT;
|
info.at(target).status = isValid ? ParsingStatus::VERIFIED : ParsingStatus::INCORRECT;
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
|
@ -396,24 +393,6 @@ void Schema::ParseCst(const EntityUID target) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Schema::CheckTypeConstistency(const rslang::ExpressionType& type, const CstType cstType) noexcept {
|
|
||||||
switch (cstType) {
|
|
||||||
default: return false;
|
|
||||||
case CstType::base:
|
|
||||||
case CstType::constant:
|
|
||||||
case CstType::structured:
|
|
||||||
case CstType::function:
|
|
||||||
case CstType::term: {
|
|
||||||
return std::holds_alternative<rslang::Typification>(type);
|
|
||||||
}
|
|
||||||
case CstType::predicate:
|
|
||||||
case CstType::axiom:
|
|
||||||
case CstType::theorem: {
|
|
||||||
return std::holds_alternative<rslang::LogicT>(type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Schema::SaveInfoTo(ParsingInfo& out) {
|
void Schema::SaveInfoTo(ParsingInfo& out) {
|
||||||
out.exprType = auditor->GetType();
|
out.exprType = auditor->GetType();
|
||||||
if (const auto& funcArgs = auditor->GetDeclarationArgs(); !std::empty(funcArgs)) {
|
if (const auto& funcArgs = auditor->GetDeclarationArgs(); !std::empty(funcArgs)) {
|
||||||
|
@ -422,8 +401,8 @@ void Schema::SaveInfoTo(ParsingInfo& out) {
|
||||||
if (auditor->CheckValue()) {
|
if (auditor->CheckValue()) {
|
||||||
out.valueClass = auditor->GetValueClass();
|
out.valueClass = auditor->GetValueClass();
|
||||||
}
|
}
|
||||||
if (auditor->isParsed) {
|
if (out.status == ParsingStatus::VERIFIED) {
|
||||||
out.ast = auditor->parser.ExtractAST();
|
out.ast = auditor->ExtractAST();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
99
ccl/core/src/semantic/schema/SchemaAuditor.cpp
Normal file
99
ccl/core/src/semantic/schema/SchemaAuditor.cpp
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
#include "ccl/semantic/SchemaAuditor.h"
|
||||||
|
|
||||||
|
#include "ccl/rslang/RSGenerator.h"
|
||||||
|
|
||||||
|
namespace ccl::semantic {
|
||||||
|
|
||||||
|
SchemaAuditor::SchemaAuditor(
|
||||||
|
const rslang::TypeContext& types,
|
||||||
|
rslang::ValueClassContext globalClass,
|
||||||
|
rslang::SyntaxTreeContext globalAST
|
||||||
|
) : prefixLen{ 0 }, auditor { types, globalClass, globalAST } {}
|
||||||
|
|
||||||
|
|
||||||
|
bool SchemaAuditor::CheckConstituenta(const std::string& alias, const std::string& definition, const CstType targetType) {
|
||||||
|
auditor.parser.log.Clear();
|
||||||
|
const auto expr = rslang::Generator::GlobalDefinition(alias, definition, targetType == CstType::structured);
|
||||||
|
prefixLen = static_cast<StrPos>(std::ssize(expr) - std::ssize(definition));
|
||||||
|
|
||||||
|
const auto isBaseSet = IsBaseSet(targetType);
|
||||||
|
if (isBaseSet != empty(definition)) {
|
||||||
|
OnError(isBaseSet ? CstTypeEID::cstNonemptyBase : CstTypeEID::cstEmptyDerived);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!auditor.CheckType(expr, rslang::Syntax::MATH)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto isCallable = IsCallable(targetType);
|
||||||
|
if (isCallable == std::empty(auditor.GetDeclarationArgs())) {
|
||||||
|
auditor.isTypeCorrect = false;
|
||||||
|
OnError(isCallable ? CstTypeEID::cstCallableNoArgs : CstTypeEID::cstNonCallableHasArgs);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& resultType = auditor.GetType();
|
||||||
|
const auto isLogical = IsLogical(targetType);
|
||||||
|
if (isLogical == std::holds_alternative<rslang::Typification>(resultType)) {
|
||||||
|
auditor.isTypeCorrect = false;
|
||||||
|
OnError(isLogical ? CstTypeEID::cstExpectedLogical : CstTypeEID::cstExpectedTyped);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SchemaAuditor::CheckExpression(const std::string& expr, const rslang::Syntax syntax) {
|
||||||
|
auditor.parser.log.Clear();
|
||||||
|
return auditor.CheckType(expr, syntax);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SchemaAuditor::CheckValue() {
|
||||||
|
return auditor.CheckValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SchemaAuditor::IsParsed() const noexcept {
|
||||||
|
return auditor.isParsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SchemaAuditor::IsTypeCorrect() const noexcept {
|
||||||
|
return auditor.isTypeCorrect;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SchemaAuditor::IsValueCorrect() const noexcept {
|
||||||
|
return auditor.isValueCorrect;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rslang::Syntax& SchemaAuditor::GetSyntax() const noexcept {
|
||||||
|
return auditor.parser.syntax;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rslang::SyntaxTree& SchemaAuditor::AST() const noexcept {
|
||||||
|
return auditor.parser.AST();
|
||||||
|
}
|
||||||
|
|
||||||
|
const rslang::ErrorLogger& SchemaAuditor::Errors() const noexcept {
|
||||||
|
return auditor.Errors();
|
||||||
|
}
|
||||||
|
|
||||||
|
const rslang::FunctionArguments& SchemaAuditor::GetDeclarationArgs() const noexcept {
|
||||||
|
return auditor.GetDeclarationArgs();
|
||||||
|
}
|
||||||
|
|
||||||
|
const rslang::ExpressionType& SchemaAuditor::GetType() const noexcept {
|
||||||
|
return auditor.GetType();
|
||||||
|
}
|
||||||
|
|
||||||
|
rslang::ValueClass SchemaAuditor::GetValueClass() const noexcept {
|
||||||
|
return auditor.GetValueClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
meta::UniqueCPPtr<rslang::SyntaxTree> SchemaAuditor::ExtractAST() noexcept {
|
||||||
|
return auditor.parser.ExtractAST();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SchemaAuditor::OnError(const CstTypeEID errorID) {
|
||||||
|
auditor.parser.log.LogError(rslang::Error{ static_cast<uint32_t>(errorID), 0 });
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ccl::semantic
|
|
@ -214,6 +214,7 @@
|
||||||
<ClCompile Include="src\testRelativation.cpp" />
|
<ClCompile Include="src\testRelativation.cpp" />
|
||||||
<ClCompile Include="src\testRSCalculationFacet.cpp" />
|
<ClCompile Include="src\testRSCalculationFacet.cpp" />
|
||||||
<ClCompile Include="src\testSchema.cpp" />
|
<ClCompile Include="src\testSchema.cpp" />
|
||||||
|
<ClCompile Include="src\testSchemaAuditor.cpp" />
|
||||||
<ClCompile Include="src\testSourceManager.cpp" />
|
<ClCompile Include="src\testSourceManager.cpp" />
|
||||||
<ClCompile Include="src\testSynthes.cpp" />
|
<ClCompile Include="src\testSynthes.cpp" />
|
||||||
<ClCompile Include="src\testCstNameGenerator.cpp" />
|
<ClCompile Include="src\testCstNameGenerator.cpp" />
|
||||||
|
|
|
@ -118,6 +118,9 @@
|
||||||
<ClCompile Include="src\testOperation.cpp">
|
<ClCompile Include="src\testOperation.cpp">
|
||||||
<Filter>s_Concept\06 OPS</Filter>
|
<Filter>s_Concept\06 OPS</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\testSchemaAuditor.cpp">
|
||||||
|
<Filter>s_Concept\01 Schema</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="s_OSS">
|
<Filter Include="s_OSS">
|
||||||
|
|
|
@ -84,4 +84,15 @@ TEST_F(UTCstType, IsStatement) {
|
||||||
EXPECT_FALSE(ccl::semantic::IsStatement(CstType::function));
|
EXPECT_FALSE(ccl::semantic::IsStatement(CstType::function));
|
||||||
EXPECT_TRUE(ccl::semantic::IsStatement(CstType::theorem));
|
EXPECT_TRUE(ccl::semantic::IsStatement(CstType::theorem));
|
||||||
EXPECT_FALSE(ccl::semantic::IsStatement(CstType::predicate));
|
EXPECT_FALSE(ccl::semantic::IsStatement(CstType::predicate));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(UTCstType, IsLogical) {
|
||||||
|
EXPECT_FALSE(ccl::semantic::IsLogical(CstType::base));
|
||||||
|
EXPECT_FALSE(ccl::semantic::IsLogical(CstType::constant));
|
||||||
|
EXPECT_FALSE(ccl::semantic::IsLogical(CstType::structured));
|
||||||
|
EXPECT_TRUE(ccl::semantic::IsLogical(CstType::axiom));
|
||||||
|
EXPECT_FALSE(ccl::semantic::IsLogical(CstType::term));
|
||||||
|
EXPECT_FALSE(ccl::semantic::IsLogical(CstType::function));
|
||||||
|
EXPECT_TRUE(ccl::semantic::IsLogical(CstType::theorem));
|
||||||
|
EXPECT_TRUE(ccl::semantic::IsLogical(CstType::predicate));
|
||||||
}
|
}
|
|
@ -131,4 +131,15 @@ TEST_F(UTRSFormJA, CheckExpression) {
|
||||||
EXPECT_EQ(reponse.at("args")[0].at("alias"), "a");
|
EXPECT_EQ(reponse.at("args")[0].at("alias"), "a");
|
||||||
EXPECT_EQ(reponse.at("args")[0].at("typification"), "X1");
|
EXPECT_EQ(reponse.at("args")[0].at("typification"), "X1");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(UTRSFormJA, CheckConstituenta) {
|
||||||
|
auto wrapper = RSFormJA::FromData(SetupSchema());
|
||||||
|
auto reponse = JSON::parse(wrapper.CheckConstituenta("A100", "X1=X1", CstType::axiom));
|
||||||
|
EXPECT_EQ(reponse.at("parseResult").get<bool>(), true);
|
||||||
|
EXPECT_EQ(reponse.at("prefixLen"), 7);
|
||||||
|
EXPECT_EQ(reponse.at("syntax"), "math");
|
||||||
|
EXPECT_EQ(reponse.at("typification"), "LOGIC");
|
||||||
|
EXPECT_EQ(reponse.at("errors").size(), 0U);
|
||||||
|
|
||||||
}
|
}
|
|
@ -22,6 +22,7 @@ protected:
|
||||||
using FunctionArguments = ccl::rslang::FunctionArguments;
|
using FunctionArguments = ccl::rslang::FunctionArguments;
|
||||||
using ValueClass = ccl::rslang::ValueClass;
|
using ValueClass = ccl::rslang::ValueClass;
|
||||||
using Syntax = ccl::rslang::Syntax;
|
using Syntax = ccl::rslang::Syntax;
|
||||||
|
using TypeID = ccl::rslang::TypedID;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Schema core{};
|
Schema core{};
|
||||||
|
@ -722,28 +723,6 @@ TEST_F(UTSchema, Translations) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(UTSchema, TypeConsistency) {
|
|
||||||
const Typification rsType{"X1"};
|
|
||||||
EXPECT_TRUE(Schema::CheckTypeConstistency(rsType, CstType::base));
|
|
||||||
EXPECT_TRUE(Schema::CheckTypeConstistency(rsType, CstType::constant));
|
|
||||||
EXPECT_TRUE(Schema::CheckTypeConstistency(rsType, CstType::structured));
|
|
||||||
EXPECT_TRUE(Schema::CheckTypeConstistency(rsType, CstType::term));
|
|
||||||
EXPECT_FALSE(Schema::CheckTypeConstistency(rsType, CstType::axiom));
|
|
||||||
EXPECT_FALSE(Schema::CheckTypeConstistency(rsType, CstType::theorem));
|
|
||||||
EXPECT_TRUE(Schema::CheckTypeConstistency(rsType, CstType::function));
|
|
||||||
EXPECT_FALSE(Schema::CheckTypeConstistency(rsType, CstType::predicate));
|
|
||||||
|
|
||||||
const LogicT logicType{};
|
|
||||||
EXPECT_FALSE(Schema::CheckTypeConstistency(logicType, CstType::base));
|
|
||||||
EXPECT_FALSE(Schema::CheckTypeConstistency(logicType, CstType::constant));
|
|
||||||
EXPECT_FALSE(Schema::CheckTypeConstistency(logicType, CstType::structured));
|
|
||||||
EXPECT_FALSE(Schema::CheckTypeConstistency(logicType, CstType::term));
|
|
||||||
EXPECT_TRUE(Schema::CheckTypeConstistency(logicType, CstType::axiom));
|
|
||||||
EXPECT_TRUE(Schema::CheckTypeConstistency(logicType, CstType::theorem));
|
|
||||||
EXPECT_FALSE(Schema::CheckTypeConstistency(logicType, CstType::function));
|
|
||||||
EXPECT_TRUE(Schema::CheckTypeConstistency(logicType, CstType::predicate));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(UTSchema, Evaluate) {
|
TEST_F(UTSchema, Evaluate) {
|
||||||
{
|
{
|
||||||
EXPECT_FALSE(core.Evaluate("X1=X1").has_value());
|
EXPECT_FALSE(core.Evaluate("X1=X1").has_value());
|
||||||
|
@ -766,13 +745,13 @@ TEST_F(UTSchema, MakeAuditor) {
|
||||||
{
|
{
|
||||||
auto auditor = core.MakeAuditor();
|
auto auditor = core.MakeAuditor();
|
||||||
ASSERT_NE(auditor, nullptr);
|
ASSERT_NE(auditor, nullptr);
|
||||||
EXPECT_TRUE(auditor->CheckType(R"(X1 \in B(X1))"_rs, Syntax::MATH));
|
EXPECT_TRUE(auditor->CheckExpression(R"(X1 \in B(X1))"_rs, Syntax::MATH));
|
||||||
EXPECT_FALSE(auditor->CheckType(R"(X1 \in B(X1))", Syntax::MATH));
|
EXPECT_FALSE(auditor->CheckExpression(R"(X1 \in B(X1))", Syntax::MATH));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto auditor = core.MakeAuditor();
|
auto auditor = core.MakeAuditor();
|
||||||
ASSERT_NE(auditor, nullptr);
|
ASSERT_NE(auditor, nullptr);
|
||||||
EXPECT_FALSE(auditor->CheckType(R"(X1 \in B(X1))"_rs, Syntax::ASCII));
|
EXPECT_FALSE(auditor->CheckExpression(R"(X1 \in B(X1))"_rs, Syntax::ASCII));
|
||||||
EXPECT_TRUE(auditor->CheckType(R"(X1 \in B(X1))", Syntax::ASCII));
|
EXPECT_TRUE(auditor->CheckExpression(R"(X1 \in B(X1))", Syntax::ASCII));
|
||||||
}
|
}
|
||||||
}
|
}
|
90
ccl/core/test/src/testSchemaAuditor.cpp
Normal file
90
ccl/core/test/src/testSchemaAuditor.cpp
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
#define GTEST_LANG_CXX11 1
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include "ccl/semantic/SchemaAuditor.h"
|
||||||
|
#include "ccl/semantic/Schema.h"
|
||||||
|
#include "RSLHelper.hpp"
|
||||||
|
|
||||||
|
class UTSchemaAuditor : public ::testing::Test {
|
||||||
|
protected:
|
||||||
|
UTSchemaAuditor();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using EntityUID = ccl::EntityUID;
|
||||||
|
using Schema = ccl::semantic::Schema;
|
||||||
|
using CstType = ccl::semantic::CstType;
|
||||||
|
using SchemaAuditor = ccl::semantic::SchemaAuditor;
|
||||||
|
using Syntax = ccl::rslang::Syntax;
|
||||||
|
using ValueClass = ccl::rslang::ValueClass;
|
||||||
|
using Typification = ccl::rslang::Typification;
|
||||||
|
using LogicT = ccl::rslang::LogicT;
|
||||||
|
using ExpressionType = ccl::rslang::ExpressionType;
|
||||||
|
using CstTypeEID = ccl::semantic::CstTypeEID;
|
||||||
|
|
||||||
|
using ParsingStatus = ccl::semantic::ParsingStatus;
|
||||||
|
using ParsingInfo = ccl::semantic::ParsingInfo;
|
||||||
|
using FunctionArguments = ccl::rslang::FunctionArguments;
|
||||||
|
using TypeID = ccl::rslang::TypedID;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Schema core{};
|
||||||
|
std::unique_ptr<SchemaAuditor> auditor;
|
||||||
|
|
||||||
|
static constexpr EntityUID x1{ 42 };
|
||||||
|
static constexpr EntityUID s1{ 44 };
|
||||||
|
static constexpr EntityUID d1{ 45 };
|
||||||
|
static constexpr EntityUID a1{ 46 };
|
||||||
|
static constexpr EntityUID f1{ 47 };
|
||||||
|
static constexpr EntityUID p1{ 48 };
|
||||||
|
|
||||||
|
void ExpectError(const std::string& alias, const std::string& input, CstType type, CstTypeEID errorCode);
|
||||||
|
};
|
||||||
|
|
||||||
|
UTSchemaAuditor::UTSchemaAuditor() : auditor{core.MakeAuditor()} {
|
||||||
|
core.Emplace(x1, "X1", CstType::base);
|
||||||
|
core.Emplace(s1, "S1", CstType::structured, "B(X1*X1)"_rs);
|
||||||
|
core.UpdateState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UTSchemaAuditor::ExpectError(
|
||||||
|
const std::string& alias,
|
||||||
|
const std::string& input,
|
||||||
|
const CstType type,
|
||||||
|
const CstTypeEID errorCode
|
||||||
|
) {
|
||||||
|
ASSERT_FALSE(auditor->CheckConstituenta(alias, input, type)) << input;
|
||||||
|
EXPECT_EQ(begin(auditor->Errors().All())->eid, static_cast<uint32_t>(errorCode)) << input;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(UTSchemaAuditor, CheckExression) {
|
||||||
|
EXPECT_TRUE(auditor->CheckExpression(R"(X1=X1)", Syntax::MATH));
|
||||||
|
EXPECT_TRUE(auditor->CheckExpression(R"(X1 \eq X1)", Syntax::ASCII));
|
||||||
|
EXPECT_FALSE(auditor->CheckExpression(R"(X2=X2)", Syntax::MATH));
|
||||||
|
EXPECT_FALSE(auditor->CheckExpression(R"(X1=X1)", Syntax::ASCII));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(UTSchemaAuditor, CheckConstituentaCorrect) {
|
||||||
|
EXPECT_TRUE(auditor->CheckConstituenta("X2", "", CstType::base));
|
||||||
|
EXPECT_TRUE(auditor->CheckConstituenta("C2", "", CstType::constant));
|
||||||
|
EXPECT_TRUE(auditor->CheckConstituenta("S2", R"(X1)", CstType::structured));
|
||||||
|
EXPECT_TRUE(auditor->CheckConstituenta("D2", R"(Pr1(S1))", CstType::term));
|
||||||
|
EXPECT_TRUE(auditor->CheckConstituenta("A2", R"(X1=X1)", CstType::axiom));
|
||||||
|
EXPECT_TRUE(auditor->CheckConstituenta("T2", R"(X1=X1)", CstType::theorem));
|
||||||
|
EXPECT_TRUE(auditor->CheckConstituenta("F2", R"([a \in X1] a)"_rs, CstType::function));
|
||||||
|
EXPECT_TRUE(auditor->CheckConstituenta("P2", R"([a \in X1] a \eq a)"_rs, CstType::predicate));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(UTSchemaAuditor, CheckConstituentaErrors) {
|
||||||
|
ExpectError("X2", "1", CstType::base, CstTypeEID::cstNonemptyBase);
|
||||||
|
ExpectError("D2", "", CstType::term, CstTypeEID::cstEmptyDerived);
|
||||||
|
ExpectError("F2", "1=1", CstType::function, CstTypeEID::cstCallableNoArgs);
|
||||||
|
ExpectError("P2", "1=1", CstType::predicate, CstTypeEID::cstCallableNoArgs);
|
||||||
|
ExpectError("D2", R"([a \in X1] a \eq a)"_rs, CstType::term, CstTypeEID::cstNonCallableHasArgs);
|
||||||
|
ExpectError("A2", R"([a \in X1] a \eq a)"_rs, CstType::axiom, CstTypeEID::cstNonCallableHasArgs);
|
||||||
|
ExpectError("A2", R"(X1 \union X1)"_rs, CstType::axiom, CstTypeEID::cstExpectedLogical);
|
||||||
|
ExpectError("T2", R"(X1 \union X1)"_rs, CstType::theorem, CstTypeEID::cstExpectedLogical);
|
||||||
|
ExpectError("P2", R"([a \in X1] a)"_rs, CstType::predicate, CstTypeEID::cstExpectedLogical);
|
||||||
|
ExpectError("D2", R"(1 \eq 1)"_rs, CstType::term, CstTypeEID::cstExpectedTyped);
|
||||||
|
ExpectError("F2", R"([a \in X1] a \eq a)"_rs, CstType::function, CstTypeEID::cstExpectedTyped);
|
||||||
|
}
|
|
@ -7,6 +7,7 @@
|
||||||
#include "../src/testTextData.cpp"
|
#include "../src/testTextData.cpp"
|
||||||
#include "../src/testRSConcept.cpp"
|
#include "../src/testRSConcept.cpp"
|
||||||
#include "../src/testSchema.cpp"
|
#include "../src/testSchema.cpp"
|
||||||
|
#include "../src/testSchemaAuditor.cpp"
|
||||||
#include "../src/testTextConcept.cpp"
|
#include "../src/testTextConcept.cpp"
|
||||||
#include "../src/testThesaurus.cpp"
|
#include "../src/testThesaurus.cpp"
|
||||||
#include "../src/testConceptRecord.cpp"
|
#include "../src/testConceptRecord.cpp"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! Unity build for Concept Core Library
|
//! Unity build for Concept Core Library
|
||||||
|
|
||||||
#include "../src/JSON.cpp"
|
#include "../src/JSON.cpp"
|
||||||
|
#include "../src/semantic/schema/SchemaAuditor.cpp"
|
||||||
#include "../src/semantic/schema/Schema.cpp"
|
#include "../src/semantic/schema/Schema.cpp"
|
||||||
#include "../src/semantic/schema/RSConcept.cpp"
|
#include "../src/semantic/schema/RSConcept.cpp"
|
||||||
#include "../src/semantic/thesaurus/Thesaurus.cpp"
|
#include "../src/semantic/thesaurus/Thesaurus.cpp"
|
||||||
|
|
|
@ -207,6 +207,8 @@
|
||||||
<None Include="src\MathLexerImpl.l">
|
<None Include="src\MathLexerImpl.l">
|
||||||
<Filter>11 parse\lexer</Filter>
|
<Filter>11 parse\lexer</Filter>
|
||||||
</None>
|
</None>
|
||||||
<None Include="src\RSParserImpl.y" />
|
<None Include="src\RSParserImpl.y">
|
||||||
|
<Filter>11 parse</Filter>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -450,40 +450,42 @@ namespace ccl { namespace rslang { namespace detail {
|
||||||
S_SEMICOLON = 60, // SEMICOLON
|
S_SEMICOLON = 60, // SEMICOLON
|
||||||
S_YYACCEPT = 61, // $accept
|
S_YYACCEPT = 61, // $accept
|
||||||
S_expression = 62, // expression
|
S_expression = 62, // expression
|
||||||
S_global_declaration = 63, // global_declaration
|
S_no_declaration = 63, // no_declaration
|
||||||
S_logic_or_setexpr = 64, // logic_or_setexpr
|
S_global_declaration = 64, // global_declaration
|
||||||
S_function_definition = 65, // function_definition
|
S_logic_or_setexpr = 65, // logic_or_setexpr
|
||||||
S_arguments = 66, // arguments
|
S_function_definition = 66, // function_definition
|
||||||
S_declaration = 67, // declaration
|
S_arguments = 67, // arguments
|
||||||
S_variable = 68, // variable
|
S_declaration = 68, // declaration
|
||||||
S_variable_pack = 69, // variable_pack
|
S_variable = 69, // variable
|
||||||
S_logic = 70, // logic
|
S_variable_pack = 70, // variable_pack
|
||||||
S_logic_no_binary = 71, // logic_no_binary
|
S_logic = 71, // logic
|
||||||
S_logic_all = 72, // logic_all
|
S_logic_no_binary = 72, // logic_no_binary
|
||||||
S_logic_par = 73, // logic_par
|
S_logic_all = 73, // logic_all
|
||||||
S_logic_predicates = 74, // logic_predicates
|
S_logic_par = 74, // logic_par
|
||||||
S_binary_predicate = 75, // binary_predicate
|
S_logic_predicates = 75, // logic_predicates
|
||||||
S_logic_unary = 76, // logic_unary
|
S_binary_predicate = 76, // binary_predicate
|
||||||
S_quantifier = 77, // quantifier
|
S_logic_unary = 77, // logic_unary
|
||||||
S_logic_binary = 78, // logic_binary
|
S_quantifier = 78, // quantifier
|
||||||
S_setexpr = 79, // setexpr
|
S_logic_binary = 79, // logic_binary
|
||||||
S_text_function = 80, // text_function
|
S_setexpr = 80, // setexpr
|
||||||
S_setexpr_enum = 81, // setexpr_enum
|
S_text_function = 81, // text_function
|
||||||
S_setexpr_enum_min2 = 82, // setexpr_enum_min2
|
S_setexpr_enum = 82, // setexpr_enum
|
||||||
S_literal = 83, // literal
|
S_setexpr_enum_min2 = 83, // setexpr_enum_min2
|
||||||
S_identifier = 84, // identifier
|
S_global_name = 84, // global_name
|
||||||
S_setexpr_binary = 85, // setexpr_binary
|
S_literal = 85, // literal
|
||||||
S_setexpr_generators = 86, // setexpr_generators
|
S_identifier = 86, // identifier
|
||||||
S_enumeration = 87, // enumeration
|
S_setexpr_binary = 87, // setexpr_binary
|
||||||
S_tuple = 88, // tuple
|
S_setexpr_generators = 88, // setexpr_generators
|
||||||
S_boolean = 89, // boolean
|
S_enumeration = 89, // enumeration
|
||||||
S_filter_expression = 90, // filter_expression
|
S_tuple = 90, // tuple
|
||||||
S_declarative = 91, // declarative
|
S_boolean = 91, // boolean
|
||||||
S_recursion = 92, // recursion
|
S_filter_expression = 92, // filter_expression
|
||||||
S_imperative = 93, // imperative
|
S_declarative = 93, // declarative
|
||||||
S_imp_blocks = 94, // imp_blocks
|
S_recursion = 94, // recursion
|
||||||
S_RPE = 95, // RPE
|
S_imperative = 95, // imperative
|
||||||
S_RCE = 96 // RCE
|
S_imp_blocks = 96, // imp_blocks
|
||||||
|
S_RPE = 97, // RPE
|
||||||
|
S_RCE = 98 // RCE
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -981,9 +983,9 @@ namespace ccl { namespace rslang { namespace detail {
|
||||||
/// Constants.
|
/// Constants.
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
yylast_ = 620, ///< Last index in yytable_.
|
yylast_ = 567, ///< Last index in yytable_.
|
||||||
yynnts_ = 36, ///< Number of nonterminal symbols.
|
yynnts_ = 38, ///< Number of nonterminal symbols.
|
||||||
yyfinal_ = 89 ///< Termination state number.
|
yyfinal_ = 85 ///< Termination state number.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -995,7 +997,7 @@ namespace ccl { namespace rslang { namespace detail {
|
||||||
|
|
||||||
#line 15 "RSParserImpl.y"
|
#line 15 "RSParserImpl.y"
|
||||||
} } } // ccl::rslang::detail
|
} } } // ccl::rslang::detail
|
||||||
#line 999 "../header/RSParserImpl.h"
|
#line 1001 "../header/RSParserImpl.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,11 @@ private:
|
||||||
ValueAuditor valueAuditor;
|
ValueAuditor valueAuditor;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Auditor(const TypeContext& types,
|
explicit Auditor(
|
||||||
ValueClassContext globalClass,
|
const TypeContext& types,
|
||||||
SyntaxTreeContext globalAST);
|
ValueClassContext globalClass,
|
||||||
|
SyntaxTreeContext globalAST
|
||||||
|
);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool CheckType(const std::string& expr, Syntax syntaxHint = Syntax::UNDEF);
|
bool CheckType(const std::string& expr, Syntax syntaxHint = Syntax::UNDEF);
|
||||||
|
|
|
@ -50,9 +50,6 @@ enum class SemanticEID : uint32_t {
|
||||||
invalidArgumentType = 0x8819, // Типизация аргумента не совпадает с объявленной
|
invalidArgumentType = 0x8819, // Типизация аргумента не совпадает с объявленной
|
||||||
globalStructure = 0x881C, // Родовая структура должна быть ступенью
|
globalStructure = 0x881C, // Родовая структура должна быть ступенью
|
||||||
|
|
||||||
// TODO: следующий идентификатор сейчас не используется. Нужно подобрать место для проверки
|
|
||||||
globalExpectedFunction = 0x881F, // Ожидалось выражение объявления функции
|
|
||||||
|
|
||||||
radicalUsage = 0x8821, // Радикалы запрещены вне деклараций терм-функций
|
radicalUsage = 0x8821, // Радикалы запрещены вне деклараций терм-функций
|
||||||
invalidFilterArgumentType = 0x8822, // Типизация аргумента фильтра не корректна
|
invalidFilterArgumentType = 0x8822, // Типизация аргумента фильтра не корректна
|
||||||
invalidFilterArity = 0x8823, // Количество параметров фильра не соответствует количеству индексов
|
invalidFilterArity = 0x8823, // Количество параметров фильра не соответствует количеству индексов
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -268,16 +268,18 @@ RawNode Imperative(
|
||||||
// ------------------------- Language Expression ------------------------------
|
// ------------------------- Language Expression ------------------------------
|
||||||
expression
|
expression
|
||||||
: global_declaration
|
: global_declaration
|
||||||
| logic_or_setexpr { if(!state->FinalizeExpression($1)) YYABORT; }
|
| no_declaration { if(!state->FinalizeExpression($1)) YYABORT; }
|
||||||
| function_definition { if(!state->FinalizeExpression($1)) YYABORT; }
|
;
|
||||||
|
|
||||||
|
no_declaration
|
||||||
|
: logic_or_setexpr
|
||||||
|
| function_definition
|
||||||
;
|
;
|
||||||
|
|
||||||
global_declaration
|
global_declaration
|
||||||
: GLOBAL DEFINE { if(!state->FinalizeCstEmpty($1, $2)) YYABORT; }
|
: global_name DEFINE { if(!state->FinalizeCstEmpty($1, $2)) YYABORT; }
|
||||||
| GLOBAL STRUCT setexpr { if(!state->FinalizeCstExpression($1, $2, $3)) YYABORT; }
|
| global_name DEFINE no_declaration { if(!state->FinalizeCstExpression($1, $2, $3)) YYABORT; }
|
||||||
| GLOBAL DEFINE logic_or_setexpr { if(!state->FinalizeCstExpression($1, $2, $3)) YYABORT; }
|
| global_name STRUCT no_declaration { if(!state->FinalizeCstExpression($1, $2, $3)) YYABORT; }
|
||||||
| FUNCTION DEFINE function_definition { if(!state->FinalizeCstExpression($1, $2, $3)) YYABORT; }
|
|
||||||
| PREDICATE DEFINE function_definition { if(!state->FinalizeCstExpression($1, $2, $3)) YYABORT; }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
logic_or_setexpr
|
logic_or_setexpr
|
||||||
|
@ -394,6 +396,12 @@ setexpr_enum_min2
|
||||||
: setexpr_enum COMMA setexpr { $$ = Enumeration(TokenID::INTERRUPT, $1, $3); }
|
: setexpr_enum COMMA setexpr { $$ = Enumeration(TokenID::INTERRUPT, $1, $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
global_name
|
||||||
|
: GLOBAL
|
||||||
|
| FUNCTION
|
||||||
|
| PREDICATE
|
||||||
|
;
|
||||||
|
|
||||||
literal
|
literal
|
||||||
: INTEGER
|
: INTEGER
|
||||||
| EMPTYSET
|
| EMPTYSET
|
||||||
|
@ -401,9 +409,7 @@ literal
|
||||||
;
|
;
|
||||||
|
|
||||||
identifier
|
identifier
|
||||||
: GLOBAL
|
: global_name
|
||||||
| FUNCTION
|
|
||||||
| PREDICATE
|
|
||||||
| LOCAL
|
| LOCAL
|
||||||
| RADICAL
|
| RADICAL
|
||||||
;
|
;
|
||||||
|
|
|
@ -333,6 +333,7 @@ bool TypeAuditor::ViGlobalDeclaration(Cursor iter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TypeAuditor::ViFunctionDefinition(Cursor iter) {
|
bool TypeAuditor::ViFunctionDefinition(Cursor iter) {
|
||||||
|
StartScope();
|
||||||
{
|
{
|
||||||
const auto guard = isFuncDeclaration.CreateGuard();
|
const auto guard = isFuncDeclaration.CreateGuard();
|
||||||
if (!VisitChild(iter, 0)) {
|
if (!VisitChild(iter, 0)) {
|
||||||
|
@ -348,6 +349,7 @@ bool TypeAuditor::ViFunctionDefinition(Cursor iter) {
|
||||||
if (!type.has_value()) {
|
if (!type.has_value()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
EndScope(iter->pos.start);
|
||||||
return SetCurrent(type.value());
|
return SetCurrent(type.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,14 +85,26 @@ TEST_F(UTRSParser, GlobalDeclCorrect) {
|
||||||
ExpectNoWarnings(R"(S1 \defexpr B(C1))");
|
ExpectNoWarnings(R"(S1 \defexpr B(C1))");
|
||||||
ExpectNoWarnings(R"(S1 \defexpr B(D1))");
|
ExpectNoWarnings(R"(S1 \defexpr B(D1))");
|
||||||
ExpectNoWarnings(R"(S1 \defexpr B(X1*(X1*X1)))");
|
ExpectNoWarnings(R"(S1 \defexpr B(X1*(X1*X1)))");
|
||||||
|
ExpectNoWarnings(R"(F1 \defexpr B(X1*(X1*X1)))");
|
||||||
|
ExpectNoWarnings(R"(D1 \defexpr B(X1*(X1*X1)))");
|
||||||
|
ExpectNoWarnings(R"(P1 \defexpr B(X1*(X1*X1)))");
|
||||||
ExpectNoWarnings(R"(D1 \defexpr X1 \setminus X1)");
|
ExpectNoWarnings(R"(D1 \defexpr X1 \setminus X1)");
|
||||||
|
ExpectNoWarnings(R"(A1 \defexpr X1 \setminus X1)");
|
||||||
|
ExpectNoWarnings(R"(F1 \defexpr X1 \setminus X1)");
|
||||||
|
ExpectNoWarnings(R"(P1 \defexpr X1 \setminus X1)");
|
||||||
ExpectNoWarnings(R"(A1 \defexpr 1 \eq 1)");
|
ExpectNoWarnings(R"(A1 \defexpr 1 \eq 1)");
|
||||||
ExpectNoWarnings(R"(T1 \defexpr 1 \eq 1)");
|
ExpectNoWarnings(R"(T1 \defexpr 1 \eq 1)");
|
||||||
|
ExpectNoWarnings(R"(F1 \defexpr 1 \eq 1)");
|
||||||
|
ExpectNoWarnings(R"(D1 \defexpr 1 \eq 1)");
|
||||||
|
ExpectNoWarnings(R"(S1 \defexpr [a \in X1] X1 \setminus a)");
|
||||||
|
ExpectNoWarnings(R"(D1 \defexpr [a \in X1] X1 \setminus a)");
|
||||||
ExpectNoWarnings(R"(F1 \defexpr [a \in X1] X1 \setminus a)");
|
ExpectNoWarnings(R"(F1 \defexpr [a \in X1] X1 \setminus a)");
|
||||||
ExpectNoWarnings(R"(F1 \defexpr [a \in R1] {a})");
|
ExpectNoWarnings(R"(F1 \defexpr [a \in R1] {a})");
|
||||||
ExpectNoWarnings(R"(F1 \defexpr [a \in B(D1)] X1 \setminus a)");
|
ExpectNoWarnings(R"(F1 \defexpr [a \in B(D1)] X1 \setminus a)");
|
||||||
ExpectNoWarnings(R"(F1 \defexpr [a \in D1 \setminus D1] X1 \setminus a)");
|
ExpectNoWarnings(R"(F1 \defexpr [a \in D1 \setminus D1] X1 \setminus a)");
|
||||||
ExpectNoWarnings(R"(P1 \defexpr [a \in D1 \setminus D1] 1 \eq 1)");
|
ExpectNoWarnings(R"(P1 \defexpr [a \in D1 \setminus D1] 1 \eq 1)");
|
||||||
|
ExpectNoWarnings(R"(D1 \defexpr [a \in D1 \setminus D1] 1 \eq 1)");
|
||||||
|
ExpectNoWarnings(R"(S1 \defexpr [a \in D1 \setminus D1] 1 \eq 1)");
|
||||||
ExpectNoWarnings(R"(F1 \defexpr [a \in B(X1)] card(a))");
|
ExpectNoWarnings(R"(F1 \defexpr [a \in B(X1)] card(a))");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,10 +135,6 @@ TEST_F(UTRSParser, GlobalDeclErrors) {
|
||||||
ExpectError(R"(F1 \defexpr [] X1 \setminus X1)", ParseEID::expectedDeclaration, 13);
|
ExpectError(R"(F1 \defexpr [] X1 \setminus X1)", ParseEID::expectedDeclaration, 13);
|
||||||
ExpectError(R"(F1 \defexpr [a] X1 \setminus a)", ParseEID::expectedDeclaration, 14);
|
ExpectError(R"(F1 \defexpr [a] X1 \setminus a)", ParseEID::expectedDeclaration, 14);
|
||||||
ExpectError(R"(F1 \defexpr [a \subseteq X1] X1 \setminus a)", ParseEID::expectedDeclaration, 15);
|
ExpectError(R"(F1 \defexpr [a \subseteq X1] X1 \setminus a)", ParseEID::expectedDeclaration, 15);
|
||||||
ExpectError(R"(S1 \deftype 1 \eq 1)", ParseEID::syntax);
|
|
||||||
ExpectError(R"(F1 \defexpr )", ParseEID::syntax);
|
|
||||||
ExpectError(R"(F1 \defexpr 1 \eq 1)", ParseEID::syntax);
|
|
||||||
ExpectError(R"(F1 \defexpr X1)", ParseEID::syntax);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(UTRSParser, LogicPredicatesCorrect) {
|
TEST_F(UTRSParser, LogicPredicatesCorrect) {
|
||||||
|
|
|
@ -86,7 +86,8 @@ TEST_F(UTRSToken, TokenDefault) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(UTRSToken, TokenCompare) {
|
TEST_F(UTRSToken, TokenCompare) {
|
||||||
Token t1{}, t2{};
|
Token t1{};
|
||||||
|
Token t2{};
|
||||||
EXPECT_EQ(t1, t2);
|
EXPECT_EQ(t1, t2);
|
||||||
|
|
||||||
t2.id = TokenID::PUNC_DEFINE;
|
t2.id = TokenID::PUNC_DEFINE;
|
||||||
|
|
|
@ -127,6 +127,8 @@ TEST_F(UTTypeAuditor, DefinitionsCorrect) {
|
||||||
TEST_F(UTTypeAuditor, DefinitionsErrors) {
|
TEST_F(UTTypeAuditor, DefinitionsErrors) {
|
||||||
ExpectError(R"(S1 \deftype R1)", SemanticEID::globalStructure);
|
ExpectError(R"(S1 \deftype R1)", SemanticEID::globalStructure);
|
||||||
ExpectError(R"(S1 \deftype 1)", SemanticEID::globalStructure);
|
ExpectError(R"(S1 \deftype 1)", SemanticEID::globalStructure);
|
||||||
|
ExpectError(R"(S1 \deftype 1 \eq 1)", SemanticEID::globalStructure);
|
||||||
|
ExpectError(R"(S1 \deftype [a \in X1] a \eq a)", SemanticEID::globalStructure);
|
||||||
ExpectError(R"(S1 \deftype X1 \union X1)", SemanticEID::globalStructure);
|
ExpectError(R"(S1 \deftype X1 \union X1)", SemanticEID::globalStructure);
|
||||||
ExpectError(R"(S1 \deftype B(X1 \union X1))", SemanticEID::globalStructure);
|
ExpectError(R"(S1 \deftype B(X1 \union X1))", SemanticEID::globalStructure);
|
||||||
ExpectError(R"(S1 \deftype X1*(X1 \union X1))", SemanticEID::globalStructure);
|
ExpectError(R"(S1 \deftype X1*(X1 \union X1))", SemanticEID::globalStructure);
|
||||||
|
@ -519,6 +521,14 @@ TEST_F(UTTypeAuditor, WarningLocalNotUsed) {
|
||||||
EXPECT_EQ(begin(parser.log.All())->eid, static_cast<uint32_t>(SemanticEID::localNotUsed));
|
EXPECT_EQ(begin(parser.log.All())->eid, static_cast<uint32_t>(SemanticEID::localNotUsed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(UTTypeAuditor, WarningParameterNotUsed) {
|
||||||
|
const auto input = R"([a \in X1] 1 \eq 1)";
|
||||||
|
ASSERT_TRUE(parser.Parse(input, Syntax::ASCII));
|
||||||
|
ASSERT_TRUE(analyse.CheckType(parser.AST()));
|
||||||
|
EXPECT_EQ(parser.log.Count(ErrorStatus::WARNING), 1);
|
||||||
|
EXPECT_EQ(begin(parser.log.All())->eid, static_cast<uint32_t>(SemanticEID::localNotUsed));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(UTTypeAuditor, NoWarningAfterError) {
|
TEST_F(UTTypeAuditor, NoWarningAfterError) {
|
||||||
const auto input = R"(D{t \in X1 | \A a \in X1 \A b \in red(X1) {a,b} \eq t})";
|
const auto input = R"(D{t \in X1 | \A a \in X1 \A b \in red(X1) {a,b} \eq t})";
|
||||||
ASSERT_TRUE(parser.Parse(input, Syntax::ASCII));
|
ASSERT_TRUE(parser.Parse(input, Syntax::ASCII));
|
||||||
|
|
|
@ -19,6 +19,13 @@ Here we write upgrading notes. Make them as straightforward as possible.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
## [0.1.7] - 2024-09-22
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Improve error messages for invalid types
|
||||||
|
- Add API for checking constituenta expressions
|
||||||
|
|
||||||
## [0.1.6] - 2024-06-14
|
## [0.1.6] - 2024-06-14
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
0.1.6
|
0.1.7
|
|
@ -15,6 +15,12 @@ std::string ConvertToMath(const std::string& expression);
|
||||||
// ======= Expression parse =========
|
// ======= Expression parse =========
|
||||||
std::string ParseExpression(const std::string& expression);
|
std::string ParseExpression(const std::string& expression);
|
||||||
std::string CheckExpression(const std::string& jSchema, const std::string& expression);
|
std::string CheckExpression(const std::string& jSchema, const std::string& expression);
|
||||||
|
std::string CheckConstituenta(
|
||||||
|
const std::string& jSchema,
|
||||||
|
const std::string& alias,
|
||||||
|
const std::string& expression,
|
||||||
|
int cstType
|
||||||
|
);
|
||||||
|
|
||||||
PYBIND11_MODULE(pyconcept, m) {
|
PYBIND11_MODULE(pyconcept, m) {
|
||||||
m.def("check_schema", &CheckSchema, R"pbdoc(Check schema definition.)pbdoc");
|
m.def("check_schema", &CheckSchema, R"pbdoc(Check schema definition.)pbdoc");
|
||||||
|
@ -24,5 +30,14 @@ PYBIND11_MODULE(pyconcept, m) {
|
||||||
m.def("convert_to_math", &ConvertToMath, R"pbdoc(Convert expression syntax to Math.)pbdoc");
|
m.def("convert_to_math", &ConvertToMath, R"pbdoc(Convert expression syntax to Math.)pbdoc");
|
||||||
|
|
||||||
m.def("parse_expression", &ParseExpression, R"pbdoc(Parse expression and create syntax tree.)pbdoc");
|
m.def("parse_expression", &ParseExpression, R"pbdoc(Parse expression and create syntax tree.)pbdoc");
|
||||||
m.def("check_expression", &CheckExpression, R"pbdoc(Validate expression against given schema and calculate typification.)pbdoc");
|
m.def(
|
||||||
|
"check_expression",
|
||||||
|
&CheckExpression,
|
||||||
|
R"pbdoc(Validate expression against given schema and calculate typification.)pbdoc"
|
||||||
|
);
|
||||||
|
m.def(
|
||||||
|
"check_constituenta",
|
||||||
|
&CheckConstituenta,
|
||||||
|
R"pbdoc(Validate constituenta expression against given schema and calculate typification.)pbdoc"
|
||||||
|
);
|
||||||
}
|
}
|
|
@ -7,7 +7,6 @@
|
||||||
using ccl::api::RSFormJA;
|
using ccl::api::RSFormJA;
|
||||||
|
|
||||||
std::string CheckSchema(const std::string& jSchema) {
|
std::string CheckSchema(const std::string& jSchema) {
|
||||||
// TODO: consider try-catch if need to process invalid input gracefully
|
|
||||||
ccl::lang::TextEnvironment::Instance().skipResolving = true;
|
ccl::lang::TextEnvironment::Instance().skipResolving = true;
|
||||||
auto schema = RSFormJA::FromJSON(jSchema);
|
auto schema = RSFormJA::FromJSON(jSchema);
|
||||||
return schema.ToJSON();
|
return schema.ToJSON();
|
||||||
|
@ -35,4 +34,14 @@ std::string ParseExpression(const std::string& expression) {
|
||||||
std::string CheckExpression(const std::string& jSchema, const std::string& expression) {
|
std::string CheckExpression(const std::string& jSchema, const std::string& expression) {
|
||||||
auto schema = RSFormJA::FromJSON(jSchema);
|
auto schema = RSFormJA::FromJSON(jSchema);
|
||||||
return schema.CheckExpression(expression);
|
return schema.CheckExpression(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CheckConstituenta(
|
||||||
|
const std::string& jSchema,
|
||||||
|
const std::string& alias,
|
||||||
|
const std::string& expression,
|
||||||
|
int cstType
|
||||||
|
) {
|
||||||
|
auto schema = RSFormJA::FromJSON(jSchema);
|
||||||
|
return schema.CheckConstituenta(alias, expression, static_cast<ccl::semantic::CstType>(cstType));
|
||||||
}
|
}
|
|
@ -55,6 +55,15 @@ class TestBinding(unittest.TestCase):
|
||||||
|
|
||||||
out2 = json.loads(pc.check_expression(schema, 'X1=X2'))
|
out2 = json.loads(pc.check_expression(schema, 'X1=X2'))
|
||||||
self.assertEqual(out2['parseResult'], False)
|
self.assertEqual(out2['parseResult'], False)
|
||||||
|
|
||||||
|
def test_check_constituenta(self):
|
||||||
|
''' Test checking expression against given schema '''
|
||||||
|
schema = self._get_default_schema()
|
||||||
|
out1 = json.loads(pc.check_constituenta(schema, 'A100', 'X1=X1', 5))
|
||||||
|
self.assertEqual(out1['parseResult'], True)
|
||||||
|
|
||||||
|
out2 = json.loads(pc.check_constituenta(schema, 'A100', 'X1=X2', 5))
|
||||||
|
self.assertEqual(out2['parseResult'], False)
|
||||||
|
|
||||||
def test_reset_aliases(self):
|
def test_reset_aliases(self):
|
||||||
''' Test reset aliases in schema '''
|
''' Test reset aliases in schema '''
|
||||||
|
|
Loading…
Reference in New Issue
Block a user