| /**CFile**************************************************************** |
| |
| FileName [ltl_parser.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Liveness property checking.] |
| |
| Synopsis [LTL checker.] |
| |
| Author [Sayak Ray] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - January 1, 2009.] |
| |
| Revision [$Id: ltl_parser.c,v 1.00 2009/01/01 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include <stdio.h> |
| #include <string.h> |
| #include <assert.h> |
| #include <stdlib.h> |
| #include "aig/aig/aig.h" |
| #include "base/abc/abc.h" |
| #include "base/main/mainInt.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| enum ltlToken { AND, OR, NOT, IMPLY, GLOBALLY, EVENTUALLY, NEXT, UNTIL, BOOL }; |
| enum ltlGrammerToken { OPERAND, LTL, BINOP, UOP }; |
| typedef enum ltlToken tokenType; |
| typedef enum ltlGrammerToken ltlGrammerTokenType; |
| |
| struct ltlNode_t |
| { |
| tokenType type; |
| char *name; |
| Aig_Obj_t *pObj; |
| struct ltlNode_t *left; |
| struct ltlNode_t *right; |
| }; |
| |
| typedef struct ltlNode_t ltlNode; |
| |
| ltlNode *generateTypedNode( tokenType new_type ) |
| //void generateTypedNode( ltlNode *new_node, tokenType new_type ) |
| { |
| ltlNode *new_node; |
| |
| new_node = (ltlNode *)malloc( sizeof(ltlNode) ); |
| if( new_node ) |
| { |
| new_node->type = new_type; |
| new_node->pObj = NULL; |
| new_node->name = NULL; |
| new_node->left = NULL; |
| new_node->right = NULL; |
| } |
| |
| return new_node; |
| } |
| |
| Aig_Obj_t *buildLogicFromLTLNode_combinationalOnly( Aig_Man_t *pAig, ltlNode *pLtlNode ); |
| |
| static inline int isNotVarNameSymbol( char c ) |
| { |
| return ( c == ' ' || c == '\t' || c == '\n' || c == ':' || c == '\0' ); |
| } |
| |
| void Abc_FrameCopyLTLDataBase( Abc_Frame_t *pAbc, Abc_Ntk_t * pNtk ) |
| { |
| char *pLtlFormula, *tempFormula; |
| int i; |
| |
| if( pAbc->vLTLProperties_global != NULL ) |
| { |
| // printf("Deleting exisitng LTL database from the frame\n"); |
| Vec_PtrFree( pAbc->vLTLProperties_global ); |
| pAbc->vLTLProperties_global = NULL; |
| } |
| pAbc->vLTLProperties_global = Vec_PtrAlloc(Vec_PtrSize(pNtk->vLtlProperties)); |
| Vec_PtrForEachEntry( char *, pNtk->vLtlProperties, pLtlFormula, i ) |
| { |
| tempFormula = (char *)malloc( sizeof(char)*(strlen(pLtlFormula)+1) ); |
| sprintf( tempFormula, "%s", pLtlFormula ); |
| Vec_PtrPush( pAbc->vLTLProperties_global, tempFormula ); |
| } |
| } |
| |
| char *getVarName( char *suffixFormula, int startLoc, int *endLocation ) |
| { |
| int i = startLoc, length; |
| char *name; |
| |
| if( isNotVarNameSymbol( suffixFormula[startLoc] ) ) |
| return NULL; |
| |
| while( !isNotVarNameSymbol( suffixFormula[i] ) ) |
| i++; |
| *endLocation = i; |
| length = i - startLoc; |
| name = (char *)malloc( sizeof(char) * (length + 1)); |
| for( i=0; i<length; i++ ) |
| name[i] = suffixFormula[i+startLoc]; |
| name[i] = '\0'; |
| |
| return name; |
| } |
| |
| |
| int startOfSuffixString = 0; |
| |
| int isUnexpectedEOS( char *formula, int index ) |
| { |
| assert( formula ); |
| if( index >= (int)strlen( formula ) ) |
| { |
| printf("\nInvalid LTL formula: unexpected end of string..." ); |
| return 1; |
| } |
| return 0; |
| } |
| |
| int isTemporalOperator( char *formula, int index ) |
| { |
| if( !(isUnexpectedEOS( formula, index ) || formula[ index ] == 'G' || formula[ index ] == 'F' || formula[ index ] == 'U' || formula[ index ] == 'X') ) |
| { |
| printf("\nInvalid LTL formula: expecting temporal operator at the position %d....\n", index); |
| return 0; |
| } |
| return 1; |
| } |
| |
| ltlNode *readLtlFormula( char *formula ) |
| { |
| char ch; |
| char *varName; |
| int formulaLength, rememberEnd; |
| int i = startOfSuffixString; |
| ltlNode *curr_node, *temp_node_left, *temp_node_right; |
| char prevChar; |
| |
| formulaLength = strlen( formula ); |
| if( isUnexpectedEOS( formula, startOfSuffixString ) ) |
| { |
| printf("\nFAULTING POINT: formula = %s\nstartOfSuffixString = %d, formula[%d] = %c\n\n", formula, startOfSuffixString, startOfSuffixString - 1, formula[startOfSuffixString-1]); |
| return NULL; |
| } |
| |
| while( i < formulaLength ) |
| { |
| ch = formula[i]; |
| |
| switch(ch){ |
| case ' ': |
| case '\n': |
| case '\r': |
| case '\t': |
| case '\v': |
| case '\f': |
| i++; |
| startOfSuffixString = i; |
| break; |
| case ':': |
| i++; |
| if( !isTemporalOperator( formula, i ) ) |
| return NULL; |
| startOfSuffixString = i; |
| break; |
| case 'G': |
| prevChar = formula[i-1]; |
| if( prevChar == ':' ) //i.e. 'G' is a temporal operator |
| { |
| i++; |
| startOfSuffixString = i; |
| temp_node_left = readLtlFormula( formula ); |
| if( temp_node_left == NULL ) |
| return NULL; |
| else |
| { |
| curr_node = generateTypedNode(GLOBALLY); |
| curr_node->left = temp_node_left; |
| return curr_node; |
| } |
| } |
| else //i.e. 'G' must be starting a variable name |
| { |
| varName = getVarName( formula, i, &rememberEnd ); |
| if( !varName ) |
| { |
| printf("\nInvalid LTL formula: expecting valid variable name token...aborting" ); |
| return NULL; |
| } |
| curr_node = generateTypedNode(BOOL); |
| curr_node->name = varName; |
| i = rememberEnd; |
| startOfSuffixString = i; |
| return curr_node; |
| } |
| case 'F': |
| prevChar = formula[i-1]; |
| if( prevChar == ':' ) //i.e. 'F' is a temporal operator |
| { |
| i++; |
| startOfSuffixString = i; |
| temp_node_left = readLtlFormula( formula ); |
| if( temp_node_left == NULL ) |
| return NULL; |
| else |
| { |
| curr_node = generateTypedNode(EVENTUALLY); |
| curr_node->left = temp_node_left; |
| return curr_node; |
| } |
| } |
| else //i.e. 'F' must be starting a variable name |
| { |
| varName = getVarName( formula, i, &rememberEnd ); |
| if( !varName ) |
| { |
| printf("\nInvalid LTL formula: expecting valid variable name token...aborting" ); |
| return NULL; |
| } |
| curr_node = generateTypedNode(BOOL); |
| curr_node->name = varName; |
| i = rememberEnd; |
| startOfSuffixString = i; |
| return curr_node; |
| } |
| case 'X': |
| prevChar = formula[i-1]; |
| if( prevChar == ':' ) //i.e. 'X' is a temporal operator |
| { |
| i++; |
| startOfSuffixString = i; |
| temp_node_left = readLtlFormula( formula ); |
| if( temp_node_left == NULL ) |
| return NULL; |
| else |
| { |
| curr_node = generateTypedNode(NEXT); |
| curr_node->left = temp_node_left; |
| return curr_node; |
| } |
| } |
| else //i.e. 'X' must be starting a variable name |
| { |
| varName = getVarName( formula, i, &rememberEnd ); |
| if( !varName ) |
| { |
| printf("\nInvalid LTL formula: expecting valid variable name token...aborting" ); |
| return NULL; |
| } |
| curr_node = generateTypedNode(BOOL); |
| curr_node->name = varName; |
| i = rememberEnd; |
| startOfSuffixString = i; |
| return curr_node; |
| } |
| case 'U': |
| prevChar = formula[i-1]; |
| if( prevChar == ':' ) //i.e. 'X' is a temporal operator |
| { |
| i++; |
| startOfSuffixString = i; |
| temp_node_left = readLtlFormula( formula ); |
| if( temp_node_left == NULL ) |
| return NULL; |
| temp_node_right = readLtlFormula( formula ); |
| if( temp_node_right == NULL ) |
| { |
| //need to do memory management: if right subtree is NULL then left |
| //subtree must be freed. |
| return NULL; |
| } |
| curr_node = generateTypedNode(UNTIL); |
| curr_node->left = temp_node_left; |
| curr_node->right = temp_node_right; |
| return curr_node; |
| } |
| else //i.e. 'U' must be starting a variable name |
| { |
| varName = getVarName( formula, i, &rememberEnd ); |
| if( !varName ) |
| { |
| printf("\nInvalid LTL formula: expecting valid variable name token...aborting" ); |
| return NULL; |
| } |
| curr_node = generateTypedNode(BOOL); |
| curr_node->name = varName; |
| i = rememberEnd; |
| startOfSuffixString = i; |
| return curr_node; |
| } |
| case '+': |
| i++; |
| startOfSuffixString = i; |
| temp_node_left = readLtlFormula( formula ); |
| if( temp_node_left == NULL ) |
| return NULL; |
| temp_node_right = readLtlFormula( formula ); |
| if( temp_node_right == NULL ) |
| { |
| //need to do memory management: if right subtree is NULL then left |
| //subtree must be freed. |
| return NULL; |
| } |
| curr_node = generateTypedNode(OR); |
| curr_node->left = temp_node_left; |
| curr_node->right = temp_node_right; |
| return curr_node; |
| case '&': |
| i++; |
| startOfSuffixString = i; |
| temp_node_left = readLtlFormula( formula ); |
| if( temp_node_left == NULL ) |
| return NULL; |
| temp_node_right = readLtlFormula( formula ); |
| if( temp_node_right == NULL ) |
| { |
| //need to do memory management: if right subtree is NULL then left |
| //subtree must be freed. |
| return NULL; |
| } |
| curr_node = generateTypedNode(AND); |
| curr_node->left = temp_node_left; |
| curr_node->right = temp_node_right; |
| return curr_node; |
| case '!': |
| i++; |
| startOfSuffixString = i; |
| temp_node_left = readLtlFormula( formula ); |
| if( temp_node_left == NULL ) |
| return NULL; |
| else |
| { |
| curr_node = generateTypedNode(NOT); |
| curr_node->left = temp_node_left; |
| return curr_node; |
| } |
| default: |
| varName = getVarName( formula, i, &rememberEnd ); |
| if( !varName ) |
| { |
| printf("\nInvalid LTL formula: expecting valid variable name token...aborting" ); |
| return NULL; |
| } |
| curr_node = generateTypedNode(BOOL); |
| curr_node->name = varName; |
| i = rememberEnd; |
| startOfSuffixString = i; |
| return curr_node; |
| } |
| } |
| return NULL; |
| } |
| |
| void resetGlobalVar() |
| { |
| startOfSuffixString = 0; |
| } |
| |
| ltlNode *parseFormulaCreateAST( char *inputFormula ) |
| { |
| ltlNode *temp; |
| |
| temp = readLtlFormula( inputFormula ); |
| //if( temp == NULL ) |
| // printf("\nAST creation failed for formula %s", inputFormula ); |
| resetGlobalVar(); |
| return temp; |
| } |
| |
| void traverseAbstractSyntaxTree( ltlNode *node ) |
| { |
| switch(node->type){ |
| case( AND ): |
| printf("& "); |
| assert( node->left != NULL ); |
| assert( node->right != NULL ); |
| traverseAbstractSyntaxTree( node->left ); |
| traverseAbstractSyntaxTree( node->right ); |
| return; |
| case( OR ): |
| printf("+ "); |
| assert( node->left != NULL ); |
| assert( node->right != NULL ); |
| traverseAbstractSyntaxTree( node->left ); |
| traverseAbstractSyntaxTree( node->right ); |
| return; |
| case( NOT ): |
| printf("~ "); |
| assert( node->left != NULL ); |
| traverseAbstractSyntaxTree( node->left ); |
| assert( node->right == NULL ); |
| return; |
| case( GLOBALLY ): |
| printf("G "); |
| assert( node->left != NULL ); |
| traverseAbstractSyntaxTree( node->left ); |
| assert( node->right == NULL ); |
| return; |
| case( EVENTUALLY ): |
| printf("F "); |
| assert( node->left != NULL ); |
| traverseAbstractSyntaxTree( node->left ); |
| assert( node->right == NULL ); |
| return; |
| case( NEXT ): |
| printf("X "); |
| assert( node->left != NULL ); |
| traverseAbstractSyntaxTree( node->left ); |
| assert( node->right == NULL ); |
| return; |
| case( UNTIL ): |
| printf("U "); |
| assert( node->left != NULL ); |
| assert( node->right != NULL ); |
| traverseAbstractSyntaxTree( node->left ); |
| traverseAbstractSyntaxTree( node->right ); |
| return; |
| case( BOOL ): |
| printf("%s ", node->name); |
| assert( node->left == NULL ); |
| assert( node->right == NULL ); |
| return; |
| default: |
| printf("\nUnsupported token type: Exiting execution\n"); |
| exit(0); |
| } |
| } |
| |
| void traverseAbstractSyntaxTree_postFix( ltlNode *node ) |
| { |
| switch(node->type){ |
| case( AND ): |
| printf("( "); |
| assert( node->left != NULL ); |
| assert( node->right != NULL ); |
| traverseAbstractSyntaxTree_postFix( node->left ); |
| printf("& "); |
| traverseAbstractSyntaxTree_postFix( node->right ); |
| printf(") "); |
| return; |
| case( OR ): |
| printf("( "); |
| assert( node->left != NULL ); |
| assert( node->right != NULL ); |
| traverseAbstractSyntaxTree_postFix( node->left ); |
| printf("+ "); |
| traverseAbstractSyntaxTree_postFix( node->right ); |
| printf(") "); |
| return; |
| case( NOT ): |
| printf("~ "); |
| assert( node->left != NULL ); |
| traverseAbstractSyntaxTree_postFix( node->left ); |
| assert( node->right == NULL ); |
| return; |
| case( GLOBALLY ): |
| printf("G "); |
| //printf("( "); |
| assert( node->left != NULL ); |
| traverseAbstractSyntaxTree_postFix( node->left ); |
| assert( node->right == NULL ); |
| //printf(") "); |
| return; |
| case( EVENTUALLY ): |
| printf("F "); |
| //printf("( "); |
| assert( node->left != NULL ); |
| traverseAbstractSyntaxTree_postFix( node->left ); |
| assert( node->right == NULL ); |
| //printf(") "); |
| return; |
| case( NEXT ): |
| printf("X "); |
| assert( node->left != NULL ); |
| traverseAbstractSyntaxTree_postFix( node->left ); |
| assert( node->right == NULL ); |
| return; |
| case( UNTIL ): |
| printf("( "); |
| assert( node->left != NULL ); |
| assert( node->right != NULL ); |
| traverseAbstractSyntaxTree_postFix( node->left ); |
| printf("U "); |
| traverseAbstractSyntaxTree_postFix( node->right ); |
| printf(") "); |
| return; |
| case( BOOL ): |
| printf("%s ", node->name); |
| assert( node->left == NULL ); |
| assert( node->right == NULL ); |
| return; |
| default: |
| printf("\nUnsupported token type: Exiting execution\n"); |
| exit(0); |
| } |
| } |
| |
| void populateAigPointerUnitGF( Aig_Man_t *pAigNew, ltlNode *topASTNode, Vec_Ptr_t *vSignal, Vec_Vec_t *vAigGFMap ) |
| { |
| ltlNode *nextNode, *nextToNextNode; |
| int serialNumSignal; |
| |
| switch( topASTNode->type ){ |
| case AND: |
| case OR: |
| case IMPLY: |
| populateAigPointerUnitGF( pAigNew, topASTNode->left, vSignal, vAigGFMap ); |
| populateAigPointerUnitGF( pAigNew, topASTNode->right, vSignal, vAigGFMap ); |
| return; |
| case NOT: |
| populateAigPointerUnitGF( pAigNew, topASTNode->left, vSignal, vAigGFMap ); |
| return; |
| case GLOBALLY: |
| nextNode = topASTNode->left; |
| assert( nextNode->type = EVENTUALLY ); |
| nextToNextNode = nextNode->left; |
| if( nextToNextNode->type == BOOL ) |
| { |
| assert( nextToNextNode->pObj ); |
| serialNumSignal = Vec_PtrFind( vSignal, nextToNextNode->pObj ); |
| if( serialNumSignal == -1 ) |
| { |
| Vec_PtrPush( vSignal, nextToNextNode->pObj ); |
| serialNumSignal = Vec_PtrFind( vSignal, nextToNextNode->pObj ); |
| } |
| //Vec_PtrPush( vGLOBALLY, topASTNode ); |
| Vec_VecPush( vAigGFMap, serialNumSignal, topASTNode ); |
| } |
| else |
| { |
| assert( nextToNextNode->pObj == NULL ); |
| buildLogicFromLTLNode_combinationalOnly( pAigNew, nextToNextNode ); |
| serialNumSignal = Vec_PtrFind( vSignal, nextToNextNode->pObj ); |
| if( serialNumSignal == -1 ) |
| { |
| Vec_PtrPush( vSignal, nextToNextNode->pObj ); |
| serialNumSignal = Vec_PtrFind( vSignal, nextToNextNode->pObj ); |
| } |
| //Vec_PtrPush( vGLOBALLY, topASTNode ); |
| Vec_VecPush( vAigGFMap, serialNumSignal, topASTNode ); |
| } |
| return; |
| case BOOL: |
| return; |
| default: |
| printf("\nINVALID situation: aborting...\n"); |
| exit(0); |
| } |
| } |
| |
| Aig_Obj_t *buildLogicFromLTLNode_combinationalOnly( Aig_Man_t *pAigNew, ltlNode *pLtlNode ) |
| { |
| Aig_Obj_t *leftAigObj, *rightAigObj; |
| |
| if( pLtlNode->pObj != NULL ) |
| return pLtlNode->pObj; |
| else |
| { |
| assert( pLtlNode->type != BOOL ); |
| switch( pLtlNode->type ){ |
| case AND: |
| assert( pLtlNode->left ); assert( pLtlNode->right ); |
| leftAigObj = buildLogicFromLTLNode_combinationalOnly( pAigNew, pLtlNode->left ); |
| rightAigObj = buildLogicFromLTLNode_combinationalOnly( pAigNew, pLtlNode->right ); |
| assert( leftAigObj ); assert( rightAigObj ); |
| pLtlNode->pObj = Aig_And( pAigNew, leftAigObj, rightAigObj ); |
| return pLtlNode->pObj; |
| case OR: |
| assert( pLtlNode->left ); assert( pLtlNode->right ); |
| leftAigObj = buildLogicFromLTLNode_combinationalOnly( pAigNew, pLtlNode->left ); |
| rightAigObj = buildLogicFromLTLNode_combinationalOnly( pAigNew, pLtlNode->right ); |
| assert( leftAigObj ); assert( rightAigObj ); |
| pLtlNode->pObj = Aig_Or( pAigNew, leftAigObj, rightAigObj ); |
| return pLtlNode->pObj; |
| case NOT: |
| assert( pLtlNode->left ); assert( pLtlNode->right == NULL ); |
| leftAigObj = buildLogicFromLTLNode_combinationalOnly( pAigNew, pLtlNode->left ); |
| assert( leftAigObj ); |
| pLtlNode->pObj = Aig_Not( leftAigObj ); |
| return pLtlNode->pObj; |
| case GLOBALLY: |
| case EVENTUALLY: |
| case NEXT: |
| case UNTIL: |
| printf("FORBIDDEN node: ABORTING!!\n"); |
| exit(0); |
| default: |
| printf("\nSerious ERROR: attempting to create AIG node from a temporal node\n"); |
| exit(0); |
| } |
| } |
| } |
| |
| Aig_Obj_t *buildLogicFromLTLNode( Aig_Man_t *pAig, ltlNode *pLtlNode ) |
| { |
| Aig_Obj_t *leftAigObj, *rightAigObj; |
| |
| if( pLtlNode->pObj != NULL ) |
| return pLtlNode->pObj; |
| else |
| { |
| assert( pLtlNode->type != BOOL ); |
| switch( pLtlNode->type ){ |
| case AND: |
| assert( pLtlNode->left ); assert( pLtlNode->right ); |
| leftAigObj = buildLogicFromLTLNode( pAig, pLtlNode->left ); |
| rightAigObj = buildLogicFromLTLNode( pAig, pLtlNode->right ); |
| assert( leftAigObj ); assert( rightAigObj ); |
| pLtlNode->pObj = Aig_And( pAig, leftAigObj, rightAigObj ); |
| return pLtlNode->pObj; |
| case OR: |
| assert( pLtlNode->left ); assert( pLtlNode->right ); |
| leftAigObj = buildLogicFromLTLNode( pAig, pLtlNode->left ); |
| rightAigObj = buildLogicFromLTLNode( pAig, pLtlNode->right ); |
| assert( leftAigObj ); assert( rightAigObj ); |
| pLtlNode->pObj = Aig_Or( pAig, leftAigObj, rightAigObj ); |
| return pLtlNode->pObj; |
| case NOT: |
| assert( pLtlNode->left ); assert( pLtlNode->right == NULL ); |
| leftAigObj = buildLogicFromLTLNode( pAig, pLtlNode->left ); |
| assert( leftAigObj ); |
| pLtlNode->pObj = Aig_Not( leftAigObj ); |
| return pLtlNode->pObj; |
| case GLOBALLY: |
| case EVENTUALLY: |
| case NEXT: |
| case UNTIL: |
| printf("\nAttempting to create circuit with missing AIG pointer in a TEMPORAL node: ABORTING!!\n"); |
| exit(0); |
| default: |
| printf("\nSerious ERROR: attempting to create AIG node from a temporal node\n"); |
| exit(0); |
| } |
| } |
| } |
| |
| int isNonTemporalSubformula( ltlNode *topNode ) |
| { |
| switch( topNode->type ){ |
| case AND: |
| case OR: |
| case IMPLY: |
| return isNonTemporalSubformula( topNode->left) && isNonTemporalSubformula( topNode->right ) ; |
| case NOT: |
| assert( topNode->right == NULL ); |
| return isNonTemporalSubformula( topNode->left ); |
| case BOOL: |
| return 1; |
| default: |
| return 0; |
| } |
| } |
| |
| int isWellFormed( ltlNode *topNode ) |
| { |
| ltlNode *nextNode; |
| |
| switch( topNode->type ){ |
| case AND: |
| case OR: |
| case IMPLY: |
| return isWellFormed( topNode->left) && isWellFormed( topNode->right ) ; |
| case NOT: |
| assert( topNode->right == NULL ); |
| return isWellFormed( topNode->left ); |
| case BOOL: |
| return 1; |
| case GLOBALLY: |
| nextNode = topNode->left; |
| assert( topNode->right == NULL ); |
| if( nextNode->type != EVENTUALLY ) |
| return 0; |
| else |
| { |
| assert( nextNode->right == NULL ); |
| return isNonTemporalSubformula( nextNode->left ); |
| } |
| default: |
| return 0; |
| } |
| } |
| |
| int checkBooleanConstant( char *targetName ) |
| { |
| if( strcmp( targetName, "true" ) == 0 ) |
| return 1; |
| if( strcmp( targetName, "false" ) == 0 ) |
| return 0; |
| return -1; |
| } |
| |
| int checkSignalNameExistence( Abc_Ntk_t *pNtk, ltlNode *topASTNode ) |
| { |
| char *targetName; |
| Abc_Obj_t * pNode; |
| int i; |
| |
| switch( topASTNode->type ){ |
| case BOOL: |
| targetName = topASTNode->name; |
| //printf("\nTrying to match name %s\n", targetName); |
| if( checkBooleanConstant( targetName ) != -1 ) |
| return 1; |
| Abc_NtkForEachPo( pNtk, pNode, i ) |
| { |
| if( strcmp( Abc_ObjName( pNode ), targetName ) == 0 ) |
| { |
| //printf("\nVariable name \"%s\" MATCHED\n", targetName); |
| return 1; |
| } |
| } |
| printf("\nVariable name \"%s\" not found in the PO name list\n", targetName); |
| return 0; |
| case AND: |
| case OR: |
| case IMPLY: |
| case UNTIL: |
| assert( topASTNode->left != NULL ); |
| assert( topASTNode->right != NULL ); |
| return checkSignalNameExistence( pNtk, topASTNode->left ) && checkSignalNameExistence( pNtk, topASTNode->right ); |
| |
| case NOT: |
| case NEXT: |
| case GLOBALLY: |
| case EVENTUALLY: |
| assert( topASTNode->left != NULL ); |
| assert( topASTNode->right == NULL ); |
| return checkSignalNameExistence( pNtk, topASTNode->left ); |
| default: |
| printf("\nUNSUPPORTED LTL NODE TYPE:: Aborting execution\n"); |
| exit(0); |
| } |
| } |
| |
| void populateBoolWithAigNodePtr( Abc_Ntk_t *pNtk, Aig_Man_t *pAigOld, Aig_Man_t *pAigNew, ltlNode *topASTNode ) |
| { |
| char *targetName; |
| Abc_Obj_t * pNode; |
| int i; |
| Aig_Obj_t *pObj, *pDriverImage; |
| |
| switch( topASTNode->type ){ |
| case BOOL: |
| targetName = topASTNode->name; |
| if( checkBooleanConstant( targetName ) == 1 ) |
| { |
| topASTNode->pObj = Aig_ManConst1( pAigNew ); |
| return; |
| } |
| if( checkBooleanConstant( targetName ) == 0 ) |
| { |
| topASTNode->pObj = Aig_Not(topASTNode->pObj = Aig_ManConst1( pAigNew )); |
| return; |
| } |
| Abc_NtkForEachPo( pNtk, pNode, i ) |
| if( strcmp( Abc_ObjName( pNode ), targetName ) == 0 ) |
| { |
| pObj = Aig_ManCo( pAigOld, i ); |
| assert( Aig_ObjIsCo( pObj )); |
| pDriverImage = Aig_NotCond((Aig_Obj_t *)Aig_Regular(Aig_ObjChild0( pObj ))->pData, Aig_ObjFaninC0(pObj)); |
| topASTNode->pObj = pDriverImage; |
| return; |
| } |
| assert(0); |
| case AND: |
| case OR: |
| case IMPLY: |
| case UNTIL: |
| assert( topASTNode->left != NULL ); |
| assert( topASTNode->right != NULL ); |
| populateBoolWithAigNodePtr( pNtk, pAigOld, pAigNew, topASTNode->left ); |
| populateBoolWithAigNodePtr( pNtk, pAigOld, pAigNew, topASTNode->right ); |
| return; |
| case NOT: |
| case NEXT: |
| case GLOBALLY: |
| case EVENTUALLY: |
| assert( topASTNode->left != NULL ); |
| assert( topASTNode->right == NULL ); |
| populateBoolWithAigNodePtr( pNtk, pAigOld, pAigNew, topASTNode->left ); |
| return; |
| default: |
| printf("\nUNSUPPORTED LTL NODE TYPE:: Aborting execution\n"); |
| exit(0); |
| } |
| } |
| |
| int checkAllBoolHaveAIGPointer( ltlNode *topASTNode ) |
| { |
| |
| switch( topASTNode->type ){ |
| case BOOL: |
| if( topASTNode->pObj != NULL ) |
| return 1; |
| else |
| { |
| printf("\nfaulting PODMANDYO topASTNode->name = %s\n", topASTNode->name); |
| return 0; |
| } |
| case AND: |
| case OR: |
| case IMPLY: |
| case UNTIL: |
| assert( topASTNode->left != NULL ); |
| assert( topASTNode->right != NULL ); |
| return checkAllBoolHaveAIGPointer( topASTNode->left ) && checkAllBoolHaveAIGPointer( topASTNode->right ); |
| |
| case NOT: |
| case NEXT: |
| case GLOBALLY: |
| case EVENTUALLY: |
| assert( topASTNode->left != NULL ); |
| assert( topASTNode->right == NULL ); |
| return checkAllBoolHaveAIGPointer( topASTNode->left ); |
| default: |
| printf("\nUNSUPPORTED LTL NODE TYPE:: Aborting execution\n"); |
| exit(0); |
| } |
| } |
| |
| void setAIGNodePtrOfGloballyNode( ltlNode *astNode, Aig_Obj_t *pObjLo ) |
| { |
| astNode->pObj = pObjLo; |
| } |
| |
| Aig_Obj_t *retriveAIGPointerFromLTLNode( ltlNode *astNode ) |
| { |
| return astNode->pObj; |
| } |
| |
| |
| ABC_NAMESPACE_IMPL_END |