in meta/src/main/java/org/arend/lib/goal/ConstructorGoalSolver.java [49:126]
public void solve(@NotNull ExpressionTypechecker typechecker, @NotNull ConcreteGoalExpression goalExpression, @Nullable CoreExpression expectedType, @NotNull ArendUI ui, @NotNull Consumer<ConcreteExpression> callback) {
CoreExpression type = expectedType == null ? null : Utils.unfoldType(expectedType.normalize(NormalizationMode.WHNF));
ConcreteFactory factory = ext.factory.withData(goalExpression.getData());
ConcreteExpression result;
if (type instanceof CoreSigmaExpression) {
List<ConcreteExpression> goals = new ArrayList<>();
for (CoreParameter param = ((CoreSigmaExpression) type).getParameters(); param.hasNext(); param = param.getNext()) {
goals.add(factory.goal());
}
result = factory.tuple(goals);
} else if (type instanceof CorePiExpression) {
List<CoreParameter> params = new ArrayList<>();
type.getPiParameters(params);
List<ConcreteParameter> cParams = new ArrayList<>(params.size());
VariableRenamer renamer = ext.renamerFactory.variableRenamer();
List<CoreBinding> freeVars = typechecker.getFreeBindingsList();
for (CoreParameter param : params) {
cParams.add(factory.param(param.isExplicit(), factory.local(renamer.generateFreshName(param.getBinding(), freeVars))));
freeVars.add(param.getBinding());
}
result = factory.lam(cParams, factory.goal());
} else if (type instanceof CoreClassCallExpression) {
Boolean isEmptyArray = Utils.isArrayEmpty(type, ext);
if (isEmptyArray == null) {
CoreClassCallExpression classCall = (CoreClassCallExpression) type;
List<ConcreteClassElement> classElements = new ArrayList<>();
for (CoreClassField field : classCall.getDefinition().getNotImplementedFields()) {
if (!classCall.isImplementedHere(field)) {
classElements.add(factory.implementation(field.getRef(), factory.goal()));
}
}
result = factory.newExpr(factory.classExt(factory.ref(classCall.getDefinition().getRef()), classElements));
} else if (isEmptyArray) {
result = factory.ref(ext.prelude.getEmptyArray().getRef());
} else {
result = factory.app(factory.ref(ext.prelude.getArrayCons().getRef()), true, Arrays.asList(factory.goal(), factory.goal()));
}
} else if (type instanceof CoreDataCallExpression dataCall) {
if (dataCall.getDefinition() == ext.prelude.getPath()) {
CoreFunCallExpression eq = dataCall.toEquality();
if (eq != null && eq.getDefCallArguments().get(1).compare(eq.getDefCallArguments().get(2), CMP.EQ)) {
callback.accept(factory.ref(ext.prelude.getIdp().getRef()));
return;
}
}
List<CoreConstructor> constructors = new ArrayList<>();
dataCall.computeMatchedConstructors(constructors);
if (constructors.isEmpty()) {
result = null;
} else if (constructors.size() == 1) {
result = Utils.addArguments(factory.ref(constructors.get(0).getRef()), factory, Utils.numberOfExplicitParameters(constructors.get(0)), true);
} else {
ArendSession session = ui.newSession();
session.setDescription("Goal");
ArendQuery<CoreConstructor> query = session.listQuery("Choose constructor", constructors, null);
session.setCallback(ok -> {
if (ok) {
CoreConstructor constructor = query.getResult();
if (constructor != null) {
callback.accept(Utils.addArguments(factory.ref(constructor.getRef()), factory, Utils.numberOfExplicitParameters(constructor), true));
}
}
});
session.startSession();
return;
}
} else {
result = null;
}
if (result != null) {
callback.accept(result);
} else {
ui.showErrorMessage(null, "Goal type does not have constructors");
}
}