Fix some bugs of the unification explanation

see #20
This commit is contained in:
Arne Keller 2021-08-16 09:50:43 +02:00
parent 208c21277b
commit 7abfd66aa8
10 changed files with 111 additions and 60 deletions

View File

@ -43,6 +43,7 @@ tc-explanation {
max-width: 40em; max-width: 40em;
padding-left: 1em; padding-left: 1em;
padding-right: 1em; padding-right: 1em;
overflow-y: auto;
} }
#rules-button { #rules-button {

View File

@ -24,7 +24,8 @@ public class Unification {
steps = new ArrayList<>(); steps = new ArrayList<>();
List<Substitution> substitutions = new ArrayList<>(); List<Substitution> substitutions = new ArrayList<>();
steps.add(new UnificationStep(new Result<>(Collections.emptyList()), new ArrayList<>(constraints))); steps.add(new UnificationStep(
new Result<>(Collections.emptyList()), new ArrayList<>(constraints), Optional.empty()));
while (!constraints.isEmpty()) { while (!constraints.isEmpty()) {
Constraint c = constraints.removeFirst(); Constraint c = constraints.removeFirst();
// calculate the result of this constraint // calculate the result of this constraint
@ -32,7 +33,7 @@ public class Unification {
Type b = c.getSecondType(); Type b = c.getSecondType();
Result<UnificationActions, UnificationError> actions = a.constrainEqualTo(b); Result<UnificationActions, UnificationError> actions = a.constrainEqualTo(b);
if (actions.isError()) { if (actions.isError()) {
steps.add(new UnificationStep(new Result<>(actions), new ArrayList<>(constraints))); steps.add(new UnificationStep(new Result<>(actions), new ArrayList<>(constraints), Optional.of(c)));
substitutionsResult = new Result<>(actions); substitutionsResult = new Result<>(actions);
return; return;
} }
@ -56,7 +57,8 @@ public class Unification {
for (Constraint constraint : thisStep.getConstraints()) { for (Constraint constraint : thisStep.getConstraints()) {
constraints.addFirst(constraint); constraints.addFirst(constraint);
} }
steps.add(new UnificationStep(new Result<>(new ArrayList<>(substitutions)), new ArrayList<>(constraints))); steps.add(new UnificationStep(
new Result<>(new ArrayList<>(substitutions)), new ArrayList<>(constraints), Optional.of(c)));
} }
substitutionsResult = new Result<>(substitutions); substitutionsResult = new Result<>(substitutions);

View File

@ -5,6 +5,7 @@ import edu.kit.typicalc.util.Result;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
/** /**
* Models one step of the unification algorithm with a list of constraints and a list of substitutions. * Models one step of the unification algorithm with a list of constraints and a list of substitutions.
@ -15,6 +16,7 @@ import java.util.Objects;
public class UnificationStep { public class UnificationStep {
private final Result<List<Substitution>, UnificationError> substitutions; private final Result<List<Substitution>, UnificationError> substitutions;
private final List<Constraint> constraints; private final List<Constraint> constraints;
private final Optional<Constraint> processedConstraint;
/** /**
* Initializes a new {@link UnificationStep} with the given lists of constraints and substitutions. * Initializes a new {@link UnificationStep} with the given lists of constraints and substitutions.
@ -23,11 +25,14 @@ public class UnificationStep {
* *
* @param substitutions list of substitutions, or an error * @param substitutions list of substitutions, or an error
* @param constraints the list of all constraints of the unification (in the state resulting from this step) * @param constraints the list of all constraints of the unification (in the state resulting from this step)
* @param processedConstraint the constraint processed in this step, if any
*/ */
protected UnificationStep(Result<List<Substitution>, UnificationError> substitutions, protected UnificationStep(Result<List<Substitution>, UnificationError> substitutions,
List<Constraint> constraints) { List<Constraint> constraints,
Optional<Constraint> processedConstraint) {
this.substitutions = substitutions; this.substitutions = substitutions;
this.constraints = constraints; this.constraints = constraints;
this.processedConstraint = processedConstraint;
} }
/** /**
@ -50,11 +55,19 @@ public class UnificationStep {
return constraints; return constraints;
} }
/**
* @return the constraint processed in this step
*/
public Optional<Constraint> getProcessedConstraint() {
return processedConstraint;
}
@Override @Override
public String toString() { public String toString() {
return "UnificationStep{" return "UnificationStep{"
+ "substitutions=" + substitutions + "substitutions=" + substitutions
+ ", constraints=" + Arrays.toString(constraints.toArray()) + ", constraints=" + Arrays.toString(constraints.toArray())
+ ", processed=" + processedConstraint
+ '}'; + '}';
} }
@ -67,7 +80,8 @@ public class UnificationStep {
return false; return false;
} }
UnificationStep that = (UnificationStep) o; UnificationStep that = (UnificationStep) o;
return substitutions.equals(that.substitutions) && constraints.equals(that.constraints); return substitutions.equals(that.substitutions) && constraints.equals(that.constraints)
&& processedConstraint.equals(that.processedConstraint);
} }
@Override @Override

