Towards replacing that option with a logic check throughout.
// not have a model builder
if (d_modelBuilder == nullptr)
{
- d_alocModelBuilder.reset(new TheoryEngineModelBuilder);
+ d_alocModelBuilder.reset(new TheoryEngineModelBuilder(d_env));
d_modelBuilder = d_alocModelBuilder.get();
}
// notice that the equality engine of the model has yet to be assigned.
QuantifiersInferenceManager& qim,
QuantifiersRegistry& qr,
TermRegistry& tr)
- : TheoryEngineModelBuilder(),
+ : TheoryEngineModelBuilder(qs.getEnv()),
d_addedLemmas(0),
d_triedLemmas(0),
d_qstate(qs),
#include "options/quantifiers_options.h"
#include "options/smt_options.h"
#include "options/uf_options.h"
+#include "smt/env.h"
#include "theory/quantifiers/quant_util.h"
#include "theory/rewriter.h"
bool SortInference::isHandledApplyUf(Kind k) const
{
- return k == APPLY_UF && !options::ufHo();
+ return k == APPLY_UF && !d_env.getLogicInfo().isHigherOrder();
}
} // namespace theory
#include "expr/type_node.h"
namespace cvc5 {
+
+class Env;
+
namespace theory {
/** sort inference
};
private:
+ /** Reference to the env */
+ Env& d_env;
/** the id count for all subsorts we have allocated */
int d_sortCount;
UnionFind d_type_union_find;
void reset();
public:
- SortInference() : d_sortCount(1) {}
+ SortInference(Env& env) : d_env(env), d_sortCount(1) {}
~SortInference(){}
/** initialize
if (options::sortInference())
{
- d_sortInfer.reset(new SortInference);
+ d_sortInfer.reset(new SortInference(env));
}
d_true = NodeManager::currentNM()->mkConst<bool>(true);
d_enableFuncModels(enableFuncModels)
{
// must use function models when ufHo is enabled
- Assert(d_enableFuncModels || !options::ufHo());
+ Assert(d_enableFuncModels || !d_env.getLogicInfo().isHigherOrder());
d_true = NodeManager::currentNM()->mkConst( true );
d_false = NodeManager::currentNM()->mkConst( false );
}
Assert(ee != nullptr);
d_equalityEngine = ee;
// The kinds we are treating as function application in congruence
- d_equalityEngine->addFunctionKind(kind::APPLY_UF, false, options::ufHo());
+ d_equalityEngine->addFunctionKind(
+ kind::APPLY_UF, false, d_env.getLogicInfo().isHigherOrder());
d_equalityEngine->addFunctionKind(kind::HO_APPLY);
d_equalityEngine->addFunctionKind(kind::SELECT);
// d_equalityEngine->addFunctionKind(kind::STORE);
// return the representative of the term in the equality engine, if it exists
TypeNode t = ret.getType();
bool eeHasTerm;
- if (!options::ufHo() && (t.isFunction() || t.isPredicate()))
+ if (!d_env.getLogicInfo().isHigherOrder()
+ && (t.isFunction() || t.isPredicate()))
{
// functions are in the equality engine, but *not* as first-class members
// when higher-order is disabled. In this case, we cannot query
Trace("model-builder") << " Assigning function (" << f << ") to (" << f_def << ")" << endl;
Assert(d_uf_models.find(f) == d_uf_models.end());
- if( options::ufHo() ){
+ if (d_env.getLogicInfo().isHigherOrder())
+ {
//we must rewrite the function value since the definition needs to be a constant value
f_def = Rewriter::rewrite( f_def );
Trace("model-builder-debug")
d_uf_models[f] = f_def;
}
- if (options::ufHo() && d_equalityEngine->hasTerm(f))
+ if (d_env.getLogicInfo().isHigherOrder() && d_equalityEngine->hasTerm(f))
{
Trace("model-builder-debug") << " ...function is first-class member of equality engine" << std::endl;
// assign to representative if higher-order
Assert(d_env.getTopLevelSubstitutions().apply(n) == n);
if( !hasAssignedFunctionDefinition( n ) ){
Trace("model-builder-fun-debug") << "Look at function : " << n << std::endl;
- if( options::ufHo() ){
+ if (d_env.getLogicInfo().isHigherOrder())
+ {
// if in higher-order mode, assign function definitions modulo equality
Node r = getRepresentative( n );
std::map< Node, Node >::iterator itf = func_to_rep.find( r );
#include "options/smt_options.h"
#include "options/theory_options.h"
#include "options/uf_options.h"
+#include "smt/env.h"
#include "theory/rewriter.h"
#include "theory/uf/theory_uf_model.h"
namespace cvc5 {
namespace theory {
+TheoryEngineModelBuilder::TheoryEngineModelBuilder(Env& env) : d_env(env) {}
+
void TheoryEngineModelBuilder::Assigner::initialize(
TypeNode tn, TypeEnumeratorProperties* tep, const std::vector<Node>& aes)
{
return n;
}
-TheoryEngineModelBuilder::TheoryEngineModelBuilder() {}
-
Node TheoryEngineModelBuilder::evaluateEqc(TheoryModel* m, TNode r)
{
eq::EqClassIterator eqc_i = eq::EqClassIterator(r, m->d_equalityEngine);
{
// selectors are always assignable (where we guarantee that they are not
// evaluatable here)
- if (!options::ufHo())
+ if (!d_env.getLogicInfo().isHigherOrder())
{
Assert(!n.getType().isFunction());
return true;
else
{
// non-function variables, and fully applied functions
- if (!options::ufHo())
+ if (!d_env.getLogicInfo().isHigherOrder())
{
// no functions exist, all functions are fully applied
Assert(n.getKind() != kind::HO_APPLY);
void TheoryEngineModelBuilder::assignFunction(TheoryModel* m, Node f)
{
- Assert(!options::ufHo());
+ Assert(!d_env.getLogicInfo().isHigherOrder());
uf::UfModelTree ufmt(f);
Node default_v;
for (size_t i = 0; i < m->d_uf_terms[f].size(); i++)
void TheoryEngineModelBuilder::assignHoFunction(TheoryModel* m, Node f)
{
- Assert(options::ufHo());
+ Assert(d_env.getLogicInfo().isHigherOrder());
TypeNode type = f.getType();
std::vector<TypeNode> argTypes = type.getArgTypes();
std::vector<Node> args;
Trace("model-builder") << "Assigning function values..." << std::endl;
std::vector<Node> funcs_to_assign = m->getFunctionsToAssign();
- if (options::ufHo())
+ if (d_env.getLogicInfo().isHigherOrder())
{
// sort based on type size if higher-order
Trace("model-builder") << "Sort functions by type..." << std::endl;
Trace("model-builder") << " Function #" << k << " is " << f << std::endl;
// std::map< Node, std::vector< Node > >::iterator itht =
// m->d_ho_uf_terms.find( f );
- if (!options::ufHo())
+ if (!d_env.getLogicInfo().isHigherOrder())
{
Trace("model-builder") << " Assign function value for " << f
<< " based on APPLY_UF" << std::endl;
namespace cvc5 {
-class TheoryEngine;
+class Env;
namespace theory {
typedef std::unordered_set<Node> NodeSet;
public:
- TheoryEngineModelBuilder();
+ TheoryEngineModelBuilder(Env& env);
virtual ~TheoryEngineModelBuilder() {}
/**
* Should be called only on models m after they have been prepared
* Assign all unassigned functions in the model m (those returned by
* TheoryModel::getFunctionsToAssign),
* using the two functions above. Currently:
- * If ufHo is disabled, we call assignFunction for all functions.
- * If ufHo is enabled, we call assignHoFunction.
+ * If HO logic is disabled, we call assignFunction for all functions.
+ * If HO logic is enabled, we call assignHoFunction.
*/
void assignFunctions(TheoryModel* m);
Node v,
std::map<Node, bool>& visited);
//---------------------------------end for debugging finite model finding
+ /** Reference to the env */
+ Env& d_env;
}; /* class TheoryEngineModelBuilder */
for (std::set<Node>::iterator it = termSet.begin(); it != termSet.end(); ++it)
{
Node n = *it;
- // For model-building with ufHo, we require that APPLY_UF is always
+ // For model-building with higher-order, we require that APPLY_UF is always
// expanded to HO_APPLY. That is, we always expand to a fully applicative
// encoding during model construction.
if (!collectModelInfoHoTerm(n, m))
d_ho(nullptr),
d_functionsTerms(getSatContext()),
d_symb(getUserContext(), instanceName),
+ d_rewriter(env.getLogicInfo().isHigherOrder()),
d_state(env, valuation),
d_im(*this, d_state, d_pnm, "theory::uf::" + instanceName, false),
d_notify(d_im, *this)
d_thss.reset(new CardinalityExtension(d_state, d_im, this));
}
// The kinds we are treating as function application in congruence
- d_equalityEngine->addFunctionKind(kind::APPLY_UF, false, options::ufHo());
- if (options::ufHo())
+ d_equalityEngine->addFunctionKind(
+ kind::APPLY_UF, false, getLogicInfo().isHigherOrder());
+ if (getLogicInfo().isHigherOrder())
{
d_equalityEngine->addFunctionKind(kind::HO_APPLY);
d_ho.reset(new HoExtension(d_state, d_im));
// check with the higher-order extension at full effort
if (!d_state.isInConflict() && fullEffort(level))
{
- if (options::ufHo())
+ if (getLogicInfo().isHigherOrder())
{
d_ho->check();
}
{
case kind::EQUAL:
{
- if (options::ufHo() && options::ufHoExt())
+ if (getLogicInfo().isHigherOrder() && options::ufHoExt())
{
if (!pol && !d_state.isInConflict() && atom[0].getType().isFunction())
{
Kind k = node.getKind();
if (k == kind::HO_APPLY)
{
- if( !options::ufHo() ){
+ if (!getLogicInfo().isHigherOrder())
+ {
std::stringstream ss;
ss << "Partial function applications are only supported with "
"higher-order logic. Try adding the logic prefix HO_.";
{
// check for higher-order
// logic exception if higher-order is not enabled
- if (isHigherOrderType(node.getOperator().getType()) && !options::ufHo())
+ if (isHigherOrderType(node.getOperator().getType())
+ && !getLogicInfo().isHigherOrder())
{
std::stringstream ss;
ss << "UF received an application whose operator has higher-order type "
}
// we always use APPLY_UF if not higher-order, HO_APPLY if higher-order
- //Assert( node.getKind()!=kind::APPLY_UF || !options::ufHo() );
- Assert(node.getKind() != kind::HO_APPLY || options::ufHo());
+ Assert(node.getKind() != kind::HO_APPLY
+ || getLogicInfo().isHigherOrder());
Kind k = node.getKind();
switch (k)
bool TheoryUF::collectModelValues(TheoryModel* m, const std::set<Node>& termSet)
{
- if( options::ufHo() ){
+ if (getLogicInfo().isHigherOrder())
+ {
// must add extensionality disequalities for all pairs of (non-disequal)
// function equivalence classes.
if (!d_ho->collectModelInfoHo(m, termSet))
#include "theory/uf/theory_uf_rewriter.h"
#include "expr/node_algorithm.h"
-#include "options/uf_options.h"
#include "theory/rewriter.h"
#include "theory/substitutions.h"
namespace theory {
namespace uf {
+TheoryUfRewriter::TheoryUfRewriter(bool isHigherOrder)
+ : d_isHigherOrder(isHigherOrder)
+{
+}
+
RewriteResponse TheoryUfRewriter::postRewrite(TNode node)
{
if (node.getKind() == kind::EQUAL)
Node ret;
// build capture-avoiding substitution since in HOL shadowing may have
// been introduced
- if (options::ufHo())
+ if (d_isHigherOrder)
{
std::vector<Node> vars;
std::vector<Node> subs;
// build capture-avoiding substitution since in HOL shadowing may have
// been introduced
- if (options::ufHo())
+ if (d_isHigherOrder)
{
Node arg = Rewriter::rewrite(node[1]);
Node var = node[0][0][0];
class TheoryUfRewriter : public TheoryRewriter
{
public:
+ TheoryUfRewriter(bool isHigherOrder = false);
RewriteResponse postRewrite(TNode node) override;
RewriteResponse preRewrite(TNode node) override;
* Then, f and g can be used as APPLY_UF operators, but (ite C f g), (lambda x1. (f x1)) as well as the variable x above are not.
*/
static bool canUseAsApplyUfOperator(TNode n);
+ /** Is the logic higher-order? */
+ bool d_isHigherOrder;
}; /* class TheoryUfRewriter */
} // namespace uf