latereasoning.h
No OneTemporary

File Metadata

Created
Wed, Jul 8, 11:37 AM

latereasoning.h

/*
* 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/.
*
* \file latereasoning.h
* \brief Late reasoning support
*
* Author: pgess <v.melnychenko@xreate.org>
*
* Created on June 2, 2018, 1:08 PM
*/
#ifndef LATEREASONING_H
#define LATEREASONING_H
#include "transcendlayer.h"
namespace xreate {
struct LateBindingT;
template<>
struct AttachmentsDict<LateBindingT>{
typedef Expression Data;
static const unsigned int key = 12;
};
}
namespace xreate{ namespace latereasoning{
struct LateAnnotation{
std::list<std::pair<std::list<Expression>, Gringo::Symbol>> guardedSymbols;
boost::optional<Gringo::Symbol> select(const std::list<Expression>& keys) const;
};
struct LateAnnotationsGroup{
std::unordered_map<SymbolNode, LateAnnotation> annotations;
std::unordered_map<SymbolNode, std::list<SymbolPacked>> bindings;
};
//DEBT implement querying as a view/joining iterators without actual data copying
//DEBT how to implement late model RESET(invalidate all child models)
template<class Parent>
class LateReasoningTranscendDecorator: public Parent{
public:
StaticModel queryLate(const std::string& alias, const SymbolNode& symbol) const{
StaticModel result;
if(!__modelLate.count(alias)) return StaticModel();
const LateAnnotationsGroup& group = __modelLate.at(alias);
assert(group.bindings.count(symbol));
const std::list<SymbolPacked>& bindings = group.bindings.at(symbol);
std::list<Expression>&& keys = findKeys(bindings);
const LateAnnotation& annLate = group.annotations.at(symbol);
auto ann = annLate.select(keys);
if(ann){
result.emplace(std::make_pair(alias, *ann));
}
return result;
}
protected:
virtual bool processSolution(Gringo::Model const &model) override{
const std::string& atomLateStatement = "late";
for(const Gringo::Symbol& atom: model.atoms(clingo_show_type_atoms)){
std::string atomName(atom.name().c_str());
SymbolPacked aaaa;
if(atomName == atomLateStatement){
//late atom's format: (Symbol, (tuple of keys), (tuple of values), late-annotation)
auto atomLate = TranscendLayer::parse<SymbolPacked, std::list<SymbolPacked>, std::list<Expression>, Gringo::Symbol>(atom);
const std::string& atomAlias = std::get<3>(atomLate).name().c_str();
addLateAtom(atomAlias, std::get<0>(atomLate),
std::get<3>(atomLate), std::get<1>(atomLate),
std::get<2>(atomLate));
}
}
return Parent::processSolution(model);
}
private:
std::map<std::string, LateAnnotationsGroup> __modelLate;
void addLateAtom(const std::string& alias, const SymbolNode& symbol,
const Gringo::Symbol& atom, const std::list<SymbolPacked>& guardKeys,
const std::list<Expression>& guardBindings){
LateAnnotationsGroup& group = __modelLate[alias];
if(!group.bindings.count(symbol)){
group.bindings.emplace(symbol, guardKeys);
}
LateAnnotation& annotation = group.annotations[symbol];
annotation.guardedSymbols.push_back(std::make_pair(guardBindings, atom));
}
std::list<Expression> findKeys(const std::list<SymbolPacked>& keys) const{
std::list<Expression> result;
std::transform(keys.begin(), keys.end(), std::inserter(result, result.end()), [this](const SymbolPacked & key){
return Attachments::get<LateBindingT>(Parent::unpack(key));
});
return result;
}
};
}} // end of xreate::latereasoning
#endif /* LATEREASONING_H */

Event Timeline