File: float.hh

package info (click to toggle)
gecode-snapshot 6.2.0%2Bgit20240207-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 35,308 kB
  • sloc: cpp: 475,516; perl: 2,077; makefile: 1,816; sh: 198
file content (373 lines) | stat: -rw-r--r-- 13,963 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
 *  Main authors:
 *     Christian Schulte <schulte@gecode.org>
 *     Mikael Lagerkvist <lagerkvist@gecode.org>
 *     Vincent Barichard <Vincent.Barichard@univ-angers.fr>
 *
 *  Copyright:
 *     Christian Schulte, 2005
 *     Mikael Lagerkvist, 2006
 *     Vincent Barichard, 2012
 *
 *  This file is part of Gecode, the generic constraint
 *  development environment:
 *     http://www.gecode.org
 *
 *  Permission is hereby granted, free of charge, to any person obtaining
 *  a copy of this software and associated documentation files (the
 *  "Software"), to deal in the Software without restriction, including
 *  without limitation the rights to use, copy, modify, merge, publish,
 *  distribute, sublicense, and/or sell copies of the Software, and to
 *  permit persons to whom the Software is furnished to do so, subject to
 *  the following conditions:
 *
 *  The above copyright notice and this permission notice shall be
 *  included in all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */

#ifndef GECODE_TEST_FLOAT_HH
#define GECODE_TEST_FLOAT_HH

#include "test/test.hh"

#include <gecode/float.hh>

namespace Test {

  /// Testing domain floats
  namespace Float {

    /// Type for comparisons and solutions
    enum MaybeType {
      MT_FALSE = 0, //< Does hold
      MT_TRUE,      //< Does not hold
      MT_MAYBE      //< Might or might not hold
    };

    /// Three-valued conjunction of MaybeType
    MaybeType operator &(MaybeType a, MaybeType b);

    /// Assignment possible types
    enum AssignmentType {
      CPLT_ASSIGNMENT = 0,
      RANDOM_ASSIGNMENT,
      EXTEND_ASSIGNMENT
    };

    class Test;

    /**
     * \defgroup TaskTestFloat Testing domain floats
     * \ingroup TaskTest
     */

    /**
     * \defgroup TaskTestFloatFloat General test support
     * \ingroup TaskTestFloat
     */
    //@{
    /// %Base class for assignments
    class Assignment {
    protected:
      int n;              ///< Number of variables
      Gecode::FloatVal d; ///< Domain for each variable
    public:
      /// Initialize assignments for \a n0 variables and values \a d0
      Assignment(int n0, const Gecode::FloatVal& d0);
      /// Test whether all assignments have been iterated
      virtual bool has_more(void) const = 0;
      /// Move to next assignment
      virtual void next(Gecode::Support::RandomGenerator& rand) = 0;
      /// Return value for variable \a i
      virtual Gecode::FloatVal operator[](int i) const = 0;
      /// Set assignment to value \a val for variable \a i
      virtual void set(int i, const Gecode::FloatVal& val) = 0;
      /// Return number of variables
      int size(void) const;
      /// Destructor
      virtual ~Assignment(void);
    };

    /// Generate all assignments
    class CpltAssignment : public Assignment {
    protected:
      Gecode::FloatVal* dsv; ///< Iterator for each variable
      Gecode::FloatNum step; ///< Step for next assignment
    public:
      /// Initialize assignments for \a n variables and values \a d with step \a s
      CpltAssignment(int n, const Gecode::FloatVal& d, Gecode::FloatNum s);
      /// Test whether all assignments have been iterated
      virtual bool has_more(void) const;
      /// Move to next assignment
      virtual void next(Gecode::Support::RandomGenerator& rand);
      /// Return value for variable \a i
      virtual Gecode::FloatVal operator[](int i) const;
      /// Set assignment to value \a val for variable \a i
      virtual void set(int i, const Gecode::FloatVal& val);
      /// Destructor
      virtual ~CpltAssignment(void);
    };

