/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package fuzzysat;
import expressions.FuzzyVariableExpression;
import expressions.FuzzyConstantExpression;
import expressions.FuzzyBinaryExpression;
import expressions.FuzzyUnaryExpression;
import expressions.FuzzyExpression;
import java.util.*;
import util.*;
import linearProgramming.*;
import finiteReduction.*;
import lpsolve.*;
import operators.*;
/**
*
* @author sschocka
*/
public class LinearProgrammingSolver implements FuzzySATSolver{
int freshVariableIndex = 0;
DisjunctiveLinearReasoner reasoner;
Map<String, Integer> variableOrder;
List<DisjunctiveLinearInequality> relations;
boolean possiblySatisfiable = true;
Set<String> variables;
List<FuzzyClause> constraints;
public LinearProgrammingSolver(List<FuzzyClause> constraints) {
this.constraints = constraints;
}
private void init(long timeout) {
long starttime = System.currentTimeMillis();
// System.out.println(" beep1");
variables = new HashSet();
Set<String> originalVariables = new HashSet();
relations = new ArrayList();
// System.out.println("constraints 0 = "+ constraints);
// System.out.println("trivialAssignments = "+ trivialAssignments);
// System.out.println("constraints 1 = "+ constraints);
// System.out.println(" beep2");
for (FuzzyClause fc : constraints) {
long currenttime = System.currentTimeMillis();
if (currenttime - starttime < timeout) {
if (fc.numberOfDisjuncts() > 1)
System.err.println("Disjunctive fuzzy clauses not yet supported (LinearProgrammingSolver)");
Literal lit = fc.getDisjunct(0);
variables.addAll(lit.getAllVariables());
originalVariables.addAll(lit.getAllVariables());
if (lit instanceof FuzzyLiteral) {
// System.out.println(" Lit = " + lit);
List<DisjunctiveLinearInequality> l0;
if (FiniteReductionConfig.processType == 1)
l0 = process((FuzzyLiteral) lit);
else if (FiniteReductionConfig.processType == 2)
l0 = FuzzyToDLR.process((FuzzyLiteral) lit,timeout-(currenttime-starttime));
else if (FiniteReductionConfig.processType == 3)
l0 = FuzzyToDLR2.process((FuzzyLiteral) lit,timeout-(currenttime-starttime));
else
throw new UnsupportedOperationException();
// System.out.println(" rels = " + l0);
if (l0 == null)
possiblySatisfiable = false;
else
relations.addAll(l0);
}
else if (lit instanceof LinearLiteral)
relations.add(new DisjunctiveLinearInequality(new LinearInequality(((LinearLiteral) lit).getLinearInequality())));
else
throw new UnsupportedOperationException();
}
}
// System.out.println(" beep3");
reasoner = new DisjunctiveLinearReasoner(variables.size());
variableOrder = new HashMap();
int current = 0;
for (String s : variables)
variableOrder.put(s, current++);
for (String s : originalVariables) {
// add constraints to ensure that all variables are in [0,1]
String[] vars = new String[1];
vars[0] = s;
double[] coeff = new double[1];
coeff[0] = 1;
relations.add(new DisjunctiveLinearInequality(new LinearInequality(vars, coeff, LpSolve.LE, 1)));
relations.add(new DisjunctiveLinearInequality(new LinearInequality(vars, coeff, LpSolve.GE, 0)));
}
}
public static Map<String, Double> simplify(List<DisjunctiveLinearInequality> rels) {
Map<String, Double> trivialAssignments = new HashMap();
boolean changed = true;
eliminateNegExpressions(rels);
while (changed) {
changed = false;
// System.out.println("relations 0 = " + rels);
changed = eliminateEqualities(rels, trivialAssignments) || changed;
// System.out.println("trivialAssignments a = " + trivialAssignments );
// System.out.println("relations 1 = " + rels);
changed = eliminateTriviallySatisfiableRelations(rels, trivialAssignments) || changed;
// System.out.println("trivialAssignments b = " + trivialAssignments );
// System.out.println("relations 2 = " + rels);
changed = eliminateEntailedDisjuncts(rels) || changed;
// System.out.println("relations 3 = " + rels);
changed = removeViolatedDisjuncts(rels) || changed;
//// System.out.println("relations 4 = " + rels);
}
return trivialAssignments;
}
public List<DisjunctiveLinearInequality> getRelations(long timeout) {
if (relations == null)
init(timeout);
return relations;
}
public Map<String, Integer> getVariableOrder() {
return variableOrder;
}
public static boolean isNegation(FuzzyExpression exp) {
if (!(exp instanceof FuzzyUnaryExpression))
return false;
FuzzyUnaryExpression fu = (FuzzyUnaryExpression) exp;
return (fu.getOperator() instanceof N);
}
public static boolean isMaximum(FuzzyExpression exp) {
if (!(exp instanceof FuzzyBinaryExpression))
return false;
FuzzyBinaryExpression fu = (FuzzyBinaryExpression) exp;
return (fu.getOperator() instanceof SM);
}
public FuzzyExpression getUnaryArgument(FuzzyExpression exp) {
FuzzyUnaryExpression fu = (FuzzyUnaryExpression) exp;
return fu.getArgument();
}
public Pair<FuzzyExpression, FuzzyExpression> getBinaryArgument(FuzzyExpression exp) {
FuzzyBinaryExpression fu = (FuzzyBinaryExpression) exp;
return new Pair(fu.getArgument1(), fu.getArgument2());
}
private List<DisjunctiveLinearInequality> process(FuzzyLiteral lit) {
List<DisjunctiveLinearInequality> res = new ArrayList();
FuzzyExpression exp = lit.getExpression().normalise();
if (isNegation(exp)) {
return process(new FuzzyLiteral(1 - lit.upperbound, 1 - lit.lowerbound, getUnaryArgument(exp)));
}
if (isMaximum(exp)) {
Pair<FuzzyExpression, FuzzyExpression> args = getBinaryArgument(exp);
IntermediateResult ir1 = process(args.a, false);
IntermediateResult ir2 = process(args.b, false);
double lowerbound = lit.getLowerBound();
double upperbound = lit.getUpperBound();
if ((ir1 instanceof VariableResult) && (ir2 instanceof VariableResult)) {
String name1 = ((VariableResult) ir1).name;
String name2 = ((VariableResult) ir2).name;
res.addAll(((VariableResult) ir1).rels);
res.addAll(((VariableResult) ir2).rels);
String[] vars1 = new String[1];
vars1[0] = name1;
String[] vars2 = new String[1];
vars2[0] = name2;
double[] coeffs = new double[1];
coeffs[0] = 1;
if (upperbound < 0.9999) {
LinearInequality li1 = new LinearInequality(vars1, coeffs, LpSolve.LE, upperbound);
LinearInequality li2 = new LinearInequality(vars2, coeffs, LpSolve.LE, upperbound);
res.add(new DisjunctiveLinearInequality(li1));
res.add(new DisjunctiveLinearInequality(li2));
}
if (lowerbound > 0.0001) {
LinearInequality li1 = new LinearInequality(vars1, coeffs, LpSolve.GE, lowerbound);
LinearInequality li2 = new LinearInequality(vars2, coeffs, LpSolve.GE, lowerbound);
res.add(new DisjunctiveLinearInequality(li1, li2));
}
return res;
}
else if (ir1 instanceof VariableResult) {
String name1 = ((VariableResult) ir1).name;
double constant2 = ((ConstantResult) ir2).value;
res.addAll(((VariableResult) ir1).rels);
String[] vars1 = new String[1];
vars1[0] = name1;
double[] coeffs = new double[1];
coeffs[0] = 1;
LinearInequality li1 = new LinearInequality(vars1, coeffs, LpSolve.LE, upperbound);
res.add(new DisjunctiveLinearInequality(li1));
if (constant2 > upperbound + 0.001)
return null;
if (constant2 < lowerbound - 0.001) {
li1 = new LinearInequality(vars1, coeffs, LpSolve.GE, lowerbound);
res.add(new DisjunctiveLinearInequality(li1));
}
return res;
}
else if (ir2 instanceof VariableResult) {
String name2 = ((VariableResult) ir2).name;
double constant1 = ((ConstantResult) ir1).value;
res.addAll(((VariableResult) ir2).rels);
String[] vars2 = new String[1];
vars2[0] = name2;
double[] coeffs = new double[1];
coeffs[0] = 1;
LinearInequality li2 = new LinearInequality(vars2, coeffs, LpSolve.LE, upperbound);
res.add(new DisjunctiveLinearInequality(li2));
if (constant1 > upperbound + 0.001)
return null;
if (constant1 < lowerbound - 0.001) {
li2 = new LinearInequality(vars2, coeffs, LpSolve.GE, lowerbound);
res.add(new DisjunctiveLinearInequality(li2));
}
return res;
}
else {
double constant1 = ((ConstantResult) ir1).value;
double constant2 = ((ConstantResult) ir2).value;
double constant = Math.max(constant1, constant2);
if (constant >= lowerbound - 0.001 && constant <= upperbound + 0.001)
return new ArrayList();
else
return null;
}
}
else {
IntermediateResult ir = process(exp, false);
double lowerbound = lit.getLowerBound();
double upperbound = lit.getUpperBound();
if (ir instanceof VariableResult) {
String name = ((VariableResult) ir).name;
res.addAll(((VariableResult) ir).rels);
String[] vars = new String[1];
vars[0] = name;
double[] coeffs = new double[1];
coeffs[0] = 1;
if (lowerbound < upperbound - 0.001) {
LinearInequality li1 = new LinearInequality(vars, coeffs, LpSolve.LE, upperbound);
LinearInequality li2 = new LinearInequality(vars, coeffs, LpSolve.GE, lowerbound);
if (upperbound < 0.9999)
res.add(new DisjunctiveLinearInequality(li1));
if (lowerbound > 0.0001)
res.add(new DisjunctiveLinearInequality(li2));
}
else {
LinearInequality li = new LinearInequality(vars, coeffs, LpSolve.EQ, upperbound);
res.add(new DisjunctiveLinearInequality(li));
}
return res;
}
else {
double constant = ((ConstantResult) ir).value;
if (constant >= lowerbound - 0.001 && constant <= upperbound + 0.001)
return new ArrayList();
else
return null;
}
}
}
private IntermediateResult process(FuzzyExpression exp, boolean negated) {
if (exp instanceof FuzzyConstantExpression) {
FuzzyConstantExpression exp1 = (FuzzyConstantExpression) exp;
double constant = exp1.getValue();
return new ConstantResult(negated ? 1 - constant : constant);
}
else if (exp instanceof FuzzyVariableExpression) {
FuzzyVariableExpression exp1 = (FuzzyVariableExpression) exp;
if (!negated)
return new VariableResult(exp1.getName(), new ArrayList());
else {
String name = exp1.getName();
String var = name.startsWith("neg") ? name.substring(3) : "neg" + name;
variables.add(var);
String[] vars = new String[2];
vars[0] = name;
vars[1] = var;
double[] coeffs = new double[2];
coeffs[0] = 1;
coeffs[1] = 1;
LinearInequality li1 = new LinearInequality(vars, coeffs, LpSolve.EQ, 1);
List<DisjunctiveLinearInequality> res = new ArrayList();
res.add(new DisjunctiveLinearInequality(li1));
return new VariableResult(var, res);
}
}
else if (exp instanceof FuzzyUnaryExpression) {
FuzzyUnaryExpression exp1 = (FuzzyUnaryExpression) exp;
UnaryOperator op = exp1.getOperator();
if (op instanceof N)
return process(exp1.getArgument(), !negated);
else {
System.err.println("Unary operator not supported (LinearProgrammingSolver) : " + op);
return null;
}
}
else if (exp instanceof FuzzyBinaryExpression) {
FuzzyBinaryExpression exp1 = (FuzzyBinaryExpression) exp;
BinaryOperator op = exp1.getOperator();
FuzzyExpression arg1 = exp1.getArgument1();
FuzzyExpression arg2 = exp1.getArgument2();
List<DisjunctiveLinearInequality> res = new ArrayList();
if (op instanceof SM) {
IntermediateResult ir1 = process(arg1, false);
IntermediateResult ir2 = process(arg2, false);
if ((ir1 instanceof VariableResult) && (ir2 instanceof ConstantResult)) {
IntermediateResult dummy = ir1;
ir1 = ir2;
ir2 = dummy;
}
if ((ir1 instanceof ConstantResult) && ir2 instanceof ConstantResult) {
double val1 = ((ConstantResult) ir1).value;
double val2 = ((ConstantResult) ir2).value;
res.addAll(ir1.rels);
res.addAll(ir2.rels);
String newVar = (negated ? "neg" : "") + "(" + ((val1 < val2) ? "cst" + val1 + "Mcst" + val2 : "cst" + val2 + "Mcst" + val1) + ")";
variables.add(newVar);
String[] vars1 = new String[1];
vars1[0] = newVar;
double[] coeffs = new double[1];
coeffs[0] = negated ? 1 : -1;
LinearInequality li = new LinearInequality(vars1, coeffs, LpSolve.LE, (negated ? 1 : 0) - val1);
res.add(new DisjunctiveLinearInequality(li));
li = new LinearInequality(vars1, coeffs, LpSolve.LE, (negated ? 1 : 0) - val2);
res.add(new DisjunctiveLinearInequality(li));
LinearInequality li1 = new LinearInequality(vars1, coeffs, LpSolve.GE, (negated ? 1 : 0) - val1);
LinearInequality li2 = new LinearInequality(vars1, coeffs, LpSolve.GE, (negated ? 1 : 0) - val2);
res.add(new DisjunctiveLinearInequality(li1, li2));
return new VariableResult(newVar, res);
}
else if ((ir1 instanceof ConstantResult) && ir2 instanceof VariableResult) {
double val1 = ((ConstantResult) ir1).value;
String var2 = ((VariableResult) ir2).name;
res.addAll(ir1.rels);
res.addAll(ir2.rels);
String newVar = (negated ? "neg" : "") + "cst" + val1 + "M" + var2 + ")";
variables.add(newVar);
String[] vars1 = new String[1];
vars1[0] = newVar;
double[] coeffs1 = new double[1];
coeffs1[0] = negated ? 1 : -1;
LinearInequality li = new LinearInequality(vars1, coeffs1, LpSolve.LE, (negated ? 1 : 0) - val1);
res.add(new DisjunctiveLinearInequality(li));
double[] coeffs2 = new double[2];
coeffs2[0] = 1;
coeffs2[1] = negated ? 1 : -1;
String[] vars2 = new String[2];
vars2[0] = var2;
vars2[1] = newVar;
li = new LinearInequality(vars2, coeffs2, LpSolve.LE, negated ? 1 : 0);
res.add(new DisjunctiveLinearInequality(li));
LinearInequality li1 = new LinearInequality(vars1, coeffs1, LpSolve.GE, (negated ? 1 : 0) - val1);
LinearInequality li2 = new LinearInequality(vars2, coeffs2, LpSolve.GE, negated ? 1 : 0);
res.add(new DisjunctiveLinearInequality(li1, li2));
return new VariableResult(newVar, res);
}
else if ((ir1 instanceof VariableResult) && ir2 instanceof VariableResult) {
String var1 = ((VariableResult) ir1).name;
String var2 = ((VariableResult) ir2).name;
res.addAll(ir1.rels);
res.addAll(ir2.rels);
String newVar = (negated ? "neg" : "") + "(" + ((var1.compareTo(var2) < 0) ? var1 + "M" + var2 : var2 + "M" + var1) + ")";
variables.add(newVar);
String[] vars1 = new String[2];
vars1[0] = var1;
vars1[1] = newVar;
double[] coeffs = new double[2];
coeffs[0] = 1;
coeffs[1] = negated ? 1 : -1;
LinearInequality li = new LinearInequality(vars1, coeffs, LpSolve.LE, negated ? 1 : 0);
res.add(new DisjunctiveLinearInequality(li));
String[] vars2 = new String[2];
vars2[0] = var2;
vars2[1] = newVar;
li = new LinearInequality(vars2, coeffs, LpSolve.LE, negated ? 1 : 0);
res.add(new DisjunctiveLinearInequality(li));
LinearInequality li1 = new LinearInequality(vars1, coeffs, LpSolve.GE, negated ? 1 : 0);
LinearInequality li2 = new LinearInequality(vars2, coeffs, LpSolve.GE, negated ? 1 : 0);
res.add(new DisjunctiveLinearInequality(li1, li2));
return new VariableResult(newVar, res);
}
else
throw new UnsupportedOperationException();
}
else if (op instanceof TW) {
IntermediateResult ir1 = process(arg1, false);
IntermediateResult ir2 = process(arg2, false);
if ((ir1 instanceof ConstantResult) && (ir2 instanceof ConstantResult)) {
double value = 0;
try{
value = op.apply(((ConstantResult) ir1).value, ((ConstantResult) ir2).value);
}
catch(Exception e){
e.printStackTrace();
}
return new ConstantResult(negated ? 1 - value : value);
}
else if (ir1 instanceof ConstantResult) {
double value1 = ((ConstantResult) ir1).value;
String var2 = ((VariableResult) ir2).name;
res.addAll(ir2.rels);
// String newVar = "(" + var2 + "Xcst" + value1 + ")";
String newVar = (negated ? "neg" : "") + "(" + var2 + "Xcst" + value1 + ")";
variables.add(newVar);
String[] vars = new String[2];
vars[0] = var2;
vars[1] = newVar;
double[] coeffs = new double[2];
coeffs[0] = 1;
coeffs[1] = negated ? 1 : -1;
LinearInequality li = new LinearInequality(vars, coeffs, LpSolve.LE, negated ? 2 - value1 : 1 - value1);
res.add(new DisjunctiveLinearInequality(li));
LinearInequality li1 = new LinearInequality(vars, coeffs, LpSolve.GE, negated ? 2 - value1 : 1 - value1);
vars = new String[1];
vars[0] = newVar;
coeffs = new double[1];
coeffs[0] = 1;
// LinearInequality li2 = new LinearInequality(vars, coeffs, negated ? LpSolve.GE : LpSolve.LE, negated ? 1 : 0);
LinearInequality li2 = new LinearInequality(vars, coeffs, LpSolve.EQ, negated ? 1 : 0);
res.add(new DisjunctiveLinearInequality(li1, li2));
return new VariableResult(newVar, res);
}
else if (ir2 instanceof ConstantResult) {
double value1 = ((ConstantResult) ir2).value;
String var2 = ((VariableResult) ir1).name;
res.addAll(ir1.rels);
String newVar = (negated ? "neg" : "") + "(" + var2 + "Xcst" + value1 + ")";
// String newVar = "(" + var2 + "Xcst" + value1 + ")";
variables.add(newVar);
String[] vars = new String[2];
vars[0] = var2;
vars[1] = newVar;
double[] coeffs = new double[2];
coeffs[0] = 1;
coeffs[1] = negated ? 1 : -1;
LinearInequality li = new LinearInequality(vars, coeffs, LpSolve.LE, negated ? 2 - value1 : 1 - value1);
res.add(new DisjunctiveLinearInequality(li));
LinearInequality li1 = new LinearInequality(vars, coeffs, LpSolve.GE, negated ? 2 - value1 : 1 - value1);
vars = new String[1];
vars[0] = newVar;
coeffs = new double[1];
coeffs[0] = 1;
// LinearInequality li2 = new LinearInequality(vars, coeffs, negated ? LpSolve.GE : LpSolve.LE, negated ? 1 : 0);
LinearInequality li2 = new LinearInequality(vars, coeffs, LpSolve.EQ, negated ? 1 : 0);
res.add(new DisjunctiveLinearInequality(li1, li2));
return new VariableResult(newVar, res);
}
else {
String var1 = ((VariableResult) ir1).name;
String var2 = ((VariableResult) ir2).name;
res.addAll(ir1.rels);
res.addAll(ir2.rels);
// String newVar = "(" + ((var1.compareTo(var2) < 0) ? var1 + "X" + var2 : var2 + "X" + var1) + ")";
String newVar = (negated ? "neg" : "") + "(" + ((var1.compareTo(var2) < 0) ? var1 + "X" + var2 : var2 + "X" + var1) + ")";
variables.add(newVar);
String[] vars = new String[3];
vars[0] = var1;
vars[1] = var2;
vars[2] = newVar;
double[] coeffs = new double[3];
coeffs[0] = 1;
coeffs[1] = 1;
coeffs[2] = negated ? 1 : -1;
LinearInequality li = new LinearInequality(vars, coeffs, LpSolve.LE, negated ? 2 : 1);
res.add(new DisjunctiveLinearInequality(li));
LinearInequality li1 = new LinearInequality(vars, coeffs, LpSolve.GE, negated ? 2 : 1);
vars = new String[1];
vars[0] = newVar;
coeffs = new double[1];
coeffs[0] = 1;
// LinearInequality li2 = new LinearInequality(vars, coeffs, negated ? LpSolve.GE : LpSolve.LE, negated ? 1 : 0);
LinearInequality li2 = new LinearInequality(vars, coeffs, LpSolve.EQ, negated ? 1 : 0);
res.add(new DisjunctiveLinearInequality(li1, li2));
return new VariableResult(newVar, res);
}
}
else {
System.err.println("Binary operator not supported (LinearProgrammingSolver) : " + op);
return null;
}
}
else {
System.err.println("FuzzyExpression type not supported (LinearProgrammingSolver) : " + exp);
return null;
}
}
private static boolean eliminateEqualities(List<DisjunctiveLinearInequality> relations, Map<String, Double> trivialAssignments) {
boolean changed = false;
for (int i = 0; i < relations.size(); i++) {
List<LinearInequality> l = relations.get(i).getDisjuncts();
if (l.size() == 1 && l.get(0).isEquality()) {
LinearInequality li = l.get(0);
Set<String> eqvars = li.getVariables();
if (eqvars.size() == 1 || eqvars.size() == 2) {
boolean ok = true;
List<String> l0 = new ArrayList();
l0.addAll(li.getVariables());
String splitvar;
if (eqvars.size() == 1) {
splitvar = eqvars.iterator().next();
trivialAssignments.put(splitvar, li.getRHS() / li.getCoefficient(splitvar));
}
else {
// System.out.println(" eliminating equality " + li);
Iterator<String> it = eqvars.iterator();
String var1 = it.next();
String var2 = it.next();
if (var1.length() < var2.length())
splitvar = var2;
else
splitvar = var1;
}
for (int j = 0; j < relations.size(); j++)
if (i != j)
ok = ok && relations.get(j).eliminateEqualityCoeff1(li, splitvar);
if (ok) {
changed = true;
relations.remove(i);
i--;
}
}
}
}
return changed;
}
private static boolean eliminateTriviallySatisfiableRelations(List<DisjunctiveLinearInequality> rels, Map<String, Double> trivialAssignments) {
Map<String, Double> lowerbounds = new HashMap();
Map<String, Double> upperbounds = new HashMap();
Set<String> positiveVariables = new HashSet();
Set<String> negativeVariables = new HashSet();
Set<String> exactVariables = new HashSet();
for (DisjunctiveLinearInequality dlr : rels) {
for (LinearInequality lr : dlr.getDisjuncts()) {
if (lr.getVariables().size() > 1 || dlr.getDisjuncts().size()>1) {
positiveVariables.addAll(lr.getPositiveVariables());
negativeVariables.addAll(lr.getNegativeVariables());
exactVariables.addAll(lr.getExactVariables());
// System.out.println("lr = " + lr);
// System.out.println("exactVariables = " + lr.getExactVariables());
}
else if (lr.getVariables().size() == 1) {
exactVariables.addAll(lr.getExactVariables());
String var = lr.getVariables().iterator().next();
Double lower = lr.getLowerbound();
Double upper = lr.getUpperbound();
if (lower != null) {
if (lowerbounds.containsKey(var))
lowerbounds.put(var, Math.max(lowerbounds.get(var), lower));
else
lowerbounds.put(var, lower);
}
if (upper != null) {
if (upperbounds.containsKey(var))
upperbounds.put(var, Math.min(upperbounds.get(var), upper));
else
upperbounds.put(var, upper);
}
}
}
}
for(String s:lowerbounds.keySet()){
if(upperbounds.containsKey(s)){
if(upperbounds.get(s)<lowerbounds.get(s)+0.00001){
// relations are inconsistent
while(rels.size()>0)
rels.remove(0);
rels.add(new DisjunctiveLinearInequality());
}
}
}
Set<String> intersection = new HashSet();
intersection.addAll(positiveVariables);
intersection.retainAll(negativeVariables);
positiveVariables.removeAll(intersection);
positiveVariables.removeAll(exactVariables);
negativeVariables.removeAll(intersection);
negativeVariables.removeAll(exactVariables);
// System.out.println("positiveVariables = " + positiveVariables);
// System.out.println("exactVariables = " + exactVariables);
// System.out.println("negativeVariables = " + negativeVariables);
// System.out.println("lowerbounds = "+lowerbounds);
// System.out.println("upperbounds = "+upperbounds);
boolean changed = false;
for (DisjunctiveLinearInequality dlr : rels) {
for (LinearInequality lr : dlr.getDisjuncts()) {
Set<String> vars = lr.getVariables();
Set<String> posocc = new HashSet();
posocc.addAll(vars);
posocc.retainAll(positiveVariables);
Set<String> negocc = new HashSet();
negocc.addAll(vars);
negocc.retainAll(negativeVariables);
// System.out.println("LR voor = " + lr);
for (String s : posocc) {
lr.instantiate(s, upperbounds.get(s));
changed = true;
trivialAssignments.put(s, upperbounds.get(s));
}
for (String s : negocc) {
lr.instantiate(s, lowerbounds.get(s));
changed = true;
trivialAssignments.put(s, lowerbounds.get(s));
}
// System.out.println("LR na = " + lr);
}
}
return changed;
}
public static boolean eliminateEntailedDisjuncts(List<DisjunctiveLinearInequality> rels) {
DomainFinder.ensurePositiveCoefficient(rels);
Map<String, Double> lowerbounds = new HashMap();
Map<String, Double> upperbounds = new HashMap();
// System.out.println("rels.size() = " + rels.size());
for (DisjunctiveLinearInequality dlr : rels) {
if (dlr.getNumberOfDisjuncts() == 1) {
for (LinearInequality lr : dlr.getDisjuncts()) {
if (lr.getVariables().size() == 1) {
String var = lr.getVariables().iterator().next();
Double lower = lr.getLowerbound();
Double upper = lr.getUpperbound();
if (lower != null) {
if (lowerbounds.containsKey(var))
lowerbounds.put(var, Math.max(lowerbounds.get(var), lower));
else
lowerbounds.put(var, lower);
}
if (upper != null) {
if (upperbounds.containsKey(var))
upperbounds.put(var, Math.min(upperbounds.get(var), upper));
else
upperbounds.put(var, upper);
}
}
}
}
}
boolean changed = false;
for (int i = 1; i < rels.size(); i++) {
DisjunctiveLinearInequality dli1 = rels.get(i);
for (int j = 0; j < i && j < rels.size(); j++) {
DisjunctiveLinearInequality dli2 = rels.get(j);
// System.out.println("dli1 = " + dli1);
// System.out.println("dli2 = " + dli2);
if (DisjunctiveLinearInequality.entails(dli1, dli2, lowerbounds, upperbounds)) {
// System.out.println("biep1");
if (dli2.getNumberOfDisjuncts() > 1 || dli2.getVariables().size() != 1) {
rels.remove(j);
changed = true;
j--;
i--;
}
}
else if (DisjunctiveLinearInequality.entails(dli2, dli1, lowerbounds, upperbounds)) {
// System.out.println("biep2");
if (dli1.getNumberOfDisjuncts() > 1 || dli1.getVariables().size() != 1) {
rels.remove(i);
changed = true;
i--;
break;
}
}
}
}
return changed;
}
public static boolean removeViolatedDisjuncts(List<DisjunctiveLinearInequality> rels) {
boolean changed = false;
for (DisjunctiveLinearInequality dlr : rels) {
// System.out.println("voor = " +dlr);
changed = dlr.eliminateInconsistentDisjuncts() || changed;
// System.out.println("na = " +dlr);
}
return changed;
}
public static void eliminateNegExpressions(List<DisjunctiveLinearInequality> rels) {
for (DisjunctiveLinearInequality dlr : rels) {
for (LinearInequality lr : dlr.getDisjuncts()) {
Set<String> vars = lr.getVariables();
for (String var : vars) {
if (var.startsWith("neg")) {
double[] coeffs = new double[2];
coeffs[0] = 1;
coeffs[1] = 1;
String[] vars0 = new String[2];
vars0[0] = var;
vars0[1] = var.substring(3, var.length());
lr.eliminateEquality(new LinearInequality(vars0, coeffs, LpSolve.EQ, 1), var);
}
}
}
}
}
public Map<String, Double> findFuzzyModel() {
for (DisjunctiveLinearInequality rel : relations)
reasoner.addConstraint(rel, variableOrder);
double[] solution = reasoner.getSolution();
if (solution == null)
return null;
else {
Map<String, Double> res = new HashMap();
for (String s : variableOrder.keySet())
res.put(s, solution[variableOrder.get(s)]);
return res;
}
}
static abstract class IntermediateResult {
List<DisjunctiveLinearInequality> rels;
public IntermediateResult(List<DisjunctiveLinearInequality> rels) {
this.rels = rels;
}
}
static class ConstantResult extends IntermediateResult {
double value;
public ConstantResult(double value) {
super(new ArrayList());
this.value = value;
}
}
static class VariableResult extends IntermediateResult {
String name;
public VariableResult(String name, List<DisjunctiveLinearInequality> rels) {
super(rels);
this.name = name;
}
}
public static void main(String[] args) {
FuzzyExpression exp1 = new FuzzyBinaryExpression(new FuzzyVariableExpression("a"), new FuzzyVariableExpression("b"), new TW());
FuzzyExpression exp2 = new FuzzyUnaryExpression(new FuzzyVariableExpression("c"), new N());
FuzzyExpression exp = new FuzzyBinaryExpression(exp1, exp2, new TW());
FuzzyLiteral lit = new FuzzyLiteral(0.2, 0.4, exp);
FuzzyClause cl = new FuzzyClause(lit);
List<FuzzyClause> constraints = new ArrayList();
constraints.add(cl);
LinearProgrammingSolver solver = new LinearProgrammingSolver(constraints);
System.out.println(solver.findFuzzyModel());
}
public void setTimeout(long sec) {
throw new UnsupportedOperationException("Not supported yet.");
}
}