def buchberger_improved(F): """ Compute a Groebner basis using an improved version of Buchberger's algorithm as presented in [BW1993]_, page 232. This variant uses the Gebauer-Moeller Installation to apply Buchberger's first and second criterion to avoid useless pairs. INPUT: - ``F`` -- an ideal in a multivariate polynomial ring OUTPUT: a Groebner basis for F .. NOTE:: The verbosity of this function may be controlled with a ``set_verbose()`` call. Any value ``>=1`` will result in this function printing intermediate Groebner bases. EXAMPLES:: sage: from sage.rings.polynomial.toy_buchberger import buchberger_improved sage: R.<x,y,z> = PolynomialRing(QQ) sage: set_verbose(0) sage: sorted(buchberger_improved(R.ideal([x^4 - y - z, x*y*z - 1]))) [x*y*z - 1, x^3 - y^2*z - y*z^2, y^3*z^2 + y^2*z^3 - x^2] """ F = inter_reduction(F.gens()) G = set() B = set() if get_verbose() >= 1: reductions_to_zero = 0 while F: f = min(F) F.remove(f) G, B = update(G, B, f) while B: g1, g2 = select(B) B.remove((g1, g2)) h = spol(g1, g2).reduce(G) if h != 0: G, B = update(G, B, h) if get_verbose() >= 1: print("(%s, %s) => %s" % (g1, g2, h)) print("G: %s\n" % G) if h == 0: reductions_to_zero += 1 if get_verbose() >= 1: print("%d reductions to zero." % reductions_to_zero) return Sequence(inter_reduction(G))
def buchberger(F): """ Compute a Groebner basis using the original version of Buchberger's algorithm as presented in [BW1993]_, page 214. INPUT: - ``F`` -- an ideal in a multivariate polynomial ring OUTPUT: a Groebner basis for F .. NOTE:: The verbosity of this function may be controlled with a ``set_verbose()`` call. Any value >=1 will result in this function printing intermediate bases. EXAMPLES:: sage: from sage.rings.polynomial.toy_buchberger import buchberger sage: R.<x,y,z> = PolynomialRing(QQ) sage: I = R.ideal([x^2 - z - 1, z^2 - y - 1, x*y^2 - x - 1]) sage: set_verbose(0) sage: gb = buchberger(I) sage: gb.is_groebner() True sage: gb.ideal() == I True """ G = set(F.gens()) B = set((g1, g2) for g1 in G for g2 in G if g1 != g2) if get_verbose() >= 1: reductions_to_zero = 0 while B: g1, g2 = select(B) B.remove((g1, g2)) h = spol(g1, g2).reduce(G) if h != 0: B = B.union((g, h) for g in G) G.add(h) if get_verbose() >= 1: print("(%s, %s) => %s" % (g1, g2, h)) print("G: %s\n" % G) if h == 0: reductions_to_zero += 1 if get_verbose() >= 1: print("%d reductions to zero." % reductions_to_zero) return Sequence(G)
def __call__(self, assumptions=None): """ Run 'command' and collect output. INPUT: - ``assumptions`` - ignored, accepted for compatibility with other solvers (default: ``None``) TESTS: This class is not meant to be called directly:: sage: from sage.sat.solvers.dimacs import DIMACS sage: fn = tmp_filename() sage: solver = DIMACS(filename=fn) sage: solver.add_clause( (1, -2 , 3) ) sage: solver() Traceback (most recent call last): ... ValueError: No SAT solver command selected. """ from sage.misc.verbose import get_verbose if assumptions is not None: raise NotImplementedError("Assumptions are not supported for DIMACS based solvers.") self.write() output_filename = None self._output = [] command = self._command.strip() if not command: raise ValueError("No SAT solver command selected.") if "{output}" in command: output_filename = tmp_filename() command = command.format(input=self._headname, output=output_filename) args = shlex.split(command) try: process = subprocess.Popen(args, stdout=subprocess.PIPE) except OSError: raise OSError("Could run '%s', perhaps you need to add your SAT solver to $PATH?"%(" ".join(args))) try: while process.poll() is None: for line in iter(process.stdout.readline, b''): if get_verbose() or self._verbosity: print(line) sys.stdout.flush() self._output.append(line.decode('utf-8')) sleep(0.1) if output_filename: self._output.extend(open(output_filename).readlines()) except BaseException: process.kill() raise