package org.aksw.jena_sparql_api.restriction;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.aksw.jena_sparql_api.views.PrefixSet;
import org.aksw.jena_sparql_api.views.RdfTermType;
import org.apache.jena.graph.Node;
/**
* A disjunction of restrictions.
*
* Only becomes unsatisfiable if all members are unsatisfiable
*
* @author Claus Stadler <cstadler@informatik.uni-leipzig.de>
*
*/
public class RestrictionSetImpl
{
private List<RestrictionImpl> restrictions;// = new ArrayList<? extends IRestriction>();
public PrefixSet getUriPrefixes() {
PrefixSet result = null;
for(RestrictionImpl r : restrictions) {
if(result == null) {
result = r.getUriPrefixes();
} else {
PrefixSet tmp = r.getUriPrefixes();
result.addAll(tmp);
}
}
return result;
}
public RdfTermType getType() {
RdfTermType t = null;
for(RestrictionImpl r : restrictions) {
if(t == null) {
t = r.getType();
} else if(r.getType() != t) {
return RdfTermType.UNKNOWN;
}
}
if(t == null) {
return RdfTermType.UNKNOWN;
}
return t;
}
public Collection<RestrictionImpl> getRestrictions() {
return restrictions;
}
public boolean addAlternatives(RestrictionSetImpl rs) {
if(rs.restrictions == null) {
return rs.addAlternative(new RestrictionImpl());
}
boolean result = false;
for(RestrictionImpl r : rs.restrictions) {
boolean change = addAlternative(r);
result = result || change;
}
return result;
}
public boolean addAlternative(RestrictionImpl r) {
if(r.getSatisfiability() == Boolean.TRUE) {
return false;
}
// TODO Check subsumption, and possibly merge restrictions
// For now just append the new element
if(!r.isUnsatisfiable()) {
if(restrictions == null) {
restrictions = new ArrayList<RestrictionImpl>();
}
// Remove all subsumed items
Iterator<RestrictionImpl> it = restrictions.iterator();
while(it.hasNext()) {
RestrictionImpl x = it.next();
if(x.subsumesOrIsEqual(r)) {
// since subsumesOrIsEqual is transitive, it means
// that r cannot subsume anything, as x would
// already do so
return false;
}
if(r.subsumesOrIsEqual(x)) {
it.remove();
}
}
restrictions.add(r);
return true;
}
return false;
/*
RestrictionClass c = r.getRestrictionClass();
classToRestrictions.get(c);*/
}
//private boolean isUnsatisfiable = false;
//public Restriction()
public RestrictionSetImpl() {
restrictions = null; // means 'true'
}
public RestrictionSetImpl(boolean value) {
restrictions = (value == false)
? new ArrayList<RestrictionImpl>()
: null;
}
public RestrictionSetImpl(RestrictionImpl restriction) {
if(restriction.isUnsatisfiable()) {
restrictions = Collections.emptyList();
} else {
restrictions = new ArrayList<RestrictionImpl>();
restrictions.add(restriction);
}
}
public RestrictionSetImpl(List<RestrictionImpl> restrictions) {
Iterator<RestrictionImpl> it = restrictions.iterator();
while(it.hasNext()) {
if(it.next().isUnsatisfiable()) {
it.remove();
}
}
this.restrictions = restrictions;
}
public RestrictionSetImpl(RestrictionSetImpl other) {
this.restrictions = new ArrayList<RestrictionImpl>(other.restrictions);
}
public boolean stateRestriction(RestrictionImpl other) {
if(restrictions == null) {
restrictions = new ArrayList<RestrictionImpl>();
restrictions.add(other.clone());
return true;
}
boolean result = false;
Iterator<RestrictionImpl> it = restrictions.iterator();
while(it.hasNext()) {
RestrictionImpl r = it.next();
boolean change = r.stateRestriction(other);
result = result || change;
if(r.isUnsatisfiable()) {
it.remove();
}
}
return result;
}
public boolean stateRestriction(RestrictionSetImpl other) {
if(other.restrictions == null) {
return false;
}
else if(this.restrictions == null) {
restrictions = new ArrayList<RestrictionImpl>();
for(RestrictionImpl _a : other.restrictions) {
restrictions.add(_a.clone());
}
return true;
} else {
List<RestrictionImpl> joined = new ArrayList<RestrictionImpl>();
boolean result = false;
for(RestrictionImpl _a : this.restrictions) {
for(RestrictionImpl b : other.restrictions) {
RestrictionImpl a = _a.clone();
boolean change = a.stateRestriction(b);
result = result || change;
if(!a.isUnsatisfiable()) {
joined.add(a);
}
}
}
this.restrictions = joined;
return result;
}
}
public boolean isUnsatisfiable() {
return restrictions != null && restrictions.isEmpty();
}
public RestrictionSetImpl clone() {
if(restrictions == null) {
return new RestrictionSetImpl();
}
List<RestrictionImpl> copy = new ArrayList<RestrictionImpl>();
for(RestrictionImpl r : restrictions) {
copy.add(r.clone());
}
//Collections.copy(copy, restrictions);
return new RestrictionSetImpl(copy);
}
public boolean stateType(RdfTermType newType) {
if(restrictions == null) {
return stateRestriction(new RestrictionImpl(newType));
}
Iterator<? extends Restriction> it = restrictions.iterator();
boolean result = false;
while(it.hasNext()) {
Restriction r = it.next();
boolean change = r.stateType(newType);
result = result || change;
if(r.isUnsatisfiable()) {
it.remove();
}
}
return result;
}
public boolean stateNode(Node newNode) {
if(restrictions == null) {
return stateRestriction(new RestrictionImpl(newNode));
}
Iterator<? extends Restriction> it = restrictions.iterator();
boolean result = false;
while(it.hasNext()) {
Restriction r = it.next();
boolean change = r.stateNode(newNode);
result = result || change;
if(r.isUnsatisfiable()) {
it.remove();
}
}
return result;
}
public boolean stateUriPrefixes(PrefixSet prefixes) {
if(restrictions == null) {
return stateRestriction(new RestrictionImpl(prefixes));
}
Iterator<? extends Restriction> it = restrictions.iterator();
boolean result = false;
while(it.hasNext()) {
Restriction r = it.next();
boolean change = r.stateUriPrefixes(prefixes);
result = result || change;
if(r.isUnsatisfiable()) {
it.remove();
}
}
return result;
}
// public void statePattern(PatternPro pattern) {
// throw new NotImplementedException();
// }
public String toString()
{
return (restrictions == null)
? "true"
: (restrictions.isEmpty()) ? "false" : restrictions.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((restrictions == null) ? 0 : restrictions.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
RestrictionSetImpl other = (RestrictionSetImpl) obj;
if (restrictions == null) {
if (other.restrictions != null)
return false;
} else if (!restrictions.equals(other.restrictions))
return false;
return true;
}
}