Package com.hpctoday.fada

Source Code of com.hpctoday.fada.Global

package com.hpctoday.fada;

import java.util.Map;
import java.util.List;

import com.hpctoday.fada.integersolver.Solver;
import com.hpctoday.fada.integersolver.SolverFactory;
import com.hpctoday.fada.pointers.BooleanPointer;

import java.util.ArrayList;
import java.util.HashMap;

import org.apache.log4j.Logger;

public class Global {
  private static final Logger log = Logger.getLogger(Global.class.getName());
 
  //! \brief Prefix used to define the parameters of maximums.
  public static final String FADA_Alpha = "Alpha";
  //! \brief Prefix used to parameterize iteration vector
  public static final String FADA_Prefix = "current_";
  //! \brief Prefix used to define new variables.
  public static final String FADA_New_var = "FADA_Z";
  //! \brief Bottom of quasts.
  public static final String FADA_Bottom = "Bottom"
 
  //! \brief constant used to secure print for some printing functions
  public static final int  __NORMAL_PRINT  = 0;
  //! \brief constant used to secure print for some printing functions
  public static final int  __SECURE_PRINT = 0;
  //! \brief constant used for a fully print.
  public static final int  __PRINT_ALL = 1;
 
  // ! \name Handling global options

  /*
   * ! \brief look for an option argument. \param s[in] : the option. \param
   * argc[in] : the number of atomic words in the command-line used to run
   * ADaAn. \param argv[in] : the List of all words used to invocate ADaAn.
   * \return the argument of the option "s"
   */
  //public static void ParseOptions(String argv[], Options options) {}

  // ! \name Common printings
  // ! \brief Print a vector of Strings
  public static String PrintVector(List<String> v) {
    String result = "( ";
    boolean first = true;
    for (String it : v) {
      if (first) {
        first = false;
        result += it;
      } else {
        result += ", " + it;
      }
    }
    result += " )";
    return result;
  }

  // void PrintADaAn();
  // void PrintVersion();
  // void PrintHelp();
  // ! \brief Print an operation(an instance of a statement)
  public static String PrintOperation(int stmt_id, List<Expression> __iteration) {
    StringBuilder sout = new StringBuilder();
    sout.append("<S_");
    sout.append(stmt_id);
    if (__iteration.isEmpty()) {
      sout.append(">");
      return sout.toString();
    }
    sout.append(": (");
    boolean first = true;
    for (Expression it : __iteration) {
      if (first) {
        sout.append(it);
        first = false;
      } else {
        sout.append(",");
        sout.append(it);
      }
    }
    sout.append(") >");
    return sout.toString();
  }

  // public static String PrintOperation(int stmt_id ,List<Expression>
  // __iteration,GraphPrinterOptions op);
  // public static String PrintTexOperation(int stmt_id ,List<Expression>
  // __iteration){}
  // ! \name Common questions
  // ! \brief Is "__str" is "__List" ?
//  public static boolean IsIn(String __str, List<String> __List) {
//    return __List.contains(__str);
//  }

  // !\brief Is all "__scalars" is "__invariables" ?
  public static boolean InvariableIn(List<String> __variable, List<String> __invariable) {
    if (__variable.size() > __invariable.size()) {
      return false;
    }

    for (String it : __variable) {
      if (!__invariable.contains(it)) {
        return false;
      }
    }
    return true;
  }

  // ! \name Useful for lexicographic tasks
  // ! \brief compute the common loop counters.
  public static List<String> Common(List<String> v1, List<String> v2) {
    List<String> result = new ArrayList<String>();
    int i = 0;
    while (i < v1.size() && i < v2.size() && v1.get(i).equals(v2.get(i))) {
      result.add(v1.get(i));
      i++;
    }
    return result;
  }

  // ! \brief provide a parameterized loop List.
  public static List<String> ParametrizeReadIteration(List<String> loop_counters) {
    List<String> result = new ArrayList<String>();
    for (String it : loop_counters) {
      result.add(FADA_Prefix + it);
    }

    return result;
  }

  // ! \brief compute the lexicographic precedence between two statements at a
  // given level
  public static List<Inequation> Precedence(List<String> __write, List<String> __read, int __common_loops, int __common) {
    List<Inequation> result = new ArrayList<Inequation>();
    if (__common_loops == 0) {
      return result;
    }

    for (int i = 0; i < __common; i++) {
      result.add(new Inequation(new Expression(__write.get(i)), Inequation.Predicate.FADA_EQ, new Expression(__read.get(i))));
    }

    if (__common < __write.size() && __common < __read.size() && __common < __common_loops) {
      result.add(new Inequation(new Expression(__write.get(__common)), Inequation.Predicate.FADA_LESS, new Expression(__read.get(__common))));
    }

    return result;
  }

