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.

552 lines
11 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: bnts.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. //
  11. // BNTS.CPP: Belief Network Troubleshooting interface
  12. //
  13. #include <windows.h>
  14. #include "bnts.h"
  15. #include "gmobj.h"
  16. #include "recomend.h"
  17. #include "tchar.h"
  18. /////////////////////////////////////////////////////////////////////////////////////
  19. // class MBNETDSCTS: slightly extended version of MBNETDSC to simplify T/S interface
  20. /////////////////////////////////////////////////////////////////////////////////////
  21. class MBNETDSCTS : public MBNETDSC
  22. {
  23. friend class BNTS;
  24. public:
  25. MBNETDSCTS ();
  26. virtual ~ MBNETDSCTS ();
  27. void PrepareForTS ();
  28. const VPGNODEMBND & Vpgndd ()
  29. { return _vpgndd; }
  30. PROPMGR & PropMgr ()
  31. { return _propMgr; }
  32. GOBJMBN_CLIQSET & InferEng ()
  33. {
  34. assert( _pCliqueSet );
  35. return *_pCliqueSet;
  36. }
  37. MBNET_RECOMMENDER & MbRecom ()
  38. {
  39. assert( _pmbRecom );
  40. return *_pmbRecom;
  41. }
  42. int INode ( int inodeSparse );
  43. int INode ( ZSREF zsr );
  44. bool BValid () const
  45. {
  46. return _pCliqueSet != NULL
  47. && _pmbRecom != NULL;
  48. }
  49. bool BDirty () const
  50. { return _bDirty; }
  51. void SetDirty ( bool bSet = true )
  52. { _bDirty = bSet; }
  53. protected:
  54. void BuildNodeMap ();
  55. protected:
  56. VPGNODEMBND _vpgndd; // Map to node ptrs based on dense inode
  57. VINT _vimap; // Map to dense inodes based on real (sparse) inodes
  58. PROPMGR _propMgr; // Property management
  59. GOBJMBN_CLIQSET * _pCliqueSet; // The clique tree inference engine
  60. MBNET_RECOMMENDER * _pmbRecom; // The recommender
  61. bool _bDirty; // Do recommendations need to be recalced?
  62. // Result fields for API
  63. ZSTR _zstr;
  64. VREAL _vreal;
  65. VINT _vint;
  66. };
  67. MBNETDSCTS :: MBNETDSCTS ()
  68. : _propMgr(self),
  69. _pmbRecom(NULL),
  70. _pCliqueSet(NULL),
  71. _bDirty(true)
  72. {
  73. }
  74. MBNETDSCTS :: ~ MBNETDSCTS ()
  75. {
  76. delete _pmbRecom;
  77. if ( PInferEngine() )
  78. DestroyInferEngine();
  79. }
  80. // Convert from the model's node index to the user's index
  81. int MBNETDSCTS :: INode ( int inodeSparse )
  82. {
  83. return _vimap[inodeSparse];
  84. }
  85. // Convert from a string name to the user's node index
  86. int MBNETDSCTS :: INode ( ZSREF zsr )
  87. {
  88. int inode = INameIndex( zsr );
  89. if ( inode < 0 )
  90. return -1;
  91. return INode(inode);
  92. }
  93. // Build the bi-directional maps
  94. void MBNETDSCTS :: BuildNodeMap ()
  95. {
  96. // Allocate room to store pointers to all the named objects
  97. _vpgndd.resize( CNameMax() );
  98. _vimap.resize( CNameMax() );
  99. // Find the discrete nodes
  100. GNODEMBND * pgndd;
  101. int igndd = 0;
  102. for ( int i = 0; i < CNameMax(); i++ )
  103. {
  104. _vimap[i] = -1;
  105. GOBJMBN * pgobj = PgobjFindByIndex( i );
  106. if ( pgobj == NULL )
  107. continue;
  108. pgndd = dynamic_cast<GNODEMBND *>( pgobj );
  109. if ( pgndd == NULL )
  110. continue;
  111. _vpgndd[igndd] = pgndd;
  112. _vimap[i] = igndd++;
  113. }
  114. _vpgndd.resize(igndd);
  115. }
  116. void MBNETDSCTS :: PrepareForTS ()
  117. {
  118. BuildNodeMap();
  119. CreateInferEngine();
  120. DynCastThrow( PInferEngine(), _pCliqueSet);
  121. _pmbRecom = new MBNET_RECOMMENDER( *_pCliqueSet );
  122. }
  123. // CTOR and DTOR
  124. BNTS :: BNTS ()
  125. :_pmbnet(NULL),
  126. _inodeCurrent(-1)
  127. {
  128. }
  129. BNTS :: ~ BNTS ()
  130. {
  131. Clear();
  132. }
  133. void BNTS :: Clear ()
  134. {
  135. delete _pmbnet;
  136. _pmbnet = NULL;
  137. _inodeCurrent = -1;
  138. }
  139. void BNTS :: ClearArrays ()
  140. {
  141. if ( ! _pmbnet )
  142. return;
  143. Mbnet()._vreal.resize(0);
  144. Mbnet()._vint.resize(0);
  145. }
  146. ZSTR & BNTS :: ZstrResult ()
  147. {
  148. return Mbnet()._zstr;
  149. }
  150. void BNTS :: ClearString ()
  151. {
  152. ZstrResult() == "";
  153. }
  154. MBNETDSCTS & BNTS :: Mbnet()
  155. {
  156. assert( _pmbnet );
  157. return *_pmbnet;
  158. }
  159. const MBNETDSCTS & BNTS :: Mbnet() const
  160. {
  161. assert( _pmbnet );
  162. return *_pmbnet;
  163. }
  164. bool BNTS :: BValidNet () const
  165. {
  166. return _pmbnet != NULL
  167. && Mbnet().BValid();
  168. }
  169. bool BNTS :: BValidNode () const
  170. {
  171. MBNETDSCTS & mbnts = const_cast<MBNETDSCTS &>(Mbnet());
  172. return BValidNet()
  173. && _inodeCurrent >= 0
  174. && _inodeCurrent < mbnts.Vpgndd().size();
  175. }
  176. ////////////////////////////////////////////////////////////////////
  177. // Model-level queries and functions
  178. ////////////////////////////////////////////////////////////////////
  179. // Load and process a DSC-based model
  180. BOOL BNTS :: BReadModel ( SZC szcFn, SZC szcFnError )
  181. {
  182. BOOL bResult = FALSE;;
  183. try
  184. {
  185. Clear();
  186. _pmbnet = new MBNETDSCTS;
  187. assert( _pmbnet );
  188. FILE * pfErr = szcFnError
  189. ? fopen( szcFnError, "w" )
  190. : NULL;
  191. if ( ! Mbnet().BParse( szcFn, pfErr ) )
  192. {
  193. Clear();
  194. }
  195. else
  196. {
  197. Mbnet().PrepareForTS();
  198. bResult = TRUE;
  199. }
  200. }
  201. catch ( GMException & )
  202. {
  203. }
  204. return bResult;
  205. }
  206. // Return the number of (pre-expansion) nodes in the model
  207. int BNTS :: CNode ()
  208. {
  209. if ( ! BValidNet() )
  210. return -1;
  211. return Mbnet().Vpgndd().size();
  212. }
  213. // Return our dense node index given a node name
  214. int BNTS :: INode ( SZC szcNodeSymName )
  215. {
  216. GOBJMBN * pgobj = Mbnet().Mpsymtbl().find( szcNodeSymName );
  217. if ( pgobj == NULL )
  218. return -1;
  219. ZSREF zsrNodeSymName = Mbnet().Mpsymtbl().intern( szcNodeSymName );
  220. return Mbnet().INode( zsrNodeSymName );
  221. }
  222. // Return TRUE if the state of information is impossible
  223. BOOL BNTS :: BImpossible ()
  224. {
  225. if ( ! BValidNet() )
  226. return FALSE;
  227. return Mbnet().InferEng().BImpossible();
  228. }
  229. // Return a property item string from the network
  230. BOOL BNTS :: BGetPropItemStr (
  231. LTBNPROP & ltprop,
  232. SZC szcPropType,
  233. int index,
  234. ZSTR & zstr )
  235. {
  236. ZSREF zsrPropName = Mbnet().Mpsymtbl().intern( szcPropType );
  237. PROPMBN * pprop = ltprop.PFind( zsrPropName );
  238. if ( pprop == NULL )
  239. return FALSE; // Not present in network property list
  240. if ( (pprop->FPropType() & fPropString) == 0 )
  241. return FALSE; // Not a string
  242. if ( index >= pprop->Count() )
  243. return FALSE; // Out of range
  244. zstr = pprop->Zsr( index );
  245. return true;
  246. }
  247. // Return a property item number from the network
  248. BOOL BNTS :: BGetPropItemReal (
  249. LTBNPROP & ltprop,
  250. SZC szcPropType,
  251. int index,
  252. double & dbl )
  253. {
  254. ZSREF zsrPropName = Mbnet().Mpsymtbl().intern( szcPropType );
  255. PROPMBN * pprop = ltprop.PFind( zsrPropName );
  256. if ( pprop == NULL )
  257. return FALSE; // Not present in network property list
  258. if ( (pprop->FPropType() & fPropString) != 0 )
  259. return FALSE; // Not a number
  260. if ( index >= pprop->Count() )
  261. return FALSE; // Out of range
  262. dbl = pprop->Real(index);
  263. return true;
  264. }
  265. BOOL BNTS :: BNetPropItemStr ( SZC szcPropType, int index)
  266. {
  267. return BGetPropItemStr( Mbnet().LtProp(),
  268. szcPropType,
  269. index,
  270. ZstrResult() );
  271. }
  272. BOOL BNTS :: BNetPropItemReal ( SZC szcPropType, int index, double & dbl )
  273. {
  274. return BGetPropItemReal( Mbnet().LtProp(),
  275. szcPropType, index,
  276. dbl );
  277. }
  278. ////////////////////////////////////////////////////////////////////
  279. // Operations involving the "Currrent Node": call NodeSetCurrent()
  280. ////////////////////////////////////////////////////////////////////
  281. // Set the current node for other calls
  282. BOOL BNTS :: BNodeSetCurrent( int inode )
  283. {
  284. _inodeCurrent = inode;
  285. if ( ! BValidNode() )
  286. {
  287. _inodeCurrent = -1;
  288. return FALSE;
  289. }
  290. return TRUE;
  291. }
  292. // Get the current node
  293. int BNTS :: INodeCurrent ()
  294. {
  295. return _inodeCurrent;
  296. }
  297. // Return the label of the current node
  298. ESTDLBL BNTS :: ELblNode ()
  299. {
  300. GNODEMBND * pgndd = Pgndd();
  301. if ( pgndd == NULL )
  302. return ESTDLBL_other;
  303. return Mbnet().MbRecom().ELbl( *pgndd );
  304. }
  305. // Return the number of discrete states in the current node
  306. int BNTS :: INodeCst ()
  307. {
  308. GNODEMBND * pgndd = Pgndd();
  309. if ( pgndd == NULL )
  310. return -1;
  311. return pgndd->CState();
  312. }
  313. // Set the state of a node
  314. BOOL BNTS :: BNodeSet ( int istate, bool bSet )
  315. {
  316. GNODEMBND * pgndd = Pgndd();
  317. if ( pgndd == NULL )
  318. return FALSE;
  319. Mbnet().SetDirty();
  320. int cst = pgndd->CState();
  321. if ( cst <= istate )
  322. return FALSE;
  323. CLAMP clamp( true, istate, istate >= 0 );
  324. Mbnet().MbRecom().EnterEvidence( pgndd, clamp, bSet ) ;
  325. return TRUE;
  326. }
  327. // Return the state of a node
  328. int BNTS :: INodeState ()
  329. {
  330. GNODEMBND * pgndd = Pgndd();
  331. if ( pgndd == NULL )
  332. return FALSE;
  333. CLAMP clamp;
  334. Mbnet().InferEng().GetEvidence( pgndd, clamp ) ;
  335. return clamp.BActive()
  336. ? clamp.Ist()
  337. : -1;
  338. }
  339. // Return the name of a node's state
  340. void BNTS :: NodeStateName ( int istate )
  341. {
  342. ClearString();
  343. GNODEMBND * pgndd = Pgndd();
  344. if ( pgndd == NULL )
  345. return;
  346. if ( istate >= pgndd->CState() )
  347. return;
  348. ZstrResult() = pgndd->VzsrStates()[istate];
  349. }
  350. // Return the symbolic name of the node
  351. void BNTS :: NodeSymName ()
  352. {
  353. ClearString();
  354. GNODEMBND * pgndd = Pgndd();
  355. if ( pgndd == NULL )
  356. return;
  357. ZstrResult() = pgndd->ZsrefName();
  358. }
  359. // Return the full name of the node
  360. void BNTS :: NodeFullName ()
  361. {
  362. ClearString();
  363. GNODEMBND * pgndd = Pgndd();
  364. if ( pgndd == NULL )
  365. return;
  366. ZstrResult() = pgndd->ZsFullName();
  367. }
  368. GNODEMBND * BNTS :: Pgndd ()
  369. {
  370. if ( ! BValidNode() )
  371. return NULL;
  372. GNODEMBND * pgndd = Mbnet().Vpgndd()[_inodeCurrent];
  373. assert( pgndd );
  374. return pgndd;
  375. }
  376. // Return a property item string from the node
  377. BOOL BNTS :: BNodePropItemStr ( SZC szcPropType, int index )
  378. {
  379. GNODEMBND * pgndd = Pgndd();
  380. if ( pgndd == NULL )
  381. return FALSE;
  382. return BGetPropItemStr( pgndd->LtProp(),
  383. szcPropType,
  384. index,
  385. ZstrResult() );
  386. }
  387. // Return a property item number from the node
  388. BOOL BNTS :: BNodePropItemReal ( SZC szcPropType, int index, double & dbl )
  389. {
  390. GNODEMBND * pgndd = Pgndd();
  391. if ( pgndd == NULL )
  392. return FALSE;
  393. return BGetPropItemReal( pgndd->LtProp(), szcPropType, index, dbl );
  394. }
  395. // Return the belief for a node
  396. void BNTS :: NodeBelief ()
  397. {
  398. ClearArrays();
  399. GNODEMBND * pgndd = Pgndd();
  400. if ( pgndd == NULL )
  401. return;
  402. int cState = pgndd->CState();
  403. MDVCPD mdvBel;
  404. Mbnet().InferEng().GetBelief( pgndd, mdvBel );
  405. assert( cState == mdvBel.size() );
  406. VREAL & vr = Mbnet()._vreal;
  407. vr.resize( cState );
  408. for ( int i = 0; i < cState; i++ )
  409. {
  410. vr[i] = mdvBel[i];
  411. }
  412. }
  413. // Return the recommended nodes and, optionally, their values
  414. BOOL BNTS :: BGetRecommendations ()
  415. {
  416. ClearArrays();
  417. if ( ! BValidNet() )
  418. return FALSE;
  419. if ( Mbnet().BDirty() )
  420. {
  421. Mbnet().SetDirty( false );
  422. // Compute the recommendations
  423. try
  424. {
  425. Mbnet().MbRecom()();
  426. }
  427. catch ( GMException & ex )
  428. {
  429. BOOL bResult = FALSE;
  430. switch ( ex.Ec() )
  431. {
  432. case EC_VOI_PROBDEF_ABNORMAL:
  433. // This is an expected condition
  434. bResult = TRUE;
  435. break;
  436. default:
  437. break;
  438. }
  439. return bResult;
  440. }
  441. }
  442. const VZSREF & vzsrNodes = Mbnet().MbRecom().VzsrefNodes();
  443. const VLREAL & vlrUtil = Mbnet().MbRecom().VlrValues();
  444. VREAL & vr = Mbnet()._vreal;
  445. VINT & vi = Mbnet()._vint;
  446. vr.resize( vzsrNodes.size() );
  447. vi.resize( vzsrNodes.size() );
  448. for ( int i = 0; i < vzsrNodes.size(); i++ )
  449. {
  450. int inode = Mbnet().INode( vzsrNodes[i] );
  451. assert( inode >= 0 ) ;
  452. vi[i] = inode;
  453. vr[i] = vlrUtil[i];
  454. }
  455. return TRUE;
  456. }
  457. SZC BNTS :: SzcResult () const
  458. {
  459. return Mbnet()._zstr.Szc();
  460. }
  461. const REAL * BNTS :: RgReal () const
  462. {
  463. return & Mbnet()._vreal[0];
  464. }
  465. const int * BNTS :: RgInt () const
  466. {
  467. return & Mbnet()._vint[0];
  468. }
  469. int BNTS :: CReal () const
  470. {
  471. return Mbnet()._vreal.size();
  472. }
  473. int BNTS :: CInt () const
  474. {
  475. return Mbnet()._vint.size();
  476. }
  477. // End of BNTS.CPP