solution: how to retrieve syntactic representation

there is now a mechanism to allow sprcialised queries
to generate this syntactic representation only on demand

The actual concrete representation e.g. for scope queries
still remains TODO, but this won't really change
until we target the integration of a real resoloution engine
This commit is contained in:
Fischlurch 2013-01-02 04:18:05 +01:00
parent 65feeb83fd
commit 1328ef4aa6
3 changed files with 65 additions and 8 deletions

View file

@ -98,6 +98,7 @@ namespace lumiera {
using lib::IxID;
using lib::Symbol;
using lib::Literal;
using util::isnil;
using util::unConst;
using boost::lexical_cast;
using std::string;
@ -132,6 +133,7 @@ namespace lumiera {
{ EMPTY = 0
, GENERIC = 1
, DISCOVERY
, PLACEMENT
};
struct QueryID
@ -258,6 +260,12 @@ namespace lumiera {
* of specific resolution mechanisms. This way, clients may retrieve a set of results,
* each representing a possible solution to the posed query.
*
* @remarks lumiera::Query is an interface, but can be used as-is to represent a generic query.
* Specialised subclasses are required to provide a syntactic representation, but are
* free to do so only on demand. In this case, generate an \em empty lib::QueryText
* definition and implement the Query#buildSyntacticRepresentation function.
* Every fundamentally different kind of query needs to be listed in Goal::Kind.
*
* @note until really integrating a rules based system
* this is largely dummy placeholder implementation.
* Some more specific query resolvers are available already,
@ -273,7 +281,7 @@ namespace lumiera {
: public Goal
{
/** generic syntactical definition */
lib::QueryText def_;
mutable lib::QueryText def_;
protected:
static QueryID
@ -283,6 +291,33 @@ namespace lumiera {
return id;
}
/**
* Extension point to generate a generic query definition on demand.
* Some specialised kinds of queries, intended to be treated by a specific resolver,
* may choose skip constructing a generic query representation, but are then bound
* to supplement such a generic definition through this function when required.
* The generated query definition must be sufficient to reconstruct the query
* in all respects.
* @return a complete definition of this query in predicate form
* @retval bottom token to indicate failure to comply to this requirement.
*/
virtual lib::QueryText
buildSyntacticRepresentation() const
{
WARN (query, "internal query not outfitted with a suitable query definition");
return string("bottom");
}
/** access the complete syntactical representation of this query.
* May trigger on-demand initialisation */
lib::QueryText
getQueryDefinition() const
{
if (isnil(this->def_))
def_ = this->buildSyntacticRepresentation();
return def_;
}
class Builder;
@ -348,7 +383,7 @@ namespace lumiera {
friend size_t
hash_value (Query const& q)
{
return taggedHash (hash_value(q.def_), q.id_);
return taggedHash (hash_value(q.getQueryDefinition()), q.id_);
}
};
@ -370,12 +405,14 @@ namespace lumiera {
QueryKey (Goal::QueryID id, lib::QueryText q)
: id_(id)
, def_(q)
{ }
{
ENSURE (!isnil(def_));
}
/** the empty or bottom query key */
QueryKey()
: id_()
, def_("NIL")
, def_("false")
{ }
// default copyable
@ -544,7 +581,7 @@ namespace lumiera {
inline typename Query<RES>::Builder
Query<RES>::rebuild() const
{
return Builder(this->id_, this->def_);
return Builder(this->id_, getQueryDefinition());
}
@ -566,7 +603,7 @@ namespace lumiera {
inline bool
Query<RES>::usesPredicate (Symbol predicate) const
{
return lib::query::hasTerm(predicate, this->def_);
return lib::query::hasTerm(predicate, getQueryDefinition());
}
@ -579,7 +616,7 @@ namespace lumiera {
inline
Query<RES>::operator QueryKey() const
{
return QueryKey (this->id_, this->def_);
return QueryKey (this->id_, getQueryDefinition());
}

View file

@ -164,6 +164,9 @@ NOBUG_CPP_DEFINE_FLAG_PARENT ( plugins, progress);
/** base channel flag to track overall working of the render engine */
NOBUG_CPP_DEFINE_FLAG_PARENT ( render, logging);
NOBUG_CPP_DEFINE_FLAG_PARENT ( config, logging); //TODO: here seems to be an ambiguity weather "config" should denote the global config channel or the config-loder internals
NOBUG_CPP_DEFINE_FLAG_PARENT ( rules, config);
NOBUG_CPP_DEFINE_FLAG_PARENT ( query, config);
NOBUG_CPP_DEFINE_FLAG_PARENT ( resolver, config);
/** base flag for software testing */
NOBUG_CPP_DEFINE_FLAG_PARENT ( test, logging);

View file

@ -44,6 +44,7 @@
#include "proc/mobject/placement.hpp"
#include "common/query/query-resolver.hpp"
#include "lib/format-string.hpp"
#include <tr1/functional>
@ -97,7 +98,7 @@ namespace session {
DiscoveryQuery ()
: _Query (_Query::defineQueryTypeID (Goal::DISCOVERY)
, lib::QueryText("TODO")) /////////////////////////////////////////////TODO: generate syntactic representation
, lib::QueryText("")) // syntactic representation supplied on demand
{ }
private:
@ -189,6 +190,22 @@ namespace session {
{
return bind (&PlacementMO::isCompatible<MO>, _1 );
}
/** supplement a syntactic representation (as generic query in predicate form).
* Building this representation is done on demand for performance reasons;
* typically a ScopeQuery is issued immediately into a known sub scope
* of the Session/Model and resolved by the PlacementIndex
* @todo we need a readable and sensible representation as generic query ///////////////////TICKET #901
*/
lib::QueryText
buildSyntacticRepresentation() const
{
using util::_Fmt;
TODO ("valid syntactic representation of scope queries");
return lib::QueryText (_Fmt ("scope(X, %08X), scopeRelation(X, %d)")
% hash_value(searchScope()) ////////TODO how to represent a placement in queries
% uint(searchDirection())); ////////TODO how to translate that in textual terms
}
};