  // ! \brief compute the lexicographic precedence between two statements.
  public static List<Condition> lex_preced(int rank1, List<String> counters1, int rank2, List<String> counters2, List<String> param_counters2) {
    int commun = 0;

    List<Condition> result = new ArrayList<Condition>();

    for (int i = 0; i < counters1.size() && i < counters2.size(); ++i) {
      String it1 = counters1.get(i);
      String it2 = counters2.get(i);
      if (it1.equals(it2)) {
        ++commun;
      }
    }

    for (int i = 0; i < commun; ++i) {
      Inequation preced_i = new Inequation(new Expression(counters1.get(i)), Inequation.Predicate.FADA_LESS, new Expression(param_counters2.get(i)));

      Condition preced_deep_i = new Condition(preced_i);
      for (int j = 0; j < i; ++j) {
        Inequation equal_j = new Inequation(new Expression(counters1.get(j)), Inequation.Predicate.FADA_EQ, new Expression(param_counters2.get(j)));

        preced_deep_i = new Condition(preced_deep_i, Condition.Logical_Operator.FADA_AND, new Condition(equal_j));
      }
      result.add(preced_deep_i);
    }

    if (rank1 < rank2) {
      Condition preced_tex = new Condition(new Inequation(true));
      for (int i = 0; i < commun; ++i) {
        Inequation equal_j = new Inequation(new Expression(counters1.get(i)), Inequation.Predicate.FADA_EQ, new Expression(param_counters2.get(i)));

        preced_tex = new Condition(preced_tex, Condition.Logical_Operator.FADA_AND, new Condition(equal_j));
      }
      result.add(preced_tex);
    }
    return result;
  }

  // ! \brief Rebuild an expression from a List of coefficients
  public static Expression VectorToExpression(List<Integer> __coefs, List<String> __var, List<String> __param) {
    int var_org = 0;
    int var_end = __var.size() - 1;
    int param_org = var_end + 1;
    int param_end = __coefs.size() - 2;
    int constant = param_end + 1;

    Expression result = new Expression(__coefs.get(constant));

    for (int i = var_org; i <= var_end; ++i) {
      if (__coefs.get(i) != 0) {
        if (__coefs.get(i) == 1) {
          result = new Expression(result, Expression.Operation.FADA_ADD, new Expression(__var.get(i)));
        } else {
          result = new Expression(result, Expression.Operation.FADA_ADD, new Expression(new Expression(__coefs.get(i)),
              Expression.Operation.FADA_MUL, new Expression(__var.get(i))));
        }
      }
    }

    for (int i = param_org; i <= param_end; ++i) {
      if (__coefs.get(i) != 0) {
        if (__coefs.get(i) == 1) {
          result = new Expression(result, Expression.Operation.FADA_ADD, new Expression(__param.get(i - param_org)));
        } else {
          result = new Expression(result, Expression.Operation.FADA_ADD, new Expression(new Expression(__coefs.get(i)),
              Expression.Operation.FADA_MUL, new Expression(__param.get(i - param_org))));
        }
      }
    }
    return result;
  }

  // ! \brief Generate a trivial true inequation
  public static List<Integer> GenerateTruePipVector(int size) {
    List<Integer> result = new ArrayList<Integer>(size + 2);
    for (int i = 0; i < size + 2; i++) {
      result.add(0);
    }

    return result; // true <=> (0 == 0)
  }

  // ! \brief Generate a trivial false inequation
  public static List<Integer> GenerateFalsePipVector(int size) {
    List<Integer> result = new ArrayList<Integer>(size + 2);

    for (int i = 0; i < size + 2; i++) {
      result.add(0);
    }

    result.set(size + 1, 1); // constant

    return result; // false <=> (1 == 0)
  }

  // ! \name Collecting
  // !\brief Collect references from an expression
  public static void CollectReferences(Expression __expr, List<Read_Reference> _ref) {
    if (!__expr.IsLeaf()) {
      CollectReferences(__expr.GetLeftChild(), _ref);
      CollectReferences(__expr.GetRightChild(), _ref);
      return;
    }

    if (__expr.IsVariable()) {
      List<Expression> v = new ArrayList<Expression>();
      FADA_Index empty = new FADA_Index(v);
      _ref.add(new Read_Reference(__expr.GetVariableName(), empty));
      return;
    }

    if (__expr.IsArray()) {
      FADA_Index __index = new FADA_Index(__expr.GetIndex());
      _ref.add(new Read_Reference(__expr.GetArrayName(), __index));

      for (Expression it : __expr.GetIndex()) {
        CollectReferences(it, _ref);
      }
      return;
    }

    if (__expr.IsFunction()) {
      for (Expression it : __expr.GetArguments()) {
        CollectReferences(it, _ref);
      }
      return;
    }
    if (__expr.IsValue()) {
      return;
    }

    throw new RuntimeException("CollectReferences(expression), fata error : invalid leaf information");
  }

  // !\brief Collect references from an index
  public static void CollectReferences(FADA_Index __i, List<Read_Reference> _ref) {
    for (int i = 0; i < __i.GetSize(); ++i) {
      CollectReferences(__i.GetItem(i), _ref);
    }
  }

  // !\brief Collect references from a condition
  public static void CollectReferences(Condition __c, List<Read_Reference> _ref) {
    if (__c.IsLeaf()) {
      CollectReferences(__c.GetInequation(), _ref);
      return;
    }
    if (__c.IsAND() || __c.IsOR()) {
      CollectReferences(__c.GetLeftChild(), _ref);
      CollectReferences(__c.GetRightChild(), _ref);
      return;
    }
    if (__c.IsNot()) {
      CollectReferences(__c.GetLeftChild(), _ref);
    }
    throw new RuntimeException("CollectReferences(condition), inappropriate value");
  }

