File: SemanticLocalityChecker.h

package info (click to toggle)
fact%2B%2B 1.6.5~dfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 4,496 kB
  • sloc: cpp: 28,000; java: 22,674; xml: 3,268; makefile: 102; ansic: 61; sh: 3
file content (231 lines) | stat: -rw-r--r-- 10,695 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/* This file is part of the FaCT++ DL reasoner
Copyright (C) 2011-2015 Dmitry Tsarkov and The University of Manchester
Copyright (C) 2015-2016 Dmitry Tsarkov

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#ifndef SEMLOCCHECKER_H
#define SEMLOCCHECKER_H

#include "LocalityChecker.h"
#include "Kernel.h"

/// semantic locality checker for DL axioms
class SemanticLocalityChecker: public LocalityChecker
{
protected:	// members
		/// Reasoner to detect the tautology
	ReasoningKernel Kernel;
		/// Expression manager of a kernel
	TExpressionManager* pEM;
		/// map between axioms and concept expressions
	std::map<const TDLAxiom*, const TDLConceptExpression*> ExprMap;

protected:	// methods
		/// @return expression necessary to build query for a given type of an axiom; @return NULL if none necessary
	const TDLConceptExpression* getExpr ( const TDLAxiom* axiom )
	{
		if ( const TDLAxiomRelatedTo* art = dynamic_cast<const TDLAxiomRelatedTo*>(axiom) )
			return pEM->Value ( art->getRelation(), art->getRelatedIndividual() );
		if ( const TDLAxiomValueOf* avo = dynamic_cast<const TDLAxiomValueOf*>(axiom) )
			return pEM->Value ( avo->getAttribute(), avo->getValue() );
		if ( const TDLAxiomORoleDomain* ord = dynamic_cast<const TDLAxiomORoleDomain*>(axiom) )
			return pEM->Exists ( ord->getRole(), pEM->Top() );
		if ( const TDLAxiomORoleRange* orr = dynamic_cast<const TDLAxiomORoleRange*>(axiom) )
			return pEM->Exists ( orr->getRole(), pEM->Not(orr->getRange()) );
		if ( const TDLAxiomDRoleDomain* drd = dynamic_cast<const TDLAxiomDRoleDomain*>(axiom) )
			return pEM->Exists ( drd->getRole(), pEM->DataTop() );
		if ( const TDLAxiomDRoleRange* drr = dynamic_cast<const TDLAxiomDRoleRange*>(axiom) )
			return pEM->Exists ( drr->getRole(), pEM->DataNot(drr->getRange()) );
		if ( const TDLAxiomRelatedToNot* rtn = dynamic_cast<const TDLAxiomRelatedToNot*>(axiom) )
			return pEM->Not ( pEM->Value ( rtn->getRelation(), rtn->getRelatedIndividual() ) );
		if ( const TDLAxiomValueOfNot* von = dynamic_cast<const TDLAxiomValueOfNot*>(axiom) )
			return pEM->Not ( pEM->Value ( von->getAttribute(), von->getValue() ) );
		// everything else doesn't require expression to be build
		return NULL;
	}

public:		// interface
		/// init c'tor
	SemanticLocalityChecker ( const TSignature* sig ) : LocalityChecker(sig)
	{
		pEM = Kernel.getExpressionManager();
		// for tests we will need TB names to be from the OWL 2 namespace
		pEM->setTopBottomRoles(
			"http://www.w3.org/2002/07/owl#topObjectProperty",
			"http://www.w3.org/2002/07/owl#bottomObjectProperty",
			"http://www.w3.org/2002/07/owl#topDataProperty",
			"http://www.w3.org/2002/07/owl#bottomDataProperty");
	}
		/// empty d'tor
	virtual ~SemanticLocalityChecker ( void ) {}

		/// init kernel with the ontology signature and init expression map
	virtual void preprocessOntology ( const AxiomVec& Axioms )
	{
		TSignature s;
		ExprMap.clear();
		for ( AxiomVec::const_iterator q = Axioms.begin(), q_end = Axioms.end(); q != q_end; ++q )
		{
			ExprMap[*q] = getExpr(*q);
			s.add((*q)->getSignature());
		}

		Kernel.clearKB();
		// register all the objects in the ontology signature
		for ( TSignature::iterator p = s.begin(), p_end = s.end(); p != p_end; ++p )
			Kernel.declare(dynamic_cast<const TDLExpression*>(*p));
		// prepare the reasoner to check tautologies
		Kernel.realiseKB();
		// after TBox appears there, set signature to translate
		Kernel.setSignature(getSignature());
		// disallow usage of the expression cache as same expressions will lead to different translations
		Kernel.setIgnoreExprCache(true);
	}

public:		// visitor interface
	virtual void visit ( const TDLAxiomDeclaration& ) { isLocal = true; }

	virtual void visit ( const TDLAxiomEquivalentConcepts& axiom )
	{
		isLocal = false;
		TDLAxiomEquivalentConcepts::iterator p = axiom.begin(), p_end = axiom.end();
		const TDLConceptExpression* C = *p;
		while (  ++p != p_end )
			if ( !Kernel.isEquivalent ( C, *p ) )
				return;
		isLocal = true;
	}
	virtual void visit ( const TDLAxiomDisjointConcepts& axiom )
	{
		isLocal = false;
		for ( TDLAxiomDisjointConcepts::iterator p = axiom.begin(), q, p_end = axiom.end(); p != p_end; ++p )
			for ( q = p+1; q != p_end; ++q )
				if ( !Kernel.isDisjoint ( *p, *q ) )
					return;
		isLocal = true;
	}
	virtual void visit ( const TDLAxiomDisjointUnion& axiom )
	{
		isLocal = false;
		// check A = (or C1... Cn)
		TDLAxiomDisjointUnion::iterator p, q, p_end = axiom.end();
		pEM->newArgList();
		for ( p = axiom.begin(); p != p_end; ++p )
			pEM->addArg(*p);
		if ( !Kernel.isEquivalent ( axiom.getC(), pEM->Or() ) )
			return;
		// check disjoint(C1... Cn)
		for ( p = axiom.begin(); p != p_end; ++p )
			for ( q = p+1; q != p_end; ++q )
				if ( !Kernel.isDisjoint ( *p, *q ) )
					return;
		isLocal = true;
	}
	virtual void visit ( const TDLAxiomEquivalentORoles& axiom )
	{
		isLocal = false;
		TDLAxiomEquivalentORoles::iterator p = axiom.begin(), p_end = axiom.end();
		const TDLObjectRoleExpression* R = *p;
		while (  ++p != p_end )
			if ( !(Kernel.isSubRoles ( R, *p ) && Kernel.isSubRoles ( *p, R )) )
				return;
		isLocal = true;
	}
		// tautology if all the subsumptions Ri [= Rj holds
	virtual void visit ( const TDLAxiomEquivalentDRoles& axiom )
	{
		isLocal = false;
		TDLAxiomEquivalentDRoles::iterator p = axiom.begin(), p_end = axiom.end();
		const TDLDataRoleExpression* R = *p;
		while (  ++p != p_end )
			if ( !(Kernel.isSubRoles ( R, *p ) && Kernel.isSubRoles ( *p, R )) )
				return;
		isLocal = true;
	}
	virtual void visit ( const TDLAxiomDisjointORoles& axiom )
	{
		pEM->newArgList();
		for ( TDLAxiomDisjointORoles::iterator p = axiom.begin(), p_end = axiom.end(); p != p_end; ++p )
			pEM->addArg(*p);
		isLocal = Kernel.isDisjointRoles();
	}
	virtual void visit ( const TDLAxiomDisjointDRoles& axiom )
	{
		pEM->newArgList();
		for ( TDLAxiomDisjointDRoles::iterator p = axiom.begin(), p_end = axiom.end(); p != p_end; ++p )
			pEM->addArg(*p);
		isLocal = Kernel.isDisjointRoles();
	}
		// never local
	virtual void visit ( const TDLAxiomSameIndividuals& ) { isLocal = false; }
		// never local
	virtual void visit ( const TDLAxiomDifferentIndividuals& ) { isLocal = false; }
		/// there is no such axiom in OWL API, but I hope nobody would use Fairness here
	virtual void visit ( const TDLAxiomFairnessConstraint& ) { isLocal = true; }

		// R = inverse(S) is tautology iff R [= S- and S [= R-
	virtual void visit ( const TDLAxiomRoleInverse& axiom )
	{
		isLocal = Kernel.isSubRoles ( axiom.getRole(), pEM->Inverse(axiom.getInvRole()) ) &&
				Kernel.isSubRoles ( axiom.getInvRole(), pEM->Inverse(axiom.getRole()) );
	}
	virtual void visit ( const TDLAxiomORoleSubsumption& axiom )
	{
		// check whether the LHS is a role chain
		if ( const TDLObjectRoleChain* Chain = dynamic_cast<const TDLObjectRoleChain*>(axiom.getSubRole()) )
		{
			pEM->newArgList();
			for ( TDLObjectRoleChain::iterator p = Chain->begin(), p_end = Chain->end(); p != p_end; ++p )
				pEM->addArg(*p);
			isLocal = Kernel.isSubChain(axiom.getRole());
		}
		// check whether the LHS is a plain role or inverse
		else if ( const TDLObjectRoleExpression* Sub = dynamic_cast<const TDLObjectRoleExpression*>(axiom.getSubRole()) )
			isLocal = Kernel.isSubRoles ( Sub, axiom.getRole() );
		else	// here we have a projection expression. FIXME!! for now
			isLocal = true;
	}
	virtual void visit ( const TDLAxiomDRoleSubsumption& axiom ) { isLocal = Kernel.isSubRoles ( axiom.getSubRole(), axiom.getRole() ); }
		// Domain(R) = C is tautology iff ER.Top [= C
	virtual void visit ( const TDLAxiomORoleDomain& axiom ) { isLocal = Kernel.isSubsumedBy ( ExprMap[&axiom], axiom.getDomain() ); }
	virtual void visit ( const TDLAxiomDRoleDomain& axiom ) { isLocal = Kernel.isSubsumedBy ( ExprMap[&axiom], axiom.getDomain() ); }
		// Range(R) = C is tautology iff ER.~C is unsatisfiable
	virtual void visit ( const TDLAxiomORoleRange& axiom ) { isLocal = !Kernel.isSatisfiable(ExprMap[&axiom]); }
	virtual void visit ( const TDLAxiomDRoleRange& axiom ) { isLocal = !Kernel.isSatisfiable(ExprMap[&axiom]); }
	virtual void visit ( const TDLAxiomRoleTransitive& axiom ) { isLocal = Kernel.isTransitive(axiom.getRole()); }
	virtual void visit ( const TDLAxiomRoleReflexive& axiom ) { isLocal = Kernel.isReflexive(axiom.getRole()); }
	virtual void visit ( const TDLAxiomRoleIrreflexive& axiom ) { isLocal = Kernel.isIrreflexive(axiom.getRole()); }
	virtual void visit ( const TDLAxiomRoleSymmetric& axiom ) { isLocal = Kernel.isSymmetric(axiom.getRole()); }
	virtual void visit ( const TDLAxiomRoleAsymmetric& axiom ) { isLocal = Kernel.isAsymmetric(axiom.getRole()); }
	virtual void visit ( const TDLAxiomORoleFunctional& axiom ) { isLocal = Kernel.isFunctional(axiom.getRole()); }
	virtual void visit ( const TDLAxiomDRoleFunctional& axiom ) { isLocal = Kernel.isFunctional(axiom.getRole()); }
	virtual void visit ( const TDLAxiomRoleInverseFunctional& axiom ) { isLocal = Kernel.isInverseFunctional(axiom.getRole()); }

	virtual void visit ( const TDLAxiomConceptInclusion& axiom ) { isLocal = Kernel.isSubsumedBy ( axiom.getSubC(), axiom.getSupC() ); }
		// for top locality, this might be local
	virtual void visit ( const TDLAxiomInstanceOf& axiom ) { isLocal = Kernel.isInstance ( axiom.getIndividual(), axiom.getC() ); }
		// R(i,j) holds if {i} [= \ER.{j}
	virtual void visit ( const TDLAxiomRelatedTo& axiom ) { isLocal = Kernel.isInstance ( axiom.getIndividual(), ExprMap[&axiom] ); }
		///!R(i,j) holds if {i} [= \AR.!{j}=!\ER.{j}
	virtual void visit ( const TDLAxiomRelatedToNot& axiom ) { isLocal = Kernel.isInstance ( axiom.getIndividual(), ExprMap[&axiom] ); }
		// R(i,v) holds if {i} [= \ER.{v}
	virtual void visit ( const TDLAxiomValueOf& axiom ) { isLocal = Kernel.isInstance ( axiom.getIndividual(), ExprMap[&axiom] ); }
		// !R(i,v) holds if {i} [= !\ER.{v}
	virtual void visit ( const TDLAxiomValueOfNot& axiom ) { isLocal = Kernel.isInstance ( axiom.getIndividual(), ExprMap[&axiom] ); }
}; // SemanticLocalityChecker

#endif