예제 #1
0
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] );
  }
}
예제 #2
0
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 );
}
예제 #3
0
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 );
}
예제 #4
0
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];
}
예제 #5
0
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;
  }
}
예제 #6
0
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;
}
예제 #7
0
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;
}
예제 #8
0
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;
      }
    }