PageRenderTime 38ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 0ms

/src/proof/live/ltl_parser.c

https://bitbucket.org/alanmi/abc/
C | 839 lines | 750 code | 52 blank | 37 comment | 147 complexity | bbea36b9fbc09dc09a4d789ea4d265a8 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /**CFile****************************************************************
  2. FileName [ltl_parser.c]
  3. SystemName [ABC: Logic synthesis and verification system.]
  4. PackageName [Liveness property checking.]
  5. Synopsis [LTL checker.]
  6. Author [Sayak Ray]
  7. Affiliation [UC Berkeley]
  8. Date [Ver. 1.0. Started - January 1, 2009.]
  9. Revision [$Id: ltl_parser.c,v 1.00 2009/01/01 00:00:00 alanmi Exp $]
  10. ***********************************************************************/
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <assert.h>
  14. #include <stdlib.h>
  15. #include "aig/aig/aig.h"
  16. #include "base/abc/abc.h"
  17. #include "base/main/mainInt.h"
  18. ABC_NAMESPACE_IMPL_START
  19. enum ltlToken { AND, OR, NOT, IMPLY, GLOBALLY, EVENTUALLY, NEXT, UNTIL, BOOL };
  20. enum ltlGrammerToken { OPERAND, LTL, BINOP, UOP };
  21. typedef enum ltlToken tokenType;
  22. typedef enum ltlGrammerToken ltlGrammerTokenType;
  23. struct ltlNode_t
  24. {
  25. tokenType type;
  26. char *name;
  27. Aig_Obj_t *pObj;
  28. struct ltlNode_t *left;
  29. struct ltlNode_t *right;
  30. };
  31. typedef struct ltlNode_t ltlNode;
  32. ltlNode *generateTypedNode( tokenType new_type )
  33. //void generateTypedNode( ltlNode *new_node, tokenType new_type )
  34. {
  35. ltlNode *new_node;
  36. new_node = (ltlNode *)malloc( sizeof(ltlNode) );
  37. if( new_node )
  38. {
  39. new_node->type = new_type;
  40. new_node->pObj = NULL;
  41. new_node->name = NULL;
  42. new_node->left = NULL;
  43. new_node->right = NULL;
  44. }
  45. return new_node;
  46. }
  47. Aig_Obj_t *buildLogicFromLTLNode_combinationalOnly( Aig_Man_t *pAig, ltlNode *pLtlNode );
  48. static inline int isNotVarNameSymbol( char c )
  49. {
  50. return ( c == ' ' || c == '\t' || c == '\n' || c == ':' || c == '\0' );
  51. }
  52. void Abc_FrameCopyLTLDataBase( Abc_Frame_t *pAbc, Abc_Ntk_t * pNtk )
  53. {
  54. char *pLtlFormula, *tempFormula;
  55. int i;
  56. if( pAbc->vLTLProperties_global != NULL )
  57. {
  58. // printf("Deleting exisitng LTL database from the frame\n");
  59. Vec_PtrFree( pAbc->vLTLProperties_global );
  60. pAbc->vLTLProperties_global = NULL;
  61. }
  62. pAbc->vLTLProperties_global = Vec_PtrAlloc(Vec_PtrSize(pNtk->vLtlProperties));
  63. Vec_PtrForEachEntry( char *, pNtk->vLtlProperties, pLtlFormula, i )
  64. {
  65. tempFormula = (char *)malloc( sizeof(char)*(strlen(pLtlFormula)+1) );
  66. sprintf( tempFormula, "%s", pLtlFormula );
  67. Vec_PtrPush( pAbc->vLTLProperties_global, tempFormula );
  68. }
  69. }
  70. char *getVarName( char *suffixFormula, int startLoc, int *endLocation )
  71. {
  72. int i = startLoc, length;
  73. char *name;
  74. if( isNotVarNameSymbol( suffixFormula[startLoc] ) )
  75. return NULL;
  76. while( !isNotVarNameSymbol( suffixFormula[i] ) )
  77. i++;
  78. *endLocation = i;
  79. length = i - startLoc;
  80. name = (char *)malloc( sizeof(char) * (length + 1));
  81. for( i=0; i<length; i++ )
  82. name[i] = suffixFormula[i+startLoc];
  83. name[i] = '\0';
  84. return name;
  85. }
  86. int startOfSuffixString = 0;
  87. int isUnexpectedEOS( char *formula, int index )
  88. {
  89. assert( formula );
  90. if( index >= (int)strlen( formula ) )
  91. {
  92. printf("\nInvalid LTL formula: unexpected end of string..." );
  93. return 1;
  94. }
  95. return 0;
  96. }
  97. int isTemporalOperator( char *formula, int index )
  98. {
  99. if( !(isUnexpectedEOS( formula, index ) || formula[ index ] == 'G' || formula[ index ] == 'F' || formula[ index ] == 'U' || formula[ index ] == 'X') )
  100. {
  101. printf("\nInvalid LTL formula: expecting temporal operator at the position %d....\n", index);
  102. return 0;
  103. }
  104. return 1;
  105. }
  106. ltlNode *readLtlFormula( char *formula )
  107. {
  108. char ch;
  109. char *varName;
  110. int formulaLength, rememberEnd;
  111. int i = startOfSuffixString;
  112. ltlNode *curr_node, *temp_node_left, *temp_node_right;
  113. char prevChar;
  114. formulaLength = strlen( formula );
  115. if( isUnexpectedEOS( formula, startOfSuffixString ) )
  116. {
  117. printf("\nFAULTING POINT: formula = %s\nstartOfSuffixString = %d, formula[%d] = %c\n\n", formula, startOfSuffixString, startOfSuffixString - 1, formula[startOfSuffixString-1]);
  118. return NULL;
  119. }
  120. while( i < formulaLength )
  121. {
  122. ch = formula[i];
  123. switch(ch){
  124. case ' ':
  125. case '\n':
  126. case '\r':
  127. case '\t':
  128. case '\v':
  129. case '\f':
  130. i++;
  131. startOfSuffixString = i;
  132. break;
  133. case ':':
  134. i++;
  135. if( !isTemporalOperator( formula, i ) )
  136. return NULL;
  137. startOfSuffixString = i;
  138. break;
  139. case 'G':
  140. prevChar = formula[i-1];
  141. if( prevChar == ':' ) //i.e. 'G' is a temporal operator
  142. {
  143. i++;
  144. startOfSuffixString = i;
  145. temp_node_left = readLtlFormula( formula );
  146. if( temp_node_left == NULL )
  147. return NULL;
  148. else
  149. {
  150. curr_node = generateTypedNode(GLOBALLY);
  151. curr_node->left = temp_node_left;
  152. return curr_node;
  153. }
  154. }
  155. else //i.e. 'G' must be starting a variable name
  156. {
  157. varName = getVarName( formula, i, &rememberEnd );
  158. if( !varName )
  159. {
  160. printf("\nInvalid LTL formula: expecting valid variable name token...aborting" );
  161. return NULL;
  162. }
  163. curr_node = generateTypedNode(BOOL);
  164. curr_node->name = varName;
  165. i = rememberEnd;
  166. startOfSuffixString = i;
  167. return curr_node;
  168. }
  169. case 'F':
  170. prevChar = formula[i-1];
  171. if( prevChar == ':' ) //i.e. 'F' is a temporal operator
  172. {
  173. i++;
  174. startOfSuffixString = i;
  175. temp_node_left = readLtlFormula( formula );
  176. if( temp_node_left == NULL )
  177. return NULL;
  178. else
  179. {
  180. curr_node = generateTypedNode(EVENTUALLY);
  181. curr_node->left = temp_node_left;
  182. return curr_node;
  183. }
  184. }
  185. else //i.e. 'F' must be starting a variable name
  186. {
  187. varName = getVarName( formula, i, &rememberEnd );
  188. if( !varName )
  189. {
  190. printf("\nInvalid LTL formula: expecting valid variable name token...aborting" );
  191. return NULL;
  192. }
  193. curr_node = generateTypedNode(BOOL);
  194. curr_node->name = varName;
  195. i = rememberEnd;
  196. startOfSuffixString = i;
  197. return curr_node;
  198. }
  199. case 'X':
  200. prevChar = formula[i-1];
  201. if( prevChar == ':' ) //i.e. 'X' is a temporal operator
  202. {
  203. i++;
  204. startOfSuffixString = i;
  205. temp_node_left = readLtlFormula( formula );
  206. if( temp_node_left == NULL )
  207. return NULL;
  208. else
  209. {
  210. curr_node = generateTypedNode(NEXT);
  211. curr_node->left = temp_node_left;
  212. return curr_node;
  213. }
  214. }
  215. else //i.e. 'X' must be starting a variable name
  216. {
  217. varName = getVarName( formula, i, &rememberEnd );
  218. if( !varName )
  219. {
  220. printf("\nInvalid LTL formula: expecting valid variable name token...aborting" );
  221. return NULL;
  222. }
  223. curr_node = generateTypedNode(BOOL);
  224. curr_node->name = varName;
  225. i = rememberEnd;
  226. startOfSuffixString = i;
  227. return curr_node;
  228. }
  229. case 'U':
  230. prevChar = formula[i-1];
  231. if( prevChar == ':' ) //i.e. 'X' is a temporal operator
  232. {
  233. i++;
  234. startOfSuffixString = i;
  235. temp_node_left = readLtlFormula( formula );
  236. if( temp_node_left == NULL )
  237. return NULL;
  238. temp_node_right = readLtlFormula( formula );
  239. if( temp_node_right == NULL )
  240. {
  241. //need to do memory management: if right subtree is NULL then left
  242. //subtree must be freed.
  243. return NULL;
  244. }
  245. curr_node = generateTypedNode(UNTIL);
  246. curr_node->left = temp_node_left;
  247. curr_node->right = temp_node_right;
  248. return curr_node;
  249. }
  250. else //i.e. 'U' must be starting a variable name
  251. {
  252. varName = getVarName( formula, i, &rememberEnd );
  253. if( !varName )
  254. {
  255. printf("\nInvalid LTL formula: expecting valid variable name token...aborting" );
  256. return NULL;
  257. }
  258. curr_node = generateTypedNode(BOOL);
  259. curr_node->name = varName;
  260. i = rememberEnd;
  261. startOfSuffixString = i;
  262. return curr_node;
  263. }
  264. case '+':
  265. i++;
  266. startOfSuffixString = i;
  267. temp_node_left = readLtlFormula( formula );
  268. if( temp_node_left == NULL )
  269. return NULL;
  270. temp_node_right = readLtlFormula( formula );
  271. if( temp_node_right == NULL )
  272. {
  273. //need to do memory management: if right subtree is NULL then left
  274. //subtree must be freed.
  275. return NULL;
  276. }
  277. curr_node = generateTypedNode(OR);
  278. curr_node->left = temp_node_left;
  279. curr_node->right = temp_node_right;
  280. return curr_node;
  281. case '&':
  282. i++;
  283. startOfSuffixString = i;
  284. temp_node_left = readLtlFormula( formula );
  285. if( temp_node_left == NULL )
  286. return NULL;
  287. temp_node_right = readLtlFormula( formula );
  288. if( temp_node_right == NULL )
  289. {
  290. //need to do memory management: if right subtree is NULL then left
  291. //subtree must be freed.
  292. return NULL;
  293. }
  294. curr_node = generateTypedNode(AND);
  295. curr_node->left = temp_node_left;
  296. curr_node->right = temp_node_right;
  297. return curr_node;
  298. case '!':
  299. i++;
  300. startOfSuffixString = i;
  301. temp_node_left = readLtlFormula( formula );
  302. if( temp_node_left == NULL )
  303. return NULL;
  304. else
  305. {
  306. curr_node = generateTypedNode(NOT);
  307. curr_node->left = temp_node_left;
  308. return curr_node;
  309. }
  310. default:
  311. varName = getVarName( formula, i, &rememberEnd );
  312. if( !varName )
  313. {
  314. printf("\nInvalid LTL formula: expecting valid variable name token...aborting" );
  315. return NULL;
  316. }
  317. curr_node = generateTypedNode(BOOL);
  318. curr_node->name = varName;
  319. i = rememberEnd;
  320. startOfSuffixString = i;
  321. return curr_node;
  322. }
  323. }
  324. return NULL;
  325. }
  326. void resetGlobalVar()
  327. {
  328. startOfSuffixString = 0;
  329. }
  330. ltlNode *parseFormulaCreateAST( char *inputFormula )
  331. {
  332. ltlNode *temp;
  333. temp = readLtlFormula( inputFormula );
  334. //if( temp == NULL )
  335. // printf("\nAST creation failed for formula %s", inputFormula );
  336. resetGlobalVar();
  337. return temp;
  338. }
  339. void traverseAbstractSyntaxTree( ltlNode *node )
  340. {
  341. switch(node->type){
  342. case( AND ):
  343. printf("& ");
  344. assert( node->left != NULL );
  345. assert( node->right != NULL );
  346. traverseAbstractSyntaxTree( node->left );
  347. traverseAbstractSyntaxTree( node->right );
  348. return;
  349. case( OR ):
  350. printf("+ ");
  351. assert( node->left != NULL );
  352. assert( node->right != NULL );
  353. traverseAbstractSyntaxTree( node->left );
  354. traverseAbstractSyntaxTree( node->right );
  355. return;
  356. case( NOT ):
  357. printf("~ ");
  358. assert( node->left != NULL );
  359. traverseAbstractSyntaxTree( node->left );
  360. assert( node->right == NULL );
  361. return;
  362. case( GLOBALLY ):
  363. printf("G ");
  364. assert( node->left != NULL );
  365. traverseAbstractSyntaxTree( node->left );
  366. assert( node->right == NULL );
  367. return;
  368. case( EVENTUALLY ):
  369. printf("F ");
  370. assert( node->left != NULL );
  371. traverseAbstractSyntaxTree( node->left );
  372. assert( node->right == NULL );
  373. return;
  374. case( NEXT ):
  375. printf("X ");
  376. assert( node->left != NULL );
  377. traverseAbstractSyntaxTree( node->left );
  378. assert( node->right == NULL );
  379. return;
  380. case( UNTIL ):
  381. printf("U ");
  382. assert( node->left != NULL );
  383. assert( node->right != NULL );
  384. traverseAbstractSyntaxTree( node->left );
  385. traverseAbstractSyntaxTree( node->right );
  386. return;
  387. case( BOOL ):
  388. printf("%s ", node->name);
  389. assert( node->left == NULL );
  390. assert( node->right == NULL );
  391. return;
  392. default:
  393. printf("\nUnsupported token type: Exiting execution\n");
  394. exit(0);
  395. }
  396. }
  397. void traverseAbstractSyntaxTree_postFix( ltlNode *node )
  398. {
  399. switch(node->type){
  400. case( AND ):
  401. printf("( ");
  402. assert( node->left != NULL );
  403. assert( node->right != NULL );
  404. traverseAbstractSyntaxTree_postFix( node->left );
  405. printf("& ");
  406. traverseAbstractSyntaxTree_postFix( node->right );
  407. printf(") ");
  408. return;
  409. case( OR ):
  410. printf("( ");
  411. assert( node->left != NULL );
  412. assert( node->right != NULL );
  413. traverseAbstractSyntaxTree_postFix( node->left );
  414. printf("+ ");
  415. traverseAbstractSyntaxTree_postFix( node->right );
  416. printf(") ");
  417. return;
  418. case( NOT ):
  419. printf("~ ");
  420. assert( node->left != NULL );
  421. traverseAbstractSyntaxTree_postFix( node->left );
  422. assert( node->right == NULL );
  423. return;
  424. case( GLOBALLY ):
  425. printf("G ");
  426. //printf("( ");
  427. assert( node->left != NULL );
  428. traverseAbstractSyntaxTree_postFix( node->left );
  429. assert( node->right == NULL );
  430. //printf(") ");
  431. return;
  432. case( EVENTUALLY ):
  433. printf("F ");
  434. //printf("( ");
  435. assert( node->left != NULL );
  436. traverseAbstractSyntaxTree_postFix( node->left );
  437. assert( node->right == NULL );
  438. //printf(") ");
  439. return;
  440. case( NEXT ):
  441. printf("X ");
  442. assert( node->left != NULL );
  443. traverseAbstractSyntaxTree_postFix( node->left );
  444. assert( node->right == NULL );
  445. return;
  446. case( UNTIL ):
  447. printf("( ");
  448. assert( node->left != NULL );
  449. assert( node->right != NULL );
  450. traverseAbstractSyntaxTree_postFix( node->left );
  451. printf("U ");
  452. traverseAbstractSyntaxTree_postFix( node->right );
  453. printf(") ");
  454. return;
  455. case( BOOL ):
  456. printf("%s ", node->name);
  457. assert( node->left == NULL );
  458. assert( node->right == NULL );
  459. return;
  460. default:
  461. printf("\nUnsupported token type: Exiting execution\n");
  462. exit(0);
  463. }
  464. }
  465. void populateAigPointerUnitGF( Aig_Man_t *pAigNew, ltlNode *topASTNode, Vec_Ptr_t *vSignal, Vec_Vec_t *vAigGFMap )
  466. {
  467. ltlNode *nextNode, *nextToNextNode;
  468. int serialNumSignal;
  469. switch( topASTNode->type ){
  470. case AND:
  471. case OR:
  472. case IMPLY:
  473. populateAigPointerUnitGF( pAigNew, topASTNode->left, vSignal, vAigGFMap );
  474. populateAigPointerUnitGF( pAigNew, topASTNode->right, vSignal, vAigGFMap );
  475. return;
  476. case NOT:
  477. populateAigPointerUnitGF( pAigNew, topASTNode->left, vSignal, vAigGFMap );
  478. return;
  479. case GLOBALLY:
  480. nextNode = topASTNode->left;
  481. assert( nextNode->type = EVENTUALLY );
  482. nextToNextNode = nextNode->left;
  483. if( nextToNextNode->type == BOOL )
  484. {
  485. assert( nextToNextNode->pObj );
  486. serialNumSignal = Vec_PtrFind( vSignal, nextToNextNode->pObj );
  487. if( serialNumSignal == -1 )
  488. {
  489. Vec_PtrPush( vSignal, nextToNextNode->pObj );
  490. serialNumSignal = Vec_PtrFind( vSignal, nextToNextNode->pObj );
  491. }
  492. //Vec_PtrPush( vGLOBALLY, topASTNode );
  493. Vec_VecPush( vAigGFMap, serialNumSignal, topASTNode );
  494. }
  495. else
  496. {
  497. assert( nextToNextNode->pObj == NULL );
  498. buildLogicFromLTLNode_combinationalOnly( pAigNew, nextToNextNode );
  499. serialNumSignal = Vec_PtrFind( vSignal, nextToNextNode->pObj );
  500. if( serialNumSignal == -1 )
  501. {
  502. Vec_PtrPush( vSignal, nextToNextNode->pObj );
  503. serialNumSignal = Vec_PtrFind( vSignal, nextToNextNode->pObj );
  504. }
  505. //Vec_PtrPush( vGLOBALLY, topASTNode );
  506. Vec_VecPush( vAigGFMap, serialNumSignal, topASTNode );
  507. }
  508. return;
  509. case BOOL:
  510. return;
  511. default:
  512. printf("\nINVALID situation: aborting...\n");
  513. exit(0);
  514. }
  515. }
  516. Aig_Obj_t *buildLogicFromLTLNode_combinationalOnly( Aig_Man_t *pAigNew, ltlNode *pLtlNode )
  517. {
  518. Aig_Obj_t *leftAigObj, *rightAigObj;
  519. if( pLtlNode->pObj != NULL )
  520. return pLtlNode->pObj;
  521. else
  522. {
  523. assert( pLtlNode->type != BOOL );
  524. switch( pLtlNode->type ){
  525. case AND:
  526. assert( pLtlNode->left ); assert( pLtlNode->right );
  527. leftAigObj = buildLogicFromLTLNode_combinationalOnly( pAigNew, pLtlNode->left );
  528. rightAigObj = buildLogicFromLTLNode_combinationalOnly( pAigNew, pLtlNode->right );
  529. assert( leftAigObj ); assert( rightAigObj );
  530. pLtlNode->pObj = Aig_And( pAigNew, leftAigObj, rightAigObj );
  531. return pLtlNode->pObj;
  532. case OR:
  533. assert( pLtlNode->left ); assert( pLtlNode->right );
  534. leftAigObj = buildLogicFromLTLNode_combinationalOnly( pAigNew, pLtlNode->left );
  535. rightAigObj = buildLogicFromLTLNode_combinationalOnly( pAigNew, pLtlNode->right );
  536. assert( leftAigObj ); assert( rightAigObj );
  537. pLtlNode->pObj = Aig_Or( pAigNew, leftAigObj, rightAigObj );
  538. return pLtlNode->pObj;
  539. case NOT:
  540. assert( pLtlNode->left ); assert( pLtlNode->right == NULL );
  541. leftAigObj = buildLogicFromLTLNode_combinationalOnly( pAigNew, pLtlNode->left );
  542. assert( leftAigObj );
  543. pLtlNode->pObj = Aig_Not( leftAigObj );
  544. return pLtlNode->pObj;
  545. case GLOBALLY:
  546. case EVENTUALLY:
  547. case NEXT:
  548. case UNTIL:
  549. printf("FORBIDDEN node: ABORTING!!\n");
  550. exit(0);
  551. default:
  552. printf("\nSerious ERROR: attempting to create AIG node from a temporal node\n");
  553. exit(0);
  554. }
  555. }
  556. }
  557. Aig_Obj_t *buildLogicFromLTLNode( Aig_Man_t *pAig, ltlNode *pLtlNode )
  558. {
  559. Aig_Obj_t *leftAigObj, *rightAigObj;
  560. if( pLtlNode->pObj != NULL )
  561. return pLtlNode->pObj;
  562. else
  563. {
  564. assert( pLtlNode->type != BOOL );
  565. switch( pLtlNode->type ){
  566. case AND:
  567. assert( pLtlNode->left ); assert( pLtlNode->right );
  568. leftAigObj = buildLogicFromLTLNode( pAig, pLtlNode->left );
  569. rightAigObj = buildLogicFromLTLNode( pAig, pLtlNode->right );
  570. assert( leftAigObj ); assert( rightAigObj );
  571. pLtlNode->pObj = Aig_And( pAig, leftAigObj, rightAigObj );
  572. return pLtlNode->pObj;
  573. case OR:
  574. assert( pLtlNode->left ); assert( pLtlNode->right );
  575. leftAigObj = buildLogicFromLTLNode( pAig, pLtlNode->left );
  576. rightAigObj = buildLogicFromLTLNode( pAig, pLtlNode->right );
  577. assert( leftAigObj ); assert( rightAigObj );
  578. pLtlNode->pObj = Aig_Or( pAig, leftAigObj, rightAigObj );
  579. return pLtlNode->pObj;
  580. case NOT:
  581. assert( pLtlNode->left ); assert( pLtlNode->right == NULL );
  582. leftAigObj = buildLogicFromLTLNode( pAig, pLtlNode->left );
  583. assert( leftAigObj );
  584. pLtlNode->pObj = Aig_Not( leftAigObj );
  585. return pLtlNode->pObj;
  586. case GLOBALLY:
  587. case EVENTUALLY:
  588. case NEXT:
  589. case UNTIL:
  590. printf("\nAttempting to create circuit with missing AIG pointer in a TEMPORAL node: ABORTING!!\n");
  591. exit(0);
  592. default:
  593. printf("\nSerious ERROR: attempting to create AIG node from a temporal node\n");
  594. exit(0);
  595. }
  596. }
  597. }
  598. int isNonTemporalSubformula( ltlNode *topNode )
  599. {
  600. switch( topNode->type ){
  601. case AND:
  602. case OR:
  603. case IMPLY:
  604. return isNonTemporalSubformula( topNode->left) && isNonTemporalSubformula( topNode->right ) ;
  605. case NOT:
  606. assert( topNode->right == NULL );
  607. return isNonTemporalSubformula( topNode->left );
  608. case BOOL:
  609. return 1;
  610. default:
  611. return 0;
  612. }
  613. }
  614. int isWellFormed( ltlNode *topNode )
  615. {
  616. ltlNode *nextNode;
  617. switch( topNode->type ){
  618. case AND:
  619. case OR:
  620. case IMPLY:
  621. return isWellFormed( topNode->left) && isWellFormed( topNode->right ) ;
  622. case NOT:
  623. assert( topNode->right == NULL );
  624. return isWellFormed( topNode->left );
  625. case BOOL:
  626. return 1;
  627. case GLOBALLY:
  628. nextNode = topNode->left;
  629. assert( topNode->right == NULL );
  630. if( nextNode->type != EVENTUALLY )
  631. return 0;
  632. else
  633. {
  634. assert( nextNode->right == NULL );
  635. return isNonTemporalSubformula( nextNode->left );
  636. }
  637. default:
  638. return 0;
  639. }
  640. }
  641. int checkBooleanConstant( char *targetName )
  642. {
  643. if( strcmp( targetName, "true" ) == 0 )
  644. return 1;
  645. if( strcmp( targetName, "false" ) == 0 )
  646. return 0;
  647. return -1;
  648. }
  649. int checkSignalNameExistence( Abc_Ntk_t *pNtk, ltlNode *topASTNode )
  650. {
  651. char *targetName;
  652. Abc_Obj_t * pNode;
  653. int i;
  654. switch( topASTNode->type ){
  655. case BOOL:
  656. targetName = topASTNode->name;
  657. //printf("\nTrying to match name %s\n", targetName);
  658. if( checkBooleanConstant( targetName ) != -1 )
  659. return 1;
  660. Abc_NtkForEachPo( pNtk, pNode, i )
  661. {
  662. if( strcmp( Abc_ObjName( pNode ), targetName ) == 0 )
  663. {
  664. //printf("\nVariable name \"%s\" MATCHED\n", targetName);
  665. return 1;
  666. }
  667. }
  668. printf("\nVariable name \"%s\" not found in the PO name list\n", targetName);
  669. return 0;
  670. case AND:
  671. case OR:
  672. case IMPLY:
  673. case UNTIL:
  674. assert( topASTNode->left != NULL );
  675. assert( topASTNode->right != NULL );
  676. return checkSignalNameExistence( pNtk, topASTNode->left ) && checkSignalNameExistence( pNtk, topASTNode->right );
  677. case NOT:
  678. case NEXT:
  679. case GLOBALLY:
  680. case EVENTUALLY:
  681. assert( topASTNode->left != NULL );
  682. assert( topASTNode->right == NULL );
  683. return checkSignalNameExistence( pNtk, topASTNode->left );
  684. default:
  685. printf("\nUNSUPPORTED LTL NODE TYPE:: Aborting execution\n");
  686. exit(0);
  687. }
  688. }
  689. void populateBoolWithAigNodePtr( Abc_Ntk_t *pNtk, Aig_Man_t *pAigOld, Aig_Man_t *pAigNew, ltlNode *topASTNode )
  690. {
  691. char *targetName;
  692. Abc_Obj_t * pNode;
  693. int i;
  694. Aig_Obj_t *pObj, *pDriverImage;
  695. switch( topASTNode->type ){
  696. case BOOL:
  697. targetName = topASTNode->name;
  698. if( checkBooleanConstant( targetName ) == 1 )
  699. {
  700. topASTNode->pObj = Aig_ManConst1( pAigNew );
  701. return;
  702. }
  703. if( checkBooleanConstant( targetName ) == 0 )
  704. {
  705. topASTNode->pObj = Aig_Not(topASTNode->pObj = Aig_ManConst1( pAigNew ));
  706. return;
  707. }
  708. Abc_NtkForEachPo( pNtk, pNode, i )
  709. if( strcmp( Abc_ObjName( pNode ), targetName ) == 0 )
  710. {
  711. pObj = Aig_ManCo( pAigOld, i );
  712. assert( Aig_ObjIsCo( pObj ));
  713. pDriverImage = Aig_NotCond((Aig_Obj_t *)Aig_Regular(Aig_ObjChild0( pObj ))->pData, Aig_ObjFaninC0(pObj));
  714. topASTNode->pObj = pDriverImage;
  715. return;
  716. }
  717. assert(0);
  718. case AND:
  719. case OR:
  720. case IMPLY:
  721. case UNTIL:
  722. assert( topASTNode->left != NULL );
  723. assert( topASTNode->right != NULL );
  724. populateBoolWithAigNodePtr( pNtk, pAigOld, pAigNew, topASTNode->left );
  725. populateBoolWithAigNodePtr( pNtk, pAigOld, pAigNew, topASTNode->right );
  726. return;
  727. case NOT:
  728. case NEXT:
  729. case GLOBALLY:
  730. case EVENTUALLY:
  731. assert( topASTNode->left != NULL );
  732. assert( topASTNode->right == NULL );
  733. populateBoolWithAigNodePtr( pNtk, pAigOld, pAigNew, topASTNode->left );
  734. return;
  735. default:
  736. printf("\nUNSUPPORTED LTL NODE TYPE:: Aborting execution\n");
  737. exit(0);
  738. }
  739. }
  740. int checkAllBoolHaveAIGPointer( ltlNode *topASTNode )
  741. {
  742. switch( topASTNode->type ){
  743. case BOOL:
  744. if( topASTNode->pObj != NULL )
  745. return 1;
  746. else
  747. {
  748. printf("\nfaulting PODMANDYO topASTNode->name = %s\n", topASTNode->name);
  749. return 0;
  750. }
  751. case AND:
  752. case OR:
  753. case IMPLY:
  754. case UNTIL:
  755. assert( topASTNode->left != NULL );
  756. assert( topASTNode->right != NULL );
  757. return checkAllBoolHaveAIGPointer( topASTNode->left ) && checkAllBoolHaveAIGPointer( topASTNode->right );
  758. case NOT:
  759. case NEXT:
  760. case GLOBALLY:
  761. case EVENTUALLY:
  762. assert( topASTNode->left != NULL );
  763. assert( topASTNode->right == NULL );
  764. return checkAllBoolHaveAIGPointer( topASTNode->left );
  765. default:
  766. printf("\nUNSUPPORTED LTL NODE TYPE:: Aborting execution\n");
  767. exit(0);
  768. }
  769. }
  770. void setAIGNodePtrOfGloballyNode( ltlNode *astNode, Aig_Obj_t *pObjLo )
  771. {
  772. astNode->pObj = pObjLo;
  773. }
  774. Aig_Obj_t *retriveAIGPointerFromLTLNode( ltlNode *astNode )
  775. {
  776. return astNode->pObj;
  777. }
  778. ABC_NAMESPACE_IMPL_END