latereasoning.cpp
No OneTemporary

File Metadata

Created
Tue, Aug 25, 12:20 PM

latereasoning.cpp

/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*
* latereasoning.cpp
*
* Author: pgess <v.melnychenko@xreate.org>
* Created on April 21, 2018, 5:10 PM
*/
#include "xreatemanager.h"
#include "transcendlayer.h"
#include "pass/latereasoningpass.h"
#include "aux/latereasoning.h"
#include "pass/dfapass.h"
#include <boost/format.hpp>
#include "gtest/gtest.h"
using namespace std;
using namespace xreate;
using namespace xreate::latereasoning;
TEST(LateReasoning, Syntax1) {
XreateManager* man = XreateManager::prepare(R"Code(
test = function:: int {
x = 0::int.
y1= switch late (x)::int{0}.
y2= switch late(x+y1->a::int)::int{1}.
y1+y2
}
)Code");
CodeScope* scope = man->root->findFunction("test")->getEntryScope();
Expression y1 = scope->getDefinition(scope->getSymbol("y1"));
Expression y2 = scope->getDefinition(scope->getSymbol("y2"));
ASSERT_EQ(1, y1.bindings.size());
ASSERT_STRCASEEQ("x", y1.bindings.at(0).c_str());
ASSERT_EQ(1, y2.bindings.size());
ASSERT_STRCASEEQ("a", y2.bindings.at(0).c_str());
}
TEST(LateReasoning, Pass_DFAPassDec_1){
typedef LateReasoningTranscendDecorator<TranscendLayer> LRTranscend;
auto man = details::tier2::XreateManager::prepare(R"Code(
Dom = type slave dom.
test = function:: int; entry
{
LateIdent = 0:: Dom.
0:: int; ann1(LateIdent)
}
)Code");
CodeScope* scopeEntry = man->root->findFunction("test")->getEntryScope();
ScopedSymbol keyS = scopeEntry->getSymbol("LateIdent");
SymbolPacked keySP = man->transcend->pack(Symbol{keyS, scopeEntry});
std::shared_ptr<LateReasoningScope> scopeLateEntry(new LateReasoningScope(nullptr));
scopeLateEntry->addIdentifier("LateIdent", keySP);
typedef LateReasoningDFAPassDecorator<dfa::DFAPass> LRDFAPass;
LRDFAPass* dfaPass = new LRDFAPass(man);
dfaPass->registerLateScope(scopeEntry, scopeLateEntry.get());
man->transcend->addRawScript("dom(guard1; guard2).\n");
man->registerPass(dfaPass, PassId::DFAPass, nullptr);
man->executePasses();
testing::internal::CaptureStdout();
man->analyse();
std::string outputActual = testing::internal::GetCapturedStdout();
cout << outputActual << endl;
string outputExpected = "late(s(0,-2,0), (s(1,-2,0)), (LateIdent), ann1(LateIdent)):- dom(LateIdent).";
ASSERT_NE(std::string::npos, outputActual.find(outputExpected));
}
TEST(LateReasoning, Transcend_LRTransDec_1) {
Attachments::init<versions::VariableVersion>();
typedef LateReasoningTranscendDecorator<TranscendLayer> LRTranscend;
std::unique_ptr<LRTranscend> transcend(new LRTranscend());
std::unique_ptr<CodeScope> scope(new CodeScope(nullptr));
Symbol symbA = scope->addDefinition(Atom<Identifier_t>("a"), Expression());
Symbol symbB = scope->addDefinition(Atom<Identifier_t>("b"), Expression());
Symbol symbC = scope->addDefinition(Atom<Identifier_t>("c"), Expression());
Symbol symbTarget1 = scope->addDefinition(Atom<Identifier_t>("target1"), Expression());
Symbol symbTarget2 = scope->addDefinition(Atom<Identifier_t>("target2"), Expression());
SymbolPacked symbpA = transcend->pack(symbA, "a");
SymbolPacked symbpB = transcend->pack(symbB, "b");
SymbolPacked symbpC = transcend->pack(symbC, "c");
SymbolPacked symbTarget1P = transcend->pack(symbTarget1, "target1");
SymbolPacked symbTarget2P = transcend->pack(symbTarget2, "target2");
boost::format formatSymb("s(%1%,%2%,%3%)");
boost::format formatLateAnnotation1("late(%1%, (%2%, %3%, %4%), (%5%, %6%, %7%), %8%).");
boost::format formatLateAnnotation2("late(%1%, (%2%, %3%), (%4%, %5%), %6%).");
#define FORMATSYMBOL(s) (formatSymb % s.identifier % s.version % s.scope).str()
// Ann1, `variant1`
transcend->addRawScript((formatLateAnnotation1
% FORMATSYMBOL(symbTarget1P)
% FORMATSYMBOL(symbpA) % FORMATSYMBOL(symbpB) % FORMATSYMBOL(symbpC)
% "guard1" % "guard1" % "guard1"
% "result(variant1)"
). str());
//Ann1 `result2` variant
transcend->addRawScript((formatLateAnnotation1
% FORMATSYMBOL(symbTarget1P)
% FORMATSYMBOL(symbpA) % FORMATSYMBOL(symbpB) % FORMATSYMBOL(symbpC)
% "guard2" % "guard2" % "guard2"
% "result(variant2)"
). str());
//Ann2 `result3` variant
transcend->addRawScript((formatLateAnnotation2
% FORMATSYMBOL(symbTarget2P)
% FORMATSYMBOL(symbpA) % FORMATSYMBOL(symbpB)
% "guard3" % "guard3"
% "result(variant3)"
). str());
transcend->run();
LateAnnotationsGroup group = transcend->queryLate("result");
ASSERT_EQ(2, group.annotations.size());
for(const auto& annEntry: group.annotations){
annEntry.first.print(cout);
cout <<endl;
Gringo::SymSpan symbsTuple;
symbsTuple.first = &annEntry.first;
symbsTuple.size = 1;
Gringo::Symbol targetWrapped = Gringo::Symbol::createTuple(symbsTuple);
SymbolPacked targetSP = get<0>(transcend->parse<SymbolPacked>(targetWrapped));
if (targetSP == symbTarget1P){
LateAnnotation ann = annEntry.second;
ASSERT_EQ(2, ann.guardedContent.size());
Expression selector(Operator::CALL, {Atom<Identifier_t>("guard2")});
auto answer = ann.select({selector, selector, selector}man->root, man->transcend);
ASSERT_TRUE(answer);
string answerS = get<0>(transcend->parse<string>(*answer));
ASSERT_STREQ("variant2", answerS.c_str());
} else if (targetSP == symbTarget2P) {
LateAnnotation ann = annEntry.second;
ASSERT_EQ(1, ann.guardedContent.size());
Expression selector(Operator::CALL, {Atom<Identifier_t>("guard3")});
auto answer = ann.select({selector, selector, selector});
ASSERT_TRUE(answer);
ASSERT_STREQ("variant3", get<0>(transcend->parse<string>(*answer)).c_str());
} else {
ASSERT_TRUE(false);
}
}
}
TEST(LateReasoning, Compilation1){
XreateManager* man = XreateManager::prepare(R"Code(
Color = type variant{RED, BLUE, GREEN}.
test = function:: int; entry {
x = RED():: Color.
y1= switch late (x):: int
{0}.
y1
}
)Code");
int (*program)() = (int (*)())man->run();
int result = program();
ASSERT_EQ(0, result);
}

Event Timeline