GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/uf/ho_extension.h Lines: 1 1 100.0 %
Date: 2021-05-22 Branches: 0 0 0.0 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds
4
 *
5
 * This file is part of the cvc5 project.
6
 *
7
 * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8
 * in the top-level source directory and their institutional affiliations.
9
 * All rights reserved.  See the file COPYING in the top-level source
10
 * directory for licensing information.
11
 * ****************************************************************************
12
 *
13
 * The higher-order extension of TheoryUF.
14
 */
15
16
#include "cvc5_private.h"
17
18
#ifndef __CVC5__THEORY__UF__HO_EXTENSION_H
19
#define __CVC5__THEORY__UF__HO_EXTENSION_H
20
21
#include "context/cdhashmap.h"
22
#include "context/cdhashset.h"
23
#include "context/cdo.h"
24
#include "expr/node.h"
25
#include "theory/theory_inference_manager.h"
26
#include "theory/theory_model.h"
27
#include "theory/theory_state.h"
28
29
namespace cvc5 {
30
namespace theory {
31
namespace uf {
32
33
class TheoryUF;
34
35
/** The higher-order extension of the theory of uninterpreted functions
36
 *
37
 * This extension is capable of handling UF constraints involving partial
38
 * applications via the applicative encoding (kind HO_APPLY), and
39
 * (dis)equalities involving function sorts. It uses a lazy applicative
40
 * encoding and implements two axiom schemes, at a high level:
41
 *
42
 * (1) Extensionality, where disequalities between functions witnessed by
43
 * arguments where the two functions differ,
44
 *
45
 * (2) App-Encode, where full applications of UF (kind APPLY_UF) are equated
46
 * with curried applications (kind HO_APPLY).
47
 *
48
 * For more details, see "Extending SMT Solvers to Higher-Order", Barbosa et al.
49
 */
50
200
class HoExtension
51
{
52
  typedef context::CDHashSet<Node> NodeSet;
53
  typedef context::CDHashMap<Node, Node> NodeNodeMap;
54
55
 public:
56
  HoExtension(TheoryState& state, TheoryInferenceManager& im);
57
58
  /** ppRewrite
59
   *
60
   * This returns the expanded form of node.
61
   *
62
   * In particular, this function will convert applications of HO_APPLY
63
   * to applications of APPLY_UF if they are fully applied, and introduce
64
   * function variables for function heads that are not variables via the
65
   * getApplyUfForHoApply method below.
66
   */
67
  Node ppRewrite(Node node);
68
69
  /** check higher order
70
   *
71
   * This is called at full effort and infers facts and sends lemmas
72
   * based on higher-order reasoning (specifically, extentionality and
73
   * app completion). It returns the number of lemmas plus facts
74
   * added to the equality engine.
75
   */
76
  unsigned check();
77
78
  /** applyExtensionality
79
   *
80
   * Given disequality deq f != g, if not already cached, this sends a lemma of
81
   * the form:
82
   *   f = g V (f k) != (g k) for fresh constant k on the output channel of the
83
   * parent TheoryUF object. This is an "extensionality lemma".
84
   * Return value is the number of lemmas of this form sent on the output
85
   * channel.
86
   */
87
  unsigned applyExtensionality(TNode deq);
88
89
  /** collect model info
90
   *
91
   * This method adds the necessary equalities to the model m such that
92
   * model construction is possible if this method returns true. These
93
   * equalities may include HO_APPLY versions of all APPLY_UF terms.
94
   *
95
   * The argument termSet is the set of relevant terms that the parent TheoryUF
96
   * object has added to m that belong to TheoryUF.
97
   *
98
   * This method ensures that the function variables in termSet
99
   * respect extensionality. If some pair does not, then this method adds an
100
   * extensionality equality directly to the equality engine of m.
101
   *
102
   * In more detail, functions f and g do not respect extensionality if f and g
103
   * are not equal in the model, and there is not a pair of unequal witness
104
   * terms f(k), g(k). In this case, we add the disequality
105
   *    f(k') != g(k')
106
   * for fresh (tuple) of variables k' to the equality engine of m. Notice
107
   * this is done only for functions whose type has infinite cardinality,
108
   * since all functions with finite cardinality are ensured to respect
109
   * extensionality by this point due to our extentionality inference schema.
110
   *
111
   * If this method returns true, then all pairs of functions that are in
112
   * distinct equivalence classes will be guaranteed to be assigned different
113
   * values in m. It returns false if any (dis)equality added to m led to
114
   * an inconsistency in m.
115
   */
116
  bool collectModelInfoHo(TheoryModel* m, const std::set<Node>& termSet);
117
118
 protected:
119
  /** get apply uf for ho apply
120
   *
121
   * This returns the APPLY_UF equivalent for the HO_APPLY term node, where
122
   * node has non-functional return type (that is, it corresponds to a fully
123
   * applied function term).
124
   * This call may introduce a skolem for the head operator and send out a lemma
125
   * specifying the definition.
126
   */
127
  Node getApplyUfForHoApply(Node node);
128
129
  /** get extensionality disequality
130
   *
131
   * Given disequality deq f != g, this returns the disequality:
132
   *   (f k) != (g k) for fresh constant(s) k.
133
   *
134
   * If isCached is true, then this returns the same k for all calls to this
135
   * method with the same deq. If it is false, it creates fresh k and does not
136
   * cache the result.
137
   */
138
  Node getExtensionalityDeq(TNode deq, bool isCached = true);
139
140
  /**
141
   * Check whether extensionality should be applied for any pair of terms in the
142
   * equality engine.
143
   *
144
   * If we pass a null model m to this function, then we add extensionality
145
   * lemmas to the output channel and return the total number of lemmas added.
146
   * We only add lemmas for functions whose type is finite, since pairs of
147
   * functions whose types are infinite can be made disequal in a model by
148
   * witnessing a point they are disequal.
149
   *
150
   * If we pass a non-null model m to this function, then we add disequalities
151
   * that correspond to the conclusion of extensionality lemmas to the model's
152
   * equality engine. We return 0 if the equality engine of m is consistent
153
   * after this call, and 1 otherwise. We only add disequalities for functions
154
   * whose type is infinite, since our decision procedure guarantees that
155
   * extensionality lemmas are added for all pairs of functions whose types are
156
   * finite.
157
   */
158
  unsigned checkExtensionality(TheoryModel* m = nullptr);
159
160
  /** applyAppCompletion
161
   * This infers a correspondence between APPLY_UF and HO_APPLY
162
   * versions of terms for higher-order.
163
   * Given APPLY_UF node e.g. (f a b c), this adds the equality to its
164
   * HO_APPLY equivalent:
165
   *   (f a b c) == (@ (@ (@ f a) b) c)
166
   * to equality engine, if not already equal.
167
   * Return value is the number of equalities added.
168
   */
169
  unsigned applyAppCompletion(TNode n);
170
171
  /** check whether app-completion should be applied for any
172
   * pair of terms in the equality engine.
173
   */
174
  unsigned checkAppCompletion();
175
  /** collect model info for higher-order term
176
   *
177
   * This adds required constraints to m for term n. In particular, if n is
178
   * an APPLY_UF term, we add its HO_APPLY equivalent in this call. We return
179
   * true if the model m is consistent after this call.
180
   */
181
  bool collectModelInfoHoTerm(Node n, TheoryModel* m);
182
183
 private:
184
  /** common constants */
185
  Node d_true;
186
  /** Reference to the state object */
187
  TheoryState& d_state;
188
  /** Reference to the inference manager */
189
  TheoryInferenceManager& d_im;
190
  /** extensionality has been applied to these disequalities */
191
  NodeSet d_extensionality;
192
193
  /** cache of getExtensionalityDeq below */
194
  std::map<Node, Node> d_extensionality_deq;
195
196
  /** map from non-standard operators to their skolems */
197
  NodeNodeMap d_uf_std_skolem;
198
}; /* class TheoryUF */
199
200
}  // namespace uf
201
}  // namespace theory
202
}  // namespace cvc5
203
204
#endif /* __CVC5__THEORY__UF__HO_EXTENSION_H */