  // !\brief Collect references from an inequation
  public static void CollectReferences(Inequation __i, List<Read_Reference> _ref) {
    if (__i.IsValue()) {
      return;
    }

    CollectReferences(__i.GetLHS(), _ref);
    CollectReferences(__i.GetRHS(), _ref);
  }

  // ! \name FADA preprocessing
  /*
   * ! \brief Have to rename a loop counter, because its identifier is already
   * used by another loop. \param counter[in] : its original name. \param
   * to_be_avoided[in] : List of names to be avoided. \return a candidate new
   * name for the loop counter.
   */
  public static String NewCounterName(String counter, List<String> to_be_avoided) {
    int i = 0;
    while (true) {
      StringBuilder result = new StringBuilder();
      result.append(counter);
      result.append("_");
      result.append(i);

      ++i;
      if (!to_be_avoided.contains(result.toString())) {
        return result.toString();
      }
    }
  }

  /*
   * ! \brief Compute the optimal way to evaluate a flow dependence between
   * two statements. \param __begin[in] : start looking for write operations
   * from the satement identified by "__begin". \param __end[in] : acheive
   * running when you reach this statement. \param read_stmt[in] : the read
   * statement identifier. \param read_array[in] : the conflictual array.
   * \param __i[in] : the read access function. \param common[in] : the number
   * of common loops. \param __references : all "read_stmt" read-references.
   */
  public static List<ElementaryDependence> ComputeDependenciesConfigs(int __begin, int __end, int read_stmt, String read_array, FADA_Index __i, int common,
      List<References> __references) {
    boolean reversed = __begin > __end;
    int stride = reversed ? -1 : 1;
    int real_end = reversed ? __end : __end;
    // int real_end= __end;

    List<ElementaryDependence> result = new ArrayList<ElementaryDependence>();
    for (int i = __begin; i != real_end; i += stride) {
      References ref = __references.get(i);
      if (ref.IsWrittenIn(read_array)) {
        ElementaryDependence config = new ElementaryDependence(read_stmt, i, common, __i);
        result.add(config);
      }
    }

    return result;
  }

  public static List<ElementaryDependence> EliminateValues2In(List<ElementaryDependence> config, Map<Integer, Integer> _to_eliminate) {
    List<ElementaryDependence> result = new ArrayList<ElementaryDependence>();

    for (ElementaryDependence it : config) {
      boolean found = false;
      for (int ite : _to_eliminate.keySet()) {
        int val = it.GetStmt2();
        if (val >= ite && val <= _to_eliminate.get(ite)) {
          found = true;
          break;
        }
      }
      if (!found) {
        result.add(it);
      }
    }
    return result;
  }

  // ! \brief Avoid the computation of the same thing twice.
  public static List<ElementaryDependence> EliminateElementaryDependenceDoubles(List<ElementaryDependence> configs) {
    List<ElementaryDependence> result = new ArrayList<ElementaryDependence>();

    for (ElementaryDependence it : configs) {
      boolean found = false;
      for (ElementaryDependence itr : result) {
        if (it.Equal(itr)) {
          found = true;
          break;
        }
      }
      if (!found) {
        result.add(it);
      }
    }
    return result;
  }

  // ! \name Handling constraints
  // ! \brief Build a condition from a List (conjunction) of affine
  // inequations.
  public static Condition ToDNFTerm(List<Inequation> __affine_constraints) {
    Condition result = null;
    for (Inequation it : __affine_constraints) {
      if (!it.IsValue() || (it.IsValue() && !it.GetValue())) {
        if (result == null) {
          result = new Condition(it);
        } else {
          result = new Condition(result, Condition.Logical_Operator.FADA_AND, new Condition(it));
        }
      }
    }

    if (result == null) {
      return new Condition(new Inequation(true));
    }
    return result;
  }

  public static Condition DNFTerms_to_Condition(List<List<Inequation>> inequations) {
    Condition result = null;
    if (inequations.isEmpty()) {
      return new Condition(new Inequation(true));
    }
    for (List<Inequation> it : inequations) {
      if (result == null) {
        result = ToDNFTerm(it);
      } else {
        result = new Condition(result, Condition.Logical_Operator.FADA_OR, ToDNFTerm(it));
      }
    }
    return result;
  }

  // ! \brief Build the AND of the two disjunction of conjunctions conditions.
  public static List<List<Inequation>> AND_DNF(List<List<Inequation>> cond1, List<List<Inequation>> cond2) {
    List<List<Inequation>> result = new ArrayList<List<Inequation>>();
    if (cond1.isEmpty()) {
      return cond2;
    }
    if (cond2.isEmpty()) {
      return cond1;
    }

    for (List<Inequation> it : cond1) {
      for (List<Inequation> it2 : cond2) {
        List<Inequation> term = new ArrayList<Inequation>(it);
        for (Inequation iti : it2) {
          term.add(iti);
        }
        result.add(term);
      }
    }
    return result;
  }

  // ! \brief Rename scalars by anothers.
  public static List<List<Inequation>> RENAME(List<List<Inequation>> constraints, Map<String, Expression> __mapping) {
    List<List<Inequation>> result = new ArrayList<List<Inequation>>();

    for (List<Inequation> itt : constraints) {
      List<Inequation> term = new ArrayList<Inequation>();
      for (Inequation iti : itt) {
        term.add(iti.SubstituteByExpression(__mapping));
      }
      result.add(term);
    }
    return result;
  }

