private ConcreteExpression computeTerm()

in meta/src/main/java/org/arend/lib/meta/equation/TermCompiler.java [94:170]


  private ConcreteExpression computeTerm(CoreExpression expression, List<Monomial> nf) {
    CoreExpression expr = expression.normalize(NormalizationMode.WHNF);
    if (zroMatcher.match(expr) != null) {
      return factory.ref(meta.zroTerm.getRef());
    }
    if (ideMatcher.match(expr) != null) {
      nf.add(new Monomial(BigInteger.ONE, Collections.emptyList()));
      return factory.ref(meta.ideTerm.getRef());
    }

    if (subTermCompiler != null && subTermCompiler.minusMatcher != null) {
      List<CoreExpression> minusArgs = subTermCompiler.minusMatcher.match(expr);
      if (minusArgs != null) {
        return getSubTermCompiler().computeMinus(minusArgs.get(0), minusArgs.get(1), nf);
      }
    }

    List<CoreExpression> addArgs = addMatcher.match(expr);
    if (addArgs != null) {
      List<ConcreteExpression> cArgs = new ArrayList<>(2);
      cArgs.add(computeTerm(addArgs.get(0), nf));
      cArgs.add(computeTerm(addArgs.get(1), nf));
      return factory.app(factory.ref(meta.addTerm.getRef()), true, cArgs);
    }

    List<CoreExpression> mulArgs = mulMatcher.match(expr);
    if (mulArgs != null) {
      List<ConcreteExpression> cArgs = new ArrayList<>(2);
      List<Monomial> nf1 = new ArrayList<>();
      List<Monomial> nf2 = new ArrayList<>();
      cArgs.add(computeTerm(mulArgs.get(0), nf1));
      cArgs.add(computeTerm(mulArgs.get(1), nf2));
      List<Monomial> newNF = new ArrayList<>();
      Monomial.multiply(nf1, nf2, newNF);
      Collections.sort(newNF);
      nf.addAll(Monomial.collapse(newNF));
      return factory.app(factory.ref(meta.mulTerm.getRef()), true, cArgs);
    }

    if (isRing) {
      List<CoreExpression> negativeArgs = negativeMatcher.match(expr);
      if (negativeArgs != null) {
        return computeNegative(negativeArgs.get(0), nf);
      }
    }

    Pair<Boolean, CoreExpression> pair = checkInt(expr);
    boolean isNeg = pair != null && pair.proj1;
    List<? extends CoreExpression> coefArgs = pair == null ? null : Collections.singletonList(pair.proj2);

    if (coefArgs == null && kind != RingKind.RAT && !isLattice) {
      coefArgs = natCoefMatcher.match(expr);
    }
    if (coefArgs != null) {
      CoreExpression arg = coefArgs.get(0).normalize(NormalizationMode.WHNF);
      if (arg instanceof CoreIntegerExpression) {
        BigInteger coef = ((CoreIntegerExpression) arg).getBigInteger();
        nf.add(new Monomial(coef, Collections.emptyList()));
        return factory.app(factory.ref(meta.coefTerm.getRef()), true, Collections.singletonList(factory.number(coef)));
      } else if (subTermCompiler != null) {
        List<Monomial> newNF = new ArrayList<>();
        ConcreteExpression term = getSubTermCompiler().computeTerm(arg, newNF);
        if (term != null) {
          if (isNeg) {
            Monomial.negate(newNF, nf);
          } else {
            nf.addAll(newNF);
          }
          return isNeg ? factory.app(factory.ref(meta.negativeTerm.getRef()), true, term) : term;
        }
      }
    }

    int index = values.addValue(expr);
    nf.add(new Monomial(BigInteger.ONE, Collections.singletonList(index)));
    return factory.app(factory.ref(meta.varTerm.getRef()), true, singletonList(factory.number(index)));
  }