Coverage Report - net.sourceforge.combean.mathprog.grooml.GSet
 
Classes in this File Line Coverage Branch Coverage Complexity
GSet
85%
22/26
66%
38/58
0
GSet$_toList_closure1
0%
0/1
N/A
0
 
 1  
 /*
 2  
     This file is part of Combean.
 3  
 
 4  
     Combean is free software; you can redistribute it and/or modify
 5  
     it under the terms of the GNU General Public License as published by
 6  
     the Free Software Foundation; either version 2 of the License, or
 7  
     (at your option) any later version.
 8  
 
 9  
     Combean is distributed in the hope that it will be useful,
 10  
     but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12  
     GNU General Public License for more details.
 13  
 
 14  
     You should have received a copy of the GNU General Public License
 15  
     along with Foobar; if not, write to the Free Software
 16  
     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 17  
 */
 18  
 package net.sourceforge.combean.mathprog.grooml;
 19  
 
 20  
 import net.sourceforge.combean.util.except.UnsupportedMethodException;
 21  
 import net.sourceforge.combean.except.GModelException;
 22  
 import net.sourceforge.combean.interfaces.base.ResettableIterator;
 23  
 
 24  
 /**
 25  
  * A set of values which can be bound to an index variable.
 26  
  * 
 27  
  * The elements of the set can be traversed in a environment from which external
 28  
  * definition are taken (if the definition of the set is dynamic and is only
 29  
  * evaluated when the elements of the set are accessed)
 30  
  * 
 31  
  * Used to generate sums with many terms, define multiple rows in an LP etc.
 32  
  */
 33  
 abstract class GSet {
 34  
         
 35  
         /**
 36  
          * Check whether the set also supports the methods of a numbered set
 37  
          * as defined by the abstract class GNumberedSet
 38  
          * 
 39  
          * @returns true if the set supports the GNumberedSet interface
 40  
          */
 41  
         public boolean isNumbered() {
 42  10
                  return false;
 43  
          }
 44  
     
 45  
     /**
 46  
           * @returns the size of the value tuples in the set (1 if the set contains
 47  
           * simple values and no tuples)
 48  
           */
 49  
         public int tupleSize() {
 50  1620
              return 1;
 51  
         }
 52  
     
 53  
     /**
 54  
      * Get an iterator through all elements in the set. The elements in the
 55  
      * set may depend on the current environment (if the definition of the set
 56  
      * is dynamic).
 57  
      * 
 58  
      * @params env the environment
 59  
      * @returns an iterator through all elements in the set.
 60  
      */
 61  
     public abstract Iterator evaluate(Object env);
 62  
 
 63  
     /**
 64  
      * Create a product set from a list of individual sets
 65  
      * 
 66  
      * @params l the list of individual sets that shall be combined into the
 67  
      * product set. The list may only contain types that can be converted
 68  
      * into sets.
 69  
      */
 70  
      /*
 71  
     public static GSet prod(List l) {
 72  
         List setColl = [];
 73  
         List lastNumbered = [];
 74  
         l.each{
 75  
             GSet s = GSet.convert(it);
 76  
             if (s instanceof GNumberedSet) {
 77  
                 lastNumbered += s;
 78  
             }
 79  
             else {
 80  
                 if (lastNumbered.size() == 1) {
 81  
                     setColl += lastNumbered.first();
 82  
                     lastNumbered = [];
 83  
                 }
 84  
                 else if (lastNumbered.size() > 1) {
 85  
                     setColl += new GProductSet(lastNumbered);
 86  
                     lastNumbered = [];
 87  
                 }
 88  
                 setColl += s;
 89  
             }
 90  
         }
 91  
         if (lastNumbered.size() == 1) {
 92  
             setColl += lastNumbered.first();
 93  
         }
 94  
         else if (lastNumbered.size() > 1) {
 95  
             setColl += new GProductSet(lastNumbered);
 96  
         }
 97  
         
 98  
         GSet result = null;
 99  
         setColl.reverseEach{
 100  
             if (result == null) {
 101  
                 result = it;
 102  
             }
 103  
             else {
 104  
                 result = new GNestedSet(it, result);
 105  
             }
 106  
         }
 107  
         
 108  
         return result;
 109  
     }
 110  
     */
 111  
     /**
 112  
      * Override operator '*' in order to support a simple syntax for the
 113  
      * definition of set products, e.g. 'x * 1..10'.
 114  
      * 
 115  
      * @params other the other set with which 'this' shall be multiplied.
 116  
      * Object must be convertable to a set.
 117  
      * 
 118  
      * @returns the product of this and other
 119  
      */
 120  
     public GSet multiply(other) {
 121  100
         GSet s = GSet.convert(other);
 122  100
         if (this instanceof GNumberedSet && s instanceof GNumberedSet) {
 123  100
             if (this instanceof GProductSet) {
 124  10
                 if (s instanceof GProductSet) {
 125  0
                     return new GProductSet(getInnerSets() + other.getInnerSets());
 126  
                 }
 127  10
                 return new GProductSet(getInnerSets() + s);
 128  
             }
 129  90
             else if (s instanceof GProductSet) {
 130  5
                 return new GProductSet([this] + s.getInnerSets());
 131  
             }
 132  85
             return new GProductSet(this, s);
 133  
         }
 134  0
         return new GNestedSet(this, s);
 135  
     }
 136  
     
 137  
     public List toList(Object env) {
 138  0
         return evaluate(env).collect{it};
 139  
     }
 140  
     
 141  
     /**
 142  
      * Convert an object of arbitrary type to a set.
 143  
      * 
 144  
      * Supported types for conversion:
 145  
      * - Sets (not much to be converted there ... the object is returned as-is)
 146  
      * - Objects that implement the List interface
 147  
      * - Integers or Strings (defining a set with exactly one element)
 148  
      * - Closures: The closure defines a dynamic set and is evaluated within a given
 149  
      * environment when the elements of the set are accessed
 150  
      * 
 151  
      * @params setDef the object to be converted. if the type of the object cannot
 152  
      * be converted to an expression, an exception is thrown
 153  
      * @returns a new set object based on the definition given by setDef
 154  
      */
 155  
     public static GSet convert(setDef)
 156  
     throws GModelException
 157  
     {
 158  2715
         GSet result = null;
 159  2715
         if (setDef instanceof GSet) {
 160  560
             result = setDef;
 161  
         }
 162  2155
         else if (setDef instanceof List) {
 163  1955
                 result = new GListSet(setDef);
 164  
         }
 165  200
         else if (setDef instanceof Closure) {
 166  50
             result = new GDynamicSet(setDef);
 167  
         }
 168  150
         else if (setDef instanceof Integer || setDef instanceof String) {
 169  85
             result = new GListSet([setDef]);
 170  
         }
 171  65
         else if (setDef instanceof Map) {
 172  65
             result = GIndexBinding.convert(setDef);
 173  
         }
 174  
         else {
 175  0
             throw new GModelException(
 176  
                     "unexpected definition for set: '$setDef'");
 177  
         }
 178  2715
         return result;
 179  
     }
 180  
 }