001package de.monochromata.anaphors.ast.strategy;
002
003import java.util.List;
004import java.util.Optional;
005
006import de.monochromata.Strategy;
007import de.monochromata.anaphors.ast.ASTBasedAnaphora;
008import de.monochromata.anaphors.ast.AnaphorPart;
009import de.monochromata.anaphors.ast.RelatedExpressionPart;
010import de.monochromata.anaphors.ast.reference.Referent;
011import de.monochromata.anaphors.ast.reference.strategy.ReferentializationStrategy;
012import de.monochromata.anaphors.ast.relatedexp.RelatedExpression;
013import de.monochromata.anaphors.ast.relatedexp.strategy.LocalTempVariableContents;
014import de.monochromata.anaphors.ast.relatedexp.strategy.LocalTempVariableIntroducingStrategy;
015import de.monochromata.anaphors.ast.relatedexp.strategy.RelatedExpressionStrategy;
016import de.monochromata.anaphors.perspectivation.Perspectivation;
017
018/**
019 * A strategy for resolving or constructing the referents of anaphors.
020 *
021 * @param <N>  The node type in the AST
022 * @param <E>  The expression type
023 * @param <T>  The type type
024 * @param <B>  The binding type
025 * @param <TB> The type binding type
026 * @param <S>  The scope type (optional)
027 * @param <I>  The type used to represent identifiers
028 * @param <QI> The type used to represent qualified identifiers
029 * @param <R>  The sub-type of related expression to use
030 * @param <A>  The sub-type of AST-based anaphora to use
031 */
032public interface AnaphorResolutionStrategy<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>>
033        extends Strategy {
034
035    /**
036     * Used to decide whether this strategy can create potential anaphora relations
037     * for the given potential related expression.
038     */
039    public boolean canRelateTo(
040            final RelatedExpressionStrategy<N, T, B, TB, S, QI, R> potentialRelatedExpressionStrategy);
041
042    /**
043     * Generates a list of potential {@link ASTBasedAnaphora} relations. Invokes
044     * {@link #canRelateTo(RelatedExpressionStrategy)} and
045     * {@link #createAnaphora(Object, String, Object, RelatedExpression, Referent, ReferentializationStrategy)}
046     * .
047     *
048     * @param scope                       The scope containing the anaphor if used
049     *                                    by the compiler-specific implementation.
050     *                                    Implementations of this method must not
051     *                                    access the scope but merely pass it on to
052     *                                    SPI's they invoke.
053     * @param anaphor                     The anaphor that is to be (re-)resolved.
054     * @param anaphorExpression           The expression that may function as
055     *                                    anaphor in the anaphora relation to be
056     *                                    generated by this method. If the anaphora
057     *                                    relation is to be re-resolved, this can be
058     *                                    a non-trivial expression. If the anaphora
059     *                                    relation is to be resolved for the first
060     *                                    time, this is typically a simple name and
061     *                                    might as well be called a definite
062     *                                    expression at this point.
063     * @param potentialRelatedExpressions Related expressions that could potentially
064     *                                    constitute an anaphora relation with the
065     *                                    given anaphor.
066     * @param refStrategies               Referentialisation strategies to be used
067     *                                    to generate anaphora relations.
068     * @return A list of potential anaphora relations.
069     * @see #canRelateTo(RelatedExpressionStrategy)
070     * @see #createAnaphora(Object, String, Object, RelatedExpression, Referent,
071     *      ReferentializationStrategy)
072     */
073    public List<A> generatePotentialAnaphora(S scope, String anaphor, E anaphorExpression,
074            List<R> potentialRelatedExpressions, List<ReferentializationStrategy<E, TB, S, I, QI>> refStrategies);
075
076    /**
077     * Create a single potential {@link ASTBasedAnaphora} relation for a pair of
078     * anaphor (TODO: definite expression) and a potential related expression.
079     *
080     * @param scope                      The scope containing the anaphor if used by
081     *                                   the compiler-specific implementation.
082     *                                   Implementations of this method must not
083     *                                   access the scope but merely pass it on to
084     *                                   SPI's they invoke.
085     * @param anaphor                    The anaphor that is to be (re-)resolved.
086     * @param anaphorExpression          The expression that may function as anaphor
087     *                                   in the anaphora relation to be generated by
088     *                                   this method. If the anaphora relation is to
089     *                                   be re-resolved, this can be a non-trivial
090     *                                   expression. If the anaphora relation is to
091     *                                   be resolved for the first time, this is
092     *                                   typically a simple name and might as well
093     *                                   be called a definite expression at this
094     *                                   point.
095     * @param potentialRelatedExpression A related expression that could potentially
096     *                                   constitute an anaphora relation with the
097     *                                   given anaphor.
098     * @param potentialReferent          As e.g. returned by
099     *                                   {@link AbstractAnaphorResolutionStrategy#createPotentialReferents(Object, RelatedExpression)}
100     *                                   of this instance.
101     * @param refStrategy                The referentialization strategies to be
102     *                                   used to generate the anaphora relation.
103     * @return A list of potential anaphora relations.
104     */
105    public A createAnaphora(S scope, String anaphor, E anaphorExpression, R potentialRelatedExpression,
106            Referent<TB, S, I, QI> potentialReferent, ReferentializationStrategy<E, TB, S, I, QI> refStrategy);
107
108    /**
109     * Re-creates a referent from a given related expression and memento.
110     * <p>
111     * TODO: This method should be renamed to reCreateReferent(...)
112     * <p>
113     * TODO: When should this method be used?
114     *
115     * @param scope             The scope containing the anaphor if used by the
116     *                          compiler-specific implementation. Implementations of
117     *                          this method must not access the scope but merely
118     *                          pass it on to SPI's they invoke.
119     * @param relatedExpression Related expressions that could potentially
120     *                          constitute an anaphora relation with the given
121     *                          anaphor.
122     * @param memento           A compiler-specific memento used to reconstruct the
123     *                          referent.
124     * @return The re-constructed referent.
125     * @throws IllegalArgumentException If the referent cannot be re-created from
126     *                                  the given related expression and memento
127     * @see Referent#getMemento()
128     */
129    public Referent<TB, S, I, QI> createReferent(S scope, R relatedExpression, Object memento);
130
131    /**
132     * Replaces the anaphor of the given anaphora relation.
133     *
134     * Note that this method will replace AST nodes in the given anaphora instance
135     * if realization involves replacing AST nodes.
136     *
137     * @param replacee        The anaphor node that will be replaced. TODO: Is this
138     *                        the anaphor, really?
139     * @param guessedTempName If the given related expression part has a
140     *                        {@link LocalTempVariableIntroducingStrategy}, the
141     *                        strategy introduced a temporary variable that might be
142     *                        used by the anaphor resolution strategy to generate
143     *                        code for the anaphors.
144     * @param support         Optional compiler-specific support objects.
145     *                        Implementations of this method must not access the
146     *                        support objects but merely pass them on to SPI's they
147     *                        invoke.
148     * @return The node that replaced the anaphor.
149     * @see ASTBasedAnaphora#getAnaphor()
150     */
151    public E realize(RelatedExpressionPart<N, E, T, B, TB, S, I, QI, R> relatedExpressionPart,
152            AnaphorPart<N, E, T, B, TB, S, I, QI, R, A> anaphorPart, E replacee, Optional<I> guessedTempName,
153            Object... support);
154
155    public List<Perspectivation> underspecifyAnaphor(final R relatedExpression, final String anaphor,
156            final E anaphorExpression, final Referent<TB, S, I, QI> referent, final S scope);
157
158    LocalTempVariableContents getLocalTempVariableContents();
159
160    /**
161     * To be invoked when a related expression resolved with this strategy is
162     * realized to obtain the kind of anaphor resolution strategy that applies after
163     * realization.
164     * <p>
165     * That realized kind will also apply when the anaphora is re-resolved. Thus
166     * setting the realized kind in the beginning will avoid a faux change being
167     * detected during re-resolution of the unmodified anaphora relation.
168     */
169    String getKindOfAnaphorResolutionStrategyToBeRealized(
170            final AnaphorPart<N, E, T, B, TB, S, I, QI, R, A> anaphorPart);
171
172    /**
173     * To be invoked when an anaphora resolved with this strategy is realized to
174     * obtain the kind of referentialization that applies after realization.
175     * <p>
176     * That realized kind will also apply when the anaphora is re-resolved. Thus
177     * setting the realized kind in the beginning will avoid a faux change being
178     * detected during re-resolution of the unmodified anaphora relation.
179     */
180    String getKindOfReferentializationStrategyToBeRealized(
181            final AnaphorPart<N, E, T, B, TB, S, I, QI, R, A> anaphorPart);
182
183    /**
184     * To be invoked when a related expression resolved with this strategy is
185     * realized to obtain the anaphor that will be present after realization.
186     * <p>
187     * That realized anaphor will also apply when the anaphora is re-resolved. Thus
188     * setting the realized anaphor in the beginning will avoid a faux change being
189     * detected during re-resolution of the unmodified anaphora relation.
190     */
191    String getAnaphorToBeRealized(final RelatedExpressionPart<N, E, T, B, TB, S, I, QI, R> relatedExpressionPart,
192            final List<AnaphorPart<N, E, T, B, TB, S, I, QI, R, A>> allAnaphorPartsRelatedToTheRelatedExpression,
193            final AnaphorPart<N, E, T, B, TB, S, I, QI, R, A> anaphorPart, final S scope);
194}