package org.geogebra.common.kernel.prover.polynomial; import java.util.HashSet; import java.util.Iterator; import java.util.Map.Entry; import java.util.SortedMap; import java.util.TreeMap; /** * A simple class for terms which are a products of potences of variables. * * @author Simon Weitzhofer * */ public class PTerm implements Comparable<PTerm> { private TreeMap<PVariable, Integer> variables; /** * creates the 1 term */ public PTerm() { variables = new TreeMap<PVariable, Integer>(); } /** * Copies a term * * @param t * the term to copy */ public PTerm(final PTerm t) { variables = new TreeMap<PVariable, Integer>(t.getTerm()); } /** * Creates a Term out of a map from variables to integers. The term is the * product of the variables raised by the corresponding integers. * * @param variables * The map */ PTerm(final TreeMap<PVariable, Integer> variables) { this.variables = variables; } /** * Creates a term which consist only of one variable * * @param variable * the variable */ public PTerm(final PVariable variable) { variables = new TreeMap<PVariable, Integer>(); variables.put(variable, 1); } /** * Creates a term variable^exponent * * @param variable * the variable * @param exponent * the exponent */ public PTerm(final PVariable variable, final int exponent) { variables = new TreeMap<PVariable, Integer>(); variables.put(variable, exponent); } /** * Calculates the product of the term and another term * * @param term * the other term * @return the product */ public PTerm times(final PTerm term) { TreeMap<PVariable, Integer> productTerm = new TreeMap<PVariable, Integer>( variables); TreeMap<PVariable, Integer> variables2 = term.getTerm(); Iterator<PVariable> it = term.getTerm().keySet().iterator(); while (it.hasNext()) { PVariable vp = it.next(); if (variables.containsKey(vp)) { productTerm.put(vp, variables.get(vp) + variables2.get(vp)); } else { productTerm.put(vp, variables2.get(vp)); } } return new PTerm(productTerm); } /** * Getter for the map containing the variables and the exponent * * @return the map */ public TreeMap<PVariable, Integer> getTerm() { return variables; } /** * Gets the variable with the highest order * * @return the variable with the highest order */ public PVariable getHighestVariable() { return variables.lastKey(); } @Override public int compareTo(PTerm o) { if (this == o) { return 0; } TreeMap<PVariable, Integer> t = o.getTerm(); if (t.isEmpty()) { if (variables.isEmpty()) { return 0; } return 1; } if (variables.isEmpty()) { return -1; } PVariable variablesLastKey = variables.lastKey(), tLastKey = t.lastKey(); int compare = variablesLastKey.compareTo(tLastKey); if (compare == 0) { compare = variables.get(variablesLastKey) .compareTo(t.get(tLastKey)); } if (compare != 0) { return compare; } do { SortedMap<PVariable, Integer> variablesSub = variables .headMap(variablesLastKey); SortedMap<PVariable, Integer> oSub = t.headMap(tLastKey); if (variablesSub.isEmpty()) { if (oSub.isEmpty()) { return 0; } return -1; } if (oSub.isEmpty()) { return 1; } variablesLastKey = variablesSub.lastKey(); tLastKey = oSub.lastKey(); compare = variablesLastKey.compareTo(tLastKey); if (compare == 0) { compare = variablesSub.get(variablesLastKey) .compareTo(oSub.get(tLastKey)); } } while (compare == 0); return compare; } @Override public boolean equals(Object o) { if (o instanceof PTerm) { return this.compareTo((PTerm) o) == 0; } return super.equals(o); } @Override public String toString() { StringBuilder sb = new StringBuilder(""); Iterator<Entry<PVariable, Integer>> it = variables.entrySet().iterator(); while (it.hasNext()) { Entry<PVariable, Integer> entry = it.next(); PVariable fv = entry.getKey(); sb.append("*"); sb.append(fv); int power = entry.getValue(); if (power > 1) { sb.append("^"); sb.append(power); } } if (sb.length() > 0) { return sb.substring(1); // removing first "*" character } return ""; } /** * Exports the term into LaTeX * * @return LaTeX formatted polynomial */ public String toTeX() { StringBuilder sb = new StringBuilder(""); Iterator<Entry<PVariable, Integer>> it = variables.entrySet().iterator(); while (it.hasNext()) { Entry<PVariable, Integer> entry = it.next(); PVariable fv = entry.getKey(); sb.append(fv.toTeX()); int power = entry.getValue(); if (power > 1) { sb.append("^{" + power + "}"); } } return sb.toString(); } /** * The set of variables in this term * * @return the set of variables */ public HashSet<PVariable> getVars() { HashSet<PVariable> v = new HashSet<PVariable>(); Iterator<PVariable> it = variables.keySet().iterator(); while (it.hasNext()) { PVariable fv = it.next(); v.add(fv); } return v; } @Override public int hashCode() { if (variables.isEmpty()) { return 0; } return variables.firstKey().hashCode() >> variables.lastKey() .hashCode(); } /** * Test whether the term f is a multiple of term g * * @param f * the dividend * @param g * the divisor * @return true if g divides f and false otherwise */ public static boolean divides(final PTerm f, final PTerm g) { TreeMap<PVariable, Integer> termG = g.getTerm(); Iterator<Entry<PVariable, Integer>> itG = termG.entrySet().iterator(); while (itG.hasNext()) { Entry<PVariable, Integer> entry = itG.next(); PVariable var = entry.getKey(); Integer powF = f.getTerm().get(var); if (powF == null || powF.intValue() < entry.getValue().intValue()) { return false; } } return true; } }