  // ! \brief Checks wether one of "inequations" can imply "ineq"
  // public static boolean IMPLY(List<Inequation> inequations, Inequation
  // ineq, List<String> param);
  // public static boolean IMPLY(List<List<Inequation>> inequations,
  // Inequation ineq, List<String> param);
  public static List<List<Inequation>> MergeListInequation(List<List<Inequation>> __rela1, List<List<Inequation>> __rela2) {
    List<List<Inequation>> result = new ArrayList<List<Inequation>>(__rela1);
    for (List<Inequation> it : __rela2) {
      result.add(it);
    }
    return result;
  }

  // ! \brief Performs the AND of two DNF terms
  public static List<Inequation> MergeInequations(List<Inequation> __ineq1, List<Inequation> __ineq2) {
    List<Inequation> result = new ArrayList<Inequation>();
    for (Inequation it : __ineq1) {
      result.add(it);
    }

    for (Inequation it : __ineq2) {
      result.add(it);
    }
    return result;
  }

  // ! \brief Negates a DNF term.
  public static List<Inequation> NegateInequations(List<Inequation> __ineqs) {
    // WARNING : input= conjuctive condition ... so output = disjonctive
    // term

    List<Inequation> result = new ArrayList<Inequation>();
    for (Inequation it : __ineqs) {
      result.add(it.Negate(true));
    }
    return result;
  }

  public static List<LC_RHS_Term> MergeLC_RHS_Term(List<LC_RHS_Term> __rela1, List<LC_RHS_Term> __rela2) {
    List<LC_RHS_Term> result = new ArrayList<LC_RHS_Term>();
    boolean __false = false;

    for (LC_RHS_Term it : __rela1) {
      LC_RHS_Term lc = it;
      if (lc.GetInequation().IsValue() && !lc.GetInequation().GetValue()) {
        __false = true;
        break;
      }
      result.add(it);
    }
    if (__false) {
      result.clear();
      result.add(new LC_RHS_Term(new Inequation(false)));
      return result;
    }

    for (LC_RHS_Term it : __rela2) {
      LC_RHS_Term lc = it;
      if (lc.GetInequation().IsValue() && !lc.GetInequation().GetValue()) {
        __false = true;
        break;
      }
      result.add(it);
    }
    if (__false) {
      result.clear();
      result.add(new LC_RHS_Term(new Inequation(false)));
      return result;
    }
    return result;
  }

  // ! \brief Avoid redendent inequations
  public static List<Inequation> EliminateInequationDoubles(List<Inequation> list) {
    List<Inequation> res = new ArrayList<Inequation>();
    for (Inequation it : list) {
      String __ineq = it.toString();
      boolean found = false;

      for (Inequation it2 : res) {
        if (__ineq.equals(it2.toString())) {
          found = true;
          break;
        }
      }
      if (!found) {
        res.add(it);
      }
    }
    return res;
  }

  // ! \brief Avoid useless inequations
  public static List<Inequation> EliminateTrueAndDoubles(List<Inequation> list) {
    List<Inequation> res = new ArrayList<Inequation>();
    for (Inequation it : list) {
      if (!(it.IsValue() && it.GetValue())) {
        String __ineq = it.toString();
        boolean found = false;
        //Inequation s;

        for (Inequation it2 : res) {
          if (__ineq.equals(it2.toString())) {
            found = true;
            break;
          }
        }
        if (!found) {
          res.add(it);
        }
      }
    }
    return res;
  }

  // ! \brief Printing inequations
  // public static String PrintTexInequations(List<Inequation> vecteur);
  public static String PrintInequations(List<Inequation> vecteur) {
    String result = "";
    for (Inequation it : vecteur) {
      result += "    " + it;
    }
    return result;
  }

  // ! \brief Printing inequations
  public static String PrintInequations(String prefix, List<Inequation> vecteur) {
    String result = prefix;
    for (Inequation it : vecteur) {
      result += prefix + it;
    }

    return result;
  }

  // ! \brief Printing inequations
  public static String PrintListInequations(List<List<Inequation>> vecteur) {
    String result = "";
    for (List<Inequation> itt : vecteur) {
      result += "\n>>";
      for (Inequation it : itt) {
        result += "    " + it;
      }
    }
    return result;
  }

  // ! \name HTML and GraphViz
  public static void Connect(Statement __stmt, References __ref){
    __stmt.SetID(__ref.GetStmtID());
    __stmt.SetReferences(__ref);
    __ref.SetOrigin(__stmt);   
  }
 
  // void WriteToFile(String file_name, String contnent);
  // !\name Miscellaneous
  // ! \brief Merges two Lists
  public static List<LexicographicInequation> MergeLexicographicInequation(List<LexicographicInequation> __rela1, List<LexicographicInequation> __rela2) {
    List<LexicographicInequation> result = new ArrayList<LexicographicInequation>();
    for (LexicographicInequation it : __rela1) {
      result.add(it);
    }

    for (LexicographicInequation it : __rela2) {
      result.add(it);
    }
    return result;
  }

  // ! \brief Merges two Lists
  public static List<String> MergeVariables(List<String> var1, List<String> var2) {
    List<String> result = new ArrayList<String>(var1);
    for (String it : var2) {
      if (!result.contains(it)) {
        result.add(it);
      }
    }

    return result;
  }

