void CollisionManager::update(float dt) { bulletToStatic(); bulletToDynamic(); dynamicToStatic(); dynamicTodynamic(); }
// a != b → R( a, i_{a,b} ) = R( b, i_{a,b} ) void Egraph::ExtAxiom( Enode * a, Enode * b ) { assert( isDynamic( a ) ); assert( isDynamic( b ) ); Enode * as = dynamicToStatic( a ); Enode * bs = dynamicToStatic( b ); assert( isStatic( as ) ); assert( isStatic( bs ) ); assert( as->isDTypeArray( ) ); assert( bs->isDTypeArray( ) ); // create fresh index i_a,b for pair a,b char def_name[ 48 ]; sprintf( def_name, IND_STR, as->getId( ), bs->getId( ) ); const unsigned type = DTYPE_ARRAY_INDEX; if ( lookupSymbol( def_name ) == NULL ) newSymbol( def_name, type ); // Create new variable Enode * i = mkVar( def_name ); // Create two new selections Enode * select1 = mkSelect( as, i ); Enode * select2 = mkSelect( bs, i ); // Create new literals Enode * lit1 = mkEq( cons( as, cons( bs ) ) ); Enode * lit2_pos = mkEq( cons( select1, cons( select2 ) ) ); Enode * lit2 = mkNot( cons( lit2_pos ) ); #ifdef PRODUCE_PROOF if ( config.gconfig.print_inter > 0 ) { const uint64_t shared = getIPartitions( as ) & getIPartitions( bs ); // Mixed can't be one at this point assert( shared != 1 ); // Set AB-mixed partition if no intersection if ( shared == 0 ) { setIPartitions( i, 1 ); setIPartitions( select1, 1 ); setIPartitions( select2, 1 ); setIPartitions( lit1, 1 ); setIPartitions( lit2_pos, 1 ); setIPartitions( lit2, 1 ); } // Otherwise they share something else { setIPartitions( i, shared ); setIPartitions( select1, shared ); setIPartitions( select2, shared ); setIPartitions( lit1, shared ); setIPartitions( lit2_pos, shared ); setIPartitions( lit2, shared ); } } #endif vector< Enode * > v; v.push_back( lit1 ); v.push_back( lit2 ); #ifdef ARR_VERB cout << "Axiom Ext -> " << "( or " << lit1 << " " << lit2 << " )" << endl; #endif splitOnDemand( v, id ); handleArrayAssertedAtomTerm( select1 ); handleArrayAssertedAtomTerm( select2 ); // New contexts to propagate info about new index // Given R(a,new) look for all store users W(a,i,e) // and instantiate RoW over R(W(a,i,e),new) vector< Enode * > sela; vector< Enode * > stoa; vector< Enode * > selb; vector< Enode * > stob; Enode * select3 = NULL; // Act over a getUsers( a, sela, stoa ); for( size_t j = 0 ; j < stoa.size( ) ; j++ ) { assert( isDynamic( stoa[ j ] ) ); Enode * ss = dynamicToStatic( stoa[ j ] ); assert( isStatic( ss ) ); // Creation new select for each store user of a select3 = mkSelect( ss, i ); // RoW over new select handleArrayAssertedAtomTerm( select3 ); #ifdef PRODUCE_PROOF if ( config.gconfig.print_inter > 0 ) { const uint64_t shared = getIPartitions( ss ) & getIPartitions( i ); // Mixed can't be one at this point assert( shared != 1 ); // Set AB-mixed partition if no intersection if ( shared == 0 ) setIPartitions( select3, 1 ); // Otherwise they share something else setIPartitions( select3, shared ); } #endif } // Act over b getUsers( b, selb, stob ); for ( size_t j = 0 ; j < stob.size( ) ; j++ ) { assert( isDynamic( stoa[ j ] ) ); Enode * ss = dynamicToStatic( stob[ j ] ); assert( isStatic( ss ) ); // Creation new select for each store user of b select3 = mkSelect( ss, i ); #ifdef PRODUCE_PROOF if ( config.gconfig.print_inter > 0 ) { const uint64_t shared = getIPartitions( ss ) & getIPartitions( i ); // Mixed can't be one at this point assert( shared != 1 ); // Set AB-mixed partition if no intersection if ( shared == 0 ) setIPartitions( select3, 1 ); // Otherwise they share something else setIPartitions( select3, shared ); } #endif // RoW over new select handleArrayAssertedAtomTerm( select3 ); } }
void Egraph::handleArrayMerge( Enode * x, Enode * y ) { assert( ( x->isDTypeArray( ) && y->isDTypeArray( ) ) || ( x->isDTypeArrayElement( ) && y->isDTypeArrayElement( ) ) ); vector< Enode * > xSelUsers, xStoUsers; getUsers( x, xSelUsers, xStoUsers ); vector<Enode * >::iterator xSelUsersIt; vector<Enode * >::iterator xStoUsersIt; vector< Enode * > ySelUsers, yStoUsers; getUsers( y, ySelUsers, yStoUsers ); vector<Enode * >::iterator ySelUsersIt; vector<Enode * >::iterator yStoUsersIt; #ifdef ARR_VERB_POSTMERGE cout << endl << "Getting x and y equivalence class users: " << endl; cout << "Equivalence class of x is: " << endl; Enode * aux=x; do { cout << aux << " "; aux=aux->getNext(); } while(aux!=x); cout << endl << "Here are x class select users: " << endl; for ( xSelUsersIt = xSelUsers.begin( ); xSelUsersIt != xSelUsers.end( ); xSelUsersIt++ ) {cout << *xSelUsersIt << " ";} cout << endl << "Here are x class store users: " << endl; for ( xStoUsersIt = xStoUsers.begin( ); xStoUsersIt != xStoUsers.end( ); xStoUsersIt++ ) {cout << *xStoUsersIt << " ";} cout << endl << "Equivalence class of y is: " << endl; aux=y; do { cout << aux << " "; aux=aux->getNext(); } while(aux!=y); cout << endl << "Here are y class select users: " << endl; for ( ySelUsersIt = ySelUsers.begin( ); ySelUsersIt != ySelUsers.end( ); ySelUsersIt++ ) {cout << *ySelUsersIt << " ";} cout << endl << "Here are y class store users: " << endl; for ( yStoUsersIt = yStoUsers.begin( ); yStoUsersIt != yStoUsers.end( ); yStoUsersIt++ ) {cout << *yStoUsersIt << " ";} cout << endl << endl; #endif Enode * z, * zIndex; // , * zElement, * zArray, // TODO join all the cases together for more efficiency // NB x,y are elements of equivalence classes X,Y, we need to scan X or Y looking for store terms if( y->isDTypeArray() ) { // Case 1: x is b, y is W(a,i,e), exists z as R(b,j) // Scan all R(b,j) for ( xSelUsersIt = xSelUsers.begin( ) ; xSelUsersIt != xSelUsers.end( ) ; xSelUsersIt++ ) { z = * xSelUsersIt; zIndex = z->get2nd( ); // scan Y looking for store terms Enode * YElem = y; do { if( YElem->isStore( ) ) { #ifdef ARR_VERB cout << "Arrow down B: " << x << " W(A,I,E): " << YElem << " R(B,J): " << z << endl; #endif // create new term R(W(a,i,e),j) Enode * s_yelem = dynamicToStatic( YElem ); Enode * s_z2nd = dynamicToStatic( z->get2nd( ) ); Enode * select = mkSelect( s_yelem, s_z2nd ); #ifdef PRODUCE_PROOF if ( config.gconfig.print_inter > 0 ) { const uint64_t shared = getIPartitions( s_yelem ) & getIPartitions( s_z2nd ); // Mixed can't be one at this point assert( shared != 1 ); // Set AB-mixed partition if no intersection if ( shared == 0 ) setIPartitions( select, 1 ); // Otherwise they share something else setIPartitions( select, shared ); } #endif handleArrayAssertedAtomTerm( select ); } YElem = YElem->getNext( ); } while ( YElem != y ); } /*// Case 2: x is b, y is W(a,i,e), exists z as W(b,j,f) // Scan all W(b,j,f) for (xStoUsersIt=xStoUsers.begin(); xStoUsersIt<xStoUsers.end(); xStoUsersIt++) { z=*xStoUsersIt; zElement=z->get3rd(); zIndex=z->get2nd(); // create new term W(W(a,i,e),j,f) newSto=mkStore(y,zIndex,zElement,present); // TODO check if term already seen in a previous assertion on the current path // deduce clauses for the new store newArrayDed(newSto); }*/ } if( x->isDTypeArray() ) { // Case 1 reverse: y is b, x is W(a,i,e), exists z as R(b,j) // Scan all R(b,j) for ( ySelUsersIt = ySelUsers.begin( ) ; ySelUsersIt != ySelUsers.end( ) ; ySelUsersIt++ ) { z = *ySelUsersIt; zIndex = z->get2nd( ); // scan X looking for store terms Enode * XElem = x; do { if( XElem->isStore( ) ) { #ifdef ARR_VERB cout << "Arrow down B: " << XElem << " W(A,I,E): " << y << " R(B,J): " << z << endl; #endif // Create new term R(W(a,i,e),j) from static version Enode * s_xelem = dynamicToStatic( XElem ); Enode * s_z2nd = dynamicToStatic( z->get2nd( ) ); Enode * select = mkSelect( s_xelem, s_z2nd ); #ifdef PRODUCE_PROOF if ( config.gconfig.print_inter > 0 ) { const uint64_t shared = getIPartitions( s_xelem ) & getIPartitions( s_z2nd ); // Mixed can't be one at this point assert( shared != 1 ); // Set AB-mixed partition if no intersection if ( shared == 0 ) setIPartitions( select, 1 ); // Otherwise they share something else setIPartitions( select, shared ); } #endif handleArrayAssertedAtomTerm( select ); } XElem = XElem->getNext( ); } while ( XElem != x ); } /*// Case 2 reverse: y is a term b of type array, x is a Store W(a,i,e), exists z as W(b,j,f) // Scan all W(b,j,f) for (yStoUsersIt=yStoUsers.begin(); yStoUsersIt<yStoUsers.end(); yStoUsersIt++) { z=*yStoUsersIt; zElement=z->get3rd(); zIndex=z->get2nd(); // create new term W(W(a,i,e),j,f) newSto=mkStore(y,zIndex,zElement,present); // TODO check if term already seen in a previous assertion on the current path // deduce clauses for the new store newArrayDed(newSto); }*/ } Enode * w; if( x->isDTypeArray( ) && y->isDTypeArray( ) ) { //Case 3: x is a term a of type array, y is a term b of type array, exist z as W(a,i,e) and w as R(b,j) //scan all W(a,i,e) and R(b,j) for ( ySelUsersIt = ySelUsers.begin( ) ; ySelUsersIt < ySelUsers.end( ) ; ySelUsersIt++ ) { for ( xStoUsersIt = xStoUsers.begin( ) ; xStoUsersIt < xStoUsers.end( ) ; xStoUsersIt++ ) { w = *ySelUsersIt; z = *xStoUsersIt; #ifdef ARR_VERB cout << "Arrow up A: " << x << " B: " << y << " W(A,I,E): " << z << " R(B,J): " << w << endl; #endif // create new term R(W(a,i,e),j) Enode * s_z = dynamicToStatic( z ); Enode * s_w2nd = dynamicToStatic( w->get2nd( ) ); Enode * select = mkSelect( s_z, s_w2nd ); #ifdef PRODUCE_PROOF if ( config.gconfig.print_inter > 0 ) { const uint64_t shared = getIPartitions( s_z ) & getIPartitions( s_w2nd ); // Mixed can't be one at this point assert( shared != 1 ); // Set AB-mixed partition if no intersection if ( shared == 0 ) setIPartitions( select, 1 ); // Otherwise they share something else setIPartitions( select, shared ); } #endif handleArrayAssertedAtomTerm( select ); } } //Case 3 reverse: y is a term a of type array, x is a term b of type array, exist z as W(a,i,e) and w as R(b,j) //scan all W(a,i,e) and R(b,j) for ( xSelUsersIt = xSelUsers.begin( ) ; xSelUsersIt < xSelUsers.end( ) ; xSelUsersIt++ ) { for ( yStoUsersIt = yStoUsers.begin( ) ; yStoUsersIt < yStoUsers.end( ) ; yStoUsersIt++) { w = *xSelUsersIt; z = *yStoUsersIt; #ifdef ARR_VERB cout << "Arrow up A: " << x << " B: " << y << " W(A,I,E): "<< z << " R(B,J): " << w << endl; #endif // create new term R(W(a,i,e),j) Enode * s_z = dynamicToStatic( z ); Enode * s_w2nd = dynamicToStatic( w->get2nd( ) ); Enode * select = mkSelect( s_z, s_w2nd ); #ifdef PRODUCE_PROOF if ( config.gconfig.print_inter > 0 ) { const uint64_t shared = getIPartitions( s_z ) & getIPartitions( s_w2nd ); // Mixed can't be one at this point assert( shared != 1 ); // Set AB-mixed partition if no intersection if ( shared == 0 ) setIPartitions( select, 1 ); // Otherwise they share something else setIPartitions( select, shared ); } #endif handleArrayAssertedAtomTerm( select ); } } } /*//Case 4: x is a term e of type element, y is a Select R(b,j), exists z as W(a,i,e) //scan all W(a,i,e) if(y->isSelect()) { for (xStoUsersIt=xStoUsers.begin(); xStoUsersIt<xStoUsers.end(); xStoUsersIt++) { z=*xStoUsersIt; zArray=z->get1st(); zIndex=z->get2nd(); // create new term W(a,i,R(b,j)) newSto=mkStore(zArray,zIndex,y); // TODO check if term already seen in a previous assertion on the current path // deduce clauses for the new store newArrayDed(newSto); } } //Case 4 reverse: y is a term e of type element, x is a Select R(b,j), exists z as W(a,i,e) //scan all W(a,i,e) if(x->isSelect()) { for (yStoUsersIt=yStoUsers.begin(); yStoUsersIt<yStoUsers.end(); yStoUsersIt++) { z=*yStoUsersIt; zArray=z->get1st(); zIndex=z->get2nd(); // create new term W(a,i,R(b,j)) newSto=mkStore(zArray,zIndex,x); // TODO check if term already seen in a previous assertion on the current path // deduce clauses for the new store newArrayDed(newSto); } }*/ }