context.cpp
No OneTemporary

File Metadata

Created
Mon, Jul 6, 11:43 PM

context.cpp

/*
* adhoc.cpp
*
* Created on: Dec 1, 2015
* Author: pgess
*/
#include <query/context.h>
#include <boost/range/iterator_range_core.hpp>
#include <boost/iterator/transform_iterator.hpp>
using namespace std;
namespace xreate {
const Domain domainEmpty;
const Decisions decisionsEmpty;
const FunctionDemand functionDemandEmpty;
bool operator < (const Expression&a, const Expression&b) {
if (a.__state != b.__state) return a.__state < b.__state;
assert(a.__state != Expression::INVALID);
switch(a.__state) {
case Expression::IDENT:
case Expression::STRING:
case Expression::VARIANT:
return a.getValueString() < b.getValueString();
case Expression::NUMBER:
return a.getValueDouble() < b.getValueDouble();
case Expression::COMPOUND: {
assert(a.op == Operator::CALL);
assert(a.blocks.size()==0);
assert(b.blocks.size()==0);
if (a.operands.size() != b.operands.size()){
return (a.operands.size() < b.operands.size());
}
if (a.getValueString() != b.getValueString()){
return a.getValueString() < b.getValueString();
}
for(size_t i=0; i<a.operands.size(); ++i){
bool result = a.operands[i] < b.operands[i];
if (result) return true;
}
return false;
}
case Expression::BINDING:
case Expression::INVALID:
assert(false);
}
return false;
}
ContextQuery::ContextQuery(){}
const Domain&
ContextQuery::getContext(const ScopePacked& scopeId) const{
if (!__modelContext.count(scopeId)){
return domainEmpty;
}
return __modelContext.at(scopeId);
}
const Domain&
ContextQuery::getContext(CodeScope* const scope) const{
return getContext(clasp->pack(scope));
}
//DEBT compatibility of forced context with context resolution for interpretation
void
ContextQuery::forceContext(const ScopePacked& scopeId, std::list<Expression> context){
// TODO remove forced context of the same class/type only, possibly
//remove any previous forced context for this scopeId
//__modelForcedContext.erase(scopeId);
//TASK restore forceContext
//std::multimap<ScopePacked, Expression> __modelForcedContext;
/*
std::transform(context.begin(), context.end(), inserter(__modelForcedContext, __modelForcedContext.end()),
[scopeId](const Expression& context){return make_pair(scopeId, context);});
*/
}
void
ContextQuery::init(ClaspLayer* clasp){
const std::string& atomEarlyBinding = Config::get("clasp.bindings.scope");
this->clasp = clasp;
ClaspLayer::ModelFragment query = clasp->query(atomEarlyBinding);
//static context
if (query){
map<ScopePacked, vector<Expression>> dictContext;
for (auto i = query->first; i!=query->second; ++i){
ScopePacked idScope;
Expression context;
tie(idScope, context) = ClaspLayer::parse<ScopePacked, Expression>(i->second);
dictContext[idScope].push_back(context);
}
for (map<ScopePacked, vector<Expression>>::value_type& entry: dictContext){
__modelContext.insert(move(entry));
}
}
prepareFunctionDemandModel();
prepareDecisionModels();
}
void
ContextQuery::prepareFunctionDemandModel(){
const std::string& atomFunctionDemand = Config::get("clasp.bindings.function_demand");
ClaspLayer::ModelFragment query = clasp->query(atomFunctionDemand);
if (query)
for (auto i = query->first; i!=query->second; ++i){
string function;
Expression topic;
tie(function, topic) = ClaspLayer::parse<string, Expression>(i->second);
FunctionDemand& demand = __modelFunctionDemand[function];
demand.left.insert(make_pair(demand.left.size(), topic));
}
}
void
ContextQuery::prepareDecisionModels(){
const std::string& atomDecision = Config::get("clasp.bindings.scope_decision");
const std::string& atomDependentDecision = Config::get("clasp.context.decisions.dependent");
std::multimap<Expression, Expression> modelDomains;
ClaspLayer::ModelFragment query = clasp->query(atomDecision);
if (query){
for (auto i = query->first; i!=query->second; ++i){
ScopePacked scopeId;
Expression topic;
Expression decision;
std::tie(scopeId, topic, decision) = ClaspLayer::parse<ScopePacked, Expression, Expression>(i->second);
if (decision.getValueString() == atomDependentDecision) {
assert(decision.operands.size() == 2);
const Expression& decisionGuard = decision.operands[1];
const Expression& decisionValue = decision.operands[0];
__modelDependentDecisions[scopeId][topic].emplace(decisionGuard, decisionValue);
modelDomains.emplace(topic, decisionValue);
} else {
Decisions& decisionsOfScope = __modelStaticDecisions[scopeId];
assert(decisionsOfScope.emplace(topic, decision).second && "Possibly more than one decision");
modelDomains.emplace(topic, decision);
}
}
}
//populate topic domains:
auto adapter = [](const std::pair<const Expression&,const Expression>& p){ return p.second; };
auto iBegin = modelDomains.begin();
while (iBegin!=modelDomains.end()){
const Expression topic = iBegin->first;
auto iEnd = modelDomains.upper_bound(topic);
auto iBeginAdapted = boost::make_transform_iterator(iBegin,adapter);
auto iEndAdapted = boost::make_transform_iterator(iEnd,adapter);
Domain dom(iBeginAdapted, iEndAdapted);
__modelTopicDomains.emplace(topic, move(dom));
iBegin = iEnd;
}
}
const FunctionDemand&
ContextQuery::getFunctionDemand(const std::string& name) const {
if (__modelFunctionDemand.count(name)){
return __modelFunctionDemand.at(name);
}
return functionDemandEmpty;
}
const Decisions&
ContextQuery::getFinalDecisions(const ScopePacked& scopeId) const{
if (__modelStaticDecisions.count(scopeId)){
return __modelStaticDecisions.at(scopeId);
}
return decisionsEmpty;
}
const Domain&
ContextQuery::getTopicDomain(const Expression& topic) const{
if (__modelTopicDomains.count(topic)){
return __modelTopicDomains.at(topic);
}
return domainEmpty;
}
const DependentDecision&
ContextQuery::getDependentDecision(ScopePacked scope, const Expression& topic) const{
auto itDecisionsAllTopics = __modelDependentDecisions.find(scope);
if (itDecisionsAllTopics != __modelDependentDecisions.end()){
auto itDecisions = itDecisionsAllTopics->second.find(topic);
if (itDecisions != itDecisionsAllTopics->second.end()){
return itDecisions->second;
}
}
return decisionsEmpty;
}
// const std::string& atomLateBinding = Config::get("clasp.bindings.function_uncertain");
// query = clasp->query(atomLateBinding);
//
// std::map<std::string, std::vector<Expression>> dictFunctionDomain;
// if (query){
// for (auto i = query->first; i!=query->second; ++i){
// string nameFunction;
// Expression context;
// tie(nameFunction, context) = ClaspLayer::parse<ScopePacked, Expression>(i->second);
// dictFunctionDomain.at(nameFunction).push_back(context);
// }
//
// for(auto& entry: dictFunctionDomain){
// __modelFunctionDomain.emplace(entry.first, move(entry.second));
// }
// }
} /* namespace xreate */

Event Timeline