File: dlDag.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 (354 lines) | stat: -rw-r--r-- 10,656 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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
/* This file is part of the FaCT++ DL reasoner
Copyright (C) 2003-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 DLDAG_H
#define DLDAG_H

#include <vector>
#include <cstring>	// strlen

#include "globaldef.h"	// for statistic printed
#include "fpp_assert.h"
#include "dlVertex.h"
#include "dlVHash.h"
#include "ifOptions.h"
#include "tRole.h"
#include "ConceptWithDep.h"
#include "tNECollection.h"

class RoleMaster;
class TConcept;

/** DAG of DL Verteces used in FaCT++ reasoner */
class DLDag
{
public:		// types
	typedef std::vector<DLVertex*> HeapType;
	typedef std::vector<BipolarPointer> StatVector;
		/// typedef for the hash-table
	typedef dlVHashTable HashTable;

protected:	// members
		/// body of DAG
	HeapType Heap;
		/// all the AND nodes (needs to recompute)
	StatVector listAnds;
		/// hash-table for vertices (and, all, LE) fast search
	HashTable indexAnd, indexAll, indexLE;

		/// DAG size after the whole ontology is loaded
	size_t finalDagSize;
		/// cache efficiency -- statistic purposes
	unsigned int nCacheHits;

#ifdef RKG_USE_SORTED_REASONING
		/// size of sort array
	size_t sortArraySize;
#endif

	// tunable flags (set by readConfig)

		/// sort strings: option[0] for SAT/cache tests, option[1] for SUB/classify tests
	const char* orSortSat;
	const char* orSortSub;
		/// sort index (if necessary). Possible values are Size, Depth, Freq
	unsigned int iSort;
		/// whether or not sorting order is ascending
	bool sortAscend;
		/// prefer non-generating rules in OR orderings
	bool preferNonGen;

		/// flag whether cache should be used
	bool useDLVCache;

private:	// no copy
		/// no copy c'tor
	DLDag ( const DLDag& );
		/// no assignment
	DLDag& operator= ( const DLDag& );

protected:	// methods
		/// setup flags by given option set
	void readConfig ( const ifOptionSet* Options );
		/// check if given string is correct sort ordering representation
	bool isCorrectOption ( const char* str )
	{
		if ( str == NULL )
			return false;
		size_t n = strlen(str);
		if ( n < 1 || n > 3 )
			return false;
		char Method = str[0],
			 Order = n >= 2 ? str[1] : 'a',
			 NGPref = n == 3 ? str[2] : 'p';
		return ( Method == 'S' || Method == 'D' || Method == 'F' ||
				 Method == 'B' || Method == 'G' || Method == '0' )
			&& ( Order == 'a' || Order == 'd' ) && ( NGPref == 'p' || NGPref == 'n' );
	}
		/// gather vertex statistics (no freq)
	void computeVertexStat ( BipolarPointer p );
		/// helper for the recursion
	void computeVertexStat ( BipolarPointer p, bool pos ) { computeVertexStat ( createBiPointer ( p, pos ) ); }
		/// update vertex statistics (no freq) wrt calculated values of children
	void updateVertexStat ( BipolarPointer p );
		/// helper for the recursion
	void updateVertexStat ( DLVertex& v, BipolarPointer p, bool pos )
	{
		const DLVertex& w = (*this)[p];
		bool posW = pos == isPositive(p);

		// update in-cycle information
		if ( w.isInCycle(posW) )
			v.setInCycle(pos);

		v.updateStatValues ( w, posW, pos );
	}
		/// gather vertex freq statistics
	void computeVertexFreq ( BipolarPointer p );
		/// helper for the recursion
	void computeVertexFreq ( BipolarPointer p, bool pos ) { computeVertexFreq ( createBiPointer ( p, pos ) ); }
		/// change order of ADD elements wrt statistic
	void Recompute ( void )
	{
		for ( StatVector::const_iterator p = listAnds.begin(), p_end = listAnds.end(); p < p_end; ++p )
			(*this)[*p].sortEntry(*this);
	}
		/// set OR sort flags based on given option string; Recompute if necessary
	void setOrderOptions ( const char* opt );
		/// clear all DFS info from elements of DAG
	void clearDFS ( void )
	{
		for ( size_t i = Heap.size()-1; i > 0; --i )
			Heap[i]->clearDFS();
	}