  /*
   * ! \brief Computes the maximum lexicographic of two quasts in a smart way.
   * \param _q1[in] : the first quast.
   * \param _q2[in] : the second quast.
   * \param _pgm[in] : a reference to the AST of the program.
   * \param _conext[in] : the context of this computation (assumed as a tautology).
   * \param _param[in] : symbolic constants.
   */
  // public static Quast Max(Quast _q1, Quast _q2, Program _pgm,
  // List<Inequation> _context, List<String> _param);
  public static Quast Max(Quast _q1, Quast _q2, List<References> __ref, List<List<Boolean>> _textual_preced, List<List<Inequation>> context,
      List<String> _param) {
   
    //Deep copy context
    List<List<Inequation>> _context = new ArrayList<List<Inequation>>();
    for(List<Inequation> list: context){
      _context.add(new ArrayList<Inequation>(list));
    }
   
    if (_q1.IsLeaf() && _q1.IsEmpty()) {
      return _q2;
    }
    if (_q2.IsLeaf() && _q2.IsEmpty()) {
      return _q1;
    }

    if (_q1.IsLeaf() && _q2.IsLeaf()) {
      List<String> c1, c2;
      c1 = (__ref.get(_q1.GetAssignment())).GetCounters();
      c2 = (__ref.get(_q2.GetAssignment())).GetCounters();

      List<String> common_counters = Common(_q1.GetCounters(), _q2.GetCounters());

      boolean q1_before_q2, q2_before_q1;
      Condition lex_eq = null;

      BooleanPointer bp1 = new BooleanPointer();
      BooleanPointer bp2 = new BooleanPointer();
      Condition preced = SmartPrecedenceComputing(_textual_preced, _q1.GetAssignment(), _q2.GetAssignment(), _q1.GetVertex(), _q2.GetVertex(),
          common_counters, bp1, bp2);
      q1_before_q2 = bp1.getValue();
      q2_before_q1 = bp2.getValue();

      if (preced != null) {
        lex_eq = preced.GetRightChild(); // S1 =lex S2
        preced = preced.GetLeftChild(); // S1 <lex[strict] S2
      }
      if (preced == null && lex_eq == null) {
        if (q1_before_q2) {
          return _q2;
        }
        if (q2_before_q1) {
          return _q1;
        }

        // FIXME: this line is added to bypass Graphite+FADA BUG while
        // computing sequential precedence.
        if (_q1.GetAssignment() < _q2.GetAssignment()) {
          return _q2;
        } else {
          return _q1;
        }

        // cerr <<
        // "\nQuast*  Max(global.h) ... (Warning) have to consider this particular case [1]\n";
        // cout << "\n [DEBUG] ........ \n";
        // cout << "\nQuast1: ";
        // _q1.Print("\n");
        // cout << "\nQuast2: ";
        // _q2.Print("\n");
        // cout << "\n Sequential Precedence [" << _q1.GetAssignment()
        // << "][" << _q2.GetAssignment() << "] = "
        // <<
        // _textual_preced.operator[](_q1.GetAssignment())[_q2.GetAssignment()]
        // ? "true"
        // : "false";
        // cout << "\n [DEBUG] ........ DONE\n";

        // throw new
        // RuntimeException("Quast Max(global.h) ... (Warning) have to consider this particular case");
      } else {
        if (preced == null) { // lex_eq != NULL
          throw new RuntimeException("Quast*  Max(global.h) ... ('FATAL' Warning) that part is (in normal case) UNREACHABLE");

          // if (q1_before_q2)
          // return new Quast(lex_eq, _q2, _q1);
          // if (q2_before_q1)
          // return new Quast(lex_eq, _q1, _q2);

        } else { // preced != NULL and lex_eq != NULL
          Quast quast_resultat;

          if (q1_before_q2) // S1 <text S2 quast= IF ( S1 <lex S2 OR
                    // S1 =lex S2 ) then S2
          // ELSE S1
          {
            quast_resultat = new Quast(new Condition(preced, Condition.Logical_Operator.FADA_OR, lex_eq), _q2, _q1);
            quast_resultat = quast_resultat.Uncompress();
            return quast_resultat.Simplify(_context, _param).Compress();
          }

          if (q2_before_q1) // S1 >tex S2 quast= IF( S1 <lex S2) then
                    // S2
          { // ELSE S1
            quast_resultat = new Quast(preced, _q2, _q1);

            quast_resultat = quast_resultat.Uncompress();
            return quast_resultat.Simplify(_context, _param).Compress();

          }

          // not(S1 <tex S2) and not(S1 >tex S2) typical case of
          // if-then S1 else S2;

          // quast = IF (S1 <lex S2) S2
          // ELSE IF S1 =lex S2 (impossible case)
          // ELSE S1

          // to simplify, we assume that "impossible case" is
          // remplaced by S1. we got in this case :

          // IF (S1 <lex S2) S2
          // ELSE S1

          quast_resultat = new Quast(preced, _q2, _q1);
          quast_resultat = quast_resultat.Uncompress();
          return quast_resultat.Simplify(_context, _param).Compress();

        }
      }
      // if( _q1 <lex[strict] _q2) _q2;
      // else
      // if( _q1 ==[lex] _q2)
      // if( s1 <tex s2 ) _q2;
      // if( s1 >tex s2) _q1;

      // return new Quast(preced, _q2.Clone(), _q1.Clone());
    }
    if (_q1.IsLeaf()) {
      /*
       * List<List<Inequation*> > env_then,env_else; env_then=_context;
       * env_else=_context;
       *
       * List<List<Inequation*> > term_ineq1;
       * term_ineq1.push_back(_q2.GetCondition().GetTermInequations());
       *
       * env_then=AND_DNF(&_context,&term_ineq1);
       */
      // for(List<Inequation*>::iterator it=term_ineq1.begin(); it !=
      // term_ineq1.end(); ++it)
      // env_then.push_back(*it);

      return new Quast(_q2.GetCondition(), Max(_q1, _q2.GetThenPart(), __ref, _textual_preced, /* env_then */
      _context, _param), Max(_q1, _q2.GetElsePart(), __ref, _textual_preced,/* env_else */
      _context, _param));
    }
    // if(_q2.IsLeaf())

    // List<Inequation*> env_then,env_else;
    // env_then=_context;
    // env_else=_context;
    //
    // List<Inequation*> term_ineq1=
    // _q1.GetCondition().GetTermInequations();
    //
    // for(List<Inequation*>::iterator it=term_ineq1.begin(); it !=
    // term_ineq1.end(); ++it)
    // env_then.push_back(*it);

    return new Quast(_q1.GetCondition(), Max(_q1.GetThenPart(), _q2, __ref, _textual_preced, _context, _param), Max(_q1.GetElsePart(), _q2, __ref,
        _textual_preced, _context, _param));

    // throw new
    // RuntimeException("Quast*  Max, ... fatal error (inappropriate case) ....");
  }

