/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package jmathexpr.set;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import jmathexpr.AbstractExpression;
import jmathexpr.Expression;
import jmathexpr.Precedence;
import jmathexpr.arithmetic.natural.Naturals;
import jmathexpr.bool.TruthValue;
/**
* Finite set of arbitrary expressions.
*
* @author Elemér Furka
*/
public class FiniteSet extends AbstractExpression implements Set, Iterable<Expression> {
private final List<Expression> elements = new ArrayList();
private final Set domain;
/**
* Creates a new finite set containing the specified elements.
*
* @param elements list of expressions
*/
public FiniteSet(Expression... elements) {
this(Arrays.asList(elements));
}
/**
* Creates a new finite set containing the specified elements.
*
* @param elements list of expressions
*/
public FiniteSet(List<Expression> elements) {
Set d = null;
for (Expression e : elements) {
if (d == null) {
d = e.codomain();
} else if (!d.equals(e.domain())) {
d = d.union(e.codomain());
}
add(e);
}
domain = d;
}
private FiniteSet(FiniteSet set) {
this(set.elements);
}
public final TruthValue add(Expression element) {
TruthValue contained = contains(element);
if (contained == TruthValue.False) {
elements.add(element);
}
return contained;
}
@Override
public TruthValue contains(Expression element) {
return TruthValue.valueOf(elements.contains(element));
}
@Override
public boolean subsetOf(Set set) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public Set evaluate() {
FiniteSet elements = new FiniteSet();
for (Expression e : this.elements) {
add(e.evaluate());
}
return elements;
}
@Override
public boolean equals(Object object) {
if (object == null) return false;
if (this == object) return true;
if (object instanceof FiniteSet) {
FiniteSet other = (FiniteSet) object;
return elements.size() == other.elements.size() && elements.containsAll(other.elements);
} else if (object instanceof EmptySet) {
return elements.isEmpty();
} else if (object instanceof Set) {
throw new UnsupportedOperationException(String.format(
"Missing implementation: %s (%s)", object, object.getClass()));
}
return false;
}
@Override
public String toString() {
StringBuilder list = new StringBuilder();
for (Expression e : elements) {
if (list.length() == 0) {
list.append(e);
} else {
list.append(", " + e);
}
}
if (elements.isEmpty()) {
list.append(" ");
}
return String.format("{%s}", list);
}
@Override
public String toUnicode() {
return toString();
}
@Override
public boolean isConstant() {
for (Expression e : elements) {
if (!e.isConstant()) {
return false;
}
}
return true;
}
@Override
public Precedence getPrecedence() {
return Precedence.Evaluation;
}
@Override
public Set domain() {
return domain;
}
@Override
public Set codomain() {
return domain;
}
@Override
public List<Expression> getChildren() {
return Collections.unmodifiableList(elements);
}
@Override
public Set union(Set set) {
if (set instanceof FiniteSet) {
FiniteSet result = new FiniteSet(this);
for (Expression e : ((FiniteSet) set).elements) {
result.add(e);
}
return result;
} else {
throw new IllegalStateException("Union not yet implemented: " + set + " " + set.getClass());
}
}
@Override
public Iterator<Expression> iterator() {
return elements.iterator();
}
@Override
public Cardinality cardinality() {
return new Cardinality(Naturals.getInstance().create(elements.size()));
}
}