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