  // Quast Max(Quast _q1, Quast _q2, List<References> __ref, void
  // _textual_preced, int (fct)(void,int,int), List<List<Inequation> >
  // _context, List<String> _param);
  /*
   * ! \brief Computes a more precise lexicographic precendence (between two
   * operations) constraints. \param _pgm[in] : a reference for the program
   * \param s1 : first statement \param s2[in] : second statement \param
   * index1[in] : the instance of the first statement \param index2[in] : the
   * instance of the second statement \param common_counters[in] : the common
   * loops. \param s1_before_s2[out] : is "S1" textually specified before "S2"
   * ? \param s2_before_s1[out] :is "S2" textually specified before "S1" ?
   * \return the strict precedence constraints
   */
  public static Condition SmartPrecedenceComputing(Program _pgm, int s1, int s2, FADA_Index index1, FADA_Index index2, List<String> common_counters,
      BooleanPointer s1_before_s2, BooleanPointer s2_before_s1) {
    if (common_counters.size() > index1.GetSize() || common_counters.size() > index2.GetSize()) {
      throw new RuntimeException("Condition*  Precedence (indexes) ... FATAL ERROR (inappropriate case)");
    }

    Condition result = null;
    Condition lex_eq = null;
    lex_eq = null;
    for (int i = 0; i < common_counters.size(); ++i) {
      Condition nest_pred = new Condition(new Inequation(index1.GetItem(i), Inequation.Predicate.FADA_LESS, index2.GetItem(i)));
      Condition equal = new Condition(new Inequation(index1.GetItem(i), Inequation.Predicate.FADA_EQ, index2.GetItem(i)));
      for (int j = 1; j < i; ++j) {
        nest_pred = new Condition(nest_pred, Condition.Logical_Operator.FADA_AND, new Condition(new Inequation(index1.GetItem(j),
            Inequation.Predicate.FADA_EQ, index2.GetItem(j))));
      }
      if (result == null) {
        result = nest_pred;
      } else {
        result = new Condition(result, Condition.Logical_Operator.FADA_OR, result);
      }
      if (lex_eq == null) {
        lex_eq = equal;
      } else {
        lex_eq = new Condition(lex_eq, Condition.Logical_Operator.FADA_AND, equal);
      }
    }

    s1_before_s2.setValue(_pgm.IsSequentiallyBefore(s1, s2, common_counters));
    s2_before_s1.setValue(_pgm.IsSequentiallyBefore(s2, s1, common_counters));

    if (result != null) {
      return new Condition(result, Condition.Logical_Operator.FADA_OR, lex_eq);
    } else {
      return null;
    }

    // throw new
    // RuntimeException("Condition*  SmartPrecedenceComputing (global.h) ... have to handle this special case ...");
    // cerr << "ID1 =" << s1 << " ID2=" << s2 << "\n";
  }

