Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

496 lines
12 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1998
  6. //
  7. // File: symtmbn.h
  8. //
  9. //--------------------------------------------------------------------------
  10. //
  11. // SYMTMBN.H: Symbol table for belief networks
  12. //
  13. #ifndef _SYMTMBN_H_
  14. #define _SYMTMBN_H_
  15. #include "basics.h"
  16. #include "algos.h"
  17. #include "symt.h"
  18. #include "gelem.h"
  19. #include "bndist.h"
  20. // Forward declaration of MBNET
  21. class MBNET;
  22. class MODEL;
  23. /*
  24. A word about BIT FLAG VECTORS:
  25. Each GOBJMBN (abstract belief network object) has a bit vector.
  26. These values are typically accesssed by name, and the names
  27. are interned in the symbol table of the outer network. Therefore,
  28. the symbol table class can return the bit flag index given the name,
  29. and the node can return the value given the bit flag index.
  30. Since these values are completely scoped by the network, they
  31. may differ (both in existence and index) from network to network.
  32. However, once they are declared they do not change, so caching is
  33. supported.
  34. */
  35. // Base class for a vector of bit flags and its index variable type
  36. typedef int IBFLAG; // Index into a bit flag vector
  37. class VFLAGS : public _Bvector // A vector of bit flags
  38. {
  39. public:
  40. bool BFlag ( IBFLAG ibf ) const
  41. {
  42. return size() > ibf
  43. && self[ibf];
  44. }
  45. // Set a bit flag; return the previous value
  46. bool BSetBFlag ( IBFLAG ibf, bool bValue = true )
  47. {
  48. bool bOldValue = false;
  49. if ( size() <= ibf )
  50. resize(ibf+1);
  51. else
  52. bOldValue = self[ibf];
  53. self[ibf] = bValue;
  54. return bOldValue;
  55. }
  56. };
  57. ////////////////////////////////////////////////////////////////////
  58. // class GOBJMBN: Abstract base class for belief network objects.
  59. //
  60. // Generic "named thing that lives in a belief network" object.
  61. // All such objects are graph nodes and can be linked with arcs.
  62. ////////////////////////////////////////////////////////////////////
  63. class GOBJMBN : public GNODE
  64. {
  65. friend class TMPSYMTBL<GOBJMBN>;
  66. public:
  67. // Return the immutable object type
  68. virtual INT EType () const
  69. { return EBNO_NONE ; }
  70. enum EBNOBJ
  71. {
  72. EBNO_NONE = GELEM::EGELM_NODE, // No value
  73. EBNO_NODE, // A probabilistic node
  74. EBNO_PROP_TYPE, // A property type
  75. EBNO_MBNET_MODIFIER, // A general network modifier
  76. EBNO_MBNET_EXPANDER, // A network CI expander
  77. EBNO_INFER_ENGINE, // A general inference engine
  78. EBNO_CLIQUE, // A clique
  79. EBNO_CLIQUE_SET, // A set of clique trees
  80. EBNO_NODE_RANKER, // A ranking/ordering mechanism
  81. EBNO_RANKER_ENTROPIC_UTIL, // A ranking by entropic utility
  82. EBNO_RANKER_RECOMMENDATIONS, // A ranking by fixplan recommendations
  83. EBNO_VARIABLE_DOMAIN, // A user-defined discretization or domain
  84. EBNO_USER, // A user-defined type
  85. EBNO_MAX
  86. };
  87. GOBJMBN () {}
  88. virtual ~ GOBJMBN() = 0;
  89. // Clone contents into a new object relative to another belief network;
  90. // return NULL if operation not supported.
  91. virtual GOBJMBN * CloneNew ( MODEL & modelSelf,
  92. MODEL & modelNew,
  93. GOBJMBN * pgobjNew = NULL );
  94. const ZSREF & ZsrefName () const
  95. { return _zsrName; }
  96. // Accessors for the array of flag bits
  97. bool BFlag ( IBFLAG ibf ) const
  98. { return _vFlags.BFlag( ibf ); }
  99. bool BSetBFlag ( IBFLAG ibf, bool bValue = true )
  100. { return _vFlags.BSetBFlag( ibf, bValue ); }
  101. protected:
  102. // Only subclasses should be able to do this.
  103. void SetName ( ZSREF zsr )
  104. { _zsrName = zsr; }
  105. protected:
  106. ZSREF _zsrName; // Symbolic (permanent) name
  107. VFLAGS _vFlags; // Bit vector of flags
  108. HIDE_UNSAFE(GOBJMBN);
  109. };
  110. ////////////////////////////////////////////////////////////////////
  111. // class MPZSRBIT: a map between a name and a bit index in a
  112. // bool/bit array.
  113. ////////////////////////////////////////////////////////////////////
  114. class MPZSRBIT : public VZSREF
  115. {
  116. public:
  117. MPZSRBIT () {}
  118. ~ MPZSRBIT() {}
  119. // Return the index of a name or -1 if not found
  120. IBFLAG IFind ( ZSREF zsr )
  121. {
  122. return ifind( self, zsr );
  123. }
  124. // Return the index of a name, adding it if necessary
  125. IBFLAG IAdd ( ZSREF zsr )
  126. {
  127. IBFLAG i = ifind( self, zsr );
  128. if ( i < 0 )
  129. {
  130. i = size();
  131. push_back(zsr);
  132. }
  133. return i;
  134. }
  135. };
  136. ////////////////////////////////////////////////////////////////////
  137. // class MPSYMTBL:
  138. // An STL "map" which is used as a symbol table.
  139. // It also supports dynamically declared named bit flags,
  140. // which are supported by classes GOBJMBN and MBNET.
  141. ////////////////////////////////////////////////////////////////////
  142. class MPSYMTBL : public TMPSYMTBL<GOBJMBN>
  143. {
  144. public:
  145. MPSYMTBL () {}
  146. ~ MPSYMTBL () {}
  147. // Support for dynamically assigned bit flags
  148. // Create a bit flag index for a name
  149. IBFLAG IAddBitFlag ( SZC szcName )
  150. {
  151. return _mpzsrbit.IAdd( intern( szcName ) );
  152. }
  153. // Return the bit flag index of name
  154. IBFLAG IFindBitFlag ( SZC szcName )
  155. {
  156. return _mpzsrbit.IFind( intern( szcName ) );
  157. }
  158. // Test the bit flag of a node
  159. bool BFlag ( const GOBJMBN & gobj, SZC szcName )
  160. {
  161. IBFLAG iBit = IFindBitFlag( szcName );
  162. if ( iBit < 0 )
  163. return false;
  164. return gobj.BFlag(iBit);
  165. }
  166. // Re/set the bit flag of a node; returns old setting
  167. bool BSetBFlag ( GOBJMBN & gobj, SZC szcName, bool bValue = true )
  168. {
  169. IBFLAG iBit = IAddBitFlag( szcName );
  170. assert( iBit >= 0 );
  171. return gobj.BSetBFlag( iBit, bValue );
  172. }
  173. void CloneVzsref ( const MPSYMTBL & mpsymtbl,
  174. const VZSREF & vzsrSource,
  175. VZSREF & vzsrTarget );
  176. // Clone this table from another
  177. void Clone ( const MPSYMTBL & mpsymtbl );
  178. protected:
  179. MPZSRBIT _mpzsrbit;
  180. };
  181. /*
  182. Probability distributions.
  183. PDs are defined similarly to their notation. Tokens in the notation
  184. are converted to descriptor tokens, and the PD data is stored in a
  185. map structure cataloged by the string of tokens. For example:
  186. p(X|Y,Z)
  187. is stored under a key which is a list of tokens:
  188. token[0] token representing 'p'
  189. token[1] token referencing interned symbolic name of node X
  190. token[2] token representing '|' (conditioning bar)
  191. token[3] token referencing interned symbolic name of node Y
  192. token[4] token representing ',' (and)
  193. token[5] token referencing interned symbolic name of node Z
  194. Special values can represent states, so that PDs such as
  195. p(X=x|Y=y)
  196. can be represented. Since 'x' and 'y' (lower case) are state indicies,
  197. they are represented as integers.
  198. */
  199. // Enumeration for token types. Values from DTKN_STRING_MIN to
  200. // DTNK_STATE_BASE are string pointers (equivalent to ZSREFs)
  201. //
  202. enum DISTTOKEN
  203. {
  204. DTKN_EMPTY = 0,
  205. DTKN_STRING, // String pointers
  206. DTKN_BASE = DTKN_STRING+1, // Base value for tokens
  207. DTKN_STATE_BASE = DTKN_BASE, // First state value (0)
  208. DTKN_TOKEN_MIN = DTKN_STATE_BASE + 0x20000, // Allow for >100000 discrete states
  209. DTKN_PD = DTKN_TOKEN_MIN, // 'p' as in p(X|Y)
  210. DTKN_COND, // '|', conditioning bar
  211. DTKN_AND, // ',' 'and' symbol
  212. DTKN_EQ, // '=' 'equals' symbol
  213. DTKN_QUAL, // token used as domain qualification specifier
  214. DTKN_DIST, // 'distribution' token, followed by name token
  215. DTKN_MAX // First illegal value
  216. };
  217. // Probability distribution descriptor token
  218. class TKNPD
  219. {
  220. public:
  221. public:
  222. // Constructors
  223. TKNPD(); // Initialization
  224. TKNPD( const TKNPD & tp ); // Copy constructor
  225. TKNPD( const ZSREF & zsr ); // From a string ref
  226. TKNPD( DISTTOKEN dtkn ); // From an explicit token
  227. ~TKNPD();
  228. // Assignment operators: similar to constructors
  229. TKNPD & operator = ( const TKNPD & tp );
  230. TKNPD & operator = ( const ZSREF & zsr );
  231. TKNPD & operator = ( DISTTOKEN dtkn );
  232. // Return true if token represents a string
  233. bool BStr () const
  234. { return _uitkn == DTKN_STRING; }
  235. bool BState () const
  236. { return _uitkn >= DTKN_STATE_BASE && _uitkn < DTKN_TOKEN_MIN; }
  237. bool BToken () const
  238. { return _uitkn >= DTKN_TOKEN_MIN && _uitkn < DTKN_MAX; }
  239. // Ordering for vector and map classes
  240. bool operator < ( const TKNPD & tp ) const;
  241. bool operator == ( const TKNPD & tp ) const;
  242. bool operator > ( const TKNPD & tp ) const;
  243. bool operator != ( const TKNPD & tp ) const;
  244. // Return the token as an integer
  245. UINT UiTkn () const { return _uitkn; }
  246. // Return the token as a DISTTOKEN
  247. DISTTOKEN Dtkn () const { return (DISTTOKEN) _uitkn; }
  248. // Return the token as a discrete state index
  249. IST Ist () const
  250. {
  251. return BState() ? _uitkn - DTKN_STATE_BASE
  252. : -1;
  253. }
  254. // Return the string as an SZC; NULL if not a string
  255. SZC Szc () const
  256. {
  257. return BStr()
  258. ? Pzst()->Szc()
  259. : NULL;
  260. }
  261. const ZSTRT * Pzst () const
  262. { return _pzst; }
  263. protected:
  264. UINT _uitkn; // Simple unsigned integer token
  265. ZSTRT * _pzst; // String pointer (optional)
  266. void Deref ();
  267. void Ref ( const ZSREF & zsr );
  268. void Ref ( const TKNPD & tknpd );
  269. void Ref ( DISTTOKEN dtkn );
  270. };
  271. // Define VTKNPD
  272. class VTKNPD : public vector<TKNPD>
  273. {
  274. public:
  275. // Generate a string containing the original probability distribution
  276. // descriptor (e.g., "p(X|Y,Z)").
  277. ZSTR ZstrSignature ( int iStart = 0 ) const;
  278. void Clone ( MPSYMTBL & mpsymtbl, const VTKNPD & vtknpd );
  279. // Provide "operator <" for map<> template.
  280. bool operator < ( const VTKNPD & vtknpd ) const
  281. {
  282. int cmin = _cpp_min( size(), vtknpd.size() );
  283. for ( int i = 0 ; i < cmin ; i++ )
  284. {
  285. if ( self[i] < vtknpd[i] )
  286. return true;
  287. if ( vtknpd[i] < self[i])
  288. return false;
  289. }
  290. return size() < vtknpd.size();
  291. }
  292. };
  293. typedef REFCWRAP<BNDIST> REFBNDIST;
  294. ////////////////////////////////////////////////////////////////////
  295. // class MPPD: A map associating probability distributions with
  296. // their descriptors (token arrays).
  297. ////////////////////////////////////////////////////////////////////
  298. class MPPD : public map<VTKNPD, REFBNDIST>
  299. {
  300. public:
  301. MPPD () {}
  302. ~ MPPD ()
  303. {
  304. #if defined(DUMP)
  305. Dump();
  306. #endif
  307. }
  308. void Clone ( MPSYMTBL & mpsymtbl, const MPPD & mppd );
  309. private:
  310. void Dump ();
  311. };
  312. ////////////////////////////////////////////////////////////////////
  313. ////////////////////////////////////////////////////////////////////
  314. // Inline member functions
  315. ////////////////////////////////////////////////////////////////////
  316. ////////////////////////////////////////////////////////////////////
  317. inline
  318. TKNPD::TKNPD()
  319. : _uitkn(DTKN_EMPTY),
  320. _pzst(NULL)
  321. {
  322. }
  323. inline
  324. TKNPD::TKNPD( const TKNPD & tp )
  325. : _uitkn(DTKN_EMPTY),
  326. _pzst(NULL)
  327. {
  328. Ref(tp);
  329. }
  330. inline
  331. TKNPD::TKNPD( const ZSREF & zsr )
  332. : _uitkn(DTKN_EMPTY),
  333. _pzst(NULL)
  334. {
  335. Ref(zsr);
  336. }
  337. inline
  338. TKNPD::TKNPD( DISTTOKEN dtkn )
  339. : _uitkn(DTKN_EMPTY),
  340. _pzst(NULL)
  341. {
  342. Ref(dtkn);
  343. }
  344. inline
  345. TKNPD::~TKNPD()
  346. {
  347. Deref();
  348. }
  349. inline
  350. void TKNPD::Deref ()
  351. {
  352. if ( BStr() )
  353. {
  354. _pzst->IncRef(-1);
  355. _pzst = NULL;
  356. }
  357. _uitkn = DTKN_EMPTY;
  358. }
  359. inline
  360. void TKNPD::Ref ( const ZSREF & zsr )
  361. {
  362. Deref();
  363. zsr.IncRef();
  364. _pzst = const_cast<ZSTRT *> (zsr.Pzst());
  365. _uitkn = DTKN_STRING;
  366. }
  367. inline
  368. void TKNPD::Ref ( const TKNPD & tknpd )
  369. {
  370. Deref();
  371. if ( tknpd.BStr() )
  372. {
  373. _pzst = tknpd._pzst;
  374. _pzst->IncRef();
  375. }
  376. _uitkn = tknpd._uitkn;
  377. }
  378. inline
  379. void TKNPD::Ref ( DISTTOKEN dtkn )
  380. {
  381. Deref();
  382. _uitkn = dtkn;
  383. }
  384. inline
  385. TKNPD & TKNPD::operator = ( const TKNPD & tp )
  386. {
  387. Ref(tp);
  388. return self;
  389. }
  390. inline
  391. TKNPD & TKNPD::operator = ( const ZSREF & zsr )
  392. {
  393. Ref(zsr);
  394. return self;
  395. }
  396. inline
  397. TKNPD & TKNPD::operator = ( DISTTOKEN dtkn )
  398. {
  399. Ref(dtkn);
  400. return self;
  401. }
  402. inline
  403. bool TKNPD::operator < ( const TKNPD & tp ) const
  404. {
  405. if ( _uitkn < tp._uitkn )
  406. return true;
  407. if ( _uitkn > tp._uitkn )
  408. return false;
  409. return _pzst < tp._pzst;
  410. }
  411. inline
  412. bool TKNPD::operator > ( const TKNPD & tp ) const
  413. {
  414. if ( _uitkn > tp._uitkn )
  415. return true;
  416. if ( _uitkn < tp._uitkn )
  417. return false;
  418. return _pzst > tp._pzst;
  419. }
  420. inline
  421. bool TKNPD::operator == ( const TKNPD & tp ) const
  422. {
  423. return _uitkn == tp._uitkn && _pzst == tp._pzst;
  424. }
  425. inline
  426. bool TKNPD::operator != ( const TKNPD & tp ) const
  427. {
  428. return _uitkn != tp._uitkn && _pzst != tp._pzst;
  429. }
  430. #endif