package org.geogebra.desktop.util; import java.util.Iterator; import java.util.Vector; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.prover.AbstractProverReciosMethod; import org.geogebra.common.main.ProverSettings; import org.geogebra.common.util.Prover; import org.geogebra.common.util.debug.Log; import org.geogebra.desktop.kernel.prover.ProverReciosMethodD; import com.ogprover.api.GeoGebraOGPInterface; import com.ogprover.main.OGPConfigurationSettings; import com.ogprover.main.OpenGeoProver; import com.ogprover.pp.GeoGebraOGPInputProverProtocol; import com.ogprover.pp.GeoGebraOGPOutputProverProtocol; /** * @author Zoltan Kovacs <zoltan@geogebra.org> * * Implements desktop dependent parts of the Prover. */ public class ProverD extends Prover { /** * Starts computation of the proof, based on the defined subsystem. */ /* This code works in JVM only. */ private class computeThread implements Runnable { protected computeThread() { } @Override public void run() { // Display info about this particular thread Log.debug(Thread.currentThread() + " running"); decideStatement(); } } @Override public void compute() { if (ProverSettings.get().proverTimeout == 0) { // Do not create a thread if there is no timeout set: decideStatement(); // This is especially useful for debugging in Eclipse. return; } result = ProofResult.UNKNOWN; Thread t = new Thread(new computeThread(), "compute"); long startTime = System.currentTimeMillis(); t.start(); int i = 0; while (t.isAlive()) { Log.debug("Waiting for the prover: " + i++); try { t.join(50); } catch (InterruptedException e) { return; } if (((System.currentTimeMillis() - startTime) > getTimeout() * 1000L) && t.isAlive()) { Log.debug("Prover timeout"); t.interrupt(); // t.join(); // // http://docs.oracle.com/javase/tutorial/essential/concurrency/simple.html return; } } } private GeoElement getGeoByLabel(String label) { Iterator<GeoElement> it = statement.getAllPredecessors().iterator(); while (it.hasNext()) { GeoElement geo = it.next(); if (geo.getLabelSimple().equals(label)) { return geo; } } return null; } @Override protected ProofResult openGeoProver(ProverEngine pe) { Log.debug("OGP is about to run..."); String c = simplifiedXML(getConstruction(), statement).replace( "command name=\"ProveDetails\"", "command name=\"Prove\""); // dirty // hack, // FIXME Log.trace("Construction: " + c); // String cd = // statement.getCommandDescription(StringTemplate.ogpTemplate); // Log.debug("Statement in the XML should be: " + cd); OpenGeoProver.settings = new OGPConfigurationSettings(); ProverSettings proverSettings = ProverSettings.get(); // Input prover object GeoGebraOGPInputProverProtocol inputObject = new GeoGebraOGPInputProverProtocol(); inputObject.setGeometryTheoremText(c); inputObject.setMethod(GeoGebraOGPInputProverProtocol.OGP_METHOD_WU); // default if (pe == ProverEngine.OPENGEOPROVER_WU) { inputObject.setMethod(GeoGebraOGPInputProverProtocol.OGP_METHOD_WU); } if (pe == ProverEngine.OPENGEOPROVER_AREA) { inputObject .setMethod(GeoGebraOGPInputProverProtocol.OGP_METHOD_AREA); } inputObject.setTimeOut(proverSettings.proverTimeout); inputObject.setMaxTerms(proverSettings.getMaxTerms()); if (isReturnExtraNDGs()) { inputObject.setReportFormat( GeoGebraOGPInputProverProtocol.OGP_REPORT_FORMAT_ALL); } else { inputObject.setReportFormat( GeoGebraOGPInputProverProtocol.OGP_REPORT_FORMAT_NONE); } // OGP API GeoGebraOGPInterface ogpInterface = new GeoGebraOGPInterface(); GeoGebraOGPOutputProverProtocol outputObject = (GeoGebraOGPOutputProverProtocol) ogpInterface .prove(inputObject); // safe cast Log.debug("Prover results"); Log.debug(GeoGebraOGPOutputProverProtocol.OGP_OUTPUT_RES_SUCCESS + ": " + outputObject.getOutputResult( GeoGebraOGPOutputProverProtocol.OGP_OUTPUT_RES_SUCCESS)); Log.debug(GeoGebraOGPOutputProverProtocol.OGP_OUTPUT_RES_FAILURE_MSG + ": " + outputObject.getOutputResult( GeoGebraOGPOutputProverProtocol.OGP_OUTPUT_RES_FAILURE_MSG)); Log.debug(GeoGebraOGPOutputProverProtocol.OGP_OUTPUT_RES_PROVER + ": " + outputObject.getOutputResult( GeoGebraOGPOutputProverProtocol.OGP_OUTPUT_RES_PROVER)); Log.debug(GeoGebraOGPOutputProverProtocol.OGP_OUTPUT_RES_PROVER_MSG + ": " + outputObject.getOutputResult( GeoGebraOGPOutputProverProtocol.OGP_OUTPUT_RES_PROVER_MSG)); Log.debug(GeoGebraOGPOutputProverProtocol.OGP_OUTPUT_RES_TIME + ": " + outputObject.getOutputResult( GeoGebraOGPOutputProverProtocol.OGP_OUTPUT_RES_TIME)); Log.debug(GeoGebraOGPOutputProverProtocol.OGP_OUTPUT_RES_NUMTERMS + ": " + outputObject.getOutputResult( GeoGebraOGPOutputProverProtocol.OGP_OUTPUT_RES_NUMTERMS)); // Obtaining NDG conditions: if (isReturnExtraNDGs()) { Vector<String> ndgList = outputObject.getNdgList(); for (String ndgString : ndgList) { int i = ndgString.indexOf("["); NDGCondition ndg = new NDGCondition(); String ndgCommand = ndgString.substring(0, i); String params = ndgString.substring(i + 1, ndgString.length() - 1); String[] paramsArray = params.split(","); GeoElement[] geos = new GeoElement[paramsArray.length]; int j = 0; for (String param : paramsArray) { // TODO: This is not really fast, improve this somehow: geos[j] = getGeoByLabel(param.trim()); if (geos[j] == null) { // We don't want to show such objects which cannot be // detected by GeoGebra: return ProofResult.TRUE_NDG_UNREADABLE; } j++; } if ("IsOnCircle".equals(ndgCommand)) { ndgCommand = "IsIsoscelesTriangle"; // IsOnCircle[A,B,C]: AB==AC // IsIsoscelesTriangle[A,B,C]: AB==BC GeoElement swap = geos[1]; geos[1] = geos[0]; geos[0] = swap; } ndg.setCondition(ndgCommand); ndg.setGeos(geos); addNDGcondition(ndg); } } // This would be faster if we could simply get the objects back from OGP // as they are. if (outputObject .getOutputResult( GeoGebraOGPOutputProverProtocol.OGP_OUTPUT_RES_SUCCESS) .equals("true")) { if (outputObject .getOutputResult( GeoGebraOGPOutputProverProtocol.OGP_OUTPUT_RES_PROVER) .equals("true")) { return ProofResult.TRUE; } if (outputObject .getOutputResult( GeoGebraOGPOutputProverProtocol.OGP_OUTPUT_RES_PROVER) .equals("false")) { return ProofResult.FALSE; } } return ProofResult.UNKNOWN; } @Override protected AbstractProverReciosMethod getNewReciosProver() { return new ProverReciosMethodD(); } }