  public static Condition SmartPrecedenceComputing(List<List<Boolean>> textual_preced, int s1, int s2, FADA_Index index1, FADA_Index index2,
      List<String> common_counters, BooleanPointer s1_before_s2, BooleanPointer s2_before_s1) {

    if (common_counters.size() > index1.GetSize() || common_counters.size() > index2.GetSize()) {
      throw new RuntimeException("Condition*  Precedence (indexes) ... FATAL ERROR (inappropriate case)");
    }
    Condition result = null;
    Condition lex_eq = null;
    lex_eq = null;
    for (int i = 0; i < common_counters.size(); ++i) {
      Condition nest_pred = new Condition(new Inequation(index1.GetItem(i), Inequation.Predicate.FADA_LESS, index2.GetItem(i)));
      Condition equal = new Condition(new Inequation(index1.GetItem(i), Inequation.Predicate.FADA_EQ, index2.GetItem(i)));
      for (int j = 1; j < i; ++j) {
        nest_pred = new Condition(nest_pred, Condition.Logical_Operator.FADA_AND, new Condition(new Inequation(index1.GetItem(j),
            Inequation.Predicate.FADA_EQ, index2.GetItem(j))));
      }
      if (result == null) {
        result = nest_pred;
      } else {
        result = new Condition(result, Condition.Logical_Operator.FADA_OR, result);
      }
      if (lex_eq == null) {
        lex_eq = equal;
      } else {
        lex_eq = new Condition(lex_eq, Condition.Logical_Operator.FADA_AND, equal);
      }
    }

    s1_before_s2.setValue(textual_preced.get(s1).get(s2));
    s2_before_s1.setValue(textual_preced.get(s2).get(s1));

    if (result != null) {
      return new Condition(result, Condition.Logical_Operator.FADA_OR, lex_eq);
    } else {
      return null;
    }

    // throw new
    // RuntimeException("Condition*  SmartPrecedenceComputing (global.h) ... have to handle this special case ...");
    // cerr << "ID1 =" << s1 << " ID2=" << s2 << "\n";
  }

  /*
   * Condition SmartPrecedenceComputing(void textual_preced, int
   * (fct)(void,int,int), int s1, int s2, FADA_Index index1, FADA_Index
   * index2, List<String> common_counters, booleans1_before_s2,
   * booleans2_before_s1);
   */
  // ! \brief Traduces inequations to a context quast.
  public static ContextQuast TraduceToContextQuast(Quast quast, List<String> var, List<List<Inequation>> inequations) {
    if (quast.IsLeaf()) {
      if (quast.IsEmpty()) {
        return new ContextQuast();
      } else {
        Map<String, Expression> __mapping = new HashMap<String, Expression>();
        for (int i = 0; i < var.size(); i++) {
          String it = var.get(i);
          if (i == quast.GetVertex().GetIndex().size() - 1) {
            throw new RuntimeException("TraduceToContextQuast ..... FATAL ERROR(inappropriate case)");
          }

          Expression ite = quast.GetVertex().GetIndex().get(i);
          __mapping.put(it, ite);
        }

        List<List<Inequation>> leaf_const = new ArrayList<List<Inequation>>();

        for (List<Inequation> it : inequations) {
          List<Inequation> term = new ArrayList<Inequation>();
          for (Inequation iti : it) {
            term.add(iti.SubstituteByExpression(__mapping));
          }
          leaf_const.add(term);
        }

        return new ContextQuast(leaf_const);
      }
    } else {
      return new ContextQuast(quast.GetCondition(), TraduceToContextQuast(quast.GetThenPart(), var, inequations), TraduceToContextQuast(
          quast.GetElsePart(), var, inequations));
    }

    // cerr <<
    // "\nContextQuast*  TraduceToContextQuast ...... Unhandled case\n";
  }

  // public static List<List<Inequation>>
  // SimplifyInequations1(List<List<Inequation>> __to_be_simplified,
  // List<Inequation> __env, List<String> __param);
  public static List<List<Inequation>> SimplifyInequations(List<List<Inequation>> __to_be_simplified, List<List<Inequation>> __env, List<String> __param) {
    List<List<Inequation>> result = new ArrayList<List<Inequation>>();
    for (List<Inequation> it : __to_be_simplified) {
      List<List<Inequation>> local_term = new ArrayList<List<Inequation>>();
      local_term.add(it);
      List<List<Inequation>> local = AND_DNF(local_term, __env);
      if (!IsUnsatisfiable2(local, __param)) {
        result.add(it);
      }
    }
    return result;
  }

  public static List<List<Inequation>> TraduceNEQOperations2(List<List<Inequation>> __constraints) {
    List<List<Inequation>> result = new ArrayList<List<Inequation>>();
    for (List<Inequation> it : __constraints) {
      List<List<Inequation>> local = TraduceNEQOperations1(it);

      for (List<Inequation> itt : local) {
        result.add(itt);
      }
    }

    return result;
  }

  public static List<List<Inequation>> TraduceNEQOperations1(List<Inequation> __constraint) {
    List<Inequation> __neq = new ArrayList<Inequation>();
    List<Inequation> __others = new ArrayList<Inequation>();

    CollectNEQInequations(__constraint, __neq, __others);

    List<List<Inequation>> result = new ArrayList<List<Inequation>>();
    result.add(__others);
    for (Inequation it : __neq) {
      Condition cond = new Condition(it);
      cond = cond.TraduceNEQInequations();
      Inequation ineq1, ineq2;
      ineq1 = cond.GetLeftChild().GetInequation();
      ineq2 = cond.GetRightChild().GetInequation();

      List<List<Inequation>> local_res = DistributeNEQuation(ineq1, ineq2, result);
      result = local_res;
    }

    return result;
  }

  public static void CollectNEQInequations(List<Inequation> __all, List<Inequation> __neq, List<Inequation> __others) {
    for (Inequation it : __all) {
      if (!it.IsValue() && it.GetPredicate() == Inequation.Predicate.FADA_NEQ) {
        __neq.add(it);
      } else {
        __others.add(it);
      }

    }
  }

