cdc.applic.expressions.content.BooleanSet Maven / Gradle / Ivy
Show all versions of cdc-applic-expressions Show documentation
package cdc.applic.expressions.content;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import cdc.applic.expressions.SyntacticException;
import cdc.applic.expressions.parsing.SItemsParsing;
import cdc.graphs.PartialOrderPosition;
import cdc.util.lang.Checks;
import cdc.util.lang.CollectionUtils;
/**
* Implementation of {@link SItemSet} containing {@link BooleanSItem}s.
*
* Order of definition of SItems is lost.
* Duplicates are removed.
*
* @author Damien Carbonne
*/
public final class BooleanSet extends AbstractSItemSet
implements CheckedSet, CountableSet, Comparable {
private final boolean hasFalse;
private final boolean hasTrue;
/** Sorted (FALSE, TRUE) values. */
private final List values;
public static final Comparator LEXICOGRAPHIC_COMPARATOR = (s1,
s2) -> {
if (s1 == s2) {
return 0;
}
if (s1 == null || s2 == null) {
return s1 == null ? -1 : 1;
}
return CollectionUtils.compareLexicographic(s1.values, s2.values);
};
/** The empty {@link BooleanSet}. */
public static final BooleanSet EMPTY = new BooleanSet(false, false);
/** The {false} {@link BooleanSet}. */
public static final BooleanSet FALSE = new BooleanSet(true, false);
/** The {true} {@link BooleanSet}. */
public static final BooleanSet TRUE = new BooleanSet(false, true);
/** The {false, true} {@link BooleanSet}. */
public static final BooleanSet FALSE_TRUE = new BooleanSet(true, true);
private BooleanSet(boolean hasFalse,
boolean hasTrue) {
this.hasFalse = hasFalse;
this.hasTrue = hasTrue;
final List tmp = new ArrayList<>();
if (hasFalse) {
tmp.add(BooleanValue.FALSE);
}
if (hasTrue) {
tmp.add(BooleanValue.TRUE);
}
this.values = Collections.unmodifiableList(tmp);
}
private static BooleanSet of(boolean hasFalse,
boolean hasTrue) {
if (hasFalse) {
if (hasTrue) {
return FALSE_TRUE;
} else {
return FALSE;
}
} else {
if (hasTrue) {
return TRUE;
} else {
return EMPTY;
}
}
}
/**
* Creates a {@link BooleanSet} from the String representation of its content.
*
* @param content The content.
* @return A new instance of {@link BooleanSet}.
* @throws SyntacticException When {@code content} can not be parsed as a {@link BooleanSet}.
*/
public static BooleanSet of(String content) {
return of(SItemsParsing.toBooleanValues(content));
}
/**
* Creates a {@link BooleanSet} from an array of {@link BooleanValue BooleanValues}.
*
* @param values The values.
* @return A new instance of {@link BooleanSet}.
* @throws IllegalArgumentException When a value is {@code null}.
*/
public static BooleanSet of(BooleanValue... values) {
boolean hasFalse = false;
boolean hasTrue = false;
for (final BooleanValue value : values) {
if (BooleanValue.TRUE.equals(value)) {
hasTrue = true;
} else if (BooleanValue.FALSE.equals(value)) {
hasFalse = true;
} else {
throw new IllegalArgumentException("Unexpected value: " + value);
}
}
return of(hasFalse, hasTrue);
}
/**
* Creates a {@link BooleanSet} from a collection of {@link BooleanValue BooleanValues}.
*
* @param values The values.
* @return A new instance of {@link BooleanSet}.
* @throws IllegalArgumentException When a value is {@code null}.
*/
public static BooleanSet of(Collection values) {
final boolean hasTrue = values.contains(BooleanValue.TRUE);
final boolean hasFalse = values.contains(BooleanValue.FALSE);
return of(hasFalse, hasTrue);
}
/**
* Creates a {@link BooleanSet} from one {@link BooleanValue}.
*
* @param value The value.
* @return A new instance of {@link BooleanSet}.
* @throws IllegalArgumentException When {@code value} is {@code null}.
*/
public static BooleanSet of(BooleanValue value) {
Checks.isNotNull(value, "value");
final boolean hasFalse = BooleanValue.FALSE.equals(value);
final boolean hasTrue = BooleanValue.TRUE.equals(value);
return of(hasFalse, hasTrue);
}
/**
* Converts an {@link SItemSet} set to a {@link BooleanSet}.
*
* @param set The set.
* @return The conversion of {@code set} to a {@link BooleanSet}.
* @throws IllegalArgumentException When {@code set} can not be converted to a {@link BooleanSet}.
*/
public static BooleanSet convert(SItemSet set) {
Checks.isNotNull(set, "set");
if (set instanceof BooleanSet) {
return (BooleanSet) set;
} else if (set.isCompliantWith(BooleanSet.class)) {
// Should not throw ClassCastException
return of(convert(set.getItems(), BooleanValue.class));
} else {
throw new IllegalArgumentException("Can not convert this set to " + BooleanSet.class.getSimpleName());
}
}
@Override
public long getExtent() {
return values.size();
}
@Override
public BooleanSet getChecked() {
return this;
}
@Override
public BooleanSet getBest() {
return this;
}
@Override
public boolean isEmpty() {
return values.isEmpty();
}
@Override
public boolean containsRanges() {
return false;
}
@Override
public boolean isSingleton() {
// No intervals
return values.size() == 1;
}
@Override
public BooleanValue getSingletonValue() {
checkIsSingleton();
return values.get(0);
}
public boolean isFull() {
return values.size() == 2;
}
@Override
public boolean isValid() {
return true;
}
@Override
public boolean isChecked() {
return true;
}
@Override
public List getItems() {
return values;
}
@Override
public boolean contains(SItem item) {
Checks.isNotNull(item, ITEM);
if (item instanceof BooleanValue) {
return contains((BooleanValue) item);
} else {
return false;
}
}
@Override
public BooleanSet union(SItem item) {
Checks.isNotNull(item, ITEM);
if (item instanceof BooleanValue) {
return union((BooleanValue) item);
} else {
throw nonSupportedItem(item);
}
}
@Override
public BooleanSet union(SItemSet set) {
Checks.isNotNull(set, SET);
if (set.isCompliantWith(getClass())) {
return union(convert(set));
} else {
throw nonSupportedSet(set);
}
}
@Override
public BooleanSet intersection(SItem item) {
Checks.isNotNull(item, ITEM);
if (item instanceof BooleanValue) {
return intersection((BooleanValue) item);
} else {
throw nonSupportedItem(item);
}
}
@Override
public BooleanSet intersection(SItemSet set) {
Checks.isNotNull(set, SET);
if (set.isCompliantWith(getClass())) {
return intersection(convert(set));
} else {
throw nonSupportedSet(set);
}
}
@Override
public BooleanSet remove(SItem item) {
Checks.isNotNull(item, ITEM);
if (item instanceof BooleanValue) {
return remove((BooleanValue) item);
} else {
throw nonSupportedItem(item);
}
}
@Override
public BooleanSet remove(SItemSet set) {
Checks.isNotNull(set, SET);
if (set.isCompliantWith(getClass())) {
return remove(convert(set));
} else {
throw nonSupportedSet(set);
}
}
@Override
public boolean contains(BooleanValue value) {
Checks.isNotNull(value, VALUE);
return value.getValue() ? hasTrue : hasFalse;
}
@Override
public boolean contains(BooleanSet set) {
Checks.isNotNull(set, SET);
return (hasFalse || !set.hasFalse)
&& (hasTrue || !set.hasTrue);
}
@Override
public BooleanSet union(BooleanValue value) {
Checks.isNotNull(value, VALUE);
final boolean f = this.hasFalse || !value.getValue();
final boolean t = this.hasTrue || value.getValue();
return of(f, t);
}
@Override
public BooleanSet union(BooleanSet set) {
Checks.isNotNull(set, SET);
final boolean f = this.hasFalse || set.hasFalse;
final boolean t = this.hasTrue || set.hasTrue;
return of(f, t);
}
@Override
public BooleanSet intersection(BooleanValue value) {
Checks.isNotNull(value, VALUE);
final boolean f = this.hasFalse && !value.getValue();
final boolean t = this.hasTrue && value.getValue();
return of(f, t);
}
@Override
public BooleanSet intersection(BooleanSet set) {
Checks.isNotNull(set, SET);
final boolean f = this.hasFalse && set.hasFalse;
final boolean t = this.hasTrue && set.hasTrue;
return of(f, t);
}
@Override
public BooleanSet remove(BooleanValue value) {
Checks.isNotNull(value, VALUE);
final boolean f = this.hasFalse && value.getValue();
final boolean t = this.hasTrue && !value.getValue();
return of(f, t);
}
@Override
public BooleanSet remove(BooleanSet set) {
Checks.isNotNull(set, SET);
final boolean f = this.hasFalse && !set.hasFalse;
final boolean t = this.hasTrue && !set.hasTrue;
return of(f, t);
}
public static BooleanSet toSet(BooleanValue value,
PartialOrderPosition position) {
Checks.isNotNull(value, VALUE);
Checks.isNotNull(position, "position");
if (position == PartialOrderPosition.EQUAL) {
return of(value);
} else if (position == PartialOrderPosition.UNRELATED) {
return EMPTY;
} else if (position == PartialOrderPosition.LESS_THAN) {
if (BooleanValue.FALSE.equals(value)) {
return EMPTY;
} else {
return TRUE;
}
} else {
if (BooleanValue.TRUE.equals(value)) {
return EMPTY;
} else {
return FALSE;
}
}
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (isEmpty() && object instanceof SItemSet) {
final SItemSet other = (SItemSet) object;
if (other.isEmpty()) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
return isEmpty() ? 0 : values.hashCode();
}
@Override
public int compareTo(BooleanSet o) {
if (this == o) {
return 0;
}
if (o == null) {
return 1;
} else {
return CollectionUtils.compareLexicographic(getItems(), o.getItems());
}
}
}