    /// Generate all assignments except the last variable and complete it to get a solution
    class ExtAssignment : public Assignment {
    protected:
      const Test* curPb;     ///< Current problem used to complete assignment
      Gecode::FloatVal* dsv; ///< Iterator for each variable
      Gecode::FloatNum step; ///< Step for next assignment
    public:
      /// Initialize assignments for \a n variables and values \a d with step \a s
      ExtAssignment(int n, const Gecode::FloatVal& d, Gecode::FloatNum s, const Test* pb,
                    Gecode::Support::RandomGenerator& rand);
      /// Test whether all assignments have been iterated
      virtual bool has_more(void) const;
      /// Move to next assignment
      virtual void next(Gecode::Support::RandomGenerator& rand);
      /// Return value for variable \a i
      virtual Gecode::FloatVal operator[](int i) const;
      /// Set assignment to value \a val for variable \a i
      virtual void set(int i, const Gecode::FloatVal& val);
      /// Destructor
      virtual ~ExtAssignment(void);
    };


    /// Generate random selection of assignments
    class RandomAssignment : public Assignment {
    protected:
      Gecode::FloatVal* vals; ///< The current values for the variables
      int  a;                 ///< How many assignments still to be generated
      /// Generate new value according to domain
      Gecode::FloatNum randval(Gecode::Support::RandomGenerator& rand);
    public:
      /// Initialize for \a a assignments for \a n variables and values \a d
      RandomAssignment(int n, const Gecode::FloatVal& d, int a0, Gecode::Support::RandomGenerator& rand);
      /// Test whether all assignments have been iterated
      virtual bool has_more(void) const;
      /// Move to next assignment
      virtual void next(Gecode::Support::RandomGenerator& rand);
      /// Return value for variable \a i
      virtual Gecode::FloatVal operator[](int i) const;
      /// Set assignment to value \a val for variable \a i
      virtual void set(int i, const Gecode::FloatVal& val);
      /// Destructor
      virtual ~RandomAssignment(void);
    };

    /// Space for executing tests
    class TestSpace : public Gecode::Space {
    public:
      /// Initial domain
      Gecode::FloatVal d;
      /// Step for going to next solution
      Gecode::FloatNum step;
      /// Variables to be tested
      Gecode::FloatVarArray x;
      /// Reification information
      Gecode::Reify r;
      /// The test currently run
      Test* test;
      /// Whether the test is for a reified propagator
      bool reified;

      /**
       * \brief Create test space
       *
       * Creates \a n variables with domain \a d and step \a s for
       * test \a t.
       *
       */
      TestSpace(int n, Gecode::FloatVal& d, Gecode::FloatNum s, Test* t);
      /**
       * \brief Create test space
       *
       * Creates \a n variables with domain \a d and step \a s for
       * test \a t and reification mode \a rm.
       *
       */
      TestSpace(int n, Gecode::FloatVal& d, Gecode::FloatNum s, Test* t,
                Gecode::ReifyMode rm);
      /// Constructor for cloning \a s
      TestSpace(TestSpace& s);
      /// Copy space during cloning
      virtual Gecode::Space* copy(void);
      /// Add constraints to skip solutions to the \a a assignment
      virtual void dropUntil(const Assignment& a);
      /// Test whether all variables are assigned
      bool assigned(void) const;
      /// Test whether all variables match assignment \a a
      bool matchAssignment(const Assignment& a) const;
      /// Post propagator
      void post(void);
      /// Compute a fixpoint and check for failure
      bool failed(void);
      /// Perform integer tell operation on \a x[i]
      void rel(int i, Gecode::FloatRelType frt, Gecode::FloatVal n);
      /// Perform Boolean tell on \a b
      void rel(bool sol);
      /// Assign all (or all but one, if \a skip is true) variables to values in \a a
      /// If assignment of a variable is MT_MAYBE (if the two intervals are contiguous),
      /// \a sol is set to MT_MAYBE
      void assign(const Assignment& a, MaybeType& sol, bool skip, Gecode::Support::RandomGenerator& rand);
      /// Assign a random variable to a random bound
      void bound(Gecode::Support::RandomGenerator& rand);
      /// Cut the bigger variable to an half sized interval. It returns
      /// the new size of the cut interval. \a cutDirections gives the direction
      /// to follow (upper part or lower part of the interval).
      Gecode::FloatNum cut(int* cutDirections);
      /// Prune some random values from variable \a i
      void prune(int i, Gecode::Support::RandomGenerator& rand);
      /// Prune some random values for some random variable
      void prune(Gecode::Support::RandomGenerator& rand);
      /// Prune values but not those in assignment \a a
      bool prune(const Assignment& a, bool testfix, Gecode::Support::RandomGenerator& rand);
      /// Disable propagators in space and compute fixpoint (make all idle)
      void disable(void);
      /// Enable propagators in space
      void enable(void);
      /// Return the number of propagators
      unsigned int propagators(void);
    };

