int seg_number_of_tribs(int r, int c, SEGMENT *streams, SEGMENT *dirs) { int trib = 0; int i, j; int streams_cell = 0; int dirs_cell = 0; for (i = 1; i < 9; ++i) { if (NOT_IN_REGION(i)) continue; j = DIAG(i); Segment_get(streams, &streams_cell, NR(i), NC(i)); Segment_get(dirs, &dirs_cell, NR(i), NC(i)); if (streams_cell && dirs_cell == j) trib++; } if (trib > 5) G_fatal_error(_("Error finding nodes. " "Stream and direction maps probably do not match.")); if (trib > 3) G_warning(_("Stream network may be too dense")); return trib; }
int autarky_stamp( const int nrval ) { int i, *tImp, lit1, lit2, flag = 0; tImp = TernaryImp[ -nrval ]; for( i = tmpTernaryImpSize[ -nrval ]; i--; ) { lit1 = *(tImp++); lit2 = *(tImp++); if( IS_NOT_FIXED(lit1) && IS_NOT_FIXED(lit2) ) { flag = 1; if( VeqDepends[ NR(lit1) ] == DUMMY ) autarky_stamp( lit1 ); else TernaryImpReduction[ lit1 ]++; if( VeqDepends[ NR(lit2) ] == DUMMY ) autarky_stamp( lit2 ); else TernaryImpReduction[ lit2 ]++; } } return flag; }
void set(int *flags, char *optionstring) { int i; int enable; char *arg; for ( arg = strtok(optionstring, ","); arg; arg = strtok(NULL, ",") ) { if ( *arg == '+' || *arg == '-' ) enable = (*arg++ == '+') ? 1 : 0; else if ( strncasecmp(arg, "no", 2) == 0 ) { arg += 2; enable = 0; } else enable = 1; for ( i=0; i < NR(opts); i++ ) if ( strcasecmp(arg, opts[i].name) == 0 ) break; if ( i < NR(opts) ) { if ( opts[i].off ) enable = !enable; if ( enable ) *flags |= opts[i].flag; else *flags &= ~opts[i].flag; } else fprintf(stderr, "%s: unknown option <%s>\n", pgm, arg); } }
int find_and_propagate_binary_equivalences() { int i, new_bieq = 0; for( i = 0; i < ( nrofclauses - 1 ); i++ ) { if( (Clength[ i ] == 2) && (Clength[ i + 1 ] == 2) && (Cv[ i ][ 0 ] == -Cv[ i + 1 ][ 0 ]) && (Cv[ i ][ 1 ] == -Cv[ i + 1 ][ 1 ]) && (NR(Cv[ i ][ 0 ]) != NR(Cv[ i ][ 1 ])) ) { /* We found a new bi-equivalency. */ new_bieq++; add_binary_equivalence( Cv[ i ][ 0 ], Cv[ i ][ 1 ] ); //printf("c found binary equivalence %i %i in parser\n", Cv[ i ][ 0 ], Cv[ i ][ 1 ]); /* Remove clauses; */ Clength[ i ] = 0; Clength[ i + 1 ] = 0; } } new_bieq += find_and_propagate_bieq(); return new_bieq; }
int sort_literals() { int i, j, k, tmp, _result = 0; for( i = 0; i < nrofclauses; i++ ) for( k = 0; k < Clength[ i ] - 1; k++ ) for( j = 0; j < Clength[ i ] - k - 1; j++ ) { if( NR(Cv[ i ][ j ]) > NR(Cv[ i ][ j + 1 ]) ) { tmp = Cv[ i ][ j ]; Cv[ i ][ j ] = Cv[ i ][ j + 1 ]; Cv[ i ][ j + 1 ] = tmp; } else if( NR(Cv[ i ][ j ]) == NR(Cv[ i ][ j + 1 ]) ) { /* Double literal? -> swap it out of the clause. */ if( Cv[ i ][ j ] == Cv[ i ][ j + 1 ] ) Cv[ i ][ j-- ] = Cv[ i ][ --Clength[ i ] ] ; else { /* The same literal positive and negative. So a tautology. -> eliminate clause. */ Clength[ i ] = 0; _result++; } } } return _result; }
static void destroy_subtree(graphcut_workspace_t*w, unsigned char*flags, node_t*pos, posqueue_t*posqueue) { DBG printf("destroying subtree starting with %d\n", NR(pos)); posqueue_t*q = w->tmpqueue; posqueue_purge(q); posqueue_addpos(q, pos); while(posqueue_notempty(q)) { node_t*p = posqueue_extract(q); halfedge_t*e = p->edges; while(e) { node_t*newpos = e->fwd->node; if(e->used) { posqueue_addpos(q, newpos); } else if((flags[NR(newpos)]&(ACTIVE|IN_TREE)) == IN_TREE) { // re-activate all nodes that surround our subtree. // TODO: we should check the weight of the edge from that other // node to our node. if it's zero, we don't need to activate that node. posqueue_addpos(posqueue, newpos); flags[NR(newpos)]|=ACTIVE; } e = e->next; } clear_node(w, p); DBG printf("removed pos %d\n", NR(p)); } }
int set_flag(mkd_flag_t *flags, char *optionstring) { int i; int enable; char *arg; for ( arg = strtok(optionstring, ","); arg; arg = strtok(NULL, ",") ) { if ( *arg == '+' || *arg == '-' ) enable = (*arg++ == '+') ? 1 : 0; else if ( strncasecmp(arg, "no", 2) == 0 ) { arg += 2; enable = 0; } else enable = 1; for ( i=0; i < NR(opts); i++ ) if ( strcasecmp(arg, opts[i].name) == 0 ) break; if ( i < NR(opts) ) { if ( opts[i].off ) enable = !enable; if ( enable ) *flags |= opts[i].flag; else *flags &= ~opts[i].flag; } else return 0; } return 1; }
weight_t graph_maxflow(graph_t*graph, node_t*pos1, node_t*pos2) { int max_flow = 0; graphcut_workspace_t* w = graphcut_workspace_new(graph, pos1, pos2); graph_reset(graph); DBG check_graph(graph); posqueue_addpos(w->queue1, pos1); w->flags1[pos1->nr] |= ACTIVE|IN_TREE; posqueue_addpos(w->queue2, pos2); w->flags2[pos2->nr] |= ACTIVE|IN_TREE; DBG workspace_print(w); while(1) { path_t*path; while(1) { char done1=0,done2=0; node_t* p1 = posqueue_extract(w->queue1); if(!p1) { graphcut_workspace_delete(w); return max_flow; } DBG printf("extend 1 from %d (%d edges)\n", NR(p1), node_count_edges(p1)); path = expand_pos(w, w->queue1, p1, 0, w->flags1, w->flags2); if(path) break; DBG workspace_print(w); #ifdef TWOTREES node_t* p2 = posqueue_extract(w->queue2); if(!p2) { graphcut_workspace_delete(w); return max_flow; } DBG printf("extend 2 from %d (%d edges)\n", NR(p2), node_count_edges(p2)); path = expand_pos(w, w->queue2, p2, 1, w->flags2, w->flags1); if(path) break; DBG workspace_print(w); #endif } DBG printf("found connection between tree1 and tree2\n"); DBG path_print(path); DBG printf("decreasing weights\n"); max_flow += decrease_weights(graph, path); DBG workspace_print(w); DBG printf("destroying trees\n"); combust_tree(w, w->queue1, w->queue2, path); DBG workspace_print(w); DBG check_graph(w->graph); path_delete(path); } graphcut_workspace_delete(w); return max_flow; }
static void clear_node(graphcut_workspace_t*w, node_t*n) { w->flags1[NR(n)] = 0; w->flags2[NR(n)] = 0; w->back[NR(n)] = 0; halfedge_t*e = n->edges; while(e) {e->used = 0;e=e->next;} }
int analyze_autarky( ) { #ifdef LOOKAHEAD_ON_DUMMIES int *tImp, lit1, lit2; #endif int i, j, nrval, twice; int new_bImp_flag, _depth, *_rstackp; if( depth == 0 ) return 0; for( i = 1; i <= nrofvars; i++ ) { TernaryImpReduction[ i ] = 0; TernaryImpReduction[ -i ] = 0; } new_bImp_flag = 0; _rstackp = rstackp; for( _depth = depth; _depth > 0; _depth-- ) { for( twice = 1 ; twice <= 2; twice++ ) while( *(--_rstackp) != STACK_BLOCK ) { nrval = *(_rstackp); #ifndef LOOKAHEAD_ON_DUMMIES if( autarky_stamp( nrval ) == 1 ) new_bImp_flag = 1; #else tImp = TernaryImp[ -nrval ]; for( i = tmpTernaryImpSize[ -nrval ]; i--; ) { lit1 = *(tImp++); lit2 = *(tImp++); if( IS_NOT_FIXED(lit1) && IS_NOT_FIXED(lit2) ) { new_bImp_flag = 1; TernaryImpReduction[ lit1 ]++; TernaryImpReduction[ lit2 ]++; } } #endif for( j = 1; j < tmpEqImpSize[NR(nrval)]; j++ ) { int ceqsubst = Veq[NR(nrval)][j]; for( i = 0; Ceq[ceqsubst][i] != NR(nrval); i++ ) { new_bImp_flag = 1; //printf("%i (%i)", Ceq[ ceqsubst][i], _depth ); TernaryImpReduction[ Ceq[ceqsubst][i] ]++; } } } if( new_bImp_flag == 1 ) break; } return _depth; }
static void posqueue_print(graphcut_workspace_t*w, posqueue_t*queue) { posqueue_entry_t*e = queue->list; while(e) { halfedge_t*back = w->back[NR(e->pos)]; printf("%d(%d) ", NR(e->pos), back?NR(back->fwd->node):-1); e = e->next; } printf("\n"); }
int tree_lookahead() { int i, _forced_literals; struct treeNode _treeNode, *_treeArray; #ifdef LONG_LOOK forced_literals = 0; if( long_lookahead( forced_literal_array, &forced_literals ) == UNSAT ) return UNSAT; if( long_fix_forced_literals() == UNSAT ) return UNSAT; #endif init_lookahead_procedure(); #ifdef ITERATE_LOOKAHEAD do { _forced_literals = forced_literals; #endif _treeArray = treeArray; for( i = tree_elements-1; i >= 0; i-- ) { _treeNode = *(_treeArray++); if( _treeNode.literal == lastChanged ) return SAT; currentTimeStamp += _treeNode.gap; if( currentTimeStamp >= LOOK_MAX ) { currentTimeStamp -= _treeNode.gap; // is dit nodig? return SAT; } if( treelookvar(_treeNode.literal) == UNSAT ) return UNSAT; currentTimeStamp -= _treeNode.gap; if( forced_literals > _forced_literals ) { if( IS_FIXED( _treeNode.literal ) && ( Rank[NR(_treeNode.literal)] < Rank_trigger) ) { Rank_trigger = Rank[NR(_treeNode.literal)]; printf("c forced var with Rank %i\n", Rank_trigger ); } _forced_literals = forced_literals; lastChanged = _treeNode.literal; } } #ifdef ITERATE_LOOKAHEAD currentTimeStamp += 2 * tree_elements; } while( lastChanged != 0 ); #endif return SAT; }
int seg_trib_nums(int r, int c, SEGMENT *streams, SEGMENT *dirs) { /* calculate number of tributaries */ int trib_num = 0; int i, j; int next_r, next_c; int streams_cell, streams_next_cell, dirs_next_cell; Segment_get(streams, &streams_cell, r, c); for (i = 1; i < 9; ++i) { if (NOT_IN_REGION(i)) continue; j = DIAG(i); next_r = NR(i); next_c = NC(i); Segment_get(streams, &streams_next_cell, next_r, next_c); Segment_get(dirs, &dirs_next_cell, next_r, next_c); if (streams_next_cell > 0 && dirs_next_cell == j) trib_num++; } if (trib_num > 1) for (i = 1; i < 9; ++i) { if (NOT_IN_REGION(i)) continue; j = DIAG(i); next_r = NR(i); next_c = NC(i); Segment_get(streams, &streams_next_cell, next_r, next_c); Segment_get(dirs, &dirs_next_cell, next_r, next_c); if (streams_next_cell == streams_cell && dirs_next_cell == j) trib_num--; } if (trib_num > 5) G_fatal_error(_("Error finding inits. Stream and direction maps probably do not match")); if (trib_num > 3) G_warning(_("Stream network may be too dense")); return trib_num; } /* end trib_num */
static void bool_op(graphcut_workspace_t*w, unsigned char*flags, node_t*pos, unsigned char and, unsigned char or) { posqueue_t*q = w->tmpqueue; posqueue_purge(q); posqueue_addpos(q, pos); while(posqueue_notempty(q)) { node_t*p = posqueue_extract(q); flags[NR(p)] = (flags[NR(p)]&and)|or; halfedge_t*e = p->edges; while(e) { if(e->used) { posqueue_addpos(q, e->fwd->node); } e = e->next; } } }
/* spit out a usage message, then die */ void usage(int rc) { char eb[BUFSIZ]; setbuf(stderr, eb); fprintf(stderr, "usage: %s [options] [args...]\n", pgm); showopts(stderr, NR(options), options); exit(rc); }
static weight_t decrease_weights(graph_t*map, path_t*path) { int t; assert(path->length); weight_t min = path->dir[0]->weight; for(t=0;t<path->length-1;t++) { int w = path->dir[t]->weight; DBG printf("%d->%d (%d)\n", NR(path->dir[t]->node), NR(path->dir[t]->fwd->node), w); if(t==0 || w < min) min = w; } assert(min); if(min<=0) return 0; for(t=0;t<path->length-1;t++) { path->dir[t]->weight-=min; path->dir[t]->fwd->weight+=min; } return min; }
/* see if t contains one of our pseudo-protocols. */ static linkytype * pseudo(Cstring t) { int i; linkytype *r; for ( i=0, r=specials; i < NR(specials); i++,r++ ) { if ( (S(t) > r->szpat) && (strncasecmp(T(t), r->pat, r->szpat) == 0) ) return r; } return 0; }
int ram_trib_nums(int r, int c, CELL ** streams, CELL ** dirs) { /* calculate number of tributaries */ int trib_num = 0; int i, j; int next_r, next_c; for (i = 1; i < 9; ++i) { if (NOT_IN_REGION(i)) continue; j = DIAG(i); next_r = NR(i); next_c = NC(i); if (streams[next_r][next_c] > 0 && dirs[next_r][next_c] == j) trib_num++; } if (trib_num > 1) for (i = 1; i < 9; ++i) { if (NOT_IN_REGION(i)) continue; j = DIAG(i); next_r = NR(i); next_c = NC(i); if (streams[next_r][next_c] == streams[r][c] && dirs[next_r][next_c] == j) trib_num--; } if (trib_num > 5) G_fatal_error(_("Error finding inits. Stream and direction maps probably do not match")); if (trib_num > 3) G_warning(_("Stream network may be too dense")); return trib_num; } /* end trib_num */
/* see if t contains one of our pseudo-protocols. */ static linkytype * extratag(Cstring t) { int i; linkytype *r; for ( i=0; i < NR(specials); i++ ) { r = &specials[i]; if ( (S(t) > r->szpat) && (strncasecmp(T(t), r->pat, r->szpat) == 0) ) return r; } return 0; }
int ram_number_of_tribs(int r, int c, CELL **streams, CELL **dirs) { int trib = 0; int i, j; for (i = 1; i < 9; ++i) { if (NOT_IN_REGION(i)) continue; j = DIAG(i); if (streams[NR(i)][NC(i)] && dirs[NR(i)][NC(i)] == j) trib++; } if (trib > 5) G_fatal_error(_("Error finding nodes. " "Stream and direction maps probably do not match.")); if (trib > 3) G_warning(_("Stream network may be too dense")); return trib; }
double get_distance(int r, int c, int d) { double northing, easting, next_northing, next_easting; int next_r, next_c; next_r = NR(d); next_c = NC(d); northing = window.north - (r + .5) * window.ns_res; easting = window.west + (c + .5) * window.ew_res; next_northing = window.north - (next_r + .5) * window.ns_res; next_easting = window.west + (next_c + .5) * window.ew_res; return G_distance(easting, northing, next_easting, next_northing); }
int seg_fill_basins(OUTLET outlet, SEGMENT * distance, SEGMENT * dirs) { /* fill empty spaces with zeros but leave -1 as a markers of NULL */ int r, c, i, j; int next_r, next_c; double stop, val; POINT n_cell; CELL dirs_cell; DCELL distance_cell; tail = 0; head = -1; r = outlet.r; c = outlet.c; val = 1; stop = 0; Segment_put(distance, &stop, r, c); while (tail != head) { for (i = 1; i < 9; ++i) { if (NOT_IN_REGION(i)) continue; /* out of border */ j = DIAG(i); next_r = NR(i); next_c = NC(i); Segment_get(dirs, &dirs_cell, next_r, next_c); if (dirs_cell == j) { /* countributing cell */ Segment_get(distance, &distance_cell, next_r, next_c); distance_cell = (distance_cell == stop) ? stop : val; Segment_put(distance, &distance_cell, next_r, next_c); n_cell.r = next_r; n_cell.c = next_c; fifo_insert(n_cell); } } /* end for i... */ n_cell = fifo_return_del(); r = n_cell.r; c = n_cell.c; } return 0; }
void show_flags(int byname) { int i; if ( byname ) { qsort(opts, NR(opts), sizeof(opts[0]), (stfu)sort_by_name); for (i=0; i < NR(opts); i++) if ( ! opts[i].skip ) fprintf(stderr, "%16s : %s\n", opts[i].name, opts[i].desc); } else { qsort(opts, NR(opts), sizeof(opts[0]), (stfu)sort_by_flag); for (i=0; i < NR(opts); i++) if ( ! opts[i].skip ) { fprintf(stderr, "%08lx : ", (long)opts[i].flag); if ( opts[i].sayenable ) fprintf(stderr, opts[i].off ? "disable " : "enable "); fprintf(stderr, "%s\n", opts[i].desc); } } }
int DPLL_add_binary_implications( int lit1, int lit2 ) { int i, *bImp; if( IS_FIXED(lit1) ) { if( !FIXED_ON_COMPLEMENT(lit1) ) return SAT; else if( IS_FIXED(lit2) ) return( !FIXED_ON_COMPLEMENT(lit2) ); else return look_fix_binary_implications(lit2); } else if( IS_FIXED(lit2) ) { if( !FIXED_ON_COMPLEMENT(lit2) ) return SAT; else return look_fix_binary_implications(lit1); } #ifdef BIEQ while( (VeqDepends[ NR(lit1) ] != INDEPENDENT) && (VeqDepends[ NR(lit1) ] != EQUIVALENT) ) lit1 = VeqDepends[ NR(lit1) ] * SGN(lit1); while( (VeqDepends[ NR(lit2) ] != INDEPENDENT) && (VeqDepends[ NR(lit2) ] != EQUIVALENT) ) lit2 = VeqDepends[ NR(lit2) ] * SGN(lit2); if( lit1 == -lit2 ) return SAT; if( lit1 == lit2 ) return look_fix_binary_implications(lit1); #endif STAMP_IMPLICATIONS( -lit1 ); if( bImp_stamps[ -lit2 ] == current_bImp_stamp ) return look_fix_binary_implications( lit1 ); if( bImp_stamps[lit2] != current_bImp_stamp ) { int _result; bImp_stamps[ BinaryImp[-lit1][ BinaryImp[-lit1][0] - 1] ] = current_bImp_stamp; _result = DPLL_add_compensation_resolvents( lit1, lit2 ); if( _result != UNKNOWN ) return _result; STAMP_IMPLICATIONS( -lit2 ); if( bImp_stamps[ -lit1 ] == current_bImp_stamp ) return look_fix_binary_implications( lit2 ); _result = DPLL_add_compensation_resolvents( lit2, lit1 ); if( _result != UNKNOWN ) return _result; ADD_BINARY_IMPLICATIONS( lit1, lit2 ); } return SAT; }
int ram_fill_basins(OUTLET outlet, DCELL ** distance, CELL ** dirs) { /* fill empty spaces with zeros but leave -1 as a markers of NULL */ int r, c, i, j; int next_r, next_c; double stop, val; POINT n_cell; tail = 0; head = -1; r = outlet.r; c = outlet.c; val = 1; stop = 0; distance[r][c] = stop; while (tail != head) { for (i = 1; i < 9; ++i) { if (NOT_IN_REGION(i)) continue; /* out of border */ j = DIAG(i); next_r = NR(i); next_c = NC(i); if (dirs[next_r][next_c] == j) { /* countributing cell */ distance[next_r][next_c] = (distance[next_r][next_c] == stop) ? stop : val; n_cell.r = next_r; n_cell.c = next_c; fifo_insert(n_cell); } } /* end for i... */ n_cell = fifo_return_del(); r = n_cell.r; c = n_cell.c; } return 0; }
static void combust_tree(graphcut_workspace_t*w, posqueue_t*q1, posqueue_t*q2, path_t*path) { graph_t*graph = w->graph; int t; for(t=0;t<path->length-1 && path->firsthalf[t+1];t++) { node_t*pos = path->pos[t]; halfedge_t*dir = path->dir[t]; node_t*newpos = dir->fwd->node; if(!dir->weight) { /* disconnect node */ DBG printf("remove link %d -> %d from tree 1\n", NR(pos), NR(newpos)); dir->used = 0; w->flags1[NR(newpos)] &= ACTIVE; bool_op(w, w->flags1, newpos, ~IN_TREE, 0); /* try to reconnect the path to some other tree part */ if(reconnect(w, w->flags1, newpos, 0)) { bool_op(w, w->flags1, newpos, ~0, IN_TREE); } else { destroy_subtree(w, w->flags1, newpos, q1); break; } } } for(t=path->length-1;t>0 && !path->firsthalf[t-1];t--) { node_t*pos = path->pos[t]; node_t*newpos = path->pos[t-1]; halfedge_t*dir = path->dir[t-1]->fwd; node_t*newpos2 = dir->fwd->node; assert(newpos == newpos2); if(!dir->fwd->weight) { /* disconnect node */ DBG printf("remove link %d->%d from tree 2\n", NR(pos), NR(newpos)); dir->used = 0; w->flags2[NR(newpos)] &= ACTIVE; bool_op(w, w->flags2, newpos, ~IN_TREE, 0); /* try to reconnect the path to some other tree part */ if(reconnect(w, w->flags2, newpos, 1)) { bool_op(w, w->flags2, newpos, ~0, IN_TREE); } else { destroy_subtree(w, w->flags2, newpos, q2); break; } } } }
void mkd_flags_are(FILE *f, DWORD flags, int htmlplease) { int i; int not, set, even=1; char *name; if ( htmlplease ) fprintf(f, "<table class=\"mkd_flags_are\">\n"); for (i=0; i < NR(flagnames); i++) { set = flags & flagnames[i].flag; name = flagnames[i].name; if ( not = (*name == '!') ) { ++name; set = !set; } if ( htmlplease ) { if ( even ) fprintf(f, " <tr>"); fprintf(f, "<td>"); } else fputc(' ', f); if ( !set ) fprintf(f, htmlplease ? "<s>" : "!"); fprintf(f, "%s", name); if ( htmlplease ) { if ( !set ) fprintf(f, "</s>"); fprintf(f, "</td>"); if ( !even ) fprintf(f, "</tr>\n"); } even = !even; } if ( htmlplease ) { if ( even ) fprintf(f, "</tr>\n"); fprintf(f, "</table>\n"); } }
int ram_find_contributing_cell(int r, int c, CELL **dirs, FCELL **elevation) { int i, j = 0; int next_r, next_c; float elev_min = 9999; for (i = 1; i < 9; ++i) { if (NOT_IN_REGION(i)) continue; next_r = NR(i); next_c = NC(i); if (dirs[next_r][next_c] == DIAG(i) && elevation[next_r][next_c] < elev_min) { elev_min = elevation[next_r][next_c]; j = i; } } return j; }
inline int look_fix_equivalences( const int nrval ) { int i, j, eq_clause, *eq_array; int lit, sign; eq_array = Veq[ NR(nrval) ] + 1; for( i = eq_array[ -1 ] - 1; i > 0; i-- ) { eq_clause = *(eq_array++); lit = 0; sign = 1; for( j = CeqSizes[ eq_clause ] - 1; j >= 0; j-- ) { if( IS_FIXED(Ceq[ eq_clause ][ j ]) ) sign *= EQSGN( Ceq[ eq_clause ][ j ] ); else if( !lit ) lit = Ceq[ eq_clause ][ j ]; else { new_binaries += 2; weighted_new_binaries += lengthWeight[ j + 2 ]; goto ceqend; } } sign = sign * CeqValues[ eq_clause ]; if( lit != 0 ) { if( add_constraint_resolvent(lit * sign) == UNSAT ) return UNSAT; } else if( sign == -1 ) return UNSAT; ceqend :; } return SAT; }
static void path_print(path_t*path) { int t; for(t=0;t<path->length;t++) { node_t*n = path->pos[t]; printf("%d (firsthalf: %d)", NR(n), path->firsthalf[t]); if(t<path->length-1) { printf(" -(%d/%d)-> \n", path->dir[t]->used, path->dir[t]->fwd->used); } else { printf("\n"); } } for(t=0;t<path->length-1;t++) { if(path->firsthalf[t]==path->firsthalf[t+1]) { assert(( path->firsthalf[t] && path->dir[t]->used) || (!path->firsthalf[t] && path->dir[t]->fwd->used)); } } printf("\n"); }