  public static List<List<Inequation>> DistributeNEQuation(Inequation ineq1, Inequation ineq2, List<List<Inequation>> constraints) {
    List<List<Inequation>> result = new ArrayList<List<Inequation>>();
    for (List<Inequation> it : constraints) {
      List<Inequation> local1, local2;
      local1 = new ArrayList<Inequation>(it);
      local2 = new ArrayList<Inequation>(it);
      local1.add(ineq1);
      local2.add(ineq2);
      result.add(local1);
      result.add(local2);
    }
    return result;
  }

  public static List<List<Inequation>> EliminateDoubles(List<List<Inequation>> __in) {
    List<List<Inequation>> result = new ArrayList<List<Inequation>>();
    /*
     * cout<<
     * "\nEliminateDoubles(List<List<Inequation*> >* __in){************************** AVANT\n"
     * ; cout<<PrintInequations(__in);
     */
    for (List<Inequation> it : __in) {
      boolean found = false;
      for (List<Inequation> itf : result) {
        if (PrintInequations(it).equals(PrintInequations(itf))) {
          found = true;
          break;
        }
      }
      if (!found) {
        result.add(it);
      }
    }

    /*
     * cout<<
     * "\nEliminateDoubles(List<List<Inequation*> >* __in){************************** APRES\n"
     * ; cout<<PrintInequations(&result);
     */
    return result;
  }

  public static List<String> RemoveDoubles(List<String> _v) {
    List<String> result = new ArrayList<String>();
    for (String it : _v) {
      if (!result.contains(it)) {
        result.add(it);
      }
    }
    return result;
  }

  // public static List<List<Inequation>> RemoveAlphas(List<List<Inequation>>
  // ineq, List<String> alphas);
  // public static List<Inequation> RemoveAlphas(List<Inequation> ineq,
  // List<String> alphas);
  public static List<List<Inequation>> RemoveFlase(List<List<Inequation>> __v, List<String> __param) {
    List<List<Inequation>> result = new ArrayList<List<Inequation>>();
    for (List<Inequation> it : __v) {
      // boolean __true;
      if (!IsUnsatisfiable1(it, __param)) {
        result.add(EliminateTrueAndDoubles(it));
      }
    }
    return result;
  }

  public static List<Inequation> Substitute1(List<Inequation> ineq, Map<String, Expression> __map) {
    List<Inequation> result = new ArrayList<Inequation>();

    for (Inequation it : ineq) {
      result.add(it.SubstituteByExpression(__map));
    }
    return result;
  }

  public static List<List<Inequation>> Substitute2(List<List<Inequation>> __v, Map<String, Expression> __map) {
    List<List<Inequation>> result = new ArrayList<List<Inequation>>();
    for (List<Inequation> it : __v) {
      result.add(Substitute1(it, __map));
    }
    return result;
  }

  public static boolean IsUnsatisfiable1(List<Inequation> constraints, List<String> parameters) {
    List<String> var = new ArrayList<String>();

    log.trace("=======IsUnsatisfiable***********************************");
    Solver s = SolverFactory.createSolver();
    s.set(-1, -1, RemoveDoubles(parameters), var, constraints);
    Quast m = s.Max();
   

      log.trace("=======IsUnsatisfiable (END)***********************************");
    if (m.IsLeaf() && m.IsEmpty())
      return true;
    return false;
  }

  public static boolean IsUnsatisfiable2(List<List<Inequation>> constraints, List<String> parameters) {
    log.trace("IsUnsatisfiable: constraints " + constraints.size());
    for (List<Inequation> it : constraints) {
      if (!IsUnsatisfiable1(it, parameters)) {
        return false;
      }
    }
    return true;
  }

  // public static boolean IsType(String identifier);
  // public static boolean AddType(String identifier);
  // public static void PrintAllTypes();
  // public static void InitTypes();

  public static List<Inequation> RecoverAndSubstituteAlphas1(List<String> alphas, List<Inequation> constraints) {
    Map<String, Expression> mapping = new HashMap<String, Expression>();
    for (Inequation it : constraints) {
      Inequation current = it;
      if (!current.IsValue()) {
        if (current.GetLHS().IsVariable() && alphas.contains(current.GetLHS().GetVariableName())) {
          mapping.put(current.GetLHS().GetVariableName(), current.GetRHS());
        }
        if (current.GetRHS().IsVariable() && alphas.contains(current.GetRHS().GetVariableName())) {
          mapping.put(current.GetRHS().GetVariableName(), current.GetLHS());
        }
      }
    }
    if (mapping.isEmpty()) {
      return constraints;
    }
    List<Inequation> result = new ArrayList<Inequation>();
    for (String key : mapping.keySet()) {
      result.add(new Inequation(new Expression(key), Inequation.Predicate.FADA_EQ, mapping.get(key)));
    }

    for (Inequation it : constraints) {
      result.add(it.SubstituteByExpression(mapping));
    }
    return result;
  }

  public static List<List<Inequation>> RecoverAndSubstituteAlphas2(List<String> alphas, List<List<Inequation>> constraints) {
    List<List<Inequation>> result = new ArrayList<List<Inequation>>();
    for (List<Inequation> it : constraints) {
      result.add(EliminateTrueAndDoubles(RecoverAndSubstituteAlphas1(alphas, it)));
    }
    return result;
  }
}
TOP

Related Classes of com.hpctoday.fada.Global

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.