in base/src/main/java/org/arend/core/expr/Expression.java [438:518]
public boolean areDisjointConstructors(@NotNull UncheckedExpression expr2) {
Expression expr1 = normalize(NormalizationMode.WHNF);
expr2 = UncheckedExpressionImpl.extract(expr2).normalize(NormalizationMode.WHNF);
if (expr1 instanceof IntegerExpression) {
return checkInteger(((IntegerExpression) expr1).getBigInteger(), expr2);
}
if (expr2 instanceof IntegerExpression) {
return checkInteger(((IntegerExpression) expr2).getBigInteger(), expr1);
}
if (expr1 instanceof ArrayExpression array1 && expr2 instanceof ArrayExpression array2) {
if (array1.getTail() == null && array1.getElements().size() < array2.getElements().size() || array2.getTail() == null && array2.getElements().size() < array1.getElements().size()) {
return true;
}
for (int i = 0; i < array1.getElements().size() && i < array2.getElements().size(); i++) {
if (array1.getElements().get(i).areDisjointConstructors(array2.getElements().get(i))) {
return true;
}
}
return array1.getTail() != null && Boolean.TRUE.equals(ConstructorExpressionPattern.isArrayEmpty(array1.getTail().getType())) || array2.getTail() != null && Boolean.TRUE.equals(ConstructorExpressionPattern.isArrayEmpty(array2.getTail().getType()));
}
if (!(expr1 instanceof ConCallExpression conCall1) || !(expr2 instanceof ConCallExpression conCall2)) {
return false;
}
Constructor con1 = conCall1.getDefinition();
Constructor con2 = conCall2.getDefinition();
if (con1.getDataType() != con2.getDataType() || con1.getDataType() == Prelude.INTERVAL) {
return false;
}
if (con1.getDataType().isHIT()) {
GraphClosure<Constructor> closure = new GraphClosure<>();
for (Constructor constructor : con1.getDataType().getConstructors()) {
Body body = constructor.getBody();
if (body instanceof IntervalElim) {
for (IntervalElim.CasePair pair : ((IntervalElim) body).getCases()) {
if (!addConstructor(pair.proj1, constructor, closure) || !addConstructor(pair.proj2, constructor, closure)) {
return false;
}
}
body = ((IntervalElim) body).getOtherwise();
}
if (body instanceof ElimBody) {
for (ElimClause<Pattern> clause : ((ElimBody) body).getClauses()) {
if (!addConstructor(clause.getExpression(), constructor, closure)) {
return false;
}
}
} else if (body != null) {
throw new IllegalStateException();
}
}
return !closure.areEquivalent(con1, con2);
} else {
List<ConCallExpression> conCalls1 = new ArrayList<>();
conCalls1.add(conCall1);
List<ConCallExpression> conCalls2 = new ArrayList<>();
conCalls2.add(conCall2);
if (!computeClosure(conCalls1) || !computeClosure(conCalls2)) {
return false;
}
for (ConCallExpression cc1 : conCalls1) {
for (ConCallExpression cc2 : conCalls2) {
if (cc1.getDefinition() == cc2.getDefinition()) {
boolean ok = false;
for (int i = 0; i < cc1.getDefCallArguments().size(); i++) {
if (cc1.getDefCallArguments().get(i).areDisjointConstructors(cc2.getDefCallArguments().get(i))) {
ok = true;
break;
}
}
if (!ok) {
return false;
}
}
}
}
return true;
}
}