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