Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Complete overhaul of Inequality Theory #86

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
07e3f06
add suffix restrictions
FredrikTaquist Jan 19, 2024
ea85e14
fix issues and add toString
FredrikTaquist Jan 19, 2024
c2b4eec
use restriction data structures in tree queries
FredrikTaquist Jan 19, 2024
311fa88
change coalesceSuffix to use restrictions
FredrikTaquist Jan 25, 2024
feeb011
make restrictions theory-specific
FredrikTaquist Feb 1, 2024
85f2b9e
use restrictions when extending distinguishing suffix
FredrikTaquist Feb 1, 2024
f638869
use restrictions when extending suffixes; add option to require suffi…
FredrikTaquist Feb 2, 2024
1e2d8d4
add tests for extending suffixes with registers; fix test failures
FredrikTaquist Feb 2, 2024
3090cd5
fix incorrect optimization for register closedness
FredrikTaquist Apr 15, 2024
c2080c9
cleanup
FredrikTaquist Apr 15, 2024
079a85d
add missing changes
FredrikTaquist Apr 15, 2024
fee6d26
merge with main; resolve merge conflicts
FredrikTaquist Apr 17, 2024
d0c9d53
remove old suffix optimization code
FredrikTaquist Apr 17, 2024
202776d
Merge branch 'main' into restricted-suffixes
FredrikTaquist Apr 17, 2024
e0feb87
correct values for tests of number of resets
FredrikTaquist Apr 19, 2024
1d0c51c
add test case for covering all equivalence classes in tree queries
FredrikTaquist Apr 19, 2024
f5ee896
add missing code
FredrikTaquist Apr 19, 2024
6aea50b
add test cases for branch merging
FredrikTaquist May 10, 2024
1e9ae0b
rework how tree queries are computed
FredrikTaquist May 29, 2024
6a096de
remove commented out code and uncalled methods
FredrikTaquist May 29, 2024
ea59c3f
extend interval guards to handle closed intervals
FredrikTaquist May 30, 2024
a7924a8
suffix optimization for inequality theory
FredrikTaquist Jun 3, 2024
b3f7c6a
tests and fixes for suffix optimization
FredrikTaquist Jun 10, 2024
7bc373c
remove commented out code and uncalled methods
FredrikTaquist Jun 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ public boolean isSatisfied(Mapping<SymbolicDataValue, DataValue<?>> val) {
return !lv.equals(rv);
case BIGGER:
case SMALLER:
case BIGGER_OR_EQUAL:
case SMALLER_OR_EQUAL:
return numCompare(lv, rv, relation);

default:
Expand Down Expand Up @@ -116,8 +118,12 @@ private boolean numCompare(DataValue l, DataValue r, Relation relation) {
switch (relation) {
case SMALLER:
return result < 0;
case SMALLER_OR_EQUAL:
return result < 0 || result == 0;
case BIGGER:
return result > 0;
case BIGGER_OR_EQUAL:
return result > 0 || result == 0;

default:
throw new UnsupportedOperationException(
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/de/learnlib/ralib/automata/guards/Relation.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
public enum Relation {

SMALLER("<"),
SMALLER_OR_EQUAL("<="),
BIGGER(">"),
BIGGER_OR_EQUAL(">="),
EQUALS("=="),
NOT_EQUALS("!=");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,18 @@ else if (pred.contains("!!")) {
related = pred.split("!!");
relation = Relation.NOT_EQUALS;
}
else if (pred.contains("<=")) {
related = pred.split("<=");
relation = Relation.SMALLER_OR_EQUAL;
}
else if (pred.contains("<")) {
related = pred.split("<");
relation = Relation.SMALLER;
}
else if (pred.contains(">=")) {
related = pred.split(">=");
relation = Relation.BIGGER_OR_EQUAL;
}
else if (pred.contains(">")) {
related = pred.split(">");
relation = Relation.BIGGER;
Expand Down
16 changes: 12 additions & 4 deletions src/main/java/de/learnlib/ralib/ceanalysis/PrefixFinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import de.learnlib.ralib.oracles.SDTLogicOracle;
import de.learnlib.ralib.oracles.TreeOracle;
import de.learnlib.ralib.oracles.TreeQueryResult;
import de.learnlib.ralib.oracles.mto.MultiTheoryTreeOracle;
import de.learnlib.ralib.oracles.mto.SymbolicSuffixRestrictionBuilder;
import de.learnlib.ralib.words.DataWords;
import de.learnlib.ralib.words.PSymbolInstance;
import de.learnlib.ralib.words.ParameterizedSymbol;
Expand All @@ -45,6 +47,7 @@ public class PrefixFinder {

private final SDTLogicOracle sdtOracle;

private final SymbolicSuffixRestrictionBuilder restrictionBuilder;
//private Map<Word<PSymbolInstance>, LocationComponent> components;

private final Constants consts;
Expand All @@ -67,6 +70,11 @@ public PrefixFinder(TreeOracle sulOracle, TreeOracle hypOracle,
this.sdtOracle = sdtOracle;
//this.components = components;
this.consts = consts;
if (sulOracle instanceof MultiTheoryTreeOracle) {
this.restrictionBuilder = new SymbolicSuffixRestrictionBuilder(consts, ((MultiTheoryTreeOracle)sulOracle).getTeachers());
} else {
this.restrictionBuilder = new SymbolicSuffixRestrictionBuilder(consts);
}
}

public CEAnalysisResult analyzeCounterexample(Word<PSymbolInstance> ce) {
Expand Down Expand Up @@ -102,7 +110,7 @@ private int findIndex(Word<PSymbolInstance> ce) {
// check for location counterexample ...
//
Word<PSymbolInstance> suffix = ce.suffix(ce.length() - nextPrefix.length());
SymbolicSuffix symSuffix = new SymbolicSuffix(nextPrefix, suffix, consts);
SymbolicSuffix symSuffix = new SymbolicSuffix(nextPrefix, suffix, restrictionBuilder);
LOC_CHECK: for (Word<PSymbolInstance> u : hypothesis.possibleAccessSequences(prefix)) {
Word<PSymbolInstance> uAlpha = hypothesis.transformTransitionSequence(nextPrefix, u);
TreeQueryResult uAlphaResult = sulOracle.treeQuery(uAlpha, symSuffix);
Expand Down Expand Up @@ -179,7 +187,7 @@ private boolean transitionHasCE(Word<PSymbolInstance> ce, int idx) {
Word<PSymbolInstance> prefix = ce.prefix(idx+1);

Word<PSymbolInstance> suffix = ce.suffix(ce.length() - (idx+1));
SymbolicSuffix symSuffix = new SymbolicSuffix(prefix, suffix, consts);
SymbolicSuffix symSuffix = new SymbolicSuffix(prefix, suffix, restrictionBuilder);

Set<Word<PSymbolInstance>> locations = hypothesis.possibleAccessSequences(prefix);
for (Word<PSymbolInstance> location : locations) {
Expand Down Expand Up @@ -217,7 +225,7 @@ private void storeCandidateCEs(Word<PSymbolInstance> ce, int idx) {
Word<PSymbolInstance> prefix = ce.prefix(idx+1);

Word<PSymbolInstance> suffix = ce.suffix(ce.length() - (idx+1));
SymbolicSuffix symSuffix = new SymbolicSuffix(prefix, suffix, consts);
SymbolicSuffix symSuffix = new SymbolicSuffix(prefix, suffix, restrictionBuilder);

Set<Word<PSymbolInstance>> locations = hypothesis.possibleAccessSequences(prefix);
for (Word<PSymbolInstance> location : locations) {
Expand Down Expand Up @@ -264,7 +272,7 @@ private SymbolicWord candidate(Word<PSymbolInstance> prefix,

if (exprR.isSatisfied(vals)) {
candidate = path.prefix(prefix.length() + 1);
SymbolicSuffix suffix = new SymbolicSuffix(candidate, ce.suffix(symSuffix.length() - 1), consts);
SymbolicSuffix suffix = new SymbolicSuffix(candidate, ce.suffix(symSuffix.length() - 1), restrictionBuilder);
return new SymbolicWord(candidate, suffix);
}
}
Expand Down
14 changes: 13 additions & 1 deletion src/main/java/de/learnlib/ralib/dt/DT.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@
import de.learnlib.ralib.learning.ralambda.RaLambda;
import de.learnlib.ralib.oracles.TreeOracle;
import de.learnlib.ralib.oracles.TreeQueryResult;
import de.learnlib.ralib.oracles.mto.MultiTheoryTreeOracle;
import de.learnlib.ralib.oracles.mto.OptimizedSymbolicSuffixBuilder;
import de.learnlib.ralib.oracles.mto.SDT;
import de.learnlib.ralib.oracles.mto.SDTLeaf;
import de.learnlib.ralib.oracles.mto.SymbolicSuffixRestrictionBuilder;
import de.learnlib.ralib.theory.SDTGuard;
import de.learnlib.ralib.theory.SDTTrueGuard;
import de.learnlib.ralib.words.OutputSymbol;
Expand All @@ -48,12 +50,17 @@ public class DT implements DiscriminationTree {
private boolean ioMode;
private final Constants consts;
private DTLeaf sink = null;
private final SymbolicSuffixRestrictionBuilder restrictionBuilder;

public DT(TreeOracle oracle, boolean ioMode, Constants consts, ParameterizedSymbol... inputs) {
this.oracle = oracle;
this.ioMode = ioMode;
this.inputs = inputs;
this.consts = consts;
if (oracle instanceof MultiTheoryTreeOracle)
this.restrictionBuilder = new SymbolicSuffixRestrictionBuilder(consts, ((MultiTheoryTreeOracle)oracle).getTeachers());
else
this.restrictionBuilder = new SymbolicSuffixRestrictionBuilder(consts);

Word<PSymbolInstance> epsilon = Word.epsilon();
SymbolicSuffix suffEps = new SymbolicSuffix(epsilon, epsilon);
Expand All @@ -67,13 +74,18 @@ public DT(DTInnerNode root, TreeOracle oracle, boolean ioMode, Constants consts,
this.ioMode = ioMode;
this.inputs = inputs;
this.consts = consts;
if (oracle instanceof MultiTheoryTreeOracle)
this.restrictionBuilder = new SymbolicSuffixRestrictionBuilder(consts, ((MultiTheoryTreeOracle)oracle).getTeachers());
else
this.restrictionBuilder = new SymbolicSuffixRestrictionBuilder(consts);
}

public DT(DT dt) {
this.inputs = dt.inputs;
this.oracle = dt.oracle;
this.ioMode = dt.ioMode;
this.consts = dt.consts;
this.restrictionBuilder = dt.restrictionBuilder;

root = new DTInnerNode(dt.root);
}
Expand Down Expand Up @@ -247,7 +259,7 @@ public void addSuffix(SymbolicSuffix suffix, DTLeaf leaf) {
public boolean addLocation(Word<PSymbolInstance> target, DTLeaf src_c, DTLeaf dest_c, DTLeaf target_c) {

Word<PSymbolInstance> prefix = target.prefix(target.length() - 1);
SymbolicSuffix suff1 = new SymbolicSuffix(prefix, target.suffix(1), consts);
SymbolicSuffix suff1 = new SymbolicSuffix(prefix, target.suffix(1), restrictionBuilder);
SymbolicSuffix suff2 = findLCA(dest_c, target_c).getSuffix();
SymbolicSuffix suffix = suff1.concat(suff2);

Expand Down
4 changes: 3 additions & 1 deletion src/main/java/de/learnlib/ralib/dt/DTLeaf.java
Original file line number Diff line number Diff line change
Expand Up @@ -487,8 +487,10 @@ private boolean checkVariableConsistency(MappedPrefix mp, DT dt, Constants const
for (SymbolicSuffix suffix : suffixes) {
TreeQueryResult suffixTQR = mp.getTQRs().get(suffix);
SymbolicDecisionTree sdt = suffixTQR.getSdt();
// suffixBuilder == null ==> suffix.isOptimizedGeneric()
assert suffixBuilder != null || suffix.isOptimizationGeneric() : "Optimized with restriction builder, but no restriction builder provided";
SymbolicSuffix newSuffix = suffixBuilder != null && sdt instanceof SDT ?
suffixBuilder.extendSuffix(mp.getPrefix(), (SDT)sdt, suffixTQR.getPiv(), suffix) :
suffixBuilder.extendSuffix(mp.getPrefix(), (SDT)sdt, suffixTQR.getPiv(), suffix, suffixTQR.getPiv().get(p)) :
new SymbolicSuffix(mp.getPrefix(), suffix, consts);
if (prefixSuffixes.contains(newSuffix))
continue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import de.learnlib.ralib.oracles.SDTLogicOracle;
import de.learnlib.ralib.oracles.TreeOracle;
import de.learnlib.ralib.oracles.TreeQueryResult;
import de.learnlib.ralib.oracles.mto.MultiTheoryTreeOracle;
import de.learnlib.ralib.oracles.mto.SymbolicSuffixRestrictionBuilder;
import de.learnlib.ralib.words.PSymbolInstance;
import de.learnlib.ralib.words.ParameterizedSymbol;
import net.automatalib.word.Word;
Expand All @@ -50,6 +52,8 @@ public class CounterexampleAnalysis {

private final SDTLogicOracle sdtOracle;

private final SymbolicSuffixRestrictionBuilder restrictionBuilder;

private final Map<Word<PSymbolInstance>, LocationComponent> components;

private final Constants consts;
Expand All @@ -68,6 +72,11 @@ public CounterexampleAnalysis(TreeOracle sulOracle, TreeOracle hypOracle,
this.sdtOracle = sdtOracle;
this.components = components;
this.consts = consts;
if (sulOracle instanceof MultiTheoryTreeOracle) {
this.restrictionBuilder = new SymbolicSuffixRestrictionBuilder(consts, ((MultiTheoryTreeOracle)sulOracle).getTeachers());
} else {
this.restrictionBuilder = new SymbolicSuffixRestrictionBuilder(consts);
}
}

public CEAnalysisResult analyzeCounterexample(Word<PSymbolInstance> ce) {
Expand All @@ -77,7 +86,7 @@ public CEAnalysisResult analyzeCounterexample(Word<PSymbolInstance> ce) {

Word<PSymbolInstance> prefix = ce.prefix(idx);
Word<PSymbolInstance> suffix = ce.suffix(ce.length() -idx);
SymbolicSuffix symSuffix = new SymbolicSuffix(prefix, suffix, consts);
SymbolicSuffix symSuffix = new SymbolicSuffix(prefix, suffix, restrictionBuilder);

return new CEAnalysisResult(prefix, symSuffix);
}
Expand All @@ -91,7 +100,7 @@ private IndexResult computeIndex(Word<PSymbolInstance> ce, int idx) {
ce.prefix(idx+1));

Word<PSymbolInstance> suffix = ce.suffix(ce.length() -idx);
SymbolicSuffix symSuffix = new SymbolicSuffix(prefix, suffix, consts);
SymbolicSuffix symSuffix = new SymbolicSuffix(prefix, suffix, restrictionBuilder);

TreeQueryResult resHyp = hypOracle.treeQuery(location, symSuffix);
TreeQueryResult resSul = sulOracle.treeQuery(location, symSuffix);
Expand Down
31 changes: 20 additions & 11 deletions src/main/java/de/learnlib/ralib/learning/MeasuringOracle.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,32 @@

import java.util.Map;

import de.learnlib.ralib.data.Constants;
import de.learnlib.ralib.data.DataType;
import de.learnlib.ralib.data.PIV;
import de.learnlib.ralib.oracles.Branching;
import de.learnlib.ralib.oracles.TreeOracle;
import de.learnlib.ralib.oracles.DataWordOracle;
import de.learnlib.ralib.oracles.TreeQueryResult;
import de.learnlib.ralib.oracles.mto.MultiTheoryTreeOracle;
import de.learnlib.ralib.solver.ConstraintSolver;
import de.learnlib.ralib.theory.Theory;
import de.learnlib.ralib.words.PSymbolInstance;
import de.learnlib.ralib.words.ParameterizedSymbol;
import net.automatalib.word.Word;

public class MeasuringOracle implements TreeOracle {

private final TreeOracle oracle;
public class MeasuringOracle extends MultiTheoryTreeOracle {

private final Measurements result;

public MeasuringOracle(TreeOracle oracle, Measurements m) {
this.oracle = oracle;
this.result = m;
public MeasuringOracle(DataWordOracle oracle, Map<DataType, Theory> teachers, Constants constants,
ConstraintSolver solver, Measurements m) {
super(oracle, teachers, constants, solver);
result = m;
}

public MeasuringOracle(MultiTheoryTreeOracle mto, Measurements m) {
super(mto);
result = m;
}

@Override
Expand All @@ -29,24 +38,24 @@ public TreeQueryResult treeQuery(Word<PSymbolInstance> prefix, SymbolicSuffix su
result.treeQueryWords.put(key, result.treeQueryWords.get(key) + 1);
else
result.treeQueryWords.put(key, 1);
return oracle.treeQuery(prefix, suffix);
return super.treeQuery(prefix, suffix);
}

@Override
public Branching getInitialBranching(Word<PSymbolInstance> prefix, ParameterizedSymbol ps, PIV piv,
SymbolicDecisionTree... sdts) {
return oracle.getInitialBranching(prefix, ps, piv, sdts);
return super.getInitialBranching(prefix, ps, piv, sdts);
}

@Override
public Branching updateBranching(Word<PSymbolInstance> prefix, ParameterizedSymbol ps, Branching current, PIV piv,
SymbolicDecisionTree... sdts) {
return oracle.updateBranching(prefix, ps, current, piv, sdts);
return super.updateBranching(prefix, ps, current, piv, sdts);
}

@Override
public Map<Word<PSymbolInstance>, Boolean> instantiate(Word<PSymbolInstance> prefix, SymbolicSuffix suffix,
SymbolicDecisionTree sdt, PIV piv) {
return oracle.instantiate(prefix, suffix, sdt, piv);
return super.instantiate(prefix, suffix, sdt, piv);
}
}
Loading