package org.geogebra.web.html5.kernel; import java.math.BigInteger; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map.Entry; import org.geogebra.common.kernel.algos.SymbolicParameters; import org.geogebra.common.kernel.prover.AbstractProverReciosMethod; import org.geogebra.common.kernel.prover.NoSymbolicParametersException; import org.geogebra.common.kernel.prover.ProverBotanasMethod.AlgebraicStatement; import org.geogebra.common.kernel.prover.polynomial.PPolynomial; import org.geogebra.common.kernel.prover.polynomial.PVariable; import org.geogebra.common.main.ProverSettings; import org.geogebra.common.util.ExtendedBoolean; import org.geogebra.common.util.Prover.ProofResult; import org.geogebra.common.util.debug.Log; /** * A non-threaded version of Recio's method. * * @author Zoltan Kovacs <zoltan@geogebra.org> */ public class ProverReciosMethodW extends AbstractProverReciosMethod { @Override protected final ProofResult computeNd(HashSet<PVariable> freeVariables, HashMap<PVariable, BigInteger> values, int deg, SymbolicParameters s, AlgebraicStatement as) { int n = freeVariables.size(); PVariable[] variables = new PVariable[n]; Iterator<PVariable> it = freeVariables.iterator(); for (int i = 0; i < n; i++) { variables[i] = it.next(); } int[] indices = new int[n]; for (int i = 0; i < n; i++) { indices[i] = n - i; } boolean indicesChanged; int nrOfTests = 0, changedIndex = n - 1; BigInteger[][] cache = new BigInteger[n][n]; do { for (int i = 0; i < n; i++) { BigInteger result; if (changedIndex == n - 1) { result = BigInteger.ONE; } else { result = cache[i][changedIndex + 1]; } for (int j = changedIndex; j >= 0; j--) { result = result.multiply((BigInteger.valueOf(n) .multiply(BigInteger.valueOf(indices[j]))) .subtract(BigInteger.valueOf(i))); cache[i][j] = result; } values.put(variables[i], result); } nrOfTests++; if (as != null) { // use Botana's method HashMap<PVariable, BigInteger> substitutions = new HashMap<PVariable, BigInteger>(); for (Entry<PVariable, BigInteger> entry : values.entrySet()) { PVariable v = entry.getKey(); // FIXME: Change Long in Variable to BigInteger substitutions.put(v, entry.getValue()); } ExtendedBoolean solvable = PPolynomial.solvable(as.getPolynomials() .toArray(new PPolynomial[as.getPolynomials().size()]), substitutions, as.geoStatement.getKernel(), ProverSettings.get().transcext); Log.debug("Recio meets Botana #" + nrOfTests + ": " + substitutions); if (solvable.boolVal()) { return ProofResult.FALSE; } } else { try { BigInteger[] exactCoordinates = s.getExactCoordinates(values); for (BigInteger result : exactCoordinates) { if (!result.equals(BigInteger.ZERO)) { return ProofResult.FALSE; } } } catch (NoSymbolicParametersException e) { return ProofResult.UNKNOWN; } } indicesChanged = false; for (int i = 0; i < n; i++) { if (indices[i] < (deg - i + n)) { indices[i]++; for (int j = 0; j < i; j++) { indices[j] = indices[i] + i - j; } changedIndex = i; indicesChanged = true; break; } } } while (indicesChanged); Log.debug(nrOfTests + " tests performed."); Log.debug("n: " + n); Log.debug("deg: " + deg); return ProofResult.TRUE; } }