summaryrefslogtreecommitdiff
path: root/src/theory/output_channel.h
blob: 524c9606ded7ec3de498bca123b2bec850f4d497 (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
/*********************                                                        */
/*! \file output_channel.h
 ** \verbatim
 ** Original author: Morgan Deters
 ** Major contributors: none
 ** Minor contributors (to current version): Andrew Reynolds, Dejan Jovanovic, Tim King
 ** This file is part of the CVC4 project.
 ** Copyright (c) 2009-2013  New York University and The University of Iowa
 ** See the file COPYING in the top-level source directory for licensing
 ** information.\endverbatim
 **
 ** \brief The theory output channel interface
 **
 ** The theory output channel interface.
 **/

#include "cvc4_private.h"

#ifndef __CVC4__THEORY__OUTPUT_CHANNEL_H
#define __CVC4__THEORY__OUTPUT_CHANNEL_H

#include "util/cvc4_assert.h"
#include "theory/interrupted.h"

namespace CVC4 {
namespace theory {

class Theory;

/**
 * A LemmaStatus, returned from OutputChannel::lemma(), provides information
 * about the lemma added.  In particular, it contains the T-rewritten lemma
 * for inspection and the user-level at which the lemma will reside.
 */
class LemmaStatus {
  Node d_rewrittenLemma;
  unsigned d_level;

public:
  LemmaStatus(TNode rewrittenLemma, unsigned level) :
    d_rewrittenLemma(rewrittenLemma),
    d_level(level) {
  }

  /** Get the T-rewritten form of the lemma. */
  TNode getRewrittenLemma() const throw() { return d_rewrittenLemma; }

  /**
   * Get the user-level at which the lemma resides.  After this user level
   * is popped, the lemma is un-asserted from the SAT layer.  This level
   * will be 0 if the lemma didn't reach the SAT layer at all.
   */
  unsigned getLevel() const throw() { return d_level; }

};/* class LemmaStatus */

/**
 * Generic "theory output channel" interface.
 */
class OutputChannel {
  /** Disallow copying: private constructor */
  OutputChannel(const OutputChannel&) CVC4_UNDEFINED;

  /** Disallow assignment: private operator=() */
  OutputChannel& operator=(const OutputChannel&) CVC4_UNDEFINED;

public:

  /**
   * Construct an OutputChannel.
   */
  OutputChannel() {
  }

  /**
   * Destructs an OutputChannel.  This implementation does nothing,
   * but we need a virtual destructor for safety in case subclasses
   * have a destructor.
   */
  virtual ~OutputChannel() {
  }

  /**
   * With safePoint(), the theory signals that it is at a safe point
   * and can be interrupted.
   */
  virtual void safePoint() throw(Interrupted, AssertionException) {
  }

  /**
   * Indicate a theory conflict has arisen.
   *
   * @param n - a conflict at the current decision level.  This should
   * be an AND-kinded node of literals that are TRUE in the current
   * assignment and are in conflict (i.e., at least one must be
   * assigned false), or else a literal by itself (in the case of a
   * unit conflict) which is assigned TRUE (and T-conflicting) in the
   * current assignment.
   */
  virtual void conflict(TNode n) throw(AssertionException) = 0;

  /**
   * Propagate a theory literal.
   *
   * @param n - a theory consequence at the current decision level
   * @return false if an immediate conflict was encountered
   */
  virtual bool propagate(TNode n) throw(AssertionException) = 0;

  /**
   * Tell the core that a valid theory lemma at decision level 0 has
   * been detected.  (This requests a split.)
   *
   * @param n - a theory lemma valid at decision level 0
   * @param removable - whether the lemma can be removed at any point
   * @return the "status" of the lemma, including user level at which
   * the lemma resides; the lemma will be removed when this user level pops
   */
  virtual LemmaStatus lemma(TNode n, bool removable = false)
    throw(TypeCheckingExceptionPrivate, AssertionException) = 0;

  /**
   * Request a split on a new theory atom.  This is equivalent to
   * calling lemma({OR n (NOT n)}).
   *
   * @param n - a theory atom; must be of Boolean type
   */
  LemmaStatus split(TNode n)
    throw(TypeCheckingExceptionPrivate, AssertionException) {
    return splitLemma(n.orNode(n.notNode()));
  }

  virtual LemmaStatus splitLemma(TNode n, bool removable = false)
    throw(TypeCheckingExceptionPrivate, AssertionException) = 0;

  /**
   * If a decision is made on n, it must be in the phase specified.
   * Note that this is enforced *globally*, i.e., it is completely
   * context-INdependent.  If you ever requirePhase() on a literal,
   * it is phase-locked forever and ever.  If it is to ever have the
   * other phase as its assignment, it will be because it has been
   * propagated that way (or it's a unit, at decision level 0).
   *
   * @param n - a theory atom with a SAT literal assigned; must have
   * been pre-registered
   * @param phase - the phase to decide on n
   */
  virtual void requirePhase(TNode n, bool phase)
    throw(Interrupted, TypeCheckingExceptionPrivate, AssertionException) = 0;

  /**
   * Flips the most recent unflipped decision to the other phase and
   * returns true.  If all decisions have been flipped, the root
   * decision is re-flipped and flipDecision() returns false.  If no
   * decisions (flipped nor unflipped) are on the decision stack, the
   * state is not affected and flipDecision() returns false.
   *
   * For example, if l1, l2, and l3 are all decision literals, and
   * have been decided in positive phase, a series of flipDecision()
   * calls has the following effects:
   *
   * l1 l2 l3 <br/>
   * l1 l2 ~l3 <br/>
   * l1 ~l2 <br/>
   * ~l1 <br/>
   * l1 (and flipDecision() returns false)
   *
   * Naturally, flipDecision() might be interleaved with search.  For example:
   *
   * l1 l2 l3 <br/>
   * flipDecision() <br/>
   * l1 l2 ~l3 <br/>
   * flipDecision() <br/>
   * l1 ~l2 <br/>
   * SAT decides l3 <br/>
   * l1 ~l2 l3 <br/>
   * flipDecision() <br/>
   * l1 ~l2 ~l3 <br/>
   * flipDecision() <br/>
   * ~l1 <br/>
   * SAT decides l2 <br/>
   * ~l1 l2 <br/>
   * flipDecision() <br/>
   * ~l1 ~l2 <br/>
   * flipDecision() returns FALSE<br/>
   * l1
   *
   * @return true if a decision was flipped; false if no decision
   * could be flipped, or if the root decision was re-flipped
   */
  virtual bool flipDecision()
    throw(Interrupted, TypeCheckingExceptionPrivate, AssertionException) = 0;

  /**
   * Notification from a theory that it realizes it is incomplete at
   * this context level.  If SAT is later determined by the
   * TheoryEngine, it should actually return an UNKNOWN result.
   */
  virtual void setIncomplete() throw(AssertionException) = 0;

  /**
   * "Spend" a "resource."  The meaning is specific to the context in
   * which the theory is operating, and may even be ignored.  The
   * intended meaning is that if the user has set a limit on the "units
   * of resource" that can be expended in a search, and that limit is
   * exceeded, then the search is terminated.  Note that the check for
   * termination occurs in the main search loop, so while theories
   * should call OutputChannel::spendResource() during particularly
   * long-running operations, they cannot rely on resource() to break
   * out of infinite or intractable computations.
   */
  virtual void spendResource() throw() {}

  /**
   * Handle user attribute.
   * Associates theory t with the attribute attr.  Theory t will be
   * notified whenever an attribute of name attr is set on a node.
   * This can happen through, for example, the SMT-LIBv2 language.
   */
  virtual void handleUserAttribute(const char* attr, Theory* t) {}


  /** Demands that the search restart from sat search level 0.
   * Using this leads to non-termination issues.
   * It is appropraite for prototyping for theories.
   */
  virtual void demandRestart() throw(TypeCheckingExceptionPrivate, AssertionException) {}

};/* class OutputChannel */

}/* CVC4::theory namespace */
}/* CVC4 namespace */

#endif /* __CVC4__THEORY__OUTPUT_CHANNEL_H */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback