State.java
/**
*
* This file is part of TRIO.
*
* TRIO is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* TRIO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with TRIO. If not, see <http://www.gnu.org/licenses/>.
*/
/*
*/
package eu.diversify.trio.core.requirements.random;
import java.util.Arrays;
import java.util.List;
/**
* Hold the internal state of the expression under construction
*/
public final class State {
public static final Command ADD_REQUIRE = new AddRequire();
public static final Command ADD_AND = new AddAnd();
public static final Command ADD_OR = new AddOr();
public static final Command ADD_NOT = new AddNot();
/*
* Below are the possible states depending on whether one can add leaves,
* branches or negation
*
* 000: (negationAllowed = FALSE ; isBigEnough() = FALSE ; wouldCloseTheTree() = FALSE)
*
* STATE | ADD_NOT | ADD_AND | ADD_OR | ADD_REQUIRE |
* 0: 000 | | X | X | X |
* 1: 001 | | X | X | |
* 2: 010 | | | | X |
* 3: 011 | | | | X |
* 4: 100 | X | X | X | X |
* 5: 101 | X | X | X | |
* 6: 110 | X | | | X |
* 7: 111 | X | | | X |
*
*/
private static final List[] RELEVANT_COMMANDS = new List[]{
Arrays.asList(new Command[]{ADD_AND, ADD_OR, ADD_REQUIRE}),
Arrays.asList(new Command[]{ADD_AND, ADD_OR}),
Arrays.asList(new Command[]{ADD_REQUIRE}),
Arrays.asList(new Command[]{ADD_REQUIRE}),
Arrays.asList(new Command[]{ADD_NOT, ADD_AND, ADD_OR, ADD_REQUIRE}),
Arrays.asList(new Command[]{ADD_NOT, ADD_AND, ADD_OR}),
Arrays.asList(new Command[]{ADD_NOT, ADD_REQUIRE}),
Arrays.asList(new Command[]{ADD_NOT, ADD_REQUIRE})
};
private final int desiredSize;
private int localSize;
private int minimumGlobalSize;
private int currentState;
private boolean allowNegation;
public State(int desiredSize) {
this(desiredSize, 0, 1);
}
public State(int desiredSize, int localSize, int minimumGlobalSize) {
this.desiredSize = desiredSize;
this.localSize = localSize;
this.minimumGlobalSize = minimumGlobalSize;
this.allowNegation = true;
this.currentState = compactState();
}
@SuppressWarnings("unchecked")
public List<Command> relevantCommands() {
return RELEVANT_COMMANDS[currentState];
}
private int compactState() {
return (wouldCloseTheTree() ? 1 : 0)
| (isBigEnough() ? 1 : 0) << 1
| (allowNegation ? 1 : 0) << 2;
}
private boolean wouldCloseTheTree() {
return minimumGlobalSize - localSize == 1;
}
private boolean isBigEnough() {
return desiredSize == minimumGlobalSize;
}
public void addNegation() {
allowNegation = false;
currentState = compactState();
}
public void addLeaf() {
allowNegation = true;
localSize++;
currentState = compactState();
}
public void addBranch() {
allowNegation = true;
minimumGlobalSize++;
currentState = compactState();
}
@Override
public String toString() {
return "[S=" + localSize + " ; M=" + minimumGlobalSize + "]";
}
}