in meta/src/main/java/org/arend/lib/meta/closure/CongruenceClosure.java [74:135]
private Integer splitIntoSubterms(V term) {
Queue<Pair<CoreExpression, Integer>> termsToSplit = new ArrayDeque<>();
Set<VarId> toBeAddedToCongrTable = new HashSet<>();
int inputTermVar = addTerm(term, null, termsToSplit);
while (!termsToSplit.isEmpty()) {
Pair<CoreExpression, Integer> subtermPair = termsToSplit.poll();
CoreExpression subterm = subtermPair.proj1;
int var = subtermPair.proj2;
toBeAddedToCongrTable.add(new VarId(var, -1));
if (subterm instanceof CoreAppExpression) {
CoreExpression func = ((CoreAppExpression) subterm).getFunction();
CoreExpression arg = ((CoreAppExpression) subterm).getArgument();
CoreExpression funcType = func.computeType();
boolean doSplitting = true;
if (funcType instanceof CorePiExpression) {
doSplitting = !((CorePiExpression) funcType).getCodomain().findFreeBinding(((CorePiExpression) funcType).getParameters().getBinding());
}
if (doSplitting) {
int funcVar = addTerm(func, new VarId(var, -1), termsToSplit);
int argVar = addTerm(arg, new VarId(var, -1), termsToSplit);
varDefs.put(new VarId(var, -1), new Pair<>(new VarId(funcVar, -1), new VarId(argVar, -1)));
}
} else if (subterm instanceof CoreDefCallExpression && !(subterm instanceof CoreFieldCallExpression)) {
int numArgs = ((CoreDefCallExpression) subterm).getDefCallArguments().size();
List<VarId> prefixVars = terms.getVarIds(subterm);
VarId appVar = prefixVars.get(0);
for (int i = 0; i < numArgs; ++i) {
int argVar = addTerm(((CoreDefCallExpression) subterm).getDefCallArguments().get(numArgs - 1 - i), appVar, termsToSplit);
VarId funcVar = prefixVars.get(i + 1);
boolean stop = funcVar != null;
if (funcVar == null) {
funcVar = new VarId(var, i);
}
varDefs.put(appVar, new Pair<>(funcVar, new VarId(argVar, -1)));
initAppExprVar(funcVar, appVar);
toBeAddedToCongrTable.add(appVar);
if (stop) {
break;
}
if (i == numArgs - 1) {
toBeAddedToCongrTable.add(funcVar);
}
appVar = funcVar;
}
}
}
Queue<Equality> pending = new ArrayDeque<>();
for (VarId var : toBeAddedToCongrTable) {
addToCongrTable(var, pending);
}
addEqualities(pending);
return inputTermVar;
}