removing SATPlan and adding conda and sypet
[Benchmarks_CSolver.git] / satPlan2006 / include / graph.c
diff --git a/satPlan2006/include/graph.c b/satPlan2006/include/graph.c
deleted file mode 100644 (file)
index bb88057..0000000
+++ /dev/null
@@ -1,1040 +0,0 @@
-
-/*********************************************************************
- * (C) Copyright 2002 Albert Ludwigs University Freiburg
- *     Institute of Computer Science
- *
- * All rights reserved. Use of this software is permitted for 
- * non-commercial research purposes, and it may be copied only 
- * for that use.  All copies must include this copyright message.
- * This software is made available AS IS, and neither the authors
- * nor the  Albert Ludwigs University Freiburg make any warranty
- * about the software or its performance. 
- *********************************************************************/
-
-
-
-
-
-/*********************************************************************
- * File: graph.c
- * Description: (initial build of) the planning graph
- *
- * Author: Joerg Hoffmann 2002
- *
- *********************************************************************/ 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#include "bb.h"
-
-#include "output.h"
-#include "memory.h"
-
-#include "instantiateI.h"
-#include "instantiateII.h"
-
-#include "graph.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Bool build_graph( int *min_time )
-
-{
-
-  int time = 0, i, ft;
-  IntList *tmp;
-  Bool reached_goals = FALSE, first = TRUE;
-
-  /* put all ops into a list so that we can directly access
-   * those that are not yet in the graph
-   */
-  for ( i = 0; i < gnum_op_conn; i++ ) {
-    tmp = new_IntList( i );
-    if ( gout_ops ) {
-      gout_ops->prev = tmp;
-    }
-    tmp->next = gout_ops;
-    gout_ops = tmp;
-  }
-
-  /* for ini fts, say that they appear, put them into graph fts list,
-   * insert their bits
-   */
-  for ( i = 0; i < ginitial_state.num_F; i++ ) {
-    ft = ginitial_state.F[i];
-    gin_ft_count++;
-    gft_conn[ft].first_appearance = 0;
-    gft_conn[ft].info_at[0] = new_FtLevelInfo();
-    tmp = new_IntList( ft );
-    tmp->next = gin_fts;
-    gin_fts = tmp;
-  }
-  gin_fts_at[0] = gin_fts;
-
-  if ( gcmd_line.display_info ) {
-    printf("\ntime: %3d, %5d facts and %7d exclusive pairs",
-            time, gin_ft_count, gin_ft_exclusion_count);
-    fflush(stdout);
-  }
-
-  for( ; time < *min_time; time++ ) {
-    if ( first ) {
-      reached_goals = are_there_non_exclusive( time, gbit_goal_state,
-                                              ggoal_state.F, ggoal_state.num_F );
-      if ( reached_goals ) {
-       if ( gcmd_line.display_info ) {
-         printf("\ngoals first reachable in %d time steps\n\n", time);
-          first = FALSE;
-         fflush(stdout);
-       }
-      }
-    }
-    if ( gsame_as_prev_flag ) break;
-    build_graph_evolution_step();
-  }
-  
-  for( ; time < MAX_GRAPH; time++ ) {
-    reached_goals = are_there_non_exclusive( time, gbit_goal_state,
-                                            ggoal_state.F, ggoal_state.num_F );
-    if ( reached_goals ) {
-      if ( gcmd_line.display_info && first ) {
-        printf("\ngoals first reachable in %d time steps\n\n", time);
-       fflush(stdout);
-      }
-      break;
-    }
-    if ( gsame_as_prev_flag ) break;
-    build_graph_evolution_step();
-  }
-
-  *min_time = time;
-  return reached_goals;
-
-}
-
-
-
-void build_graph_evolution_step( void )
-
-{
-
-  static int time = 0;
-  int in_ft_count = gin_ft_count, in_ft_exclusion_count = gin_ft_exclusion_count;
-  IntList *il, *tmp, *il2;
-
-  if ( time > MAX_GRAPH ) {
-    printf("\nEXIT: max graph size exceeded!\n\n");
-    exit( 1 );
-  }
-
-  if ( gsame_as_prev_flag ) {
-    copy_graph_layer( time );
-    if ( gcmd_line.display_info ) {
-      printf("\n           %5d ops   and %7d exclusive pairs", gin_op_count, gin_op_exclusion_count);
-      printf("\ntime: %3d, %5d facts and %7d exclusive pairs", time+1, gin_ft_count, gin_ft_exclusion_count);
-      fflush(stdout);
-    }
-    time++;
-    return;
-  }
-
-  /* extend op level infos (for already in ops)
-   */
-  for ( il = gin_ops; il; il = il->next ) {
-    gop_conn[il->i1].info_at[time] = new_OpLevelInfo();
-  }
-  /* likewise for facts
-   */
-  for ( il = gin_fts; il; il = il->next ) {
-    gft_conn[il->i1].info_at[time+1] = new_FtLevelInfo();
-    /* we also need to transfer the adders we already have to the new level.
-     *
-     * attention: like this, order is kept constant (seems cleaner...)
-     * (in particular, the NOOP remains first in list)
-     */
-    for ( il2 = gft_conn[il->i1].info_at[time]->A; il2; il2 = il2->next ) {
-      if ( !gft_conn[il->i1].info_at[time+1]->A ) {
-       gft_conn[il->i1].info_at[time+1]->A = new_IntList( il2->i1 );
-       gft_conn[il->i1].info_at[time+1]->end_A = gft_conn[il->i1].info_at[time+1]->A;
-/*     gft_conn[il->i1].info_at[time+1]->num_A = 1; */
-      } else {
-       gft_conn[il->i1].info_at[time+1]->end_A->next = new_IntList( il2->i1 );
-       gft_conn[il->i1].info_at[time+1]->end_A = gft_conn[il->i1].info_at[time+1]->end_A->next;
-/*     gft_conn[il->i1].info_at[time+1]->num_A++; */
-      }
-    }
-    /* ... and the same for the ops we are precond of, if we've been there before
-     */
-    if ( gft_conn[il->i1].first_appearance >= time ) continue;
-    for ( il2 = gft_conn[il->i1].info_at[time-1]->P; il2; il2 = il2->next ) {
-      tmp = new_IntList( il2->i1 );
-      tmp->next = gft_conn[il->i1].info_at[time]->P;
-      gft_conn[il->i1].info_at[time]->P = tmp;
-    }
-  }
-
-  /* update the pointers as to which ops/fts we had already previously
-   */
-  gin_prev_ops = gin_ops;
-  gin_prev_fts = gin_fts;
-
-  /* now try to apply all ops that are still out --- as given by resp. list
-   * --- and remove them from the list, if they are applicable.
-   *
-   * side effects are that the new ops have their uid blocks and masks set,
-   * and that the new facts are declared (in particular, gin_ft_count
-   * is incremented in that case), and that the resp. new add *edges* in the ft level 
-   * infos are inserted --- not the resp. bits; these are updated below,
-   * after allocating bit strings of appropriate size.
-   */
-  il = gout_ops;
-  while ( il ) {
-    if ( apply_operator( time, il->i1 ) ) {
-      gnum_ops++;
-      if ( gop_conn[il->i1].uid_block > gmax_block ) {
-       gmax_block = gop_conn[il->i1].uid_block;
-      }
-      if ( il->prev ) {
-       il->prev->next = il->next;
-      } else {
-       gout_ops = il->next;
-      }
-      if ( il->next ) {
-       il->next->prev = il->prev;
-      }
-      tmp = il;
-      il = il->next;
-      free( tmp );
-    } else {
-      il = il->next;
-    }
-  }
-
-  /* for access later, remember what the ops n fts are at this point.
-   */
-  gin_ops_at[time] = gin_ops;
-  gin_fts_at[time+1] = gin_fts;
-
-  /* now determine op string length, allocate the op bit strings, 
-   * and insert the bit_A information in the ft level infos!
-   *
-   * IMPLEMENT MORE EFFICIENTLY! if 1st action happens to be last in opconn,
-   * then we got all the bitstrings here already!
-   */
-  gnum_op_bit_at[time] = gmax_block + 1;
-
-  for ( il = gin_ops; il; il = il->next ) {
-    gop_conn[il->i1].info_at[time]->bit_exclusives = 
-      new_BitVector( gnum_op_bit_at[time] );
-  }
-  /* allocate adders and adders-excl space, setup adders simply by
-   * setting the respective bits in the list. 
-   *
-   * other option would be, see dir 2nd, to copy adders over for
-   * previously present facts.
-   * favor this option cause it's conceptually simpler and probably
-   * doesn't make much difference anyway.
-   */
-  for ( il = gin_fts; il; il = il->next ) {
-    gft_conn[il->i1].info_at[time+1]->bit_A = 
-      new_BitVector( gnum_op_bit_at[time] );
-    for ( il2 = gft_conn[il->i1].info_at[time+1]->A; il2; il2 = il2->next ) {
-      gft_conn[il->i1].info_at[time+1]->bit_A[gop_conn[il2->i1].uid_block] |=
-       gop_conn[il2->i1].uid_mask;
-    }
-    gft_conn[il->i1].info_at[time+1]->bit_A_exclusives = 
-      new_BitVector( gnum_op_bit_at[time] );
-  }
-
-  /* now do the mutex reasoning for the new graph layer
-   */
-  find_mutex_ops( time );
-  /* DIFFERENCE TO IPP where it's time + 1;
-   * supposed to improve readability of the code, by sticking to
-   * opslevel time, ft level time+1 convention.
-   */
-  find_mutex_fts( time );
-
-  if ( in_ft_count == gin_ft_count && in_ft_exclusion_count == gin_ft_exclusion_count ) {
-    gsame_as_prev_flag = TRUE;
-    if ( gcmd_line.display_info ) {
-      printf("\ngraph has leveled off at time step %d\n\n", time+1);
-      fflush(stdout);
-    }
-    gfirst_full_time = time;
-  }
-
-  if ( gcmd_line.display_info ) {
-    printf("\n           %5d ops   and %7d exclusive pairs", gin_op_count, gin_op_exclusion_count);
-    printf("\ntime: %3d, %5d facts and %7d exclusive pairs", time+1, gin_ft_count, gin_ft_exclusion_count);
-    fflush(stdout);
-  }
-
-  time++;
-
-}
-
-
-
-Bool apply_operator( int time, int op )
-
-{
-
-  static Bool fc = TRUE;
-  static BitVector *bit_P_exclusives;
-  int i, j, ft;
-  IntList *tmp;
-
-  if ( fc ) {
-    bit_P_exclusives = new_BitVector( gnum_ft_bit );
-    fc = FALSE;
-  } else {
-    for ( i = 0; i < gnum_ft_bit; i++ ){
-      bit_P_exclusives[i] = 0;
-    }
-  }
-
-  /* check if precs are there, and at same time get the 
-   * vector repres. of their exclusives
-   */
-  if ( !get_them_non_exclusive( time, gop_conn[op].bit_P,
-                               gop_conn[op].P, gop_conn[op].num_P,
-                               &bit_P_exclusives ) ) {
-    return FALSE;
-  }
-
-  /* "insert" that op at this point into the graph
-   */
-  gop_conn[op].uid_block = ( int ) gin_op_count / gcword_size;
-  gop_conn[op].uid_mask = 1 << ( gin_op_count % gcword_size );  
-  gin_op_count++;
-  gop_conn[op].first_appearance = time;
-  gop_conn[op].info_at[time] = new_OpLevelInfo();
-  for ( i = 0; i < time; i++ ) {
-    /* probably unnecessary... just to be nice and clean
-     */
-    gop_conn[op].info_at[i] = NULL;
-  }
-  tmp = new_IntList( op );
-  tmp->next = gin_ops;
-  gin_ops = tmp;
-  /* some more semantical stuff here:
-   *
-   * insert the prec. exclusives in the resp. level info
-   */
-  for ( i = 0; i < gnum_ft_bit; i++ ){
-    gop_conn[op].info_at[time]->bit_P_exclusives[i] = bit_P_exclusives[i];
-  }
-  /* insert the op into the list of ops that the Ps are P of at this point
-   */
-  for ( i = 0; i < gop_conn[op].num_P; i++ ) {
-    ft = gop_conn[op].P[i];
-    tmp = new_IntList( op );
-    tmp->next = gft_conn[ft].info_at[time]->P;
-    gft_conn[ft].info_at[time]->P = tmp;
-  }
-  /* now declare the existence of the new incoming add effects
-   */
-  for ( i = 0; i < gop_conn[op].num_A; i++ ) {
-    ft = gop_conn[op].A[i];
-    if ( gft_conn[ft].first_appearance == -1 ) {
-      /* new fact!
-       */
-      gin_ft_count++;
-      gft_conn[ft].first_appearance = time + 1;
-      gft_conn[ft].info_at[time+1] = new_FtLevelInfo();
-      for ( j = 0; j < time + 1; j++ ) {
-       /* again, probably unnecessary... just to be nice and clean
-        */
-       gft_conn[ft].info_at[j] = NULL;
-      }
-      tmp = new_IntList( ft );
-      tmp->next = gin_fts;
-      gin_fts = tmp;
-    }
-    /* now insert the new (possibly first) adder!
-     * (remember that for alreay existing fts the previous adders have already
-     * been inserted above when starting graph evolution step)
-     * 
-     * if adder is "real", insert at end of list, if it is the NOOP, then insert
-     * it at start --> the NOOPs are directly accessible as the first list 
-     * element.
-     */
-    if ( gft_conn[ft].info_at[time+1]->A ) {
-      if ( gop_conn[op].noop_for != -1 ) {
-       tmp = new_IntList( op );
-       tmp->next = gft_conn[ft].info_at[time+1]->A;
-       gft_conn[ft].info_at[time+1]->A = tmp;
-/*     gft_conn[ft].info_at[time+1]->num_A++; */
-      } else {
-       gft_conn[ft].info_at[time+1]->end_A->next = new_IntList( op );
-       gft_conn[ft].info_at[time+1]->end_A = gft_conn[ft].info_at[time+1]->end_A->next;
-/*     gft_conn[ft].info_at[time+1]->num_A++; */
-      }
-    } else {
-      gft_conn[ft].info_at[time+1]->A = new_IntList( op );
-      gft_conn[ft].info_at[time+1]->end_A = gft_conn[ft].info_at[time+1]->A;
-/*        gft_conn[ft].info_at[time+1]->num_A = 1; */
-    }
-  }
-
-  return TRUE;
-
-}
-
-
-
-Bool are_there_non_exclusive( int time, BitVector *bits, int *F, int num_F )
-
-{
-
-  BitVector *a;
-  int i, j;
-
-  for ( i = 0; i < num_F; i++ ) {
-    if ( gcmd_line.debug == 1 ) {
-      printf("\nchecking appearance of goal fact at %d: ", time);
-      print_ft_name( F[i] );
-    }
-    if ( gft_conn[F[i]].first_appearance == -1 ||
-        gft_conn[F[i]].first_appearance > time ) {
-      return FALSE;
-    }
-  }
-
-  /* geht das EFFIZIENTER durch zusammen OR-en der exclusives??
-   */
-  for ( i = 0; i < num_F; i++ ) {
-    a = gft_conn[F[i]].info_at[time]->bit_exclusives;
-    for ( j = 0; j < gnum_ft_bit; j++ ) {
-      if ( bits[j] & a[j] ) {
-       return FALSE;
-      }
-    }
-  }
-    
-  return TRUE;
-
-}
-
-
-
-Bool get_them_non_exclusive( int time, BitVector *bits, int *F, int num_F, BitVector **bit_P_exclusives )
-
-{
-
-  int i, j;
-
-  for ( i = 0; i < num_F; i++ ) {
-    if ( gcmd_line.debug == 2 ) {
-      printf("\nchecking appearance of prec fact at %d: ", time);
-      print_ft_name( F[i] );
-    }
-    if ( gft_conn[F[i]].first_appearance == -1 ||
-        gft_conn[F[i]].first_appearance > time ) {
-      return FALSE;
-    }
-  }
-
-  /* determine the vector of all facts that the elements of F are exclusive of
-   * --> this will be stored in the op's level specific info (prec exclusives)
-   * 
-   * if one of these is contained in F, then fail.
-   */
-  for ( i = 0; i < num_F; i++ ) {
-    for ( j = 0; j < gnum_ft_bit; j++ ) {
-      (*bit_P_exclusives)[j] |= gft_conn[F[i]].info_at[time]->bit_exclusives[j];
-      if ( bits[j] & (*bit_P_exclusives)[j] ) {
-       return FALSE;
-      }
-    }
-  }
-    
-  return TRUE;
-
-}
-
-
-
-/* we must build the graph beyond the fixpoint as the 
- * constraint system is dynamic beyond.
- */
-void copy_graph_layer( int time )
-
-{
-
-  IntList *il, *tmp, *il2;
-  int i;
-
-  gin_ops_at[time] = gin_ops_at[time-1];
-  gin_fts_at[time+1] = gin_fts_at[time];
-  gnum_op_bit_at[time] = gnum_op_bit_at[time-1];
-
-  for ( il = gin_ops; il; il = il->next ) {
-    gop_conn[il->i1].info_at[time] = new_OpLevelInfo();
-    gop_conn[il->i1].info_at[time]->bit_exclusives = new_BitVector( gnum_op_bit_at[time] );
-    for ( i = 0; i < gnum_op_bit_at[time]; i++ ) {
-      gop_conn[il->i1].info_at[time]->bit_exclusives[i] = 
-       gop_conn[il->i1].info_at[time-1]->bit_exclusives[i];
-    }
-    /* P excl vec already allocated
-     */
-    for ( i = 0; i < gnum_ft_bit; i++ ) {
-      gop_conn[il->i1].info_at[time]->bit_P_exclusives[i] = 
-       gop_conn[il->i1].info_at[time-1]->bit_P_exclusives[i];
-    }
-  }
-  /* likewise for facts
-   */
-  for ( il = gin_fts; il; il = il->next ) {
-    gft_conn[il->i1].info_at[time+1] = new_FtLevelInfo();
-    gft_conn[il->i1].info_at[time+1]->bit_A = new_BitVector( gnum_op_bit_at[time] );
-    for ( i = 0; i < gnum_op_bit_at[time]; i++ ) {
-      gft_conn[il->i1].info_at[time+1]->bit_A[i] = 
-       gft_conn[il->i1].info_at[time]->bit_A[i];
-    }
-    gft_conn[il->i1].info_at[time+1]->bit_A_exclusives = new_BitVector( gnum_op_bit_at[time] );
-    for ( i = 0; i < gnum_op_bit_at[time]; i++ ) {
-      gft_conn[il->i1].info_at[time+1]->bit_A_exclusives[i] = 
-       gft_conn[il->i1].info_at[time]->bit_A_exclusives[i];
-    }
-    for ( i = 0; i < gnum_ft_bit; i++ ) {
-      gft_conn[il->i1].info_at[time+1]->bit_exclusives[i] = 
-       gft_conn[il->i1].info_at[time]->bit_exclusives[i];
-    }
-    /* we also need to transfer the adders
-     *
-     * attention: like this, order is REVERSED (does it matter at all?)
-     */
-    for ( il2 = gft_conn[il->i1].info_at[time]->A; il2; il2 = il2->next ) {
-      if ( !gft_conn[il->i1].info_at[time+1]->A ) {
-       gft_conn[il->i1].info_at[time+1]->A = new_IntList( il2->i1 );
-       gft_conn[il->i1].info_at[time+1]->end_A = gft_conn[il->i1].info_at[time+1]->A;
-       gft_conn[il->i1].info_at[time+1]->num_A = 1;
-      } else {
-       gft_conn[il->i1].info_at[time+1]->end_A->next = new_IntList( il2->i1 );
-       gft_conn[il->i1].info_at[time+1]->end_A = gft_conn[il->i1].info_at[time+1]->end_A->next;
-       gft_conn[il->i1].info_at[time+1]->num_A++;
-      }
-    }
-    /* ... and the same for the ops we are precond of
-     *
-     * note: ft has appeared at least 2 steps before
-     */
-    for ( il2 = gft_conn[il->i1].info_at[time-1]->P; il2; il2 = il2->next ) {
-      tmp = new_IntList( il2->i1 );
-      tmp->next = gft_conn[il->i1].info_at[time]->P;
-      gft_conn[il->i1].info_at[time]->P = tmp;
-    }
-  }
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/*******************************************************
- *         EXCLUSIONS                         **********
- *******************************************************/
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/* ops
- */
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-void find_mutex_ops( int time )
-
-{
-
-  IntList *il, *il2;
-  IntPair *ip, *tmp;
-  int i, j, ft;
-
-  /* first, if not in initial state,
-   * copy over all exclusions that we had before
-   * (between ops already there, por supuesto)
-   *
-   * also, (re-)compute te new bit_P_exlusive vectors, i.e. the union of the
-   * exclusives of all preconds; this seems difficult to compute in a
-   * more efficient copy-and-update style (??!); in IPP it is done "on demand"
-   * in the facts-are-exclusive fn which is the only point where the info is
-   * needed; this here is somewhat cleaner; to be thought about later on...
-   */
-  if ( time > 0 ) {
-    for ( il = gin_prev_ops; il; il = il->next ) {
-      for ( i = 0; i < gnum_op_bit_at[time-1]; i++ ) {
-       gop_conn[il->i1].info_at[time]->bit_exclusives[i] =
-         gop_conn[il->i1].info_at[time-1]->bit_exclusives[i];
-      }
-      for ( i = 0; i < gop_conn[il->i1].num_P; i++ ) {
-       ft = gop_conn[il->i1].P[i];
-       for ( j = 0; j < gnum_ft_bit; j++ ) {
-         gop_conn[il->i1].info_at[time]->bit_P_exclusives[j] |=
-           gft_conn[ft].info_at[time]->bit_exclusives[j];
-       }
-      }
-    }
-  }
-
-  /* now examine all non-static (competing needs) of these relations;
-   * if needs are no longer competing, remove the just set bit,
-   * and remove that relation from the open list
-   * (the list itself is built by code below)
-   */
-  ip = gin_op_mutex_pairs;
-  while ( ip ) {
-    if ( !competing_needs( time, ip->i1, ip->i2 ) ) {
-      MAKE_OPS_UNEXCLUSIVE( time, ip->i1, ip->i2 );
-      /* printf("\nremoving op excl comp needs"); */
-      gin_op_exclusion_count--;
-      if ( ip->prev ) {
-       ip->prev->next = ip->next;
-      } else {
-       gin_op_mutex_pairs = ip->next;
-      }
-      if ( ip->next ) {
-       ip->next->prev = ip->prev;
-      }
-      tmp = ip;
-      ip = ip->next;
-      free( tmp );
-    } else {
-      ip = ip->next;
-    }
-  }
-  
-  /* compare all pairs new op / new op resp. new op / old op;
-   * if interfere, make mutex, if competing needs, make mutex and
-   * put resp. pair into open list (see above)
-   */
-  for ( il = gin_ops; il != gin_prev_ops; il = il->next ) {
-    for ( il2 = il->next; il2; il2 = il2->next ) {
-      if ( interfere( il->i1, il2->i1 ) ) {
-       MAKE_OPS_EXCLUSIVE( time, il->i1, il2->i1 );
-       gin_op_exclusion_count++;
-       continue;
-      }
-      if ( !competing_needs( time, il->i1, il2->i1 ) ) {
-       continue;
-      }
-      MAKE_OPS_EXCLUSIVE( time, il->i1, il2->i1 );
-      gin_op_exclusion_count++;
-      tmp = new_IntPair( il->i1, il2->i1 );
-      if ( gin_op_mutex_pairs ) {
-       gin_op_mutex_pairs->prev = tmp;
-      }
-      tmp->next = gin_op_mutex_pairs;
-      gin_op_mutex_pairs = tmp;
-    }
-  }
-
-}
-
-
-
-/* NOTE: of course it's a waste of time to do this here over again, but
- * it seems that storing all this info, i.e. an op X op table, requires to 
- * much memory.
- *
- * OTHER IDEAS??? -- perhaps hashing what has been done so far; on the other hand,
- * these comparisons are made at least between all pairs of actions that appear in the
- * graph, and these can be many already...
- */
-Bool interfere( int op1, int op2 )
-
-{
-
-  int i;
-
-  for ( i = 0; i < gnum_ft_bit; i++ ) {
-    if ( ((gop_conn[op1].bit_P[i] | gop_conn[op1].bit_A[i]) & gop_conn[op2].bit_D[i]) ||
-        ((gop_conn[op2].bit_P[i] | gop_conn[op2].bit_A[i]) & gop_conn[op1].bit_D[i]) ) {
-      return TRUE;
-    }
-  }
-
-  return FALSE;
-
-}
-
-
-
-Bool competing_needs( int time, int op1, int op2 )
-
-{
-
-  int i;
-
-  for ( i = 0; i < gnum_ft_bit; i++ ) {
-    if ( gop_conn[op1].info_at[time]->bit_P_exclusives[i] &
-        gop_conn[op2].bit_P[i] ) {
-      return TRUE;
-    }
-  }
-
-  return FALSE;
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-/* fts
- */
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-void find_mutex_fts( int time )
-
-{
-
-  IntList *il, *il2;
-  IntPair *ip, *tmp;
-  int i;
-
-  /* pre-run: now that the ops excl. relations are there at time,
-   * setup the bit_A_exclusives information, ie for all facts the ORed exclusives of
-   * all possible achievers at time
-   *
-   * (note that these vectors have been allocated above in graph evolution step
-   * already)
-   *
-   * in IPP, this info is computed in a more "on demand" style: the vectors are allocated
-   * within the function call i.e. non-computed vectors are recognized as they are NULL.
-   * This here is cleaner in style, vamos a ver whether one or the other option is more
-   * effective -- depends on the specific needs of dynamic graph updates
-   */
-  for ( il = gin_fts; il; il = il->next ) {
-    il2 = gft_conn[il->i1].info_at[time+1]->A;
-    for ( i = 0; i < gnum_op_bit_at[time]; i++ ) {
-      gft_conn[il->i1].info_at[time+1]->bit_A_exclusives[i] =
-       gop_conn[il2->i1].info_at[time]->bit_exclusives[i];
-    }
-    for ( il2 = il2->next; il2; il2 = il2->next ) {
-      for ( i = 0; i < gnum_op_bit_at[time]; i++ ) {
-       gft_conn[il->i1].info_at[time+1]->bit_A_exclusives[i] &=
-         gop_conn[il2->i1].info_at[time]->bit_exclusives[i];
-      }
-    }
-  }
-      
-  /* now copy over old exlusions info for those facts that were there
-   * before
-   */
-  for ( il = gin_prev_fts; il; il = il->next ) {
-    for ( i = 0; i < gnum_ft_bit; i++ ) {
-      gft_conn[il->i1].info_at[time+1]->bit_exclusives[i] =
-       gft_conn[il->i1].info_at[time]->bit_exclusives[i];
-    }
-  }
-
-  /* similar to ops, check all mutexes in the open list and remove those 
-   * that are not any longer valid.
-   */
-  ip = gin_ft_mutex_pairs;
-  while ( ip ) {
-    if ( !facts_are_exclusive( time, ip->i1, ip->i2 ) ) {
-      /* in the trivial helper fns, we stick to the sound of the fn call
-       * instead of to the ops-fts-schema
-       */
-      MAKE_FTS_UNEXCLUSIVE( time+1, ip->i1, ip->i2 );
-      /* printf("\nremoving ft excl"); */
-      gin_ft_exclusion_count--;
-      if ( ip->prev ) {
-       ip->prev->next = ip->next;
-      } else {
-       gin_ft_mutex_pairs = ip->next;
-      }
-      if ( ip->next ) {
-       ip->next->prev = ip->prev;
-      }
-      tmp = ip;
-      ip = ip->next;
-      free( tmp );
-    } else {
-      ip = ip->next;
-    }
-  }
-
-  /* now, again similar to ops above, check all pairs new ft / new ft resp.
-   * new ft / old ft, and see whether they are mutex. if so,
-   * mark them as being so and put the resp. pair into the open list.
-   *
-   * here we got no provably static mutexes (?!) so there's one special
-   * case less than in the ops context.
-   */
-  for ( il = gin_fts; il != gin_prev_fts; il = il->next ) {
-    for ( il2 = il->next; il2; il2 = il2->next ) {
-      if ( !facts_are_exclusive( time, il->i1, il2->i1 ) ) {
-       continue;
-      }
-      /* s.a.: in the trivial helper fns, we stick to the sound of the fn call
-       * instead of to the ops-fts-schema
-       */
-      MAKE_FTS_EXCLUSIVE( time+1, il->i1, il2->i1 );
-      gin_ft_exclusion_count++;
-      tmp = new_IntPair( il->i1, il2->i1 );
-      if ( gin_ft_mutex_pairs ) {
-       gin_ft_mutex_pairs->prev = tmp;
-      }
-      tmp->next = gin_ft_mutex_pairs;
-      gin_ft_mutex_pairs = tmp;
-    }
-  }
-
-}
-
-
-
-Bool facts_are_exclusive( int time, int ft1, int ft2 )
-
-{
-
-  int i;
-
-  for ( i = 0; i < gnum_op_bit_at[time]; i++ ) {
-    if ( gft_conn[ft1].info_at[time+1]->bit_A[i] !=
-        (gft_conn[ft1].info_at[time+1]->bit_A[i] & 
-         gft_conn[ft2].info_at[time+1]->bit_A_exclusives[i]) ) {
-      return FALSE;
-    }
-  }
-
-  return TRUE;
-
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/* trivial helpers
- */
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-void MAKE_OPS_EXCLUSIVE( int time, int op1, int op2 ) 
-
-{
-
-  gop_conn[op1].info_at[time]->bit_exclusives[gop_conn[op2].uid_block] |=
-    gop_conn[op2].uid_mask;
-
-  gop_conn[op2].info_at[time]->bit_exclusives[gop_conn[op1].uid_block] |=
-    gop_conn[op1].uid_mask;
-
-}
-
-
-                                                       
-void MAKE_OPS_UNEXCLUSIVE( int time, int op1, int op2 )
-
-{
-
-  gop_conn[op1].info_at[time]->bit_exclusives[gop_conn[op2].uid_block] &=
-    ~(gop_conn[op2].uid_mask);
-
-  gop_conn[op2].info_at[time]->bit_exclusives[gop_conn[op1].uid_block] &=
-    ~(gop_conn[op1].uid_mask);
-
-}
-
-
-
-void MAKE_FTS_EXCLUSIVE( int time, int ft1, int ft2 ) 
-
-{
-
-  gft_conn[ft1].info_at[time]->bit_exclusives[gft_conn[ft2].uid_block] |=
-    gft_conn[ft2].uid_mask;
-
-  gft_conn[ft2].info_at[time]->bit_exclusives[gft_conn[ft1].uid_block] |=
-    gft_conn[ft1].uid_mask;
-
-}
-
-
-                                                       
-void MAKE_FTS_UNEXCLUSIVE( int time, int ft1, int ft2 )
-
-{
-
-  gft_conn[ft1].info_at[time]->bit_exclusives[gft_conn[ft2].uid_block] &=
-    ~(gft_conn[ft2].uid_mask);
-
-  gft_conn[ft2].info_at[time]->bit_exclusives[gft_conn[ft1].uid_block] &=
-    ~(gft_conn[ft1].uid_mask);
-
-}