예제 #1
0
// ∀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 );
}
예제 #2
0
//∀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);
  }
}
예제 #3
0
// ∀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 );
  }
}
예제 #4
0
// 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 );
  }
}