001package de.monochromata.anaphors.ast.unify;
002
003import java.util.ArrayList;
004import java.util.List;
005import java.util.function.BiPredicate;
006
007import de.monochromata.anaphors.ast.ASTBasedAnaphora;
008import de.monochromata.anaphors.ast.relatedexp.RelatedExpression;
009
010public interface Unification {
011
012        static <N, T, B, TB extends B, S, QI, R extends RelatedExpression<N, T, B, TB, S, QI, R>> List<R> unifyCoReferentialRelatedExpressions(
013                        final List<R> potentialRelatedExpressions) {
014                return unifyListElements(potentialRelatedExpressions, (re1, re2) -> re1.canBeUsedInsteadOf(re2));
015        }
016
017        static <N, E, T, B, TB extends B, S, I, QI, R extends RelatedExpression<N, T, B, TB, S, QI, R>, A extends ASTBasedAnaphora<N, E, T, B, TB, S, I, QI, R, A>> List<A> unifyCoReferentialReferents(
018                        final List<A> potentialAnaphoraRelations) {
019                return unifyListElements(potentialAnaphoraRelations,
020                                (anaphora1, anaphora2) -> anaphora1.getReferent().canBeUsedInsteadOf(anaphora2.getReferent()));
021        }
022
023        static <N, E, T, B, TB extends B, S, I, QI, R extends RelatedExpression<N, T, B, TB, S, QI, R>, A extends ASTBasedAnaphora<N, E, T, B, TB, S, I, QI, R, A>> boolean haveEqualReferent(
024                        final A anaphora1, final A anaphora2) {
025                return anaphora1.getReferent().equals(anaphora2.getReferent());
026        }
027
028        static <T> List<T> unifyListElements(final List<T> elements, final BiPredicate<T, T> check) {
029                final List<T> retainedElements = new ArrayList<>();
030                final List<T> omittedElements = new ArrayList<>();
031                for (final T toCheck : elements) {
032                        if (!omittedElements.contains(toCheck)) {
033                                boolean retainedInsteadOfAnotherOne = false;
034                                for (final T other : elements) {
035                                        if (toCheck != other && check.test(toCheck, other)) {
036                                                if (!retainedInsteadOfAnotherOne) {
037                                                        retainedElements.add(toCheck);
038                                                        retainedInsteadOfAnotherOne = true;
039                                                }
040                                                System.err.println("Omitting " + other + " in favour of " + toCheck);
041                                                omittedElements.add(other);
042                                                retainedElements.remove(other);
043                                        }
044                                }
045                                if (!retainedInsteadOfAnotherOne) {
046                                        retainedElements.add(toCheck);
047                                }
048                        }
049                }
050                return retainedElements;
051        }
052
053}