// sorts an array lexicographically void lex_sort(CFINT* vector, int n, int block_size) { assert(vector != NULL); assert(n >= 0); assert(block_size >= 0); if (n <= 1) return; if (n == 2) { // for n = 2, sorting is easy CFINT* block1 = vector; CFINT* block2 = vector + block_size; if (lex_compare(block1, block2, block_size) > 0) swap(block1, block2, block_size); return; } // choose pivot index for sort int pivotIndex = (int) n / 2; // move pivot element to end of list CFINT* pivot_block= &vector[block_size * (n-1)]; swap(&vector[pivotIndex * block_size], pivot_block, block_size); // partition entries CFINT* block_i = vector; CFINT* store_block = vector; pivotIndex = 0; for (int i = 0; i < n - 1; i++) { if (lex_compare(block_i, pivot_block, block_size) < 0) { swap(block_i, store_block, block_size); store_block += block_size; pivotIndex++; } block_i += block_size; } swap(store_block, pivot_block, block_size); pivot_block = store_block; // recursively sort the two parts lex_sort(vector, pivotIndex, block_size); lex_sort(&pivot_block[block_size], n - pivotIndex - 1, block_size); #ifdef DEBUG // check that the resulting array is properly sorted for (int i = 0; i < n - 1; i++) { if (lex_compare(&vector[block_size * i], &vector[block_size * (i+1)], block_size) > 0) { std::cerr << "Sorting algorithm failed!!" << std::endl; for (int j = 0; j < n; j++) { for (int k = 0; k < block_size; k++) std::cerr << vector[block_size * j + k] << " "; std::cerr << std::endl; } } } #endif }
inline order::result lpo::compare_core(expr_offset s, expr_offset t, unsigned depth) { s = find(s); t = find(t); if (max_depth(depth)) return UNKNOWN; if (is_var(s.get_expr())) return s == t ? EQUAL : UNCOMPARABLE; else if (is_var(t.get_expr())) return occurs(t, s) ? GREATER : UNCOMPARABLE; else { func_decl * f = to_app(s.get_expr())->get_decl(); func_decl * g = to_app(t.get_expr())->get_decl(); if (f_greater(f, g)) return dominates_args(s, t, depth) ? GREATER : NOT_GTEQ; else if (f != g) return arg_dominates_expr(s, t, depth) ? GREATER : NOT_GTEQ; else { result r = lex_compare(s, t, depth); if (r == GREATER) { if (dominates_args(s, t, depth)) return GREATER; } else if (r == EQUAL) return EQUAL; return to_app(s.get_expr())->get_num_args() > 1 && arg_dominates_expr(s, t, depth) ? GREATER : NOT_GTEQ; } } }
// return true if a must appear before b in the sorted sequence // see: http://en.cppreference.com/w/cpp/concept/Compare bool compare( int a, int b ) // our predicate for sort { const int sa = sum_digits(a) ; const int sb = sum_digits(b) ; if( sa == sb ) return lex_compare(a,b) ; else return sa < sb ; }