1 /********************* */
4 ** Top contributors (to current version):
5 ** Andrew Reynolds, Mathias Preiner, Morgan Deters
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2020 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.\endverbatim
12 ** \brief trigger class
15 #include "cvc4_private.h"
17 #ifndef CVC4__THEORY__QUANTIFIERS__TRIGGER_H
18 #define CVC4__THEORY__QUANTIFIERS__TRIGGER_H
22 #include "expr/node.h"
23 #include "options/quantifiers_options.h"
24 #include "theory/quantifiers/inst_match.h"
25 #include "theory/valuation.h"
30 class QuantifiersEngine
;
32 namespace quantifiers
{
33 class QuantifiersInferenceManager
;
39 class InstMatchGenerator
;
40 /** A collection of nodes representing a trigger.
42 * This class encapsulates all implementations of E-matching in CVC4.
43 * Its primary use is as a utility of the quantifiers module InstantiationEngine
44 * (see theory/quantifiers/ematching/instantiation_engine.h) which uses Trigger to make
45 * appropriate calls to Instantiate::addInstantiation(...)
46 * (see theory/instantiate.h) for the instantiate utility of the quantifiers
47 * engine (d_quantEngine) associated with this trigger. These calls
48 * queue instantiation lemmas to the output channel of TheoryQuantifiers during
49 * a full effort check.
51 * Concretely, a Trigger* t is used in the following way during a full effort
52 * check. Assume that t is associated with quantified formula q (see field d_f).
55 * // setup initial information
56 * t->resetInstantiationRound();
57 * // will produce instantiations based on matching with all terms
58 * t->reset( Node::null() );
59 * // add all instantiations based on E-matching with this trigger and the
61 * t->addInstantiations();
63 * This will result in (a set of) calls to
64 * Instantiate::addInstantiation(q, m1)...Instantiate::addInstantiation(q, mn),
65 * where m1...mn are InstMatch objects. These calls add the corresponding
66 * instantiation lemma for (q,mi) on the output channel associated with
69 * The Trigger class is wrapper around an underlying IMGenerator class, which
70 * implements various forms of E-matching for its set of nodes (d_nodes), which
71 * is refered to in the literature as a "trigger". A trigger is a set of terms
72 * whose free variables are the bound variables of a quantified formula q,
73 * and that is used to guide instantiations for q (for example, see "Efficient
74 * E-Matching for SMT Solvers" by de Moura et al).
76 * For example of an instantiation lemma produced by E-matching :
78 * quantified formula : forall x. P( x )
80 * ground context : ~P( a )
82 * Then E-matching matches P( x ) and P( a ), resulting in the match { x -> a }
83 * which is used to generate the instantiation lemma :
84 * (forall x. P( x )) => P( a )
86 * Terms that are provided as input to a Trigger class via mkTrigger
87 * should be in "instantiation constant form", see TermUtil::getInstConstantNode.
88 * Say we have quantified formula q whose AST is the Node
92 * (INST_PATTERN_LIST (INST_PATTERN (P x))))
93 * then TermUtil::getInstConstantNode( q, (P x) ) = (P IC) where
94 * IC = TermUtil::getInstantiationConstant( q, i ).
95 * Trigger expects as input (P IC) to represent the Trigger (P x). This form
96 * ensures that references to bound variables are unique to quantified formulas,
97 * which is required to ensure the correctness of instantiation lemmas we
102 friend class IMGenerator
;
106 /** get the generator associated with this trigger */
107 IMGenerator
* getGenerator() { return d_mg
; }
108 /** Reset instantiation round.
110 * Called once at beginning of an instantiation round.
112 void resetInstantiationRound();
113 /** Reset the trigger.
115 * eqc is the equivalence class from which to match ground terms. If eqc is
116 * Node::null(), then we match ground terms from all equivalence classes.
118 void reset( Node eqc
);
119 /** add all available instantiations, based on the current context
121 * This function makes the appropriate calls to d_qe->addInstantiation(...)
122 * based on the current ground terms and equalities in the current context,
123 * via queries to functions in d_qe. This calls the addInstantiations function
124 * of the underlying match generator. It can be extended to
125 * produce instantiations beyond what is produced by the match generator
126 * (for example, see theory/quantifiers/ematching/ho_trigger.h).
128 virtual uint64_t addInstantiations();
129 /** Return whether this is a multi-trigger. */
130 bool isMultiTrigger() const;
131 /** Get instantiation pattern list associated with this trigger.
133 * An instantiation pattern list is the node representation of a trigger, in
134 * particular, it is the third argument of quantified formulas which have user
135 * (! ... :pattern) attributes.
137 Node
getInstPattern() const;
138 /* A heuristic value indicating how active this generator is.
140 * This returns the number of ground terms for the match operators in terms
141 * from d_nodes. This score is only used with the experimental option
142 * --trigger-active-sel.
144 int getActiveScore();
145 /** print debug information for the trigger */
146 void debugPrint(const char* c
) const;
149 * This makes an instance of a trigger object.
150 * qe : pointer to the quantifier engine;
151 * q : the quantified formula we are making a trigger for
152 * nodes : the nodes comprising the (multi-)trigger
153 * keepAll: don't remove unneeded patterns;
154 * trOption : policy for dealing with triggers that already exist
156 * useNVars : number of variables that should be bound by the trigger
157 * typically, the number of quantified variables in q.
160 TR_MAKE_NEW
, //make new trigger even if it already may exist
161 TR_GET_OLD
, //return a previous trigger if it had already been created
162 TR_RETURN_NULL
//return null if a duplicate is found
164 static Trigger
* mkTrigger(QuantifiersEngine
* qe
,
165 quantifiers::QuantifiersInferenceManager
& qim
,
167 std::vector
<Node
>& nodes
,
169 int trOption
= TR_MAKE_NEW
,
170 size_t useNVars
= 0);
171 /** single trigger version that calls the above function */
172 static Trigger
* mkTrigger(QuantifiersEngine
* qe
,
173 quantifiers::QuantifiersInferenceManager
& qim
,
177 int trOption
= TR_MAKE_NEW
,
178 size_t useNVars
= 0);
179 /** make trigger terms
181 * This takes a set of eligible trigger terms and stores a subset of them in
182 * trNodes, such that :
183 * (1) the terms in trNodes contain at least n_vars of the quantified
184 * variables in quantified formula q, and
185 * (2) the set trNodes is minimal, i.e. removing one term from trNodes
186 * always violates (1).
188 static bool mkTriggerTerms(Node q
,
189 std::vector
<Node
>& nodes
,
191 std::vector
<Node
>& trNodes
);
194 /** trigger constructor, intentionally protected (use Trigger::mkTrigger). */
195 Trigger(QuantifiersEngine
* ie
,
196 quantifiers::QuantifiersInferenceManager
& qim
,
198 std::vector
<Node
>& nodes
);
199 /** add an instantiation (called by InstMatchGenerator)
201 * This calls Instantiate::addInstantiation(...) for instantiations
202 * associated with m. Typically, m is associated with a single instantiation,
203 * but in some cases (e.g. higher-order) we may modify m before calling
204 * Instantiate::addInstantiation(...).
206 virtual bool sendInstantiation(InstMatch
& m
);
208 * Ensure that all ground subterms of n have been preprocessed. This makes
209 * calls to the provided valuation to obtain the preprocessed form of these
210 * terms. The preprocessed form of each ground subterm is added to gts.
212 * As an optimization, this method does not preprocess terms with no
213 * arguments, e.g. variables and constants are not preprocessed (as they
214 * should not change after preprocessing), nor are they added to gts.
216 * @param val The valuation to use for looking up preprocessed terms.
217 * @param n The node to process, which is in inst-constant form (free
218 * variables have been substituted by corresponding INST_CONSTANT).
219 * @param gts The set of preprocessed ground subterms of n.
220 * @return The converted form of n where all ground subterms have been
221 * replaced by their preprocessed form.
223 static Node
ensureGroundTermPreprocessed(Valuation
& val
,
225 std::vector
<Node
>& gts
);
226 /** The nodes comprising this trigger. */
227 std::vector
<Node
> d_nodes
;
229 * The preprocessed ground terms in the nodes of the trigger, which as an
230 * optimization omits variables and constant subterms. These terms are
231 * important since we must ensure that the quantifier-free solvers are
232 * aware of these terms. In particular, when adding instantiations for
233 * a trigger P(f(a), x), we first check if f(a) is a term in the master
234 * equality engine. If it is not, then we add the lemma k = f(a) where k
235 * is the purification skolem for f(a). This ensures that f(a) will be
236 * registered as a term in the master equality engine on the next
237 * instantiation round. This is particularly important for cases where
238 * P(f(a), x) is matched with P(f(b), c), where a=b in the current context.
239 * This example would fail to match when f(a) is not registered.
241 std::vector
<Node
> d_groundTerms
;
242 /** The quantifiers engine associated with this trigger. */
243 QuantifiersEngine
* d_quantEngine
;
244 /** Reference to the quantifiers inference manager */
245 quantifiers::QuantifiersInferenceManager
& d_qim
;
246 /** The quantified formula this trigger is for. */
250 * This is the back-end utility that implements the underlying matching
251 * algorithm associated with this trigger.
254 }; /* class Trigger */
256 }/* CVC4::theory::inst namespace */
257 }/* CVC4::theory namespace */
258 }/* CVC4 namespace */
260 #endif /* CVC4__THEORY__QUANTIFIERS__TRIGGER_H */