    /**
     * \brief %Base class for tests with float constraints
     *
     */
    class Test : public Base {
    protected:
      /// Number of variables
      int arity;
      /// Domain of variables
      Gecode::FloatVal dom;
      /// Step for going to next solution
      Gecode::FloatNum step;
      /// Gives the type of assignment to use
      AssignmentType assignmentType;
      /// Does the constraint also exist as reified constraint
      bool reified;
      /// Which reification modes are supported
      int rms;
      /// Whether to perform search test
      bool testsearch;
      /// Whether to perform fixpoint test
      bool testfix;
      /// Whether to test for subsumption
      bool testsubsumed;
      /// \name Test for reification modes
      //@{
      /// Test whether equivalence as reification mode is supported
      bool eqv(void) const;
      /// Test whether implication as reification mode is supported
      bool imp(void) const;
      /// Test whether reverse implication as reification mode is supported
      bool pmi(void) const;
      //@}
    public:
      /**
       * \brief Constructor
       *
       * Constructs a test with name \a s and arity \a a and variable
       * domain \a d and step \a st and assignment type \a at. Also
       * tests for a reified constraint, if \a r is true.
       */
      Test(const std::string& s, int a, const Gecode::FloatVal& d,
           Gecode::FloatNum st, AssignmentType at,
           bool r);
      /**
       * \brief Constructor
       *
       * Constructs a test with name \a s and arity \a a and variable
       * domain \a min ... \a max and step \a st and assignment type \a at. Also
       * tests for a reified constraint, if \a r is true.
       */
      Test(const std::string& s, int a,
           Gecode::FloatNum min, Gecode::FloatNum max,
           Gecode::FloatNum st, AssignmentType at,
           bool r);
      /// Create assignment
      virtual Assignment* assignment(void) const;
      /// Complete the current assignment to get a feasible one (which satisfies all constraint).
      /// If such an assignment is computed, it returns true, false otherwise
      virtual bool extendAssignment(Assignment& a) const;
      /// Check for solution
      virtual MaybeType solution(const Assignment&) const = 0;
      /// Test if \a ts is subsumed or not (i.e. if there is no more propagator unless
      /// the assignment is an extended assignment.
      bool subsumed(const TestSpace& ts) const;
      /// Whether to ignore assignment for reification
      virtual bool ignore(const Assignment& a) const;
      /// Post constraint
      virtual void post(Gecode::Space& home, Gecode::FloatVarArray& x) = 0;
      /// Post reified constraint
      virtual void post(Gecode::Space& home, Gecode::FloatVarArray& x,
                        Gecode::Reify r);
      /// Perform test
      virtual bool run(void);
      /// \name Mapping scalar values to strings
      //@{
      /// Map float relation to string
      static std::string str(Gecode::FloatRelType frt);
      /// Map floatNum to string
      static std::string str(Gecode::FloatNum f);
      /// Map floatVal to string
      static std::string str(Gecode::FloatVal f);
      /// Map float array to string
      static std::string str(const Gecode::FloatValArgs& f);
      //@}
      /// \name General support
      //@{
      /// Compare \a x and \a y with respect to \a r
      static MaybeType cmp(Gecode::FloatVal x, Gecode::FloatRelType r,
                           Gecode::FloatVal y);
      /// Whether \a x and \a y are equal
      static MaybeType eq(Gecode::FloatVal x, Gecode::FloatVal y);
      /// Flip a coin and return true or false randomly
      bool flip(void);
      //@}
    };
    //@}

    /// Iterator for float relation types
    class FloatRelTypes {
    private:
      /// Array of relation types
      static const Gecode::FloatRelType frts[6];
      /// Current position in relation type array
      int i;
    public:
      /// Initialize iterator
      FloatRelTypes(void);
      /// Reset iterator
      void reset(void);
      /// Test whether iterator is done
      bool operator()(void) const;
      /// Increment to next relation type
      void operator++(void);
      /// Return current relation type
      Gecode::FloatRelType frt(void) const;
    };

  }
}

/**
 * \brief Print assignment \a
 * \relates Assignment
 */
std::ostream& operator<<(std::ostream& os, const Test::Float::Assignment& a);

#include "test/float.hpp"

#endif

// STATISTICS: test-float