+ return false;
+}
+
+/** Compute GCD of multivariate polynomials using the heuristic GCD algorithm.
+ * get_symbol_stats() must have been called previously with the input
+ * polynomials and an iterator to the first element of the sym_desc vector
+ * passed in. This function is used internally by gcd().
+ *
+ * @param a first rational multivariate polynomial (expanded)
+ * @param b second rational multivariate polynomial (expanded)
+ * @param ca cofactor of polynomial a (returned), nullptr to suppress
+ * calculation of cofactor
+ * @param cb cofactor of polynomial b (returned), nullptr to suppress
+ * calculation of cofactor
+ * @param var iterator to first element of vector of sym_desc structs
+ * @param res the GCD (returned)
+ * @return true if GCD was computed, false otherwise.
+ * @see heur_gcd_z
+ * @see gcd
+ */
+static bool heur_gcd(ex& res, const ex& a, const ex& b, ex *ca, ex *cb,
+ sym_desc_vec::const_iterator var)
+{
+ if (a.info(info_flags::integer_polynomial) &&
+ b.info(info_flags::integer_polynomial)) {
+ try {
+ return heur_gcd_z(res, a, b, ca, cb, var);
+ } catch (gcdheu_failed) {
+ return false;
+ }
+ }
+
+ // convert polynomials to Z[X]
+ const numeric a_lcm = lcm_of_coefficients_denominators(a);
+ const numeric ab_lcm = lcmcoeff(b, a_lcm);
+
+ const ex ai = a*ab_lcm;
+ const ex bi = b*ab_lcm;
+ if (!ai.info(info_flags::integer_polynomial))
+ throw std::logic_error("heur_gcd: not an integer polynomial [1]");
+
+ if (!bi.info(info_flags::integer_polynomial))
+ throw std::logic_error("heur_gcd: not an integer polynomial [2]");
+
+ bool found = false;
+ try {
+ found = heur_gcd_z(res, ai, bi, ca, cb, var);
+ } catch (gcdheu_failed) {
+ return false;
+ }
+
+ // GCD is not unique, it's defined up to a unit (i.e. invertible
+ // element). If the coefficient ring is a field, every its element is
+ // invertible, so one can multiply the polynomial GCD with any element
+ // of the coefficient field. We use this ambiguity to make cofactors
+ // integer polynomials.
+ if (found)
+ res /= ab_lcm;
+ return found;