// ∀a, i, b, j. ( a = b → i = j → W (a, i, R(b, j)) = a ) void Egraph::WoRAxiom( Enode * wor ) { assert( false ); Enode * a = wor->get1st( ); Enode * i = wor->get2nd( ); Enode * worElement = wor->get3rd( ); Enode * b = worElement->get1st( ); Enode * j = worElement->get2nd( ); assert( worElement->isDTypeArrayElement( ) ); assert( a->isDTypeArray( ) ); assert( i->isDTypeArrayIndex( ) ); assert( b->isDTypeArray( ) ); assert( j->isDTypeArrayIndex( ) ); // create term W(a,i,R(b,j)) Enode * select = mkSelect( b, j ); Enode * store = mkStore(a,i,select); // add clause IF a=b THEN IF i=j THEN W(a,i,R(b,j))=a // that is (NOT(a=b) OR NOT(i=j) OR W(a,i,R(b,j))=a) vector< Enode * > v; Enode * lit1 = mkNot(cons(mkEq(cons(a,cons(b))))); Enode * lit2 = mkNot(cons(mkEq(cons(i,cons(j))))); Enode * lit3 = mkEq(cons(store,cons(a))); v.push_back( lit1 ); v.push_back( lit2 ); v.push_back( lit3 ); #ifdef ARR_VERB cout << "Axiom WoR -> " << "(or " << lit1 << " " << lit2 << " " << lit3 << " )" << endl; #endif splitOnDemand( v, id ); handleArrayAssertedAtomTerm( a ); }
//∀a, i, e, j, f i != j → W (W (a, i, e), j, f ) = W (W (a, j, f ), i, e) void Egraph::WoWNeqAxiom( Enode * wow ) { assert( false ); Enode * wowArray = wow->get1st( ); Enode * a = wowArray->get1st( ); Enode * i = wowArray->get2nd( ); Enode * e = wowArray->get3rd( ); Enode * j = wow->get2nd( ); Enode * f = wow->get3rd( ); assert( wowArray->isDTypeArray( ) ); assert( a->isDTypeArray( ) ); assert( i->isDTypeArrayIndex( ) ); assert( e->isDTypeArrayElement( ) ); assert( j->isDTypeArrayIndex( ) ); assert( f->isDTypeArrayElement( ) ); // Case i, j not coincident if( i != j ) { // create term W(W(a,j,f),i,e) Enode * store1 = mkStore(a,j,f); Enode * store2 = mkStore(store1,i,e); // add clause IF i!=j THEN W(W(a,i,e),j,f)=W(W(a,j,f),i,e) // that is (i=j OR W(W(a,i,e),j,f)=W(W(a,j,f),i,e)) vector< Enode * > v; Enode * lit1 = mkEq(cons(i,cons(j))); Enode * lit2 = mkEq(cons(wow,cons(store2))); v.push_back( lit1 ); v.push_back( lit2 ); #ifdef ARR_VERB cout << "Axiom WoW!= -> " << "(or " << lit1 << " " << lit2 << " )" << endl; #endif splitOnDemand( v, id ); handleArrayAssertedAtomTerm(store2); } }
// ∀a, i, e, j, f. ( i = j → W ( W ( a, i, e ), j, f ) = W ( a, j, f ) ) void Egraph::WoWEqAxiom( Enode * wow ) { assert( false ); Enode * wowArray = wow->get1st( ); Enode * a = wowArray->get1st( ); Enode * i = wowArray->get2nd( ); Enode * e = wowArray->get3rd( ); Enode * j = wow->get2nd( ); Enode * f = wow->get3rd( ); assert( wowArray->isDTypeArray( ) ); assert( a->isDTypeArray( ) ); assert( i->isDTypeArrayIndex( ) ); assert( e->isDTypeArrayElement( ) ); assert( j->isDTypeArrayIndex( ) ); assert( f->isDTypeArrayElement( ) ); //i,j not coincident if( i != j ) { // create term W(a,j,f) Enode * store = mkStore( a, j, f ); #ifdef PRODUCE_PROOF if ( config.gconfig.print_inter > 0 ) { const uint64_t shared = getIPartitions( a ) & getIPartitions( j ) & getIPartitions( f ); // Mixed can't be one at this point assert( shared != 1 ); // Set AB-mixed partition if no intersection if ( shared == 0 ) setIPartitions( store, 1 ); // Otherwise they share something else setIPartitions( store, shared ); } #endif // add clause IF i=j THEN W(W(a,i,e),j,f)=W(a,j,f) // that is (NOT(i=j) OR W(W(a,i,e),j,f)=W(a,j,f)) vector< Enode * > v; Enode * lit1_pos = mkEq( cons( i, cons( j ) ) ); Enode * lit1 = mkNot( cons( lit1_pos ) ); #ifdef PRODUCE_PROOF if ( config.gconfig.print_inter > 0 ) { const uint64_t shared = getIPartitions( i ) & getIPartitions( j ); // Mixed can't be one at this point assert( shared != 1 ); // Set AB-mixed partition if no intersection if ( shared == 0 ) { setIPartitions( lit1_pos, 1 ); setIPartitions( lit1, 1 ); } // Otherwise they share something else { setIPartitions( lit1_pos, shared ); setIPartitions( lit1, shared ); } } #endif Enode * lit2 = mkEq( cons( wow, cons( store ) ) ); #ifdef PRODUCE_PROOF if ( config.gconfig.print_inter > 0 ) { const uint64_t shared = getIPartitions( wow ) & getIPartitions( store ); // Mixed can't be one at this point assert( shared != 1 ); // Set AB-mixed partition if no intersection if ( shared == 0 ) setIPartitions( lit2, 1 ); // Otherwise they share something else setIPartitions( lit2, shared ); } #endif v.push_back( lit1 ); v.push_back( lit2 ); #ifdef ARR_VERB cout << "Axiom WoW= -> " << "(or " << lit1 << " " << lit2 << " )" << endl; #endif splitOnDemand( v, id ); handleArrayAssertedAtomTerm( store ); } }