View File

@ -52,9 +52,9 @@ public class TypicalcI18NProvider implements I18NProvider {
return "?[" + key + "]?"; return "?[" + key + "]?";
} }
} }
// replace placeholders {0} ... // replace placeholders %0% ...
for (int i = 0; i < params.length; i++) { for (int i = 0; i < params.length; i++) {
result = result.replace(String.format("{%d}", i), params[i].toString()); result = result.replace(String.format("%%%d%%", i), params[i].toString());
} }
return result; return result;
} }

View File

@ -40,8 +40,8 @@ import edu.kit.typicalc.util.Result;
public class ExplanationCreatorUnification { public class ExplanationCreatorUnification {
private static final String KEY_PREFIX = "expUnification."; private static final String KEY_PREFIX = "expUnification.";
private static final String LET_KEY_PREFIX = "expLetUnification."; private static final String LET_KEY_PREFIX = "expLetUnification.";
private final TypeArgumentVisitor typeDeterminer = new TypeArgumentVisitor(); private final TypeArgumentVisitor typeDeterminer = new TypeArgumentVisitor();
private final TypeInfererInterface typeInferer; private final TypeInfererInterface typeInferer;
private final Locale locale; private final Locale locale;
@ -88,6 +88,7 @@ public class ExplanationCreatorUnification {
typeAssumptionsToLatex(typeInferer.getFirstInferenceStep().getConclusion().getTypeAssumptions(), mode); typeAssumptionsToLatex(typeInferer.getFirstInferenceStep().getConclusion().getTypeAssumptions(), mode);
String letVariableLatex = new LatexCreatorTerm(this.letVariable.get(), mode).getLatex(); String letVariableLatex = new LatexCreatorTerm(this.letVariable.get(), mode).getLatex();
// TODO: replace with parametrized translation text (see createVariableText)
StringBuilder latex = new StringBuilder(getDefaultTextLatex(LET_KEY_PREFIX + "typeAss1")). StringBuilder latex = new StringBuilder(getDefaultTextLatex(LET_KEY_PREFIX + "typeAss1")).
append(toLatex(GAMMA)). append(toLatex(GAMMA)).
append(getDefaultTextLatex(LET_KEY_PREFIX + "typeAss2")). append(getDefaultTextLatex(LET_KEY_PREFIX + "typeAss2")).
@ -128,6 +129,7 @@ public class ExplanationCreatorUnification {
private void createFinalType(boolean isLetUnification) { private void createFinalType(boolean isLetUnification) {
String keyPrefix = isLetUnification ? LET_KEY_PREFIX : KEY_PREFIX; String keyPrefix = isLetUnification ? LET_KEY_PREFIX : KEY_PREFIX;
// TODO: replace with parametrized translation text (see createVariableText)
StringBuilder latex = new StringBuilder(getDefaultTextLatex(keyPrefix + "finalType1")). StringBuilder latex = new StringBuilder(getDefaultTextLatex(keyPrefix + "finalType1")).
append(toLatex(letCounterToLatex(SIGMA))). append(toLatex(letCounterToLatex(SIGMA))).
append(getDefaultTextLatex(keyPrefix + "finalType2")). append(getDefaultTextLatex(keyPrefix + "finalType2")).
@ -183,11 +185,10 @@ public class ExplanationCreatorUnification {
List<UnificationStep> unificationSteps = typeInferer.getUnificationSteps() List<UnificationStep> unificationSteps = typeInferer.getUnificationSteps()
.orElseThrow(IllegalStateException::new); .orElseThrow(IllegalStateException::new);
List<Constraint> initialConstraints = unificationSteps.get(0).getConstraints();
// skip first step since the substitutions list is still empty (unification introduction is shown) // skip first step since the substitutions list is still empty (unification introduction is shown)
Constraint currentConstraint = initialConstraints.get(initialConstraints.size() - 1); for (int stepNum = 1; stepNum < unificationSteps.size(); stepNum++) {
for (int stepNum = 1; stepNum < unificationSteps.size() - 1; stepNum++) {
UnificationStep step = unificationSteps.get(stepNum); UnificationStep step = unificationSteps.get(stepNum);
Constraint currentConstraint = step.getProcessedConstraint().get(); // works because only step 0 has no constraint
Result<List<Substitution>, UnificationError> subs = step.getSubstitutions(); Result<List<Substitution>, UnificationError> subs = step.getSubstitutions();
if (subs.isError()) { if (subs.isError()) {
@ -195,6 +196,7 @@ public class ExplanationCreatorUnification {
errorOccurred = true; errorOccurred = true;
break; break;
} }
List<Substitution> substitutions = subs.unwrap();
List<Constraint> constraints = step.getConstraints(); List<Constraint> constraints = step.getConstraints();
if (currentConstraint.getFirstType().equals(currentConstraint.getSecondType())) { if (currentConstraint.getFirstType().equals(currentConstraint.getSecondType())) {
@ -203,23 +205,22 @@ public class ExplanationCreatorUnification {
} else if (typeDeterminer.getArguments(currentConstraint.getFirstType()).isEmpty()) { } else if (typeDeterminer.getArguments(currentConstraint.getFirstType()).isEmpty()) {
// left side is a variable // left side is a variable
createVariableText(currentConstraint.getFirstType(), currentConstraint.getSecondType(), createVariableText(currentConstraint.getFirstType(), currentConstraint.getSecondType(),
currentConstraint, subs.unwrap().get(0)); currentConstraint, substitutions.get(substitutions.size() - 1));
} else if (typeDeterminer.getArguments(currentConstraint.getSecondType()).isEmpty()) { } else if (typeDeterminer.getArguments(currentConstraint.getSecondType()).isEmpty()) {
// right side is a variable // right side is a variable
createVariableText(currentConstraint.getSecondType(), currentConstraint.getFirstType(), createVariableText(currentConstraint.getSecondType(), currentConstraint.getFirstType(),
currentConstraint, subs.unwrap().get(0)); currentConstraint, substitutions.get(substitutions.size() - 1));
} else { } else {
// both sides are functions // both sides are functions
createFunctionText(currentConstraint, createFunctionText(currentConstraint,
constraints.get(constraints.size() - 1), constraints.get(constraints.size() - 2)); constraints.get(constraints.size() - 1), constraints.get(constraints.size() - 2));
} }
currentConstraint = constraints.get(constraints.size() - 1);
} }
} }
private void createTrivialConstraintText(Constraint currentConstraint) { private void createTrivialConstraintText(Constraint currentConstraint) {
StringBuilder latex = new StringBuilder(); StringBuilder latex = new StringBuilder();
// TODO: replace with parametrized translation text (see createVariableText)
latex.append(getDefaultTextLatex(KEY_PREFIX + "trivial1")). latex.append(getDefaultTextLatex(KEY_PREFIX + "trivial1")).
append(toLatex(LatexCreatorConstraints.createSingleConstraint(currentConstraint, mode))). append(toLatex(LatexCreatorConstraints.createSingleConstraint(currentConstraint, mode))).
append(getDefaultTextLatex(KEY_PREFIX + "trivial2")); append(getDefaultTextLatex(KEY_PREFIX + "trivial2"));
@ -228,6 +229,7 @@ public class ExplanationCreatorUnification {
private void createFunctionText(Constraint currentConstraint, Constraint newConstraint1, Constraint newConstraint2) { private void createFunctionText(Constraint currentConstraint, Constraint newConstraint1, Constraint newConstraint2) {
StringBuilder latex = new StringBuilder(); StringBuilder latex = new StringBuilder();
// TODO: replace with parametrized translation text (see createVariableText)
latex.append(getDefaultTextLatex(KEY_PREFIX + "function1")). latex.append(getDefaultTextLatex(KEY_PREFIX + "function1")).
append(toLatex(LatexCreatorConstraints.createSingleConstraint(currentConstraint, mode))). append(toLatex(LatexCreatorConstraints.createSingleConstraint(currentConstraint, mode))).
append(getDefaultTextLatex(KEY_PREFIX + "function2")). append(getDefaultTextLatex(KEY_PREFIX + "function2")).
@ -246,19 +248,13 @@ public class ExplanationCreatorUnification {
private void createVariableText(Type variable, Type anyType, Constraint currentConstraint, private void createVariableText(Type variable, Type anyType, Constraint currentConstraint,
Substitution newSubstitution) { Substitution newSubstitution) {
StringBuilder latex = new StringBuilder(); String constraintLatex = toLatex(LatexCreatorConstraints.createSingleConstraint(currentConstraint, mode));
latex.append(getDefaultTextLatex(KEY_PREFIX + "variable1")). String variableType = toLatex(new LatexCreatorType(variable, mode).getLatex());
append(toLatex(LatexCreatorConstraints.createSingleConstraint(currentConstraint, mode))). String otherType = toLatex(new LatexCreatorType(anyType, mode).getLatex());
append(getDefaultTextLatex(KEY_PREFIX + "variable2")). String substitutionLatex = toLatex(getSubstitutionLatex(newSubstitution));
append(toLatex(new LatexCreatorType(variable, mode).getLatex())). String finalText = provider.getTranslation(KEY_PREFIX + "variable", locale,
append(getDefaultTextLatex(KEY_PREFIX + "variable3")). constraintLatex, variableType, otherType, substitutionLatex);
append(toLatex(new LatexCreatorType(variable, mode).getLatex())). unificationTexts.add(finalText);
append(getDefaultTextLatex(KEY_PREFIX + "variable4")).
append(toLatex(new LatexCreatorType(anyType, mode).getLatex())).
append(getDefaultTextLatex(KEY_PREFIX + "variable5")).
append(toLatex(getSubstitutionLatex(newSubstitution))).
append(getDefaultTextLatex(KEY_PREFIX + "variable6"));
unificationTexts.add(latex.toString());
} }
private void createErrorText(UnificationError errorType) { private void createErrorText(UnificationError errorType) {

View File

@ -0,0 +1,28 @@
package edu.kit.typicalc.view.content.typeinferencecontent.latexcreator;
import com.vaadin.flow.i18n.I18NProvider;
import java.util.List;
import java.util.Locale;
public class ExplanationTranslationProvider implements I18NProvider {
private final I18NProvider innerProvider;
public ExplanationTranslationProvider(I18NProvider provider) {
this.innerProvider = provider;
}
@Override
public List<Locale> getProvidedLocales() {
return innerProvider.getProvidedLocales();
}
@Override
public String getTranslation(String key, Locale locale, Object... params) {
return innerProvider.getTranslation(key, locale, params);
}
public String getTranslationInstantiated(String key, Locale locale, Object... params) {
return "";
}
}

View File

@ -109,8 +109,8 @@ error.heading=Syntaktisch falsche Eingabe!
error.termForError=Term:\u0020 error.termForError=Term:\u0020
error.typeAssumptionForError=Typannahme:\u0020 error.typeAssumptionForError=Typannahme:\u0020
error.wrongCharacter=Falsches Zeichen:\u0020 error.wrongCharacter=Falsches Zeichen:\u0020
error.expectedToken=Erwartet: {0} error.expectedToken=Erwartet: %0%
error.additionalInformation = Information: {0} error.additionalInformation = Information: %0%
error.hint=Die Grammatiken, die die korrekte Syntax eines Terms und der Typannahmen beschreiben, \ error.hint=Die Grammatiken, die die korrekte Syntax eines Terms und der Typannahmen beschreiben, \
sind auch über das Info-Symbol zu erreichen. sind auch über das Info-Symbol zu erreichen.
tokentype.UNIVERSAL_QUANTIFIER=Allquantor tokentype.UNIVERSAL_QUANTIFIER=Allquantor
@ -252,13 +252,10 @@ ausgeführt, um den Typen der let-Variable zu finden und damit die neue Typumgeb
expUnification.trivial1=In diesem Schritt wurde der Constraint expUnification.trivial1=In diesem Schritt wurde der Constraint
expUnification.trivial2=entfernt. Da linke und rechte Seite identisch sind, ist der Constraint immer erfüllt und \ expUnification.trivial2=entfernt. Da linke und rechte Seite identisch sind, ist der Constraint immer erfüllt und \
wird somit nicht benötigt. wird somit nicht benötigt.
expUnification.variable1=In diesem Schritt wurde der Constraint expUnification.variable=In diesem Schritt wurde der Constraint %0% ersetzt.\
expUnification.variable2=ersetzt. Da t ein Variablentyp ist und nicht in Da %1% ein Variablentyp ist und nicht in %2% vorkommt, können alle Vorkommen von %1% durch %2% ersetzt werden.\
expUnification.variable3=vorkommt, können alle Vorkommen von In der Folge wird die Substitution %3% erstellt und auf die übrige Constraintmenge angewandt.\
expUnification.variable4=durch Die daraus resultierenden Veränderungen sind blau markiert.
expUnification.variable5=ersetzt werden. In der Folge wird die Substitution
expUnification.variable6=erstellt und auf die übrige Constraintmenge angewandt. Die daraus resultierenden Veräderungen \
sind blau markiert.
expUnification.function1=In diesem Schritt wurde der Constraint expUnification.function1=In diesem Schritt wurde der Constraint
expUnification.function2=ersetzt. Da sowohl expUnification.function2=ersetzt. Da sowohl
expUnification.function3=als auch expUnification.function3=als auch

View File

@ -101,8 +101,8 @@ error.heading=Input is syntactically wrong!
error.wrongCharacter=Wrong character:\u0020 error.wrongCharacter=Wrong character:\u0020
error.termForError=Term:\u0020 error.termForError=Term:\u0020
error.typeAssumptionForError=Type assumption:\u0020 error.typeAssumptionForError=Type assumption:\u0020
error.expectedToken=Expected: {0} error.expectedToken=Expected: %0%
error.additionalInformation = Information: {0} error.additionalInformation = Information: %0%
error.hint=The grammars describing the correct syntax of a term or a type assumption can also be reached \ error.hint=The grammars describing the correct syntax of a term or a type assumption can also be reached \
via the info icon. via the info icon.
tokentype.UNIVERSAL_QUANTIFIER=universal quantifier tokentype.UNIVERSAL_QUANTIFIER=universal quantifier

View File

@ -7,10 +7,7 @@ import edu.kit.typicalc.util.Result;
import nl.jqno.equalsverifier.EqualsVerifier; import nl.jqno.equalsverifier.EqualsVerifier;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import java.util.ArrayDeque; import java.util.*;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
@ -32,11 +29,11 @@ class UnificationTest {
List<UnificationStep> steps = u.getUnificationSteps(); List<UnificationStep> steps = u.getUnificationSteps();
assertEquals(2, steps.size()); assertEquals(2, steps.size());
assertEquals(new UnificationStep(new Result<>(new ArrayList<>()), assertEquals(new UnificationStep(new Result<>(new ArrayList<>()),
new ArrayList<>(initialConstraints)), steps.get(0)); new ArrayList<>(initialConstraints), Optional.empty()), steps.get(0));
List<Substitution> substitutions = new ArrayList<>(List.of(new Substitution(a, new FunctionType(b, c)))); List<Substitution> substitutions = new ArrayList<>(List.of(new Substitution(a, new FunctionType(b, c))));
assertEquals(new UnificationStep(new Result<>( assertEquals(new UnificationStep(new Result<>(
substitutions substitutions
), new ArrayList<>()), steps.get(1)); ), new ArrayList<>(), Optional.of(constraints.getFirst())), steps.get(1));
assertEquals(substitutions, u.getSubstitutions().unwrap()); assertEquals(substitutions, u.getSubstitutions().unwrap());
} }
@ -54,39 +51,39 @@ class UnificationTest {
List<UnificationStep> steps = u.getUnificationSteps(); List<UnificationStep> steps = u.getUnificationSteps();
assertEquals(6, steps.size()); assertEquals(6, steps.size());
assertEquals(new UnificationStep(new Result<>(new ArrayList<>()), assertEquals(new UnificationStep(new Result<>(new ArrayList<>()),
new ArrayList<>(initialConstraints)), steps.get(0)); new ArrayList<>(initialConstraints), Optional.empty()), steps.get(0));
initialConstraints.removeFirst(); var constraint = initialConstraints.removeFirst();
List<Substitution> substitutions = new ArrayList<>(List.of(new Substitution(a, new FunctionType(b, c)))); List<Substitution> substitutions = new ArrayList<>(List.of(new Substitution(a, new FunctionType(b, c))));
assertEquals(new UnificationStep(new Result<>( assertEquals(new UnificationStep(new Result<>(
substitutions substitutions
), new ArrayList<>(initialConstraints)), steps.get(1)); ), new ArrayList<>(initialConstraints), Optional.of(constraint)), steps.get(1));
initialConstraints.removeFirst(); constraint = initialConstraints.removeFirst();
substitutions.add(new Substitution(c, new FunctionType(a4, a5))); substitutions.add(new Substitution(c, new FunctionType(a4, a5)));
assertEquals(new UnificationStep(new Result<>( assertEquals(new UnificationStep(new Result<>(
substitutions substitutions
), new ArrayList<>(initialConstraints)), steps.get(2)); ), new ArrayList<>(initialConstraints), Optional.of(constraint)), steps.get(2));
initialConstraints.removeFirst(); constraint = initialConstraints.removeFirst();
initialConstraints.removeFirst(); initialConstraints.removeFirst();
initialConstraints.addFirst(new Constraint(new FunctionType(a7, a5), a4)); initialConstraints.addFirst(new Constraint(new FunctionType(a7, a5), a4));
substitutions.add(new Substitution(a6, new FunctionType(a7, a5))); substitutions.add(new Substitution(a6, new FunctionType(a7, a5)));
assertEquals(new UnificationStep(new Result<>( assertEquals(new UnificationStep(new Result<>(
substitutions substitutions
), new ArrayList<>(initialConstraints)), steps.get(3)); ), new ArrayList<>(initialConstraints), Optional.of(constraint)), steps.get(3));
initialConstraints.removeFirst(); constraint = initialConstraints.removeFirst();
substitutions.add(new Substitution(a4, new FunctionType(a7, a5))); substitutions.add(new Substitution(a4, new FunctionType(a7, a5)));
assertEquals(new UnificationStep(new Result<>( assertEquals(new UnificationStep(new Result<>(
substitutions substitutions
), new ArrayList<>(initialConstraints)), steps.get(4)); ), new ArrayList<>(initialConstraints), Optional.of(constraint)), steps.get(4));
initialConstraints.removeFirst(); constraint = initialConstraints.removeFirst();
substitutions.add(new Substitution(a7, b)); substitutions.add(new Substitution(a7, b));
assertEquals(new UnificationStep(new Result<>( assertEquals(new UnificationStep(new Result<>(
substitutions substitutions
), new ArrayList<>(initialConstraints)), steps.get(5)); ), new ArrayList<>(initialConstraints), Optional.of(constraint)), steps.get(5));
assertEquals(substitutions, u.getSubstitutions().unwrap()); assertEquals(substitutions, u.getSubstitutions().unwrap());
} }
@ -100,10 +97,10 @@ class UnificationTest {
List<UnificationStep> steps = u.getUnificationSteps(); List<UnificationStep> steps = u.getUnificationSteps();
assertEquals(2, steps.size()); assertEquals(2, steps.size());
assertEquals(new UnificationStep(new Result<>(new ArrayList<>()), assertEquals(new UnificationStep(new Result<>(new ArrayList<>()),
new ArrayList<>(initialConstraints)), steps.get(0)); new ArrayList<>(initialConstraints), Optional.empty()), steps.get(0));
assertEquals(new UnificationStep(new Result<>(null, assertEquals(new UnificationStep(new Result<>(null,
UnificationError.INFINITE_TYPE UnificationError.INFINITE_TYPE
), new ArrayList<>()), steps.get(1)); ), new ArrayList<>(), Optional.of(initialConstraints.getFirst())), steps.get(1));
} }
@Test @Test

View File

@ -0,0 +1,16 @@
package edu.kit.typicalc.view.content.typeinferencecontent.latexcreator;
import edu.kit.typicalc.model.Model;
import edu.kit.typicalc.model.ModelImpl;
import edu.kit.typicalc.model.TypeInfererInterface;
import org.junit.jupiter.api.Test;
import java.util.Locale;
public class ExplanationCreatorTest {
@Test
void itWorks() {
TypeInfererInterface model = new ModelImpl().getTypeInferer("λx.x", "").unwrap();
new ExplanationCreator(model, Locale.GERMAN).getExplanationTexts();
}
}