summaryrefslogtreecommitdiff
path: root/src/theory/logic_info.h
blob: fd81ea629f7fb33135868957420ecbb84b013bac (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
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
/*********************                                                        */
/*! \file logic_info.h
 ** \verbatim
 ** Original author: mdeters
 ** Major contributors: none
 ** Minor contributors (to current version): none
 ** This file is part of the CVC4 prototype.
 ** Copyright (c) 2009-2012  New York University and The University of Iowa
 ** See the file COPYING in the top-level source directory for licensing
 ** information.\endverbatim
 **
 ** \brief A class giving information about a logic (group a theory modules
 ** and configuration information)
 **
 ** A class giving information about a logic (group of theory modules and
 ** configuration information).
 **/

#include "cvc4_public.h"

#ifndef __CVC4__LOGIC_INFO_H
#define __CVC4__LOGIC_INFO_H

#include <string>
#include <vector>
#include "expr/kind.h"

namespace CVC4 {

/**
 * A LogicInfo instance describes a collection of theory modules and some
 * basic configuration about them.  Conceptually, it provides a background
 * context for all operations in CVC4.  Typically, when CVC4's SmtEngine
 * is created, it is issued a setLogic() command indicating features of the
 * assertions and queries to follow---for example, whether quantifiers are
 * used, whether integers or reals (or both) will be used, etc.
 *
 * Most places in CVC4 will only ever need to access a const reference to an
 * instance of this class.  Such an instance is generally set by the SmtEngine
 * when setLogic() is called.  However, mutating member functions are also
 * provided by this class so that it can be used as a more general mechanism
 * (e.g., for communicating to the SmtEngine which theories should be used,
 * rather than having to provide an SMT-LIB string).
 */
class CVC4_PUBLIC LogicInfo {
  mutable std::string d_logicString; /**< an SMT-LIB-like logic string */
  std::vector<bool> d_theories; /**< set of active theories */
  size_t d_sharingTheories; /**< count of theories that need sharing */

  // for arithmetic
  bool d_integers; /**< are integers used in this logic? */
  bool d_reals; /**< are reals used in this logic? */
  bool d_linear; /**< linear-only arithmetic in this logic? */
  bool d_differenceLogic; /**< difference-only arithmetic in this logic? */

  bool d_locked; /**< is this LogicInfo instance locked (and thus immutable)? */

  /**
   * Returns true iff this is a "true" theory (one that must be worried
   * about for sharing
   */
  static inline bool isTrueTheory(theory::TheoryId theory) {
    switch(theory) {
    case theory::THEORY_BUILTIN:
    case theory::THEORY_BOOL:
    case theory::THEORY_QUANTIFIERS:
    case theory::THEORY_REWRITERULES:
      return false;
    default:
      return true;
    }
  }

public:

  /**
   * Constructs a LogicInfo for the most general logic (quantifiers, all
   * background theory modules, ...).
   */
  LogicInfo();

  /**
   * Construct a LogicInfo from an SMT-LIB-like logic string.
   * Throws an IllegalArgumentException if the logic string cannot
   * be interpreted.
   */
  LogicInfo(std::string logicString) throw(IllegalArgumentException);

  /**
   * Construct a LogicInfo from an SMT-LIB-like logic string.
   * Throws an IllegalArgumentException if the logic string cannot
   * be interpreted.
   */
  LogicInfo(const char* logicString) throw(IllegalArgumentException);

  // ACCESSORS

  /**
   * Get an SMT-LIB-like logic string.  These are only guaranteed to
   * be SMT-LIB-compliant if an SMT-LIB-compliant string was used in
   * the constructor and no mutating functions were called.
   */
  std::string getLogicString() const;

  /** Is sharing enabled for this logic? */
  bool isSharingEnabled() const {
    CheckArgument(d_locked, *this, "This LogicInfo isn't locked yet, and cannot be queried");
    return d_sharingTheories > 1;
  }

  /** Is the given theory module active in this logic? */
  bool isTheoryEnabled(theory::TheoryId theory) const {
    CheckArgument(d_locked, *this, "This LogicInfo isn't locked yet, and cannot be queried");
    return d_theories[theory];
  }

  /** Is this a quantified logic? */
  bool isQuantified() const {
    CheckArgument(d_locked, *this, "This LogicInfo isn't locked yet, and cannot be queried");
    return isTheoryEnabled(theory::THEORY_QUANTIFIERS) || isTheoryEnabled(theory::THEORY_REWRITERULES);
  }

  /** Is this the all-inclusive logic? */
  bool hasEverything() const {
    CheckArgument(d_locked, *this, "This LogicInfo isn't locked yet, and cannot be queried");
    LogicInfo everything;
    everything.lock();
    return *this == everything;
  }

  /** Is this the all-exclusive logic?  (Here, that means propositional logic) */
  bool hasNothing() const {
    CheckArgument(d_locked, *this, "This LogicInfo isn't locked yet, and cannot be queried");
    LogicInfo nothing("");
    nothing.lock();
    return *this == nothing;
  }

  /**
   * Is this a pure logic (only one "true" background theory).  Quantifiers
   * can exist in such logics though; to test for quantifier-free purity,
   * use "isPure(theory) && !isQuantified()".
   */
  bool isPure(theory::TheoryId theory) const {
    CheckArgument(d_locked, *this, "This LogicInfo isn't locked yet, and cannot be queried");
    // the third and fourth conjucts are really just to rule out the misleading
    // case where you ask isPure(THEORY_BOOL) and get true even in e.g. QF_LIA
    return isTheoryEnabled(theory) && !isSharingEnabled() &&
      ( !isTrueTheory(theory) || d_sharingTheories == 1 ) &&
      ( isTrueTheory(theory) || d_sharingTheories == 0 );
  }

  // these are for arithmetic

  /** Are integers in this logic? */
  bool areIntegersUsed() const {
    CheckArgument(d_locked, *this, "This LogicInfo isn't locked yet, and cannot be queried");
    return d_integers;
  }
  /** Are reals in this logic? */
  bool areRealsUsed() const {
    CheckArgument(d_locked, *this, "This LogicInfo isn't locked yet, and cannot be queried");
    return d_reals;
  }
  /** Does this logic only linear arithmetic? */
  bool isLinear() const {
    CheckArgument(d_locked, *this, "This LogicInfo isn't locked yet, and cannot be queried");
    return d_linear || d_differenceLogic;
  }
  /** Does this logic only permit difference reasoning? (implies linear) */
  bool isDifferenceLogic() const {
    CheckArgument(d_locked, *this, "This LogicInfo isn't locked yet, and cannot be queried");
    return d_differenceLogic;
  }

  // MUTATORS

  /**
   * Initialize the LogicInfo with an SMT-LIB-like logic string.
   * Throws an IllegalArgumentException if the string can't be
   * interpreted.
   */
  void setLogicString(std::string logicString) throw(IllegalArgumentException);

  /**
   * Enable all functionality.  All theories, plus quantifiers, will be
   * enabled.
   */
  void enableEverything();

  /**
   * Disable all functionality.  The result will be a LogicInfo with
   * the BUILTIN and BOOLEAN theories enabled only ("QF_SAT").
   */
  void disableEverything();

  /**
   * Enable the given theory module.
   */
  void enableTheory(theory::TheoryId theory);

  /**
   * Disable the given theory module.  THEORY_BUILTIN and THEORY_BOOL cannot
   * be disabled (and if given here, the request will be silently ignored).
   */
  void disableTheory(theory::TheoryId theory);

  /**
   * Quantifiers are a special case, since two theory modules handle them.
   */
  void enableQuantifiers() {
    enableTheory(theory::THEORY_QUANTIFIERS);
    enableTheory(theory::THEORY_REWRITERULES);
  }

  /**
   * Quantifiers are a special case, since two theory modules handle them.
   */
  void disableQuantifiers() {
    disableTheory(theory::THEORY_QUANTIFIERS);
    disableTheory(theory::THEORY_REWRITERULES);
  }

  // these are for arithmetic

  /** Enable the use of integers in this logic. */
  void enableIntegers();
  /** Disable the use of integers in this logic. */
  void disableIntegers();
  /** Enable the use of reals in this logic. */
  void enableReals();
  /** Disable the use of reals in this logic. */
  void disableReals();
  /** Only permit difference arithmetic in this logic. */
  void arithOnlyDifference();
  /** Only permit linear arithmetic in this logic. */
  void arithOnlyLinear();
  /** Permit nonlinear arithmetic in this logic. */
  void arithNonLinear();

  // LOCKING FUNCTIONALITY

  /** Lock this LogicInfo, disabling further mutation and allowing queries */
  void lock() { d_locked = true; }
  /** Check whether this LogicInfo is locked, disallowing further mutation */
  bool isLocked() const { return d_locked; }
  /** Get a copy of this LogicInfo that is identical, but unlocked */
  LogicInfo getUnlockedCopy() const;

  // COMPARISON

  /** Are these two LogicInfos equal? */
  bool operator==(const LogicInfo& other) const {
    CheckArgument(isLocked() && other.isLocked(), *this, "This LogicInfo isn't locked yet, and cannot be queried");
    for(theory::TheoryId id = theory::THEORY_FIRST; id < theory::THEORY_LAST; ++id) {
      if(d_theories[id] != other.d_theories[id]) {
        return false;
      }
    }
    CheckArgument(d_sharingTheories == other.d_sharingTheories, *this, "LogicInfo internal inconsistency");
    if(isTheoryEnabled(theory::THEORY_ARITH)) {
      return
        d_integers == other.d_integers &&
        d_reals == other.d_reals &&
        d_linear == other.d_linear &&
        d_differenceLogic == other.d_differenceLogic;
    } else {
      return true;
    }
  }
  /** Are these two LogicInfos disequal? */
  bool operator!=(const LogicInfo& other) const {
    return !(*this == other);
  }
  /** Is this LogicInfo "greater than" (does it contain everything and more) the other? */
  bool operator>(const LogicInfo& other) const {
    return *this >= other && *this != other;
  }
  /** Is this LogicInfo "less than" (does it contain strictly less) the other? */
  bool operator<(const LogicInfo& other) const {
    return *this <= other && *this != other;
  }
  /** Is this LogicInfo "less than or equal" the other? */
  bool operator<=(const LogicInfo& other) const {
    CheckArgument(isLocked() && other.isLocked(), *this, "This LogicInfo isn't locked yet, and cannot be queried");
    for(theory::TheoryId id = theory::THEORY_FIRST; id < theory::THEORY_LAST; ++id) {
      if(d_theories[id] && !other.d_theories[id]) {
        return false;
      }
    }
    CheckArgument(d_sharingTheories <= other.d_sharingTheories, *this, "LogicInfo internal inconsistency");
    if(isTheoryEnabled(theory::THEORY_ARITH) && other.isTheoryEnabled(theory::THEORY_ARITH)) {
      return
        (!d_integers || other.d_integers) &&
        (!d_reals || other.d_reals) &&
        (d_linear || !other.d_linear) &&
        (d_differenceLogic || !other.d_differenceLogic);
    } else {
      return true;
    }
  }
  /** Is this LogicInfo "greater than or equal" the other? */
  bool operator>=(const LogicInfo& other) const {
    CheckArgument(isLocked() && other.isLocked(), *this, "This LogicInfo isn't locked yet, and cannot be queried");
    for(theory::TheoryId id = theory::THEORY_FIRST; id < theory::THEORY_LAST; ++id) {
      if(!d_theories[id] && other.d_theories[id]) {
        return false;
      }
    }
    CheckArgument(d_sharingTheories >= other.d_sharingTheories, *this, "LogicInfo internal inconsistency");
    if(isTheoryEnabled(theory::THEORY_ARITH) && other.isTheoryEnabled(theory::THEORY_ARITH)) {
      return
        (d_integers || !other.d_integers) &&
        (d_reals || !other.d_reals) &&
        (!d_linear || other.d_linear) &&
        (!d_differenceLogic || other.d_differenceLogic);
    } else {
      return true;
    }
  }

  /** Are two LogicInfos comparable?  That is, is one of <= or > true? */
  bool isComparableTo(const LogicInfo& other) const {
    return *this <= other || *this >= other;
  }

};/* class LogicInfo */

std::ostream& operator<<(std::ostream& out, const LogicInfo& logic) CVC4_PUBLIC;

}/* CVC4 namespace */

#endif /* __CVC4__LOGIC_INFO_H */

generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback