All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.learnlib.api.query.OmegaQuery Maven / Gradle / Ivy

There is a newer version: 0.17.0
Show newest version
/* Copyright (C) 2013-2020 TU Dortmund
 * This file is part of LearnLib, http://www.learnlib.de/.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.learnlib.api.query;

import java.util.Objects;

import de.learnlib.api.ObservableSUL;
import net.automatalib.words.Word;
import net.automatalib.words.WordBuilder;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
 * A query that represents information about infinite words in an ultimately periodic pattern. That is, for two finite
 * strings u, v, this class represents the query of the infinite word uvω.
 * 

* When answering OmegaQueries, one needs to specify the periodicity p of the looping suffix v, i.e. for * what p the answer contains information about the response to the query uvp (which can then * be generalized to the infinite case since u(vp)ω = uvω. *

* If one cannot determine this value (e.g. because the response exhibits a non periodic pattern), one may specify a * negative value for p. {@link #isUltimatelyPeriodic()} then consequently returns {@code false}. In this case * the output of the query ({@link #getOutput()}) may be undefined. * * @param * the input type * @param * the output type * * @see DefaultQuery * @see Query * @see ObservableSUL#getState() */ public class OmegaQuery { private final Word prefix; private final Word loop; private final int repeat; private @Nullable D output; private int periodicity; public OmegaQuery(Word prefix, Word loop, int repeat) { this.prefix = prefix; this.loop = loop; this.repeat = repeat; } public void answer(@Nullable D output, int periodicity) { this.output = output; this.periodicity = periodicity; } public Word getPrefix() { return prefix; } public Word getLoop() { return loop; } public int getRepeat() { return repeat; } public @Nullable D getOutput() { return output; } public int getPeriodicity() { return periodicity; } public boolean isUltimatelyPeriodic() { return periodicity > 0; } public DefaultQuery asDefaultQuery() { final WordBuilder wb = new WordBuilder<>(prefix.length() + loop.length() * periodicity); wb.append(prefix); wb.repeatAppend(periodicity, loop); return new DefaultQuery<>(wb.toWord(), output); } @Override public String toString() { return "OmegaQuery{" + "prefix=" + prefix + ", loop=" + loop + ", repeat=" + repeat + ", output=" + output + ", periodicity=" + periodicity + '}'; } @Override public final boolean equals(@Nullable Object o) { if (this == o) { return true; } if (!(o instanceof OmegaQuery)) { return false; } final OmegaQuery that = (OmegaQuery) o; return periodicity == that.periodicity && Objects.equals(prefix, that.prefix) && Objects.equals(loop, that.loop) && Objects.equals(output, that.output); } @Override public final int hashCode() { int result = 1; result = 31 * result + Objects.hashCode(prefix); result = 31 * result + Objects.hashCode(loop); result = 31 * result + Objects.hashCode(output); result = 31 * result + Integer.hashCode(periodicity); return result; } }