Package fuzzysat

Source Code of fuzzysat.LinearProgrammingSolver$IntermediateResult


/*
* 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.");
    }
}
TOP

Related Classes of fuzzysat.LinearProgrammingSolver$IntermediateResult

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.