		/// get index corresponding to DLVertex's tag
	const HashTable& getIndex ( DagTag tag ) const
	{
		switch(tag)
		{
		case dtAnd:		return indexAnd;
		case dtIrr:
		case dtForall:	return indexAll;
		case dtLE:		return indexLE;
		default:		fpp_unreachable();	// no such index
		}
	}
		/// update index corresponding to DLVertex's tag
	void updateIndex ( DagTag tag, BipolarPointer value )
	{
		switch(tag)
		{
		case dtAnd:		indexAnd.addElement(value); listAnds.push_back(value); break;
		case dtIrr:
		case dtForall:	indexAll.addElement(value); break;
		case dtLE:		indexLE.addElement(value); break;
		default:		break;	// nothing to do
		}
	}

#ifdef RKG_USE_SORTED_REASONING
	// internal sort interface

		/// merge sorts for a given role
	void mergeSorts ( TRole* R );
		/// merge sorts for a given vertex
	void mergeSorts ( DLVertex& v );
#endif

#ifdef RKG_PRINT_DAG_USAGE
		/// print usage of DAG
	void PrintDAGUsage ( std::ostream& o ) const;
#endif

public:		// interface
		/// the only c'tor
	DLDag ( const ifOptionSet* Options );
		/// d'tor
	~DLDag ( void );

	// construction methods

		/// get index of given vertex; include vertex to DAG if necessary
	BipolarPointer add ( DLVertex* v );
		/// add vertex to the end of DAG and calculate it's statistic if necessary
	BipolarPointer directAdd ( DLVertex* v )
	{
		BipolarPointer toReturn = BipolarPointer(Heap.size());
		Heap.push_back(v);
		// return an index of just added entry
		return toReturn;
	}
		/// add vertex to the end of DAG and calculate it's statistic if necessary; put it into cache
	BipolarPointer directAddAndCache ( DLVertex* v )
	{
		BipolarPointer ret = directAdd(v);
		if ( useDLVCache )
			updateIndex ( v->Type(), ret );
		return ret;
	}
		/// check if given index points to the last DAG entry
	bool isLast ( BipolarPointer p ) const { return (getValue(p) == Heap.size()-1); }

	// access methods

		/// whether to use cache for nodes
	void setExpressionCache ( bool val ) { useDLVCache = val; }
		/// return true if p1 is less than p2 using chosen sort order
	bool less ( BipolarPointer p1, BipolarPointer p2 ) const;

		/// access by index (non-const version)
	DLVertex& operator [] ( BipolarPointer i )
	{
#	ifdef ENABLE_CHECKING
		fpp_assert ( isValid(i) );
		fpp_assert ( getValue(i) < size() );
#	endif
		return *Heap[getValue(i)];
	}
		/// RW access by index in complex concept
	DLVertex& operator [] ( const ConceptWDep& cwd ) { return (*this)[cwd.bp()]; }
		/// access by index (const version)
	const DLVertex& operator [] ( BipolarPointer i ) const
	{
#	ifdef ENABLE_CHECKING
		fpp_assert ( isValid(i) );
		fpp_assert ( getValue(i) < size() );
#	endif
		return *Heap[getValue(i)];
	}
		/// RO access by index in complex concept
	const DLVertex& operator [] ( const ConceptWDep& cwd ) const { return (*this)[cwd.bp()]; }
		/// replace existing vertex at index I with a vertex V
	void replaceVertex ( BipolarPointer i, DLVertex* v, TNamedEntry* C )
	{
		delete Heap[getValue(i)];
		Heap[getValue(i)] = v;
		v->setConcept(C);
	}

