GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/quantifiers/sygus/sygus_eval_unfold.h Lines: 1 1 100.0 %
Date: 2021-08-20 Branches: 0 0 0.0 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds, Mathias Preiner
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
 * sygus_eval_unfold
14
 */
15
16
#include "cvc5_private.h"
17
18
#ifndef CVC5__THEORY__QUANTIFIERS__SYGUS_EVAL_UNFOLD_H
19
#define CVC5__THEORY__QUANTIFIERS__SYGUS_EVAL_UNFOLD_H
20
21
#include <map>
22
#include "expr/node.h"
23
#include "theory/quantifiers/sygus/sygus_invariance.h"
24
25
namespace cvc5 {
26
namespace theory {
27
namespace quantifiers {
28
29
class TermDbSygus;
30
31
/** SygusEvalUnfold
32
 *
33
 * This class implements techniques for eagerly unfolding sygus evaluation
34
 * functions. For example, given sygus datatype type corresponding to grammar:
35
 *   A -> 0 | 1 | A+A
36
 * whose evaluation function is eval, this class adds lemmas that "eagerly
37
 * unfold" applications of eval based on the model values of evaluation heads
38
 * in refinement lemmas.
39
 */
40
class SygusEvalUnfold
41
{
42
 public:
43
  SygusEvalUnfold(TermDbSygus* tds);
44
1150
  ~SygusEvalUnfold() {}
45
  /** register evaluation term
46
   *
47
   * This is called by TermDatabase, during standard effort calls when a term
48
   * n is registered as an equivalence class in the master equality engine.
49
   * If this term is of the form:
50
   *   eval( a, t1, ..., tn )
51
   * where a is a symbolic term of sygus datatype type (not a application of a
52
   * constructor), then we remember that n is an evaluation function application
53
   * for evaluation head a.
54
   */
55
  void registerEvalTerm(Node n);
56
  /** register model value
57
   *
58
   * This notifies this class that the model value M(a) of an anchor term a is
59
   * currently v. Assume in the following that the top symbol of v is some sygus
60
   * datatype constructor C_op.
61
   *
62
   * If we have registered terms eval( a, T1 ), ..., eval( a, Tm ), then we
63
   * ensure that for each i=1,...,m, a lemma of one of the two forms is
64
   * generated:
65
   * [A] a=v => eval( a, Ti ) = [[unfold( eval( v, Ti ) )]]
66
   * [B] is-C_op(v) => eval(a, Ti ) = op(eval( a.1, Ti ), ..., eval( a.k, Ti )),
67
   * where this corresponds to a "one step folding" of the sygus evaluation
68
   * function, i.e. op is a builtin operator encoded by constructor C_op.
69
   *
70
   * We decide which kind of lemma to send ([A] or [B]) based on the symbol
71
   * C_op. If op is an ITE, or if C_op is a Boolean operator, then we add [B].
72
   * Otherwise, we add [A]. The intuition of why [B] is better than [A] for the
73
   * former is that evaluation unfolding can lead to useful conflict analysis.
74
   *
75
   * For each lemma C => eval( a, T ) = T' we infer is necessary, we add C to
76
   * exps, eval( a, T ) to terms, and T' to vals. The caller should send the
77
   * corresponding lemma on the output channel.
78
   *
79
   * We do the above scheme *for each* selector chain (see d_subterms below)
80
   * applied to a.
81
   */
82
  void registerModelValue(Node a,
83
                          Node v,
84
                          std::vector<Node>& exps,
85
                          std::vector<Node>& terms,
86
                          std::vector<Node>& vals);
87
  /** unfold
88
   *
89
   * This method is called when a sygus term d (typically a variable for a SyGuS
90
   * enumerator) has a model value specified by the map vtm. The argument en
91
   * is an application of kind DT_SYGUS_EVAL, i.e. eval( d, c1, ..., cm ).
92
   * Typically, d is a shared selector chain, although it may also be a
93
   * non-constant application of a constructor.
94
   *
95
   * If doRec is false, this method returns the one-step unfolding of this
96
   * evaluation function application. An example of a one step unfolding is:
97
   *    eval( C_+( d1, d2 ), t ) ---> +( eval( d1, t ), eval( d2, t ) )
98
   *
99
   * This function does this unfolding for a (possibly symbolic) evaluation
100
   * head, where the argument "variable to model" vtm stores the model value of
101
   * variables from this head. This allows us to track an explanation of the
102
   * unfolding in the vector exp when track_exp is true.
103
   *
104
   * For example, if vtm[d] = C_+( C_x(), C_0() ) and track_exp is true, then
105
   * this method applied to eval( d, t ) will return
106
   * +( eval( d.0, t ), eval( d.1, t ) ), and is-C_+( d ) is added to exp.
107
   *
108
   * If the argument doRec is true, we do a multi-step unfolding instead of
109
   * a single-step unfolding. For example, if vtm[d] = C_+( C_x(), C_0() ),
110
   * then this method applied to eval(d,5) will return 5+0 = 0.
111
   *
112
   * Furthermore, notice that any-constant constructors are *never* expanded to
113
   * their concrete model values. This means that the multi-step unfolding when
114
   * vtm[d] = C_+( C_x(), any_constant(n) ), then this method applied to
115
   * eval(d,5) will return 5 + d.2.1, where the latter term is a shared selector
116
   * chain. In other words, this unfolding elaborates the connection between
117
   * the builtin integer field d.2.1 of d and the builtin interpretation of
118
   * this sygus term, for the given argument.
119
   */
120
  Node unfold(Node en,
121
              std::map<Node, Node>& vtm,
122
              std::vector<Node>& exp,
123
              bool track_exp = true,
124
              bool doRec = false);
125
  /**
126
   * Same as above, but without explanation tracking. This is used for concrete
127
   * evaluation heads
128
   */
129
  Node unfold(Node en);
130
131
 private:
132
  /** sygus term database associated with this utility */
133
  TermDbSygus* d_tds;
134
  /** the set of evaluation terms we have already processed */
135
  std::unordered_set<Node> d_eval_processed;
136
  /** map from evaluation heads to evaluation function applications */
137
  std::map<Node, std::vector<Node> > d_evals;
138
  /**
139
   * Map from evaluation function applications to their arguments (minus the
140
   * evaluation head). For example, eval(x,0,1) is mapped to { 0, 1 }.
141
   */
142
  std::map<Node, std::vector<std::vector<Node> > > d_eval_args;
143
  /**
144
   * For each (a,M(a)) pair, the number of terms in d_evals that we have added
145
   * lemmas for
146
   */
147
  std::map<Node, std::map<Node, unsigned> > d_node_mv_args_proc;
148
  /** subterms map
149
   *
150
   * This maps anchor terms to the set of shared selector chains with
151
   * them as an anchor, for example x may map to { x, x.1, x.2, x.1.1 }.
152
   */
153
  std::map<Node, std::unordered_set<Node> > d_subterms;
154
};
155
156
}  // namespace quantifiers
157
}  // namespace theory
158
}  // namespace cvc5
159
160
#endif /* CVC5__THEORY__QUANTIFIERS__SYGUS_EVAL_UNFOLD_H */