in meta/src/main/java/org/arend/lib/meta/linear/TermCompiler.java [145:170]
private ConcreteExpression computeMul(CoreExpression arg1, CoreExpression arg2, CoreExpression expr, Map<Integer, Ring> coefficients, Ring[] freeCoef, Set<Integer> vars) {
int valuesSize = values.getValues().size();
Map<Integer, Ring> coefficients1 = new HashMap<>(), coefficients2 = new HashMap<>();
Ring[] freeCoef1 = new Ring[] { getZero() }, freeCoef2 = new Ring[] { getZero() };
ConcreteExpression leftTerm = computeTerm(arg1, coefficients1, freeCoef1, vars);
ConcreteExpression rightTerm = computeTerm(arg2, coefficients2, freeCoef2, vars);
if (leftTerm == null || rightTerm == null) return null;
if (coefficients1.isEmpty() && coefficients2.isEmpty()) {
freeCoef[0] = freeCoef[0].add(freeCoef1[0].multiply(freeCoef2[0]));
} else if (coefficients1.isEmpty() || coefficients2.isEmpty()) {
Ring coef = coefficients1.isEmpty() ? freeCoef1[0] : freeCoef2[0];
for (Map.Entry<Integer, Ring> entry : coefficients1.entrySet()) {
Ring newCoef = entry.getValue().multiply(coef);
coefficients.compute(entry.getKey(), (k,v) -> v == null ? newCoef : v.add(newCoef));
}
for (Map.Entry<Integer, Ring> entry : coefficients2.entrySet()) {
Ring newCoef = entry.getValue().multiply(coef);
coefficients.compute(entry.getKey(), (k,v) -> v == null ? newCoef : v.add(newCoef));
}
freeCoef[0] = freeCoef[0].add(freeCoef1[0].multiply(freeCoef2[0]));
} else {
values.getValues().subList(valuesSize, values.getValues().size()).clear();
return computeVal(expr, coefficients, vars);
}
return factory.app(factory.ref(meta.mulTerm.getRef()), true, leftTerm, rightTerm);
}