#ifndef TOP_MODEL_H_
#define TOP_MODEL_H_
#include "rdf_rule_core.h"
#include "rdf_graph.h"
#include "rdf_session.h"
#include "knowledge_base.h"
#include "rule_session.h"
namespace model {
using rdf::index_type;
using rdf::rdf_graph;
using rdf::rdf_graph_ptr_type;
using rdf::rdf_session;
using rdf::rdf_session_ptr_type;
using rule::rule_session;
using rule::rule_session_ptr_type;
using rdf::top_lookup_iterator;
using rdf::top_rdf_lookup_iterator;
class top_model;
typedef std::tr1::shared_ptr<top_model> top_model_ptr_type;
class top_class;
typedef std::tr1::shared_ptr<top_class> top_class_ptr_type;
class top_property;
typedef std::tr1::shared_ptr<top_property> top_property_ptr_type;
/////////////////////////////////////////////////////////////////////////////////////////
// Data structure for containing class hierarchy
//
/////////////////////////////////////////////////////////////////////////////////////////
typedef std::tr1::unordered_map<index_type, top_class_ptr_type> top_class_map_type;
typedef std::tr1::unordered_map<index_type, top_property_ptr_type> top_property_map_type;
/////////////////////////////////////////////////////////////////////////////////////////
// Data structure for providing uniformed iterators
//
/////////////////////////////////////////////////////////////////////////////////////////
typedef std::tr1::unordered_set<index_type> index_type_set_type;
typedef std::vector<index_type> index_type_vector_type;
typedef std::vector<top_property_ptr_type> top_property_vector_type;
// create iterators that comply to the semantic: is_end(), get_value(), next()
typedef rdf::top_map_iterator<top_class_map_type::const_iterator, top_class_ptr_type> top_class_const_iterator;
typedef rdf::top_map_iterator<top_property_map_type::const_iterator, top_property_ptr_type> top_property_const_iterator;
typedef rdf::top_iterator<top_property_vector_type::const_iterator> top_property_v_const_iterator;
/////////////////////////////////////////////////////////////////////////////////////////
// create iterators that comply to the semantic: is_end(), get_value(), next()
/////////////////////////////////////////////////////////////////////////////////////////
struct index_triple_lookup_by_object
{
inline index_type
operator()(rdf::index_triple t)const
{
return t.get_object();
};
};
typedef top_rdf_lookup_iterator<rdf_graph::index_iterator, index_type, index_triple_lookup_by_object> rdf_graph_iterator_by_object;
typedef top_rdf_lookup_iterator<rdf_session::index_iterator, index_type, index_triple_lookup_by_object> rdf_session_iterator_by_object;
struct top_class_lookup;
struct top_class_lookup_by_object;
struct top_property_lookup;
struct top_property_lookup_by_subject;
struct top_property_lookup_by_object;
typedef top_lookup_iterator<index_type_vector_type::const_iterator, top_class_ptr_type, top_class_lookup> top_class_lookup_const_iterator;
typedef top_lookup_iterator<index_type_vector_type::const_iterator, top_property_ptr_type, top_property_lookup> top_property_lookup_const_iterator;
typedef top_rdf_lookup_iterator<rdf_graph::index_iterator, top_class_ptr_type, top_class_lookup_by_object> top_class_lookup_iterator_by_asserted_object;
typedef top_rdf_lookup_iterator<rdf_session::index_iterator, top_class_ptr_type, top_class_lookup_by_object> top_class_lookup_iterator_by_object;
typedef top_rdf_lookup_iterator<rdf_graph::index_iterator, top_property_ptr_type, top_property_lookup_by_subject> top_property_lookup_iterator_by_asserted_subject;
typedef top_rdf_lookup_iterator<rdf_session::index_iterator, top_property_ptr_type, top_property_lookup_by_subject> top_property_lookup_iterator_by_subject;
typedef top_rdf_lookup_iterator<rdf_graph::index_iterator, top_property_ptr_type, top_property_lookup_by_object> top_property_lookup_iterator_by_asserted_object;
typedef top_rdf_lookup_iterator<rdf_session::index_iterator, top_property_ptr_type, top_property_lookup_by_object> top_property_lookup_iterator_by_object;
/////////////////////////////////////////////////////////////////////////////////////////
// class owl
//
// Class having lookups to owl resources in rdf session
/////////////////////////////////////////////////////////////////////////////////////////
struct owl
{
owl(rule_session_ptr_type const& rule_session_p):
m_rule_session_p(rule_session_p)
{
rdf_graph_ptr_type meta_graph_p = m_rule_session_p->get_knowledge_base().get_meta_graph();
owl_AllDifferent = meta_graph_p->create_resource_as_index("owl:AllDifferent");
owl_AnnotationProperty = meta_graph_p->create_resource_as_index("owl:AnnotationProperty");
owl_Class = meta_graph_p->create_resource_as_index("owl:Class");
owl_DataRange = meta_graph_p->create_resource_as_index("owl:DataRange");
owl_DatatypeProperty = meta_graph_p->create_resource_as_index("owl:DatatypeProperty");
owl_FunctionalProperty = meta_graph_p->create_resource_as_index("owl:FunctionalProperty");
owl_InverseFunctionalProperty = meta_graph_p->create_resource_as_index("owl:InverseFunctionalProperty");
owl_Nothing = meta_graph_p->create_resource_as_index("owl:Nothing");
owl_ObjectProperty = meta_graph_p->create_resource_as_index("owl:ObjectProperty");
owl_Ontology = meta_graph_p->create_resource_as_index("owl:Ontology");
owl_OntologyProperty = meta_graph_p->create_resource_as_index("owl:OntologyProperty");
owl_Restriction = meta_graph_p->create_resource_as_index("owl:Restriction");
owl_SymmetricProperty = meta_graph_p->create_resource_as_index("owl:SymmetricProperty");
owl_Thing = meta_graph_p->create_resource_as_index("owl:Thing");
owl_TransitiveProperty = meta_graph_p->create_resource_as_index("owl:TransitiveProperty");
owl_allValuesFrom = meta_graph_p->create_resource_as_index("owl:allValuesFrom");
owl_backwardCompatibleWith = meta_graph_p->create_resource_as_index("owl:backwardCompatibleWith");
owl_cardinality = meta_graph_p->create_resource_as_index("owl:cardinality");
owl_complementOf = meta_graph_p->create_resource_as_index("owl:complementOf");
owl_differentFrom = meta_graph_p->create_resource_as_index("owl:differentFrom");
owl_disjointWith = meta_graph_p->create_resource_as_index("owl:disjointWith");
owl_distinctMembers = meta_graph_p->create_resource_as_index("owl:distinctMembers");
owl_equivalentClass = meta_graph_p->create_resource_as_index("owl:equivalentClass");
owl_equivalentProperty = meta_graph_p->create_resource_as_index("owl:equivalentProperty");
owl_hasValue = meta_graph_p->create_resource_as_index("owl:hasValue");
owl_incompatibleWith = meta_graph_p->create_resource_as_index("owl:incompatibleWith");
owl_intersectionOf = meta_graph_p->create_resource_as_index("owl:intersectionOf");
owl_inverseOf = meta_graph_p->create_resource_as_index("owl:inverseOf");
owl_maxCardinality = meta_graph_p->create_resource_as_index("owl:maxCardinality");
owl_minCardinality = meta_graph_p->create_resource_as_index("owl:minCardinality");
owl_onProperty = meta_graph_p->create_resource_as_index("owl:onProperty");
owl_oneOf = meta_graph_p->create_resource_as_index("owl:oneOf");
owl_priorVersion = meta_graph_p->create_resource_as_index("owl:priorVersion");
owl_sameAs = meta_graph_p->create_resource_as_index("owl:sameAs");
owl_someValuesFrom = meta_graph_p->create_resource_as_index("owl:someValuesFrom");
owl_unionOf = meta_graph_p->create_resource_as_index("owl:unionOf");
owl_versionInfo = meta_graph_p->create_resource_as_index("owl:versionInfo");
rdf_Description = meta_graph_p->create_resource_as_index("rdf:Description");
rdf_Property = meta_graph_p->create_resource_as_index("rdf:Property");
rdf_type = meta_graph_p->create_resource_as_index("rdf:type");
rdfs_Class = meta_graph_p->create_resource_as_index("rdfs:Class");
rdfs_Datatype = meta_graph_p->create_resource_as_index("rdfs:Datatype");
rdfs_comment = meta_graph_p->create_resource_as_index("rdfs:comment");
rdfs_domain = meta_graph_p->create_resource_as_index("rdfs:domain");
rdfs_range = meta_graph_p->create_resource_as_index("rdfs:range");
rdfs_subClassOf = meta_graph_p->create_resource_as_index("rdfs:subClassOf");
rdfs_subPropertyOf = meta_graph_p->create_resource_as_index("rdfs:subPropertyOf");
top_propertyError = meta_graph_p->create_resource_as_index("top:propertyError");
top_invalid_property = meta_graph_p->create_resource_as_index("top:invalid_property");
top_invalid_transitive_property = meta_graph_p->create_resource_as_index("top:invalid_transitive_property");
};
~owl(){};
index_type owl_AllDifferent ;
index_type owl_AnnotationProperty ;
index_type owl_Class ;
index_type owl_DataRange ;
index_type owl_DatatypeProperty ;
index_type owl_FunctionalProperty ;
index_type owl_InverseFunctionalProperty ;
index_type owl_Nothing ;
index_type owl_ObjectProperty ;
index_type owl_Ontology ;
index_type owl_OntologyProperty ;
index_type owl_Restriction ;
index_type owl_SymmetricProperty ;
index_type owl_Thing ;
index_type owl_TransitiveProperty ;
index_type owl_allValuesFrom ;
index_type owl_backwardCompatibleWith ;
index_type owl_cardinality ;
index_type owl_complementOf ;
index_type owl_differentFrom ;
index_type owl_disjointWith ;
index_type owl_distinctMembers ;
index_type owl_equivalentClass ;
index_type owl_equivalentProperty ;
index_type owl_hasValue ;
index_type owl_incompatibleWith ;
index_type owl_intersectionOf ;
index_type owl_inverseOf ;
index_type owl_maxCardinality ;
index_type owl_minCardinality ;
index_type owl_onProperty ;
index_type owl_oneOf ;
index_type owl_priorVersion ;
index_type owl_sameAs ;
index_type owl_someValuesFrom ;
index_type owl_unionOf ;
index_type owl_versionInfo ;
index_type rdf_Description ;
index_type rdf_Property ;
index_type rdf_type ;
index_type rdfs_Class ;
index_type rdfs_Datatype ;
index_type rdfs_comment ;
index_type rdfs_domain ;
index_type rdfs_range ;
index_type rdfs_subClassOf ;
index_type rdfs_subPropertyOf ;
index_type top_propertyError ;
index_type top_invalid_property ;
index_type top_invalid_transitive_property ;
rule_session_ptr_type m_rule_session_p;
};
/////////////////////////////////////////////////////////////////////////////////////////
// class top_model
//
// Class managing a top model (based on OWL/DL).
// This class requires a rule_session where the associated asserted graph correspond
// to the meta graph. The associated knowledge base contains rules to infer on the meta
// graph, i.e., correspond to the rules implementing the OWL/DL specification.
/////////////////////////////////////////////////////////////////////////////////////////
class top_model
{
public:
inline top_model(rdf_session_ptr_type const& rdf_session_p, rule_session_ptr_type const& rule_session_p):
m_rdf_session_p(rdf_session_p),
m_rule_session_p(rule_session_p),
m_owl(rule_session_p),
m_is_asserted_hierarchy_computed(false),
m_top_classes(),
m_top_properties(),
m_asserted_base_object_properties(),
m_asserted_base_data_type_properties(),
m_inferred_base_object_properties(),
m_inferred_base_data_type_properties()
{
};
inline ~top_model() {};
inline rdf_session_ptr_type
get_rdf_session()const
{
return m_rdf_session_p;
};
inline rule_session_ptr_type
get_rule_session()const
{
return m_rule_session_p;
};
///////////////////////////////////////////////////////////////////////////////////////////
// contains methods
///////////////////////////////////////////////////////////////////////////////////////////
inline bool
contains_asserted(index_type s, index_type p)const
{
return m_rdf_session_p->get_asserted_graph()->contains(s, p, rdf::all_objects());
};
inline bool
contains(index_type s, index_type p)const
{
return m_rdf_session_p->contains(s, p, rdf::all_objects());
};
inline bool
contains_asserted(index_type s, index_type p, index_type o)const
{
return m_rdf_session_p->get_asserted_graph()->contains(s, p, o);
};
inline bool
contains(index_type s, index_type p, index_type o)const
{
return m_rdf_session_p->contains(s, p, o);
};
///////////////////////////////////////////////////////////////////////////////////////////
// find object methods
///////////////////////////////////////////////////////////////////////////////////////////
inline rdf_graph::index_iterator
find_asserted_objects(index_type s, index_type p)const
{
return m_rdf_session_p->get_asserted_graph()->find_index(s, p, rdf::all_objects());
};
inline rdf_session::index_iterator
find_objects(index_type s, index_type p)const
{
return m_rdf_session_p->find_index(s, p, rdf::all_objects());
};
inline index_type
find_functional_asserted_object(index_type s, index_type p)const
{
rdf_graph::index_iterator itor = m_rdf_session_p->get_asserted_graph()->find_index(s, p, rdf::all_objects());
if(itor.is_end()) throw rdf::rdf_exception(rdf::invalid_index, "top_model.find_functional_object: index not found!");
return itor.get_triple().get_object();
};
inline index_type
find_functional_object(index_type s, index_type p)const
{
rdf_session::index_iterator itor = m_rdf_session_p->find_index(s, p, rdf::all_objects());
if(itor.is_end()) throw rdf::rdf_exception(rdf::invalid_index, "top_model.find_functional_object: index not found!");
return itor.get_triple().get_object();
};
///////////////////////////////////////////////////////////////////////////////////////////
// find subject methods
///////////////////////////////////////////////////////////////////////////////////////////
inline rdf_graph::index_iterator
find_asserted_subjects(index_type p, index_type o)const
{
return m_rdf_session_p->get_asserted_graph()->find_index(rdf::all_subjects(), p, o);
};
inline rdf_session::index_iterator
find_subjects(index_type p, index_type o)const
{
return m_rdf_session_p->find_index(rdf::all_subjects(), p, o);
};
inline index_type
find_functional_asserted_subject(index_type p, index_type o)const
{
rdf_graph::index_iterator itor = m_rdf_session_p->get_asserted_graph()->find_index(rdf::all_subjects(), p, o);
if(itor.is_end()) throw rdf::rdf_exception(rdf::invalid_index, "top_model.find_functional_subject: index not found!");
return itor.get_triple().get_subject();
};
inline index_type
find_functional_subject(index_type p, index_type o)const
{
rdf_session::index_iterator itor = m_rdf_session_p->find_index(rdf::all_subjects(), p, o);
if(itor.is_end()) throw rdf::rdf_exception(rdf::invalid_index, "top_model.find_functional_subject: index not found!");
return itor.get_triple().get_subject();
};
///////////////////////////////////////////////////////////////////////////////////////////
// compute class and property hierarchy
///////////////////////////////////////////////////////////////////////////////////////////
inline void
compute_asserted_hierarchy()
{
compute_asserted_class_hierarchy();
compute_asserted_property_hierarchy();
};
void
compute_asserted_class_hierarchy();
void
compute_asserted_property_hierarchy();
inline void
compute_inferred_hierarchy()
{
if(!m_is_asserted_hierarchy_computed) compute_asserted_hierarchy();
compute_inferred_class_hierarchy();
compute_inferred_property_hierarchy();
};
void
compute_inferred_class_hierarchy();
void
compute_inferred_property_hierarchy();
///////////////////////////////////////////////////////////////////////////////////////////
// access to top-class and top_property by index_type
///////////////////////////////////////////////////////////////////////////////////////////
inline top_class_ptr_type
get_top_class(index_type r)const
{
top_class_map_type::const_iterator itor = m_top_classes.find(r);
if(itor == m_top_classes.end()) {
std::string msg = "top_model.get_top_class: Invalid index!";
if(r) msg += " resource '"+r->get_name()+"' does not have a top_class";
std::cout << msg << std::endl;
throw rdf::rdf_exception(rdf::invalid_index, msg);
}
return itor->second;
};
inline top_property_ptr_type
get_top_property(index_type r)const
{
top_property_map_type::const_iterator itor = m_top_properties.find(r);
if(itor == m_top_properties.end()) throw rdf::rdf_exception(rdf::invalid_index, "top_model.get_top_property: Invalid index!");
return itor->second;
};
///////////////////////////////////////////////////////////////////////////////////////////
// access to base properties - those on top of the hierarchy
///////////////////////////////////////////////////////////////////////////////////////////
inline top_property_v_const_iterator
get_asserted_base_object_top_property()const
{
return top_property_v_const_iterator(m_asserted_base_object_properties.begin(), m_asserted_base_object_properties.end());
};
inline top_property_v_const_iterator
get_asserted_base_data_type_top_property()const
{
return top_property_v_const_iterator(m_asserted_base_data_type_properties.begin(), m_asserted_base_data_type_properties.end());
};
inline top_property_v_const_iterator
get_inferred_base_object_top_property()const
{
return top_property_v_const_iterator(m_inferred_base_object_properties.begin(), m_inferred_base_object_properties.end());
};
inline top_property_v_const_iterator
get_inferred_base_data_type_top_property()const
{
return top_property_v_const_iterator(m_inferred_base_data_type_properties.begin(), m_inferred_base_data_type_properties.end());
};
///////////////////////////////////////////////////////////////////////////////////////////
// access to top_class for owl_Thing and owl_Nothing
///////////////////////////////////////////////////////////////////////////////////////////
// This is the owl:Thing class. Direct child of the root of the class hierarchy
inline top_class_ptr_type
get_owl_thing_class()const
{
top_class_map_type::const_iterator itor = m_top_classes.find(m_owl.owl_Thing);
if(itor == m_top_classes.end()) throw rdf::rdf_exception(rdf::invalid_index, "top_model.get_owl_thing_class: Invalid index! Must call compute_asserted_hierarchy() first");
return itor->second;
};
// This is the owl:Nothing class. Direct child of the root of the class hierarchy
inline top_class_ptr_type
get_owl_nothing_class()const
{
top_class_map_type::const_iterator itor = m_top_classes.find(m_owl.owl_Nothing);
if(itor == m_top_classes.end()) throw rdf::rdf_exception(rdf::invalid_index, "top_model.get_owl_thing_class: Invalid index! Must call compute_asserted_hierarchy() first");
return itor->second;
};
///////////////////////////////////////////////////////////////////////////////////////////
// methods to access individuals and their properties
//
// rdf_type property of individual
///////////////////////////////////////////////////////////////////////////////////////////
top_class_lookup_iterator_by_asserted_object
get_asserted_types(index_type subject)const;
top_class_lookup_iterator_by_object
get_inferred_types(index_type subject)const;
inline bool
is_inconsistent_individual(index_type subject)const
{
return contains(subject, m_owl.rdf_type, m_owl.owl_Nothing);
};
///////////////////////////////////////////////////////////////////////////////////////////
// owl_sameAs property of individual
///////////////////////////////////////////////////////////////////////////////////////////
inline bool
has_asserted_same_as_individual(index_type subject)const
{
return contains_asserted(subject, m_owl.owl_sameAs);
};
inline bool
has_inferred_same_as_individual(index_type subject)const
{
return contains(subject, m_owl.owl_sameAs);
};
inline rdf_graph::index_iterator
get_asserted_same_as_individuals(index_type subject)const
{
return find_asserted_objects(subject, m_owl.owl_sameAs);
};
inline rdf_session::index_iterator
get_inferred_same_as_individuals(index_type subject)const
{
return find_objects(subject, m_owl.owl_sameAs);
};
///////////////////////////////////////////////////////////////////////////////////////////
// owl_differentFrom property of individual
///////////////////////////////////////////////////////////////////////////////////////////
inline bool
has_asserted_different_from_individual(index_type subject)const
{
return contains_asserted(subject, m_owl.owl_differentFrom);
};
inline bool
has_inferred_different_from_individual(index_type subject)const
{
return contains(subject, m_owl.owl_differentFrom);
};
inline rdf_graph::index_iterator
get_asserted_different_from_individual(index_type subject)const
{
return find_asserted_objects(subject, m_owl.owl_differentFrom);
};
inline rdf_session::index_iterator
get_inferred_different_from_individual(index_type subject)const
{
return find_objects(subject, m_owl.owl_differentFrom);
};
private:
friend class top_class;
friend class top_property;
rdf_session_ptr_type m_rdf_session_p;
rule_session_ptr_type m_rule_session_p;
public:
owl m_owl;
private:
bool m_is_asserted_hierarchy_computed;
top_class_map_type m_top_classes;
top_property_map_type m_top_properties;
// since properties don't have a single base class, we need
// to keep track of all base properties, i.e., those who
// don't have rdfs_subPropertyOf relationship
top_property_vector_type m_asserted_base_object_properties;
top_property_vector_type m_asserted_base_data_type_properties;
top_property_vector_type m_inferred_base_object_properties;
top_property_vector_type m_inferred_base_data_type_properties;
};
/////////////////////////////////////////////////////////////////////////////////////////
// class top_class_lookup
//
// Functor to lookup top_class
/////////////////////////////////////////////////////////////////////////////////////////
struct top_class_lookup
{
top_class_lookup(top_model const& model):
m_model(model)
{};
inline top_class_ptr_type
operator()(index_type index)const
{
return m_model.get_top_class(index);
};
top_model const& m_model;
};
struct top_class_lookup_by_object
{
top_class_lookup_by_object(top_model const& model):
m_model(model)
{};
inline top_class_ptr_type
operator()(rdf::index_triple t)const
{
return m_model.get_top_class(t.get_object());
};
top_model const& m_model;
};
/////////////////////////////////////////////////////////////////////////////////////////
// class top_property_lookup
//
// Functor to lookup top_property
/////////////////////////////////////////////////////////////////////////////////////////
struct top_property_lookup
{
top_property_lookup(top_model const& model):
m_model(model)
{};
inline top_property_ptr_type
operator()(index_type index)const
{
return m_model.get_top_property(index);
};
top_model const& m_model;
};
struct top_property_lookup_by_subject
{
top_property_lookup_by_subject(top_model const& model):
m_model(model)
{};
inline top_property_ptr_type
operator()(rdf::index_triple t)const
{
return m_model.get_top_property(t.get_subject());
};
top_model const& m_model;
};
struct top_property_lookup_by_object
{
top_property_lookup_by_object(top_model const& model):
m_model(model)
{};
inline top_property_ptr_type
operator()(rdf::index_triple t)const
{
return m_model.get_top_property(t.get_object());
};
top_model const& m_model;
};
/////////////////////////////////////////////////////////////////////////////////////////
// create_top_model
//
/////////////////////////////////////////////////////////////////////////////////////////
inline top_model_ptr_type
create_top_model(rdf_session_ptr_type const& rdf_session_p, rule_session_ptr_type const& rule_session_p)
{
return top_model_ptr_type(new top_model(rdf_session_p, rule_session_p));
};
}; /* model namespace */
#endif /*TOP_MODEL_H_*/