package com.hpctoday.fada.integersolver;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
//import com.hpctoday.fada.ElementaryDependence;
import com.hpctoday.fada.Expression;
import com.hpctoday.fada.Global;
import com.hpctoday.fada.Inequation;
import com.hpctoday.fada.Quast;
/*!
\class Solver
\brief It represents a parametric linear programming solvers.
There is only two known parametric solvers PIP (Parametric Integer Programming), and Omega. The current implementation integrate only PIP.
\remarks Constraints injected to this class are supposed to be affine. Otherelse, the execution will be aborted.
\remarks This class do not handle the union of polyhedra (disjunction of conjunctions of affine constraints).
\remarks Solving constraints (looking for the lexicographic max/min) is constly task, you should not call it for trivial systems.
*/
public abstract class Solver {
private static final Logger log = Logger.getLogger(Solver.class.getName());
private List<String> variables; // ! The variables of the system
private List<String> parameters; // ! symbolic constants
private List<Inequation> constraints; // ! affine constraints ont variables and parameters
private int index; // ! an integer, the quast to be tagged with
private int deep; // ! an integer, the quast to be tagged with
private boolean is_pipized;
// !\name simple setters
// a setter for "variables"
protected void SetVariables(List<String> var) {
variables = var;
}
// a setter for "parameters"
protected void SetParameters(List<String> param) {
parameters = param;
}
// a setter for "constraints"
protected void SetConstraints(List<Inequation> cons) {
constraints = cons;
}
// a setter for "index"
protected void SetIndex(int val) {
index = val;
}
// a setter for "deep"
protected void SetDeep(int val) {
deep = val;
}
// !\name simple getters
// a getter for "variables"
protected List<String> GetVariables() {
return variables;
}
// a getter for "parameters"
protected List<String> GetParameters() {
return parameters;
}
// a getter for "index"
protected int GetIndex() {
return index;
}
// a getter for "deep"
protected int GetDeep() {
return deep;
}
// a getter for "constraints"
protected List<Inequation> GetConstraints() {
return constraints;
}
// ! \name Advanced setters
/*
* Set properties mapping the arguments.
* \param __stmt[in] : the identifier of a statement.
* \param __deep[in] : its deep.
* \param __var[in] : the variables.
* \param __param[in] : list of symbolic constants.
* \param __constraints[in] : affine constraints
*/
protected void set(int __index, int __deep, List<String> __var, List<String> __param, List<Inequation> __constraints, boolean pipized) {
SetIndex(__index);
SetParameters(Global.RemoveDoubles(__param));
SetVariables(new ArrayList<String>(__var)); //Deep copy
SetConstraints(__constraints);
SetDeep(__deep);
SetPIPized(pipized);
}
/*
* Set properties mapping the arguments.
* \param __stmt : to tag with the solution.
* \param __deep : to tag with the solution.
* \param __var : the variables of the system.
* \param __param : the symbolic constants of the system.
* \param __const : constraints describing the parametric polyhedron.
* \see Max(),MIN() After the call, we can say that the solver is initialized.
* You can use "Max()" and "Min()" to look for lexicographic maximum and minimum points.
*/
public void set(int __index, int __deep, List<String> __var, List<String> __param, List<Inequation> __constraints) {
//log.trace("Index: " + __index + " Deep: " + __deep);
//log.trace("Variables: " + __var);
//log.trace("Parm: " + __param);
//log.trace("Constraints: " + __constraints);
set(__index, __deep, __var, __param, __constraints, false);
}
/*
* Set all properties to NULL values.
*/
protected void Initialize() {
SetIndex(-1);
SetPIPized(false);
variables = new ArrayList<String>();
parameters = new ArrayList<String>();
constraints = new ArrayList<Inequation>();
}
protected void PIPize(List<String> new_var, List<Inequation> new_ineq) {
for (Inequation it : GetConstraints())
new_ineq.add(it.PIPize(new_var, new_ineq));
}
protected void SetPIPized(boolean val) {
is_pipized = val;
}
protected boolean IsPIPized() {
return is_pipized;
}
protected void RemoveNegativeVariablesPIPLimitation(List<String> var, List<String> param, List<Inequation> constraints) {
List<String> to_be_ducplicated = new ArrayList<String>(var);
for (String it : to_be_ducplicated) {
StringBuilder positive = new StringBuilder();
StringBuilder negative = new StringBuilder();
positive.append("_pos_").append(it);
negative.append("_neg_").append(it);
Expression sub = new Expression(new Expression(positive.toString()), Expression.Operation.FADA_SUB, new Expression(
negative.toString()));
constraints.add(new Inequation(new Expression(it), Inequation.Predicate.FADA_EQ, sub));
constraints.add(new Inequation(new Expression(positive.toString()), Inequation.Predicate.FADA_GREATER_EQ, new Expression(0)));
constraints.add(new Inequation(new Expression(negative.toString()), Inequation.Predicate.FADA_GREATER_EQ, new Expression(0)));
var.add(positive.toString());
var.add(negative.toString());
}
}
// ! \name Building
/*
* It creates a solver with : 0 variables, 0 parameters and 0 constraints.
* \see Quast* Max(int,int, List<String>, List<String>, List<Inequation*>*), Quast* Min(int,int, List<String>, List<String>, List<Inequation*>*);
* This configuration is an environment
* (constraints are always uphled). If you decide to use this constructor, you shoud use "Max" or "Min" with parameters to solve 'real'
* problems.
*/
protected Solver() {
Initialize();
}
// ! \name Processing on build object
// ! \name Build and process
/*
* Initialize and compute the lexicographic maximum.
* \param __stmt : to tag with the solution.
* \param __deep : to tag with the solution.
* \param __var : the variables of the system.
* \param __param : the symbolic constants of the system.
* \param __const : constraints describing the parametric polyhedron.
* \see Max(),MIN(), Solver()
*/
public abstract Quast Max();
public Quast Max(int __stmt, int __deep, List<String> __var, List<String> __param, List<Inequation> __cons) {
set(__stmt, __deep, __var, __param, __cons, false);
return Max();
}
/*
* Initialize and compute the lexicographic minimum.
* \param __var : the variables of the system.
* \param __param : the symbolic constants of the system.
* \param __const : constraints describing the parametric polyhedron.
* \see Max(),MIN(), Solver()
*/
public abstract Quast Min();
public Quast Min(List<String> __var, List<String> __param, List<Inequation> __cons) {
set(0, 0, __var, __param, __cons, false);
return Min();
}
// ! \name Printing
// print all properties into String
public String toString(){
return Print_str();
}
public String Print_str() {
String result = "";
result = "\n STMT : ";
result += GetIndex();
result += "\nVariables :";
for (String it : GetVariables())
result += "\n" + it;
result += "\nParameters :";
for (String it : GetParameters())
result += "\n" + it;
result += "\n\nConstraints :";
for (Inequation it : GetConstraints())
result += "\n" + it;
return result;
}
}