summaryrefslogtreecommitdiff
path: root/libs/cassowary/cassowary/ClSolver.h
blob: 16e798d49129b70465c42525008721a33d7e64a6 (plain)
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
// $Id$
//
// Cassowary Incremental Constraint Solver
// Original Smalltalk Implementation by Alan Borning
// This C++ Implementation by Greg J. Badros, <gjb@cs.washington.edu>
// http://www.cs.washington.edu/homes/gjb
// (C) 1998, 1999 Greg J. Badros and Alan Borning
// See ../LICENSE for legal details regarding this software
//
// ClSolver.h

#ifndef ClSolver_H
#define ClSolver_H

#if defined(HAVE_CONFIG_H) && !defined(CONFIG_H_INCLUDED) && !defined(CONFIG_INLINE_H_INCLUDED)
#include <cassowary/config-inline.h>
#define CONFIG_INLINE_H_INCLUDED
#endif

#include "Cassowary.h"
#include "ClErrors.h"
#include "ClTypedefs.h"
#include <list>
#include <iostream>

using std::list;
using std::ostream;

class ClVariable;

// ClSolver is an abstract base class
class ClSolver {
 public:

  ClSolver() : _pv(0), _fAutosolve(true), _pfnChangeClvCallback(0) { }

  virtual ~ClSolver()
    { } 

  // Add the constraint cn to the solver
  virtual ClSolver &AddConstraint(ClConstraint *const pcn) = 0;

  // Remove the constraint cn from the solver
  virtual ClSolver &RemoveConstraint(ClConstraint *const pcn) = 0;

  // Same as above, but returns false if the constraint cannot be solved
  // (i.e., the resulting system would be unsatisfiable)
  // The above function "AddConstraint" throws an exception in that case
  // which may be inconvenient
  virtual bool AddConstraintNoException(ClConstraint *const pcn)
    {
      try {
          AddConstraint(pcn);
          return true;
      }
      catch (const ExCLRequiredFailure &e)
        { return false; }
      catch (const ExCLTooDifficult &e)
        { return false; }
    }

#ifndef CL_NO_DEPRECATED
  // Deprecated --02/22/99 gjb
  bool AddConstraintNoException(ClConstraint &cn)
    { return AddConstraintNoException(&cn); }
#endif

  virtual bool RemoveConstraintNoException(ClConstraint *const pcn)
    {
      try {
        RemoveConstraint(pcn);
        return true;
      }
      catch (const ExCLConstraintNotFound &e)
        { return false; }
    }

#ifndef CL_NO_DEPRECATED
  // Deprecated --02/22/99 gjb
  bool RemoveConstraintNoException(ClConstraint &cn)
    { return RemoveConstraintNoException(&cn); }
#endif


  virtual ClSolver &Solve()
    { assert(false); return *this; }

  virtual bool SolveNoException()
    {
      try {
        Solve();
        return true;
      }
      catch (const ExCLTooDifficult &e)
        { return false; }
      catch (const ExCLRequiredFailure &e)
        { return false; }
    }


  virtual void Resolve()
    { assert(false); }

  void SetPv(void *pv)
    { _pv = pv; }

  void *Pv() const
    { return _pv; }

  typedef void (*PfnChangeClvCallback)(ClVariable *pclv, ClSolver *psolver);

  void SetChangeClvCallback(PfnChangeClvCallback pfn)
    { _pfnChangeClvCallback = pfn; }

  // Control whether optimization and setting of external variables
  // is done automatically or not.  By default it is done
  // automatically and solve() never needs to be explicitly
  // called by client code; if SetAutosolve is put to false,
  // then solve() needs to be invoked explicitly before using
  // variables' values
  // (Turning off autosolve while adding lots and lots of
  // constraints [ala the addDel test in ClTests] saved
  // about 20% in runtime, from 68sec to 54sec for 900 constraints,
  // with 126 failed adds)
  ClSolver &SetAutosolve(bool f)
    { _fAutosolve = f; if (f) Solve(); return *this; }

  // Tell whether we are autosolving
  bool FIsAutosolving() const
    { return _fAutosolve; }


#ifndef CL_NO_IO
  friend ostream &operator<<(ostream &xo, const ClSolver &solver);

  virtual ostream &PrintOn(ostream &xo) const = 0;

#endif  

 protected:

  // C-style extension mechanism so I
  // don't have to wrap ScwmClSolver separately
  void *_pv;

  bool _fAutosolve;

  PfnChangeClvCallback _pfnChangeClvCallback;
};


#ifndef CL_NO_IO
ostream &PrintTo(ostream &xo, const ClVarVector &varlist);
ostream &operator<<(ostream &xo, const ClVarVector &varlist);

ostream &PrintTo(ostream &xo, const ClConstraintToVarSetMap &mapCnToVarSet);
ostream &operator<<(ostream &xo, const ClConstraintToVarSetMap &mapCnToVarSet);

ostream &PrintTo(ostream &xo, const ClConstraintSet &setCn);
ostream &operator<<(ostream &xo, const ClConstraintSet &setCn);

ostream &PrintTo(ostream &xo, const list<FDNumber> &listFDN);
ostream &operator<<(ostream &xo, const list<FDNumber> &listFDN);

#endif

#endif