001package de.monochromata.anaphors.cog; 002 003import static java.util.Arrays.asList; 004import static java.util.stream.Collectors.toList; 005import static java.util.stream.Stream.empty; 006 007import java.util.Collections; 008import java.util.List; 009import java.util.stream.Stream; 010 011import de.monochromata.anaphors.ast.ASTBasedAnaphorResolution; 012import de.monochromata.anaphors.ast.ASTBasedAnaphora; 013import de.monochromata.anaphors.ast.relatedexp.RelatedExpression; 014import de.monochromata.anaphors.ast.spi.TransformationsSpi; 015import de.monochromata.anaphors.cog.memory.Chunk; 016import de.monochromata.anaphors.cog.memory.Memory; 017import de.monochromata.anaphors.cog.spi.CogSpi; 018import de.monochromata.anaphors.cog.transform.AddParameterToCallChain; 019import de.monochromata.anaphors.cog.transform.CheckResult; 020import de.monochromata.anaphors.cog.transform.NoPreparationRequired; 021import de.monochromata.anaphors.cog.transform.PreparatoryTransformation; 022 023/** 024 * Resolve the referents of anaphors based on a cognitive model. 025 * 026 * @param <N> The node type in the AST 027 * @param <E> The expression type 028 * @param <T> The type type 029 * @param <B> The binding type 030 * @param <TB> The type binding type 031 * @param <S> The scope type (optional) 032 * @param <I> The type used to represent identifiers 033 * @param <QI> The type used to represent qualified identifiers 034 * @param <R> The sub-type of related expression to use 035 * @param <A> The sub-type of AST-based anaphora to use 036 */ 037public class ActivationBasedAnaphorResolution<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>> { 038 039 private final List<PreparatoryTransformation<N, E, T, B, TB, S, I, QI, R, A>> preparatoryTransformations; 040 private final ASTBasedAnaphorResolution<N, E, T, B, TB, S, I, QI, R, A> delegate; 041 042 /** 043 * Used in contract testing. 044 */ 045 @SuppressWarnings("unused") 046 protected ActivationBasedAnaphorResolution() { 047 delegate = null; 048 preparatoryTransformations = null; 049 } 050 051 public ActivationBasedAnaphorResolution(final ASTBasedAnaphorResolution<N, E, T, B, TB, S, I, QI, R, A> delegate, 052 final TransformationsSpi<N, E, T, B, TB, S, I, QI, R, A> transformationsSpi) { 053 this.delegate = delegate; 054 this.preparatoryTransformations = asList(new NoPreparationRequired<>(transformationsSpi), 055 new AddParameterToCallChain<>(transformationsSpi)); 056 } 057 058 /** 059 * Perform anaphora resolution on the AST implementation configured via the 060 * service provider interfaces. 061 * <p> 062 * TODO: Evaluate whether anaphora relations can be transformed into AST-based 063 * anaphora relations 064 * <p> 065 * TODO: Provide means to transform these anaphora relations into AST-based 066 * anaphora relations by performing complex AST manipulations / refactorings 067 * like introducing parameters to multiple methods ... 068 * <ol> 069 * <li>Find ways to create Anaphora relations 070 * <li>This might include a preparation step that performs complex AST 071 * transformations that prepare the referentialization of the anaphor 072 * </ol> 073 * 074 * @param anaphor The anaphor that is to be (re-)resolved. 075 * @param definiteExpression The expression that may function as anaphor 076 * in the anaphora relation to be generated by 077 * this method. If the anaphora relation is to 078 * be re-resolved, this can be a non-trivial 079 * expression. If the anaphora relation is to be 080 * resolved for the first time, this is 081 * typically a simple name and might as well be 082 * called a definite expression at this point. 083 * @param scope May be null if not required by the AST 084 * implementation configured via the service 085 * provider interfaces. 086 * @param timestamp the point in time at which the memory access 087 * occurs (in the format returned by 088 * {@link System#currentTimeMillis()} 089 * @param numberOfChunksToConsider The maximum number of chunks to consider as 090 * potential related expressions. 091 * @return TODO: Rework: A list of anaphors that the given definite expression 092 * can function as. The list is empty is the anaphor could not be 093 * resolved and will contain more than one element if the anaphor is 094 * ambiguous. 095 */ 096 public List<Resolution<N, E, T, B, TB, S, I, QI, R, A>> resolveAnaphor(final String anaphor, 097 final E definiteExpression, final S scope, final long timestamp, final int numberOfChunksToConsider) { 098 final Memory<N> memory = CogSpi.getMemory(); 099 if (memory == null) { 100 return Collections.emptyList(); 101 } 102 return memory.getChunks(timestamp, numberOfChunksToConsider).stream() 103 .flatMap(chunk -> resolve(chunk, anaphor, definiteExpression, scope)).collect(toList()); 104 } 105 106 protected Stream<Resolution<N, E, T, B, TB, S, I, QI, R, A>> resolve(final Chunk<N> chunk, final String anaphor, 107 final E definiteExpression, final S scope) { 108 for (final PreparatoryTransformation<N, E, T, B, TB, S, I, QI, R, A> preparatoryTransformation : preparatoryTransformations) { 109 final CheckResult<N, E, S> result = preparatoryTransformation.canPerform(chunk, definiteExpression, scope); 110 if (result.canPerformTransformation()) { 111 @SuppressWarnings("unchecked") 112 final R potentialRelatedExpression = delegate.getRelatedExpression(result.getChunk().getRepresented()); 113 if (potentialRelatedExpression != null) { 114 // TODO: Die Prüfung, ob AST-basierte Anaphern anwendbar 115 // sind, muss anhand des Chunks als potential related 116 // expression erfolgen und darf dann nicht reachability 117 // involvieren ... 118 return delegate.resolveAnaphor(potentialRelatedExpression, anaphor, definiteExpression, scope) 119 .stream().map(anaphora -> createResolution(result, preparatoryTransformation, anaphora)); 120 } 121 } 122 } 123 return empty(); 124 } 125 126 protected Resolution<N, E, T, B, TB, S, I, QI, R, A> createResolution(final CheckResult<N, E, S> checkResult, 127 final PreparatoryTransformation<N, E, T, B, TB, S, I, QI, R, A> preparatoryTransformation, 128 final A preliminaryAnaphora) { 129 return new DefaultResolution<>(checkResult, preparatoryTransformation, preliminaryAnaphora); 130 } 131 132}