void FirstOrderModel::initializeModelForTerm( Node n ){ if( n.getKind()==APPLY_UF ){ Node op = n.getOperator(); if( d_uf_model_tree.find( op )==d_uf_model_tree.end() ){ TypeNode tn = op.getType(); tn = tn[ (int)tn.getNumChildren()-1 ]; //only generate models for predicates and functions with uninterpreted range types if( tn==NodeManager::currentNM()->booleanType() || tn.isSort() ){ d_uf_model_tree[ op ] = uf::UfModelTree( op ); d_uf_model_gen[ op ].clear(); } } } /* if( n.getType().isArray() ){ while( n.getKind()==STORE ){ n = n[0]; } Node nn = getRepresentative( n ); if( d_array_model.find( nn )==d_array_model.end() ){ d_array_model[nn] = arrays::ArrayModel( nn, this ); } } */ for( int i=0; i<(int)n.getNumChildren(); i++ ){ initializeModelForTerm( n[i] ); } }
Node UfModelTree::getFunctionValue( const char* argPrefix, bool simplify ){ TypeNode type = d_op.getType(); std::vector< Node > vars; for( size_t i=0; i<type.getNumChildren()-1; i++ ){ std::stringstream ss; ss << argPrefix << (i+1); vars.push_back( NodeManager::currentNM()->mkBoundVar( ss.str(), type[i] ) ); } return getFunctionValue( vars, simplify ); }
bool RepSetIterator::setFunctionDomain( Node op, RepBoundExt* rext ){ Trace("rsi") << "Make rsi for " << op << std::endl; Assert( d_types.empty() ); TypeNode tn = op.getType(); for( size_t i=0; i<tn.getNumChildren()-1; i++ ){ d_types.push_back( tn[i] ); } d_owner = op; return initialize( rext ); }
Node TermDb::getModelBasisOpTerm( Node op ){ if( d_model_basis_op_term.find( op )==d_model_basis_op_term.end() ){ TypeNode t = op.getType(); std::vector< Node > children; children.push_back( op ); for( size_t i=0; i<t.getNumChildren()-1; i++ ){ children.push_back( getModelBasisTerm( t[i] ) ); } d_model_basis_op_term[op] = NodeManager::currentNM()->mkNode( APPLY_UF, children ); } return d_model_basis_op_term[op]; }
Node AbsDef::getFunctionValue( FirstOrderModelAbs * m, TNode op, std::vector< Node >& vars, unsigned depth ) { if( depth==vars.size() ){ TypeNode tn = op.getType(); if( tn.getNumChildren()>0 ){ tn = tn[tn.getNumChildren() - 1]; } if( d_value>=0 ){ Assert( d_value<(int)m->d_rep_set.d_type_reps[tn].size() ); if( tn.isBoolean() ){ return NodeManager::currentNM()->mkConst( d_value==1 ); }else{ return m->d_rep_set.d_type_reps[tn][d_value]; } }else{ return Node::null(); } }else{ TypeNode tn = vars[depth].getType(); Node curr; curr = d_def[d_default].getFunctionValue( m, op, vars, depth+1 ); for( std::map< unsigned, AbsDef >::iterator it = d_def.begin(); it != d_def.end(); ++it ){ if( it->first!=d_default ){ unsigned id = getId( it->first ); Assert( id<m->d_rep_set.d_type_reps[tn].size() ); TNode n = m->d_rep_set.d_type_reps[tn][id]; Node fv = it->second.getFunctionValue( m, op, vars, depth+1 ); if( !curr.isNull() && !fv.isNull() ){ curr = NodeManager::currentNM()->mkNode( ITE, vars[depth].eqNode( n ), fv, curr ); }else{ curr = Node::null(); } } } return curr; } }
TypeNode NodeManager::mkSort(TypeNode constructor, const std::vector<TypeNode>& children, uint32_t flags) { Assert(constructor.getKind() == kind::SORT_TYPE && constructor.getNumChildren() == 0, "expected a sort constructor"); Assert(children.size() > 0, "expected non-zero # of children"); Assert( hasAttribute(constructor.d_nv, expr::SortArityAttr()) && hasAttribute(constructor.d_nv, expr::VarNameAttr()), "expected a sort constructor" ); std::string name = getAttribute(constructor.d_nv, expr::VarNameAttr()); Assert(getAttribute(constructor.d_nv, expr::SortArityAttr()) == children.size(), "arity mismatch in application of sort constructor"); NodeBuilder<> nb(this, kind::SORT_TYPE); Node sortTag = Node(constructor.d_nv->d_children[0]); nb << sortTag; nb.append(children); TypeNode type = nb.constructTypeNode(); setAttribute(type, expr::VarNameAttr(), name); for(std::vector<NodeManagerListener*>::iterator i = d_listeners.begin(); i != d_listeners.end(); ++i) { (*i)->nmNotifyInstantiateSortConstructor(constructor, type, flags); } return type; }
TypeNode NodeManager::getDatatypeForTupleRecord(TypeNode t) { Assert(t.isTuple() || t.isRecord()); //AJR: not sure why .getBaseType() was used in two cases below, // disabling this, which is necessary to fix bug 605/667, // which involves records of INT which were mapped to records of REAL below. TypeNode tOrig = t; if(t.isTuple()) { vector<TypeNode> v; bool changed = false; for(size_t i = 0; i < t.getNumChildren(); ++i) { TypeNode tn = t[i]; TypeNode base; if(tn.isTuple() || tn.isRecord()) { base = getDatatypeForTupleRecord(tn); } else { base = tn;//.getBaseType(); } changed = changed || (tn != base); v.push_back(base); } if(changed) { t = mkTupleType(v); } } else { const Record& r = t.getRecord(); std::vector< std::pair<std::string, Type> > v; bool changed = false; const Record::FieldVector& fields = r.getFields(); for(Record::FieldVector::const_iterator i = fields.begin(); i != fields.end(); ++i) { Type tn = (*i).second; Type base; if(tn.isTuple() || tn.isRecord()) { base = getDatatypeForTupleRecord(TypeNode::fromType(tn)).toType(); } else { base = tn;//.getBaseType(); } changed = changed || (tn != base); v.push_back(std::make_pair((*i).first, base)); } if(changed) { t = mkRecordType(Record(v)); } } // if the type doesn't have an associated datatype, then make one for it TypeNode& dtt = d_tupleAndRecordTypes[t]; if(dtt.isNull()) { if(t.isTuple()) { Datatype dt("__cvc4_tuple"); DatatypeConstructor c("__cvc4_tuple_ctor"); for(TypeNode::const_iterator i = t.begin(); i != t.end(); ++i) { c.addArg("__cvc4_tuple_stor", (*i).toType()); } dt.addConstructor(c); dtt = TypeNode::fromType(toExprManager()->mkDatatypeType(dt)); Debug("tuprec") << "REWROTE " << t << " to " << dtt << std::endl; dtt.setAttribute(DatatypeTupleAttr(), tOrig); } else { const Record& rec = t.getRecord(); const Record::FieldVector& fields = rec.getFields(); Datatype dt("__cvc4_record"); DatatypeConstructor c("__cvc4_record_ctor"); for(Record::FieldVector::const_iterator i = fields.begin(); i != fields.end(); ++i) { c.addArg((*i).first, (*i).second); } dt.addConstructor(c); dtt = TypeNode::fromType(toExprManager()->mkDatatypeType(dt)); Debug("tuprec") << "REWROTE " << t << " to " << dtt << std::endl; dtt.setAttribute(DatatypeRecordAttr(), tOrig); } } else { Debug("tuprec") << "REUSING cached " << t << ": " << dtt << std::endl; } Assert(!dtt.isNull()); return dtt; }
void SortInference::simplify( std::vector< Node >& assertions, bool doSortInference, bool doMonotonicyInference ){ if( doSortInference ){ Trace("sort-inference-proc") << "Calculating sort inference..." << std::endl; NodeManager* nm = NodeManager::currentNM(); //process all assertions std::map< Node, int > visited; for( unsigned i=0; i<assertions.size(); i++ ){ Trace("sort-inference-debug") << "Process " << assertions[i] << std::endl; std::map< Node, Node > var_bound; process( assertions[i], var_bound, visited ); } Trace("sort-inference-proc") << "...done" << std::endl; for( std::map< Node, int >::iterator it = d_op_return_types.begin(); it != d_op_return_types.end(); ++it ){ Trace("sort-inference") << it->first << " : "; TypeNode retTn = it->first.getType(); if( !d_op_arg_types[ it->first ].empty() ){ Trace("sort-inference") << "( "; for( size_t i=0; i<d_op_arg_types[ it->first ].size(); i++ ){ recordSubsort( retTn[i], d_op_arg_types[ it->first ][i] ); printSort( "sort-inference", d_op_arg_types[ it->first ][i] ); Trace("sort-inference") << " "; } Trace("sort-inference") << ") -> "; retTn = retTn[(int)retTn.getNumChildren()-1]; } recordSubsort( retTn, it->second ); printSort( "sort-inference", it->second ); Trace("sort-inference") << std::endl; } for( std::map< Node, std::map< Node, int > >::iterator it = d_var_types.begin(); it != d_var_types.end(); ++it ){ Trace("sort-inference") << "Quantified formula : " << it->first << " : " << std::endl; for( unsigned i=0; i<it->first[0].getNumChildren(); i++ ){ recordSubsort( it->first[0][i].getType(), it->second[it->first[0][i]] ); printSort( "sort-inference", it->second[it->first[0][i]] ); Trace("sort-inference") << std::endl; } Trace("sort-inference") << std::endl; } bool rewritten = false; // determine monotonicity of sorts Trace("sort-inference-proc") << "Calculating monotonicty for subsorts..." << std::endl; std::map<Node, std::map<int, bool> > visitedm; for (const Node& a : assertions) { Trace("sort-inference-debug") << "Process monotonicity for " << a << std::endl; std::map<Node, Node> var_bound; processMonotonic(a, true, true, var_bound, visitedm); } Trace("sort-inference-proc") << "...done" << std::endl; Trace("sort-inference") << "We have " << d_sub_sorts.size() << " sub-sorts : " << std::endl; for (unsigned i = 0, size = d_sub_sorts.size(); i < size; i++) { printSort("sort-inference", d_sub_sorts[i]); if (d_type_types.find(d_sub_sorts[i]) != d_type_types.end()) { Trace("sort-inference") << " is interpreted." << std::endl; } else if (d_non_monotonic_sorts.find(d_sub_sorts[i]) == d_non_monotonic_sorts.end()) { Trace("sort-inference") << " is monotonic." << std::endl; } else { Trace("sort-inference") << " is not monotonic." << std::endl; } } // simplify all assertions by introducing new symbols wherever necessary Trace("sort-inference-proc") << "Perform simplification..." << std::endl; std::map<Node, std::map<TypeNode, Node> > visited2; for (unsigned i = 0, size = assertions.size(); i < size; i++) { Node prev = assertions[i]; std::map<Node, Node> var_bound; Trace("sort-inference-debug") << "Simplify " << prev << std::endl; TypeNode tnn; Node curr = simplifyNode(assertions[i], var_bound, tnn, visited2); Trace("sort-inference-debug") << "Done." << std::endl; if (curr != assertions[i]) { Trace("sort-inference-debug") << "Rewrite " << curr << std::endl; curr = theory::Rewriter::rewrite(curr); rewritten = true; Trace("sort-inference-rewrite") << assertions << std::endl; Trace("sort-inference-rewrite") << " --> " << curr << std::endl; PROOF(ProofManager::currentPM()->addDependence(curr, assertions[i]);); assertions[i] = curr; } }