#include "options/smt_options.h"
#include "options/uf_options.h"
+#include "options/quantifiers_options.h"
#include "smt/smt_engine.h"
#include "theory/quantifiers_engine.h"
#include "theory/theory_engine.h"
return false;
}
+bool TheoryEngineModelBuilder::involvesUSort( TypeNode tn ) {
+ if( tn.isSort() ){
+ return true;
+ }else if( tn.isArray() ){
+ return involvesUSort( tn.getArrayIndexType() ) || involvesUSort( tn.getArrayConstituentType() );
+ }else if( tn.isSet() ){
+ return involvesUSort( tn.getSetElementType() );
+ }else if( tn.isDatatype() ){
+ const Datatype& dt = ((DatatypeType)(tn).toType()).getDatatype();
+ return dt.involvesUninterpretedType();
+ }else{
+ return false;
+ }
+}
+
+bool TheoryEngineModelBuilder::isExcludedUSortValue( std::map< TypeNode, unsigned >& eqc_usort_count, Node v, std::map< Node, bool >& visited ) {
+ Assert( v.isConst() );
+ if( visited.find( v )==visited.end() ){
+ visited[v] = true;
+ TypeNode tn = v.getType();
+ if( tn.isSort() ){
+ Trace("exc-value-debug") << "Is excluded usort value : " << v << " " << tn << std::endl;
+ unsigned card = eqc_usort_count[tn];
+ Trace("exc-value-debug") << " Cardinality is " << card << std::endl;
+ unsigned index = v.getConst<UninterpretedConstant>().getIndex().toUnsignedInt();
+ Trace("exc-value-debug") << " Index is " << index << std::endl;
+ return index>0 && index>=card;
+ }
+ for( unsigned i=0; i<v.getNumChildren(); i++ ){
+ if( isExcludedUSortValue( eqc_usort_count, v[i], visited ) ){
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
void TheoryEngineModelBuilder::buildModel(Model* m, bool fullModel)
{
Trace("model-builder") << "TheoryEngineModelBuilder: buildModel, fullModel = " << fullModel << std::endl;
d_te->collectModelInfo(tm, fullModel);
// Loop through all terms and make sure that assignable sub-terms are in the equality engine
+ // Also, record #eqc per type (for finite model finding)
+ std::map< TypeNode, unsigned > eqc_usort_count;
eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( tm->d_equalityEngine );
{
NodeSet cache;
for ( ; !eqc_i.isFinished(); ++eqc_i) {
checkTerms(*eqc_i, tm, cache);
}
+ TypeNode tn = (*eqcs_i).getType();
+ if( tn.isSort() ){
+ if( eqc_usort_count.find( tn )==eqc_usort_count.end() ){
+ eqc_usort_count[tn] = 1;
+ }else{
+ eqc_usort_count[tn]++;
+ }
+ }
}
}
if(t.isTuple() || t.isRecord()) {
t = NodeManager::currentNM()->getDatatypeForTupleRecord(t);
}
+ //get properties of this type
bool isCorecursive = false;
+ bool isUSortFiniteRestricted = false;
if( t.isDatatype() ){
const Datatype& dt = ((DatatypeType)(t).toType()).getDatatype();
isCorecursive = dt.isCodatatype() && ( !dt.isFinite() || dt.isRecursiveSingleton() );
}
+ if( options::finiteModelFind() ){
+ isUSortFiniteRestricted = !t.isSort() && involvesUSort( t );
+ }
set<Node>* repSet = typeRepSet.getSet(t);
TypeNode tb = t.getBaseType();
if (!assignOne) {
bool success;
do{
n = typeConstSet.nextTypeEnum(t, true);
+ //--- AJR: this code checks whether n is a legal value
success = true;
- if( isCorecursive ){
+ if( isUSortFiniteRestricted ){
+ //must not involve uninterpreted constants beyond cardinality bound (which assumed to coincide with #eqc)
+ std::map< Node, bool > visited;
+ success = !isExcludedUSortValue( eqc_usort_count, n, visited );
+ if( !success ){
+ Trace("exc-value") << "Excluded value for " << t << " : " << n << " due to out of range uninterpreted constant." << std::endl;
+ }
+ }
+ if( success && isCorecursive ){
if (repSet != NULL && !repSet->empty()) {
// in the case of codatatypes, check if it is in the set of values that we cannot assign
// this will check whether n \not\in V^x_I from page 9 of Reynolds/Blanchette CADE 2015
success = !isExcludedCdtValue( n, repSet, assertedReps, *i2 );
+ if( !success ){
+ Trace("exc-value") << "Excluded value : " << n << " due to alpha-equivalent codatatype expression." << std::endl;
+ }
}
}
+ //---
}while( !success );
}
else {