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.

613 lines
19 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1997
  6. //
  7. // File: gmobj.h
  8. //
  9. //--------------------------------------------------------------------------
  10. //
  11. // GMOBJ.H: Grapical model objects declarations
  12. //
  13. #ifndef _GMOBJ_H_
  14. #define _GMOBJ_H_
  15. #include <list> // STL list template
  16. #include <assert.h>
  17. #include <iostream>
  18. #include <fstream>
  19. #include "model.h" // Graphical model
  20. #include "gmprop.h" // Properties and proplists
  21. #include "mbnflags.h" // Belief network marking flags static declarations
  22. class CLAMP; // An instantiation for a node, discrete or continuous
  23. class GOBJMBN; // A named object in a belief network
  24. class GNODEMBN; // A node in a belief network
  25. class GNODEMBND; // A discrete node
  26. class GEDGEMBN; // An arc in a belief network
  27. class MBNET; // A belief network
  28. class MBNET_MODIFIER; // An object that alters a belief network
  29. class GOBJMBN_INFER_ENGINE; // Abstract class for inference engine, based on MBNET_MODIFIER
  30. class GOBJMBN_CLIQSET; // A group of junction trees, based on GOBJMBN_INFER_ENGINE
  31. class GOBJMBN_CLIQUE; // A clique in a junction tree
  32. class GEDGEMBN_SEPSET; // An edge in the junction tree (sepset)
  33. class GOBJMBN_DOMAIN; // Named, sharable state space domain
  34. // Define VGNODEMBN, an array of nodes
  35. DEFINEVP(GNODEMBN);
  36. DEFINEVCP(GNODEMBN);
  37. struct PTPOS
  38. {
  39. PTPOS( long x = 0, long y = 0 )
  40. : _x(x),_y(y)
  41. {}
  42. long _x;
  43. long _y;
  44. };
  45. ////////////////////////////////////////////////////////////////////
  46. // class GEDGEMBN:
  47. // An edge of any kind in belief network.
  48. ////////////////////////////////////////////////////////////////////
  49. class GEDGEMBN : public GEDGE
  50. {
  51. public:
  52. enum ETYPE
  53. {
  54. ETNONE = GELEM::EGELM_EDGE, // None
  55. ETPROB, // Probabilistic
  56. ETCLIQUE, // Clique membership
  57. ETJTREE, // Junction tree linkage
  58. ETUNDIR, // Undirected edge for topological operations
  59. ETDIR, // Directed edge for topological operations
  60. ETCLIQSET, // Link to a root clique in a jtree
  61. ETEXPAND // Link from original to expanded node
  62. };
  63. GEDGEMBN ( GOBJMBN * pgnSource,
  64. GOBJMBN * pgnSink )
  65. : GEDGE( pgnSource, pgnSink )
  66. {}
  67. GOBJMBN * PobjSource () { return (GOBJMBN *) GEDGE::PnodeSource(); }
  68. GOBJMBN * PobjSink () { return (GOBJMBN *) GEDGE::PnodeSink(); }
  69. virtual GEDGEMBN * CloneNew ( MODEL & modelSelf, // the original network
  70. MODEL & modelNew, // the new network
  71. GOBJMBN * pgobjmbnSource, // the original source node
  72. GOBJMBN * pgobjmbnSink, // the original sink node
  73. GEDGEMBN * pgdegeNew = NULL ); // the new edge or NULL
  74. virtual INT EType () const
  75. { return ETNONE ; }
  76. virtual ~ GEDGEMBN () {}
  77. // Accessors for the array of flag bits
  78. bool BFlag ( IBFLAG ibf ) const
  79. { return _vFlags.BFlag( ibf ); }
  80. bool BSetBFlag ( IBFLAG ibf, bool bValue = true )
  81. { return _vFlags.BSetBFlag( ibf, bValue ); }
  82. protected:
  83. VFLAGS _vFlags; // Bit vector of flags
  84. HIDE_UNSAFE(GEDGEMBN);
  85. };
  86. ////////////////////////////////////////////////////////////////////
  87. // class CLAMP:
  88. // A forced value (evidence) for a node, continuous or discrete.
  89. // Use assignment operator to update.
  90. ////////////////////////////////////////////////////////////////////
  91. class CLAMP
  92. {
  93. public:
  94. CLAMP ( bool bDiscrete = true, RST rst = 0.0, bool bActive = false )
  95. : _bDiscrete(bDiscrete),
  96. _bActive(bActive),
  97. _rst(rst)
  98. {
  99. }
  100. bool BActive () const { return _bActive; }
  101. bool BDiscrete () const { return _bActive; }
  102. const RST & Rst () const
  103. {
  104. assert( BActive() && ! BDiscrete() );
  105. return _rst;
  106. }
  107. IST Ist () const
  108. {
  109. assert( BActive() && BDiscrete() );
  110. return IST(_rst);
  111. }
  112. bool operator == ( const CLAMP & clamp ) const
  113. {
  114. return _bDiscrete == clamp._bDiscrete
  115. && _bActive == clamp._bActive
  116. && (!_bActive || _rst == clamp._rst);
  117. }
  118. bool operator != ( const CLAMP & clamp ) const
  119. {
  120. return ! (self == clamp);
  121. }
  122. protected:
  123. bool _bActive; // Is this clamp active?
  124. bool _bDiscrete; // Is this discrete or continuous?
  125. RST _rst; // State (coerced to integer if discrete)
  126. };
  127. ////////////////////////////////////////////////////////////////////
  128. // class GNODEMBN:
  129. // A node in belief network, continuous or discrete.
  130. // Hungarian: "gndbn"
  131. ////////////////////////////////////////////////////////////////////
  132. class GNODEMBN : public GOBJMBN
  133. {
  134. friend class DSCPARSER;
  135. friend class MBNET;
  136. public:
  137. GNODEMBN ();
  138. virtual ~ GNODEMBN();
  139. virtual INT EType () const
  140. { return EBNO_NODE ; }
  141. virtual GOBJMBN * CloneNew ( MODEL & modelSelf,
  142. MODEL & modelNew,
  143. GOBJMBN * pgobjNew = NULL );
  144. // Node sub-type: use IType() to access.
  145. enum FNODETYPE
  146. { // Flag definitions (i.e., bits, not values)
  147. FND_Void = 0, // Node is abstract base class
  148. FND_Valid = 1, // Node is usable
  149. FND_Discrete = 2 // Node is discrete
  150. };
  151. UINT CParent () const { return CSourceArcByEType( GEDGEMBN::ETPROB ); }
  152. UINT CChild () const { return CSinkArcByEType( GEDGEMBN::ETPROB ); }
  153. INT & ITopLevel () { return _iTopLevel; }
  154. INT ITopLevel () const { return _iTopLevel; }
  155. PTPOS & PtPos () { return _ptPos; }
  156. ZSTR & ZsFullName () { return _zsFullName; }
  157. LTBNPROP & LtProp () { return _ltProp; }
  158. virtual void Dump ();
  159. virtual void Visit ( bool bUpwards = true );
  160. // Add topological elements to given array; if "include self", self is last.
  161. // Fill array with parent pointers (follow directed arcs)
  162. void GetParents ( VPGNODEMBN & vpgnode, // Result array
  163. bool bIncludeSelf = false, // Place self as last entry in list
  164. bool bUseExpansion = true ); // If expanded, use expansion only
  165. void GetFamily ( VPGNODEMBN & vpgnode,
  166. bool bUseExpansion = true )
  167. { GetParents(vpgnode,true,bUseExpansion); }
  168. // Fill array with child pointers (follow directed arcs)
  169. void GetChildren ( VPGNODEMBN & vpgnode, bool bIncludeSelf = false );
  170. // Fill array with neighbors (follow undirected arcs)
  171. void GetNeighbors ( VPGNODEMBN & vpgnode, bool bIncludeSelf = false );
  172. // Return true if a node is neighbor
  173. bool BIsNeighbor ( GNODEMBN * pgndmb );
  174. // Return the index number of the parent or child or -1 if no relation.
  175. int IParent ( GNODEMBN * pgndmb, bool bReverse = false );
  176. int IChild ( GNODEMBN * pgndmb, bool bReverse = false );
  177. // Build the probability descriptor describing the node and its parents
  178. void GetVtknpd ( VTKNPD & vtknpd, bool bUseExpansion = true );
  179. // Query and access clamping information
  180. const CLAMP & ClampIface () const { return _clampIface; }
  181. CLAMP & ClampIface () { return _clampIface; }
  182. protected:
  183. INT _iTopLevel; // Topological level
  184. LTBNPROP _ltProp; // The list of user-definable properties
  185. PTPOS _ptPos; // Display position in graphical display
  186. ZSTR _zsFullName; // Full name of node
  187. CLAMP _clampIface; // User interface clamp
  188. protected:
  189. // Compare the topology of this node to that of the given distribution
  190. // token list to this. If 'pvpgnode', fill it with pointers to
  191. // the parent nodes
  192. bool BMatchTopology ( MBNET & mbnet,
  193. const VTKNPD & vtknpd,
  194. VPGNODEMBN * pvpgnode = NULL );
  195. HIDE_UNSAFE(GNODEMBN);
  196. };
  197. ////////////////////////////////////////////////////////////////////
  198. // class GEDGEMBN_U: An undirected edge
  199. ////////////////////////////////////////////////////////////////////
  200. class GEDGEMBN_U : public GEDGEMBN
  201. {
  202. public:
  203. GEDGEMBN_U ( GNODEMBN * pgnSource,
  204. GNODEMBN * pgnSink )
  205. : GEDGEMBN( pgnSource, pgnSink )
  206. {}
  207. virtual INT EType () const
  208. { return ETUNDIR; }
  209. virtual ~ GEDGEMBN_U() {}
  210. };
  211. ////////////////////////////////////////////////////////////////////
  212. // class GEDGEMBN_D: A directed edge
  213. ////////////////////////////////////////////////////////////////////
  214. class GEDGEMBN_D : public GEDGEMBN
  215. {
  216. public:
  217. GEDGEMBN_D ( GNODEMBN * pgnSource,
  218. GNODEMBN * pgnSink )
  219. : GEDGEMBN( pgnSource, pgnSink )
  220. {}
  221. virtual INT EType () const
  222. { return ETDIR; }
  223. virtual ~ GEDGEMBN_D() {}
  224. };
  225. ////////////////////////////////////////////////////////////////////
  226. // class GEDGEMBN_PROB:
  227. // A probabilistic arc in a belief network.
  228. ////////////////////////////////////////////////////////////////////
  229. class GEDGEMBN_PROB : public GEDGEMBN_D
  230. {
  231. public:
  232. GEDGEMBN_PROB ( GNODEMBN * pgndSource,
  233. GNODEMBN * pgndSink )
  234. : GEDGEMBN_D( pgndSource, pgndSink )
  235. {}
  236. virtual INT EType () const
  237. { return ETPROB ; }
  238. virtual ~ GEDGEMBN_PROB () {}
  239. virtual GEDGEMBN * CloneNew ( MODEL & modelSelf, // the original network
  240. MODEL & modelNew, // the new network
  241. GOBJMBN * pgobjmbnSource, // the original source node
  242. GOBJMBN * pgobjmbnSink, // the original sink node
  243. GEDGEMBN * pgdegeNew = NULL ); // the new edge or NULL
  244. GNODEMBN * PgndSource () { return (GNODEMBN *) GEDGE::PnodeSource(); }
  245. GNODEMBN * PgndSink () { return (GNODEMBN *) GEDGE::PnodeSink(); }
  246. HIDE_UNSAFE(GEDGEMBN_PROB);
  247. };
  248. ////////////////////////////////////////////////////////////////////
  249. // class GNODEMBND:
  250. // A discrete node in belief network.
  251. ////////////////////////////////////////////////////////////////////
  252. class GNODEMBND : public GNODEMBN
  253. {
  254. friend class DSCPARSER;
  255. public:
  256. GNODEMBND ();
  257. virtual ~ GNODEMBND ();
  258. virtual GOBJMBN * CloneNew ( MODEL & modelSelf,
  259. MODEL & modelNew,
  260. GOBJMBN * pgobjNew = NULL );
  261. UINT CState() const
  262. { return _vzsrState.size(); }
  263. const VZSREF & VzsrStates() const
  264. { return _vzsrState; }
  265. void SetStates ( const VZSREF & vzsrState )
  266. { _vzsrState = vzsrState; }
  267. // Return true if there's an associated distribution
  268. bool BHasDist () const
  269. { return _refbndist.BRef(); }
  270. // Set the distribution from the given net's distribution map
  271. void SetDist ( MBNET & mbnet );
  272. // Bind the given distribution this node
  273. void SetDist ( BNDIST * pbndist );
  274. // Return the distribution
  275. BNDIST & Bndist ()
  276. {
  277. assert( BHasDist() );
  278. return *_refbndist;
  279. }
  280. const BNDIST & Bndist () const
  281. {
  282. assert( BHasDist() );
  283. return *_refbndist;
  284. }
  285. // Return true if the distribution is dense (false ==> sparse)
  286. bool BDense () const
  287. {
  288. assert( BHasDist() );
  289. return _refbndist->BDense() ;
  290. }
  291. // Return the discrete dimension vector of this node if possible;
  292. // return false if any parent is not discrete.
  293. bool BGetVimd ( VIMD & vimd, // Dimension array to fill
  294. bool bIncludeSelf = false, // Place self as last entry in list
  295. bool bUseExpansion = true ); // If expanded, use expansion only
  296. void Dump ();
  297. void ClearDist()
  298. {
  299. _refbndist = NULL;
  300. }
  301. const REFBNDIST & RefBndist ()
  302. { return _refbndist; }
  303. bool BCheckDistDense ();
  304. const ZSREF ZsrDomain() const
  305. { return _zsrDomain; }
  306. void SetDomain ( const GOBJMBN_DOMAIN & gobjrdom );
  307. protected:
  308. VZSREF _vzsrState; // Names of states
  309. ZSREF _zsrDomain; // Domain of states, if any
  310. REFBNDIST _refbndist; // Distribution object
  311. HIDE_UNSAFE(GNODEMBND);
  312. };
  313. DEFINEVP(GNODEMBND); // A vector containing pointers to nodes
  314. DEFINEV(VPGNODEMBN); // A vector of vectors containing pointers to nodes
  315. DEFINEV(VPGNODEMBND); // A vector of vectors containing pointers to discrete nodes
  316. ////////////////////////////////////////////////////////////////////
  317. ////////////////////////////////////////////////////////////////////
  318. //
  319. // MBNET_MODIFIER: A generic superclass for active objects
  320. // which modify a belief network in a reversible fashion.
  321. // The belief network (MBNET) object maintains a stack of these
  322. // things and calls each object's Destroy() function as necessary
  323. // to "unstack".
  324. //
  325. // These objects should be reusable; that is, the outer level
  326. // creator may call Create(), followed by Destroy(), followed by
  327. // Create() again.
  328. ////////////////////////////////////////////////////////////////////
  329. ////////////////////////////////////////////////////////////////////
  330. class MBNET_MODIFIER : public GOBJMBN
  331. {
  332. public:
  333. MBNET_MODIFIER ( MBNET & model )
  334. : _model(model)
  335. {}
  336. virtual ~ MBNET_MODIFIER () {}
  337. virtual INT EType () const
  338. { return EBNO_MBNET_MODIFIER; }
  339. // Perform any creation-time operations
  340. virtual void Create () = 0;
  341. // Perform any special destruction
  342. virtual void Destroy () = 0;
  343. // Return true if positions in modifier stack can be reversed;
  344. // default is "no" (false).
  345. virtual bool BCommute ( const MBNET_MODIFIER & mbnmod )
  346. { return false; }
  347. // Return true if construction resulted in no modifications to network
  348. // i.e., operation was moot; default is "no" (false).
  349. virtual bool BMoot ()
  350. { return false; }
  351. MBNET & Model () { return _model; }
  352. protected:
  353. MBNET & _model; // The model we're operating on
  354. HIDE_UNSAFE(MBNET_MODIFIER);
  355. };
  356. // Define an array of pointers to modifiers, "VPMBNET_MODIFIER".
  357. DEFINEVP(MBNET_MODIFIER);
  358. ////////////////////////////////////////////////////////////////////
  359. ////////////////////////////////////////////////////////////////////
  360. // MBNET_NODE_RANKER: A generic superclass for external objects
  361. // which rank or order nodes by some criteria. Operates as
  362. // a function object; i.e., it is activated by use of the
  363. // function call operator.
  364. //
  365. // Objects of subclasses of this class must be reusable.
  366. // That is, the functin call operator must be callable
  367. // repeatedly.
  368. ////////////////////////////////////////////////////////////////////
  369. ////////////////////////////////////////////////////////////////////
  370. class MBNET_NODE_RANKER : public GOBJMBN
  371. {
  372. public:
  373. MBNET_NODE_RANKER ( MBNET & model )
  374. : _model(model)
  375. {}
  376. virtual ~ MBNET_NODE_RANKER () {}
  377. virtual INT EType () const
  378. { return EBNO_NODE_RANKER; }
  379. MBNET & Model () { return _model; }
  380. // The ranking function
  381. virtual void operator () () = 0;
  382. // Return the number of items ranked
  383. INT CRanked () const { return _vzsrNodes.size(); }
  384. // Return the nodes in rank order
  385. const VZSREF VzsrefNodes () const { return _vzsrNodes; }
  386. // Return the computed values in rank order
  387. const VLREAL VlrValues () const { return _vlrValues; }
  388. protected:
  389. MBNET & _model; // The model we're operating on
  390. VZSREF _vzsrNodes; // The names of the nodes in rank order
  391. VLREAL _vlrValues; // THe values associated with the ranking (if any)
  392. protected:
  393. void Clear ()
  394. {
  395. _vzsrNodes.clear();
  396. _vlrValues.resize(0);
  397. }
  398. HIDE_UNSAFE(MBNET_NODE_RANKER);
  399. };
  400. ////////////////////////////////////////////////////////////////////
  401. ////////////////////////////////////////////////////////////////////
  402. // class MBNET: a belief network
  403. ////////////////////////////////////////////////////////////////////
  404. ////////////////////////////////////////////////////////////////////
  405. class MBNET : public MODEL
  406. {
  407. public:
  408. MBNET ();
  409. virtual ~ MBNET ();
  410. // Clone this belief network from another
  411. virtual void Clone ( MODEL & model );
  412. // Accessor for map of distribution
  413. MPPD & Mppd () { return _mppd; }
  414. // Return true if an edge is allowed between these two nodes
  415. bool BAcyclicEdge ( GNODEMBN * pgndSource, GNODEMBN * pgndSink );
  416. // Add a named object to the graph and symbol table
  417. virtual void AddElem ( SZC szcName, GOBJMBN * pgobj );
  418. // Delete named objects
  419. virtual void DeleteElem ( GOBJMBN * pgelem );
  420. void AddElem ( GOBJMBN * pgobjUnnamed )
  421. { MODEL::AddElem( pgobjUnnamed ); }
  422. void AddElem ( GEDGEMBN * pgedge )
  423. { MODEL::AddElem( pgedge ); }
  424. // Topology and distribution management
  425. // Add arcs conforming to the defined distributions
  426. virtual void CreateTopology ();
  427. // Destroy arcs.
  428. virtual void DestroyTopology ( bool bDirectedOnly = true ) ;
  429. // Connect distribution information in MPPD to nodes
  430. virtual void BindDistributions ( bool bBind = true );
  431. void ClearDistributions ()
  432. { BindDistributions( false ); }
  433. // Write debugging info out
  434. virtual void Dump ();
  435. // Network walking/marking helpers
  436. void ClearNodeMarks ();
  437. void TopSortNodes ();
  438. // Index-to-name mapping functions
  439. // Find the named object by index
  440. GOBJMBN * PgobjFindByIndex ( int inm );
  441. // Return the index of a name
  442. int INameIndex ( ZSREF zsr );
  443. // Return the index of an object's name
  444. int INameIndex ( const GOBJMBN * pgobj );
  445. // Return the highest+1 name index
  446. int CNameMax () const { return _vzsrNames.size(); }
  447. // Causal Independence expansion operations (automatic during inference)
  448. virtual void ExpandCI ();
  449. virtual void UnexpandCI ();
  450. // Inference operations
  451. // Return the most recently created inference engine
  452. GOBJMBN_INFER_ENGINE * PInferEngine ();
  453. // Create an inference engine
  454. void CreateInferEngine ( REAL rEstimatedMaximumSize = 10e6 );
  455. // Destroy an inference engine
  456. void DestroyInferEngine ();
  457. protected:
  458. MPPD _mppd; // Declared probability distributions
  459. VZSREF _vzsrNames; // Array associating indicies to names
  460. int _inmFree; // First free entry in _vsrNodes
  461. INT _iInferEngID; // Next inference engine identifier
  462. VPMBNET_MODIFIER _vpModifiers; // The stack of active modifiers
  463. protected:
  464. int CreateNameIndex ( const GOBJMBN * pgobj );
  465. void DeleteNameIndex ( const GOBJMBN * pgobj );
  466. void DeleteNameIndex ( int inm );
  467. void PopModifierStack ( bool bAll = false );
  468. void PushModifierStack ( MBNET_MODIFIER * pmodf );
  469. MBNET_MODIFIER * PModifierStackTop ();
  470. void VerifyTopology ();
  471. HIDE_UNSAFE(MBNET);
  472. };
  473. ////////////////////////////////////////////////////////////////////
  474. ////////////////////////////////////////////////////////////////////
  475. // class MBNETDSC:
  476. // Subclass of MBNET that knows how to load and save DSC from
  477. // the DSC file format.
  478. ////////////////////////////////////////////////////////////////////
  479. ////////////////////////////////////////////////////////////////////
  480. class MBNETDSC : public MBNET
  481. {
  482. public:
  483. MBNETDSC ();
  484. virtual ~ MBNETDSC ();
  485. // Parse the network from a DSC file
  486. virtual bool BParse ( SZC szcFn, FILE * pfErr = NULL );
  487. // Print the network in DSC format
  488. virtual void Print ( FILE * pf = NULL );
  489. // Token translation
  490. // Map a string to a token
  491. static TOKEN TokenFind ( SZC szc );
  492. // Map a distribution type to a token
  493. static SZC SzcDist ( BNDIST::EDIST edist );
  494. // Map a token to a string
  495. static SZC SzcTokenMap ( TOKEN tkn );
  496. protected:
  497. // DSC file printing functions
  498. FILE * _pfDsc; // Output print destination
  499. protected:
  500. void PrintHeaderBlock();
  501. void PrintPropertyDeclarations();
  502. void PrintNodes();
  503. void PrintDomains();
  504. void PrintTopologyAndDistributions();
  505. void PrintDistribution ( GNODEMBN & gnode, BNDIST & bndist );
  506. void PrintPropertyList ( LTBNPROP & ltprop );
  507. HIDE_UNSAFE(MBNETDSC);
  508. };
  509. class BNWALKER : public GRPHWALKER<GNODEMBN>
  510. {
  511. protected:
  512. bool BSelect ( GNODEMBN * pgn );
  513. bool BMark ( GNODEMBN * pgn );
  514. };
  515. #endif