/**
*
*/
package xhail.core.statements;
import java.util.HashSet;
import java.util.Set;
import xhail.core.Buildable;
import xhail.core.terms.Atom;
import xhail.core.terms.Scheme;
import xhail.core.terms.Variable;
/**
* @author stefano
*
*/
public class ModeH {
public static class Builder implements Buildable<ModeH> {
private int lower = 0;
private int priority = 1;
private Scheme scheme;
private int upper = Integer.MAX_VALUE;
private int weight = 1;
public Builder(Scheme scheme) {
if (null == scheme)
throw new IllegalArgumentException("Illegal 'scheme' argument in ModeH.Builder(Scheme): " + scheme);
this.scheme = scheme;
}
private static int COUNT = 0;
@Override
public ModeH build() {
return new ModeH(this, COUNT++);
}
public Builder setLower(int lower) {
this.lower = lower;
return this;
}
public Builder setPriority(int priority) {
this.priority = priority;
return this;
}
public Builder setScheme(Scheme scheme) {
if (null == scheme)
throw new IllegalArgumentException("Illegal 'scheme' argument in ModeH.Builder.setScheme(Scheme): " + scheme);
this.scheme = scheme;
return this;
}
public Builder setUpper(int upper) {
this.upper = upper;
return this;
}
public Builder setWeight(Integer weight) {
this.weight = null == weight ? 1 : weight;
return this;
}
}
public static final String CONSTRAINT_OP = ":";
public static final String KEYWORD = "#modeh";
public static final String PRIORITY_OP = "@";
public static final String SEPARATOR_OP = "-";
public static final String WEIGHT_OP = "=";
private final int lower;
private final int priority;
private final Scheme scheme;
private final int upper;
private final int weight;
private final int id;
private ModeH(Builder builder, int id) {
this.id = id;
this.lower = builder.lower;
this.priority = builder.priority;
this.scheme = builder.scheme;
this.upper = builder.upper;
this.weight = builder.weight;
}
public final String[] asClauses() {
Set<Variable> vars = new HashSet<>();
String atom = ((Atom) scheme.generalises(vars)).toString();
String types = scheme.getTypes().length > 0 ? " :" + String.join(" :", scheme.getTypes()) : "";
String list = scheme.getTypes().length > 0 ? "," + String.join(",", scheme.getTypes()) : "";
String[] result = new String[5];
result[0] = String.format("%% %s", toString());
result[1] = String.format("%d { abduced_%s%s } %d.", lower, atom, types, upper);
result[2] = String.format("#minimize[ abduced_%s =%d @%d%s ].", atom, weight, priority, types);
result[3] = String.format("%s:-abduced_%s%s.", atom, atom, list);
result[4] = String.format("number_abduced(%d,V):-V:=#count{ abduced_%s%s }.", id, atom, types);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ModeH other = (ModeH) obj;
if (lower != other.lower)
return false;
if (priority != other.priority)
return false;
if (scheme == null) {
if (other.scheme != null)
return false;
} else if (!scheme.equals(other.scheme))
return false;
if (upper != other.upper)
return false;
if (weight != other.weight)
return false;
return true;
}
public int getLower() {
return lower;
}
public int getPriority() {
return priority;
}
public Scheme getScheme() {
return scheme;
}
public int getUpper() {
return upper;
}
public int getWeigth() {
return weight;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + lower;
result = prime * result + priority;
result = prime * result + ((scheme == null) ? 0 : scheme.hashCode());
result = prime * result + upper;
result = prime * result + weight;
return result;
}
@Override
public String toString() {
String result = KEYWORD;
result += " " + scheme.toString();
if (lower != 0 || upper != Integer.MAX_VALUE)
result += " " + CONSTRAINT_OP + lower + SEPARATOR_OP + upper;
if (weight != 1)
result += " " + WEIGHT_OP + weight;
if (priority != 1)
result += " " + PRIORITY_OP + priority;
result += ".";
return result;
}
}