		/// get size of DAG
	size_t size ( void ) const { return Heap.size (); }
		/// get approximation of the size after query is added
	size_t maxSize ( void ) const { return size() + ( size() < 220 ? 10 : size()/20 ); }
		/// set the final DAG size
	void setFinalSize ( void ) { finalDagSize = size(); setExpressionCache(false); }
		/// resize DAG to its original size (to clear intermediate query)
	void removeQuery ( void );

	// option interface

		/// set defaults of OR orderings
	void setOrderDefaults ( const char* defSat, const char* defSub );
		/// use SUB options to OR ordering
	void setSubOrder ( void ) { setOrderOptions(orSortSub); }
		/// use SAT options to OR ordering;
	void setSatOrder ( void ) { setOrderOptions(orSortSat); }
		/// gather statistics necessary for the OR ordering
	void gatherStatistic ( void );

	// cache interface

		/// get cache for given BiPointer (may return NULL if no cache defined)
	const modelCacheInterface* getCache ( BipolarPointer p ) const
		{ return operator[](p).getCache(isPositive(p)); }
		/// set cache for given BiPointer; @return given cache
	void setCache ( BipolarPointer p, const modelCacheInterface* cache )
		{ operator[](p).setCache ( isPositive(p), cache ); }

	// sort interface

#ifdef RKG_USE_SORTED_REASONING
		/// merge two given DAG entries
	void merge ( mergableLabel& ml, BipolarPointer p )
	{
		if ( p != bpINVALID && p != bpTOP && p != bpBOTTOM )
			(*this)[p].merge(ml);
	}
		/// build the sort system for given TBox
	void determineSorts ( RoleMaster& ORM, RoleMaster& DRM );
		/// update sorts for <a,b>:R construction
	void updateSorts ( BipolarPointer a, TRole* R, BipolarPointer b )
	{
		merge ( R->getDomainLabel(), a );
		merge ( R->getRangeLabel(), b );
	}
		/// check if two BPs are of the same sort
	bool haveSameSort ( BipolarPointer p, BipolarPointer q ) const
	{
		fpp_assert ( p > 0 && q > 0 );	// sanity check

		// everything has the same label as TOP
		if ( unlikely(p == 1 || q == 1) )
			return true;

		// if some concepts were added to DAG => nothing to say
		if ( unlikely(getValue(p) >= sortArraySize || getValue(q) >= sortArraySize) )
			return true;

		// check whether two sorts are identical
		return (*this)[p].getSort() == (*this)[q].getSort();
	}
#else
	bool haveSameSort ( unsigned int p, unsigned int q ) { return true; }
#endif

	// output interface

		/// print DAG size and number of cache hits, together with DAG usage
	void PrintStat ( std::ostream& o ) const
	{
		o << "Heap size = " << Heap.size () << " nodes\n"
		  << "There were " << nCacheHits << " cache hits\n";
#	ifdef RKG_PRINT_DAG_USAGE
		PrintDAGUsage(o);
#	endif
	}
		/// print the whole DAG
	void Print ( std::ostream& o ) const
	{
		o << "\nDag structure";

		for ( size_t i = 1; i < size(); ++i )
		{
			o << "\n" << i << " ";
			Heap[i]->Print(o);
		}

		o << std::endl;
	}
}; // DLDag

#include "dlVHashImpl.h"

inline BipolarPointer
DLDag :: add ( DLVertex* v )
{
	BipolarPointer ret = useDLVCache ? getIndex(v->Type()).locate(*v) : bpINVALID;

	if ( !isValid(ret) )	// we fail to find such vertex -- it's new
		return directAddAndCache(v);

	// node was found in cache
	++nCacheHits;
	delete v;
	return ret;
}

#endif