interpretation.cpp
No OneTemporary

File Metadata

Created
Mon, Jul 6, 11:33 PM

interpretation.cpp

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*
* Author: pgess <v.melnychenko@xreate.org>
* Created on June 25, 2018, 3:25 PM
*
* \file interpretation.cpp
* \brief interpretation
*/
#include "analysis/interpretation.h"
using namespace std;
namespace xreate{
namespace interpretation{
typedef vector<int> InstancePacked;
std::list<Expression>
generateAllInstancesInDomain2(const ExpandedType& domainT) {
if(!domainT->isValid()) {
return {Expression()};
}
assert(domainT->__operator == TypeOperator::VARIANT);
std::list<Expression> results;
int variantId = -1;
bool flagDomainStateless = std::all_of(domainT->__operands.begin(), domainT->__operands.end(),
[](const TypeAnnotation & subdomainT) {
return !subdomainT.isValid();
});
for(const TypeAnnotation& subdomainT : domainT->__operands) {
++variantId;
if(flagDomainStateless) {
Expression result(Operator::VARIANT,{});
result.setValueDouble(variantId);
results.push_back(result);
continue;
}
std::list<Expression> subresults = generateAllInstancesInDomain2(ExpandedType(subdomainT));
for (const Expression& subresult : subresults) {
Expression result(Operator::VARIANT,{});
result.setValueDouble(variantId);
result.operands.push_back(subresult);
results.push_back(result);
}
}
return results;
}
TypeAnnotation
collapseFnGroup(const std::list<Gringo::Symbol>& symbols) {
Gringo::Symbol symbolAny = symbols.front();
size_t operandsCount = symbolAny.args().size;
TypeAnnotation resultT;
resultT.__operands.reserve(operandsCount);
for(size_t operandId = 0; operandId < operandsCount; ++operandId) {
std::list<Gringo::Symbol> column;
for(const Gringo::Symbol& row : symbols) {
column.push_back(row.args()[operandId]);
}
TypeAnnotation operandT = collapseColumn(column);
resultT.__operands.push_back(operandT);
}
if(resultT.__operands.size() == 1) {
return resultT.__operands.front();
}
if(resultT.__operands.size() > 1) {
resultT.__operator = TypeOperator::LIST_RECORD;
return resultT;
}
return resultT;
}
TypeAnnotation
collapseColumn(const std::list<Gringo::Symbol>& symbols) {
TypeAnnotation resultT;
if(!symbols.size()) return resultT;
Gringo::Symbol symbolAny = symbols.front();
switch(symbolAny.type()) {
case Gringo::SymbolType::Num:
{
return TypeAnnotation(TypePrimitive::Num);
}
case Gringo::SymbolType::Str:
{
return TypeAnnotation(TypePrimitive::String);
}
case Gringo::SymbolType::Fun:
{
map<string, list < Gringo::Symbol>> fnGroups;
for(const Gringo::Symbol& row : symbols) {
fnGroups[row.name().c_str()].push_back(row);
}
TypeAnnotation resultT;
resultT.__operands.reserve(fnGroups.size());
resultT.bindings.reserve(fnGroups.size());
for(const auto& group : fnGroups) {
if(!group.second.size()) continue;
TypeAnnotation variantT = collapseFnGroup(group.second);
Gringo::Symbol symbolAny = group.second.front();
string variantName = symbolAny.name().c_str();
resultT.fields.push_back(variantName);
resultT.__operands.push_back(variantT);
}
resultT.__operator = TypeOperator::VARIANT;
// if(resultT.__operands.size() == 1) {
// return resultT.__operands.front();
// }
return resultT;
}
case Gringo::SymbolType::Inf:
case Gringo::SymbolType::Special:
case Gringo::SymbolType::Sup:
{
break;
}
}
assert(false);
return TypeAnnotation();
}
ExpandedType
dereferenceSlaveType(ExpandedType t, const TranscendLayer* transcend) {
assert(t->__operator == TypeOperator::SLAVE);
const string& domain = t->__valueCustom;
StaticModel model = transcend->query(domain);
if(!model.size()) return ExpandedType(TypeAnnotation());
std::list<Gringo::Symbol> symbols;
for(auto row : model) {
symbols.push_back(row.second);
}
return ExpandedType(collapseFnGroup(symbols));
}
Expression
representTransExpression(const Gringo::Symbol& atom, ExpandedType schemaT, TranscendLayer* transcend) {
atom.print(std::cout); std::cout<<endl;
switch(schemaT->__operator) {
case TypeOperator::NONE:
{
switch(schemaT->__value) {
case TypePrimitive::I8:
case TypePrimitive::I32:
case TypePrimitive::I64:
case TypePrimitive::Num:
case TypePrimitive::Int:
{
return Expression(Atom<Number_t>(atom.num()));
}
case TypePrimitive::String:
{
return Expression(Atom<String_t>(atom.string().c_str()));
}
case TypePrimitive::Invalid:
case TypePrimitive::Bool:
case TypePrimitive::Float:
{
assert(false);
return Expression();
}
}
break;
}
case TypeOperator::SLAVE:
{
ExpandedType contentT = dereferenceSlaveType(schemaT, transcend);
return representTransExpression(atom, contentT, transcend);
}
case TypeOperator::VARIANT:
{
map<string, int> dictVariants;
for(size_t variantId = 0; variantId < schemaT->fields.size(); ++variantId) {
dictVariants.emplace(schemaT->fields.at(variantId), variantId);
}
string predicateName = atom.name().c_str();
assert(dictVariants.count(predicateName));
size_t predicateId = dictVariants.at(predicateName);
Expression result(Operator::VARIANT,{});
result.op = Operator::VARIANT;
result.setValueDouble(predicateId);
if(!schemaT->__operands.size()) return result;
ExpandedType contentT = schemaT->__operands.at(predicateId).__operator == TypeOperator::SLAVE
? dereferenceSlaveType(ExpandedType(schemaT->__operands.at(predicateId)), transcend)
: ExpandedType(schemaT->__operands.at(predicateId));
//edge case, content's type is LIST_NAMED:
if (contentT->__operator == TypeOperator::LIST_RECORD) {
result.operands.push_back(representTransExpression(atom, contentT, transcend));
} else if(!contentT->isValid()) {
return result;
} else {
assert(atom.args().size);
result.operands.push_back(representTransExpression(atom.args()[0], contentT, transcend));
}
return result;
}
case TypeOperator::LIST_RECORD:
{
const Gringo::SymSpan& operandsRaw = atom.args();
size_t opCount = operandsRaw.size;
assert(opCount == schemaT->__operands.size());
size_t operandId = 0;
std::vector<Expression> operands;
operands.reserve(opCount);
for(const TypeAnnotation operandT : schemaT->__operands) {
operands.push_back(representTransExpression(operandsRaw[operandId], ExpandedType(operandT), transcend));
++operandId;
}
Expression result(Operator::LIST,{});
result.operands = operands;
result.type = schemaT;
return result;
}
case TypeOperator::LIST_ARRAY:
case TypeOperator::CALL:
case TypeOperator::CUSTOM:
case TypeOperator::ACCESS:
case TypeOperator::LINK:
{
assert(false);
return Expression();
}
}
assert(false);
return Expression();
}
}
} //end of xreate namespace

Event Timeline