Example #1
0
bool TheoryUFTim::equiv(TNode x, TNode y) {
  Assert(x.getKind() == kind::APPLY_UF);
  Assert(y.getKind() == kind::APPLY_UF);

  if(x.getNumChildren() != y.getNumChildren()) {
    return false;
  }

  if(x.getOperator() != y.getOperator()) {
    return false;
  }

  // intentionally don't look at operator

  TNode::iterator xIter = x.begin();
  TNode::iterator yIter = y.begin();

  while(xIter != x.end()) {

    if(!sameCongruenceClass(*xIter, *yIter)) {
      return false;
    }

    ++xIter;
    ++yIter;
  }
  return true;
}
Example #2
0
Node AbstractionModule::substituteArguments(TNode signature, TNode apply, unsigned& index, TNodeTNodeMap& seen) {
  if (seen.find(signature) != seen.end()) {
    return seen[signature]; 
  }
  
  if (signature.getKind() == kind::SKOLEM) {
    // return corresponding argument and increment counter
    seen[signature] = apply[index];
    return apply[index++]; 
  }

  if (signature.getNumChildren() == 0) {
    Assert (signature.getKind() != kind::VARIABLE &&
            signature.getKind() != kind::SKOLEM); 
    seen[signature] = signature;
    return signature; 
  }
  
  NodeBuilder<> builder(signature.getKind());
  if (signature.getMetaKind() == kind::metakind::PARAMETERIZED) {
    builder << signature.getOperator();
  }
  
  for (unsigned i = 0; i < signature.getNumChildren(); ++i) {
    Node child = substituteArguments(signature[i], apply, index, seen);
    builder << child; 
  }

  Node result = builder; 
  seen[signature]= result;

  return result;
}
Example #3
0
Node BvToBoolPreprocessor::liftNode(TNode current) {
  Node result;
  
  if (hasLiftCache(current)) {
    result = getLiftCache(current); 
  }else if (isConvertibleBvAtom(current)) {
    result = convertBvAtom(current);
    addToLiftCache(current, result);
  } else {
    if (current.getNumChildren() == 0) {
      result = current;
    } else {
      NodeBuilder<> builder(current.getKind());
      if (current.getMetaKind() == kind::metakind::PARAMETERIZED) {
        builder << current.getOperator();
      }
      for (unsigned i = 0; i < current.getNumChildren(); ++i) {
        Node converted = liftNode(current[i]);
        Assert (converted.getType() == current[i].getType()); 
        builder << converted; 
      }
      result = builder;
      addToLiftCache(current, result);
    }
  }
  Assert (result != Node());
  Assert(result.getType() == current.getType());
  Debug("bv-to-bool") << "BvToBoolPreprocessor::liftNode " << current << " => \n" << result << "\n"; 
  return result; 
}
Example #4
0
Node AbstractionModule::computeSignatureRec(TNode node, NodeNodeMap& cache) {
  if (cache.find(node) != cache.end()) {
    return cache.find(node)->second; 
  }
  
  if (node.getNumChildren() == 0) {
    if (node.getKind() == kind::CONST_BITVECTOR)
      return node;

    Node sig = getSignatureSkolem(node);
    cache[node] = sig; 
    return sig; 
  }

  NodeBuilder<> builder(node.getKind());
  if (node.getMetaKind() == kind::metakind::PARAMETERIZED) {
    builder << node.getOperator();
  }
  for (unsigned i = 0; i < node.getNumChildren(); ++i) {
    Node converted = computeSignatureRec(node[i], cache);
    builder << converted; 
  }
  Node result = builder;
  cache[node] = result;
  return result; 
}
Example #5
0
/** add term */
void TheoryModel::addTerm(TNode n ){
  Assert(d_equalityEngine.hasTerm(n));
  //must collect UF terms
  if (n.getKind()==APPLY_UF) {
    Node op = n.getOperator();
    if( std::find( d_uf_terms[ op ].begin(), d_uf_terms[ op ].end(), n )==d_uf_terms[ op ].end() ){
      d_uf_terms[ op ].push_back( n );
      Trace("model-add-term-uf") << "Add term " << n << std::endl;
    }
  }
}
Example #6
0
Node ModelPostprocessor::rewriteAs(TNode n, TypeNode asType) {
  if(n.getType().isSubtypeOf(asType)) {
    // good to go, we have the right type
    return n;
  }
  if(!n.isConst()) {
    // we don't handle non-const right now
    return n;
  }
  if(asType.isBoolean()) {
    if(n.getType().isBitVector(1u)) {
      // type mismatch: should only happen for Boolean-term conversion under
      // datatype constructor applications; rewrite from BV(1) back to Boolean
      bool tf = (n.getConst<BitVector>().getValue() == 1);
      return NodeManager::currentNM()->mkConst(tf);
    }
    if(n.getType().isDatatype() && n.getType().hasAttribute(BooleanTermAttr())) {
      // type mismatch: should only happen for Boolean-term conversion under
      // datatype constructor applications; rewrite from datatype back to Boolean
      Assert(n.getKind() == kind::APPLY_CONSTRUCTOR);
      Assert(n.getNumChildren() == 0);
      // we assume (by construction) false is first; see boolean_terms.cpp
      bool tf = (Datatype::indexOf(n.getOperator().toExpr()) == 1);
      Debug("boolean-terms") << "+++ rewriteAs " << n << " : " << asType << " ==> " << tf << endl;
      return NodeManager::currentNM()->mkConst(tf);
    }
  }
  if(n.getType().isBoolean()) {
    bool tf = n.getConst<bool>();
    if(asType.isBitVector(1u)) {
      return NodeManager::currentNM()->mkConst(BitVector(1u, tf ? 1u : 0u));
    }
    if(asType.isDatatype() && asType.hasAttribute(BooleanTermAttr())) {
      const Datatype& asDatatype = asType.getConst<Datatype>();
      return NodeManager::currentNM()->mkNode(kind::APPLY_CONSTRUCTOR, (tf ? asDatatype[0] : asDatatype[1]).getConstructor());
    }
  }
  if(n.getType().isRecord() && asType.isRecord()) {
    Debug("boolean-terms") << "+++ got a record - rewriteAs " << n << " : " << asType << endl;
    const Record& rec CVC4_UNUSED = n.getType().getConst<Record>();
    const Record& asRec = asType.getConst<Record>();
    Assert(rec.getNumFields() == asRec.getNumFields());
    Assert(n.getNumChildren() == asRec.getNumFields());
    NodeBuilder<> b(n.getKind());
    b << asType;
    for(size_t i = 0; i < n.getNumChildren(); ++i) {
      b << rewriteAs(n[i], TypeNode::fromType(asRec[i].second));
    }
    Node out = b;
    Debug("boolean-terms") << "+++ returning record " << out << endl;
    return out;
  }
Example #7
0
void PicklerPrivate::toCaseOperator(TNode n)
{
  Kind k = n.getKind();
  kind::MetaKind m = metaKindOf(k);
  Assert(m == kind::metakind::PARAMETERIZED || m == kind::metakind::OPERATOR);
  if(m == kind::metakind::PARAMETERIZED) {
    toCaseNode(n.getOperator());
  }
  for(TNode::iterator i = n.begin(), i_end = n.end(); i != i_end; ++i) {
    toCaseNode(*i);
  }
  d_current << mkOperatorHeader(k, n.getNumChildren());
}
Example #8
0
/** 
 * Assumes the stack without top is consistent, and checks that the
 * full stack is consistent
 * 
 * @param stack 
 * 
 * @return 
 */
bool AbstractionModule::LemmaInstantiatior::isConsistent(const vector<int>& stack) {
  if (stack.empty())
    return true;
  
  unsigned current = stack.size() - 1;
  TNode func = d_functions[current];
  ArgsTableEntry& matches = d_argsTable.getEntry(func.getOperator());
  ArgsVec& args = matches.getEntry(stack[current]);
  Assert (args.size() == func.getNumChildren());
  for (unsigned k = 0; k < args.size(); ++k) {
    TNode s = func[k];
    TNode t = args[k];
      
    TNode s0 = s;
    while (d_subst.hasSubstitution(s0)) {
      s0 = d_subst.getSubstitution(s0);
    }
    
    TNode t0 = t;
    while (d_subst.hasSubstitution(t0)) {
      t0 = d_subst.getSubstitution(t0);
    }

    if (s0.isConst() && t0.isConst()) {
      if (s0 != t0)
        return false; // fail
      else
        continue;
    }
      
    if(s0.getMetaKind() == kind::metakind::VARIABLE &&
       t0.isConst()) {
      d_subst.addSubstitution(s0, t0);
      continue;
    }

    if (s0.isConst() &&
        t0.getMetaKind() == kind::metakind::VARIABLE) {
      d_subst.addSubstitution(t0, s0);
      continue;
    }

    Assert (s0.getMetaKind() == kind::metakind::VARIABLE &&
            t0.getMetaKind() == kind::metakind::VARIABLE);
      
    if (s0 != t0) {
      d_subst.addSubstitution(s0, t0);
    }
  }
  return true; 
}
Example #9
0
Node TheoryEngineModelBuilder::normalize(TheoryModel* m, TNode r, std::map< Node, Node >& constantReps, bool evalOnly)
{
  std::map<Node, Node>::iterator itMap = constantReps.find(r);
  if (itMap != constantReps.end()) {
    return (*itMap).second;
  }
  NodeMap::iterator it = d_normalizedCache.find(r);
  if (it != d_normalizedCache.end()) {
    return (*it).second;
  }
  Node retNode = r;
  if (r.getNumChildren() > 0) {
    std::vector<Node> children;
    if (r.getMetaKind() == kind::metakind::PARAMETERIZED) {
      children.push_back(r.getOperator());
    }
    bool childrenConst = true;
    for (size_t i=0; i < r.getNumChildren(); ++i) {
      Node ri = r[i];
      if (!ri.isConst()) {
        if (m->d_equalityEngine.hasTerm(ri)) {
          ri = m->d_equalityEngine.getRepresentative(ri);
          itMap = constantReps.find(ri);
          if (itMap != constantReps.end()) {
            ri = (*itMap).second;
          }
          else if (evalOnly) {
            ri = normalize(m, r[i], constantReps, evalOnly);
          }
        }
        else {
          ri = normalize(m, ri, constantReps, evalOnly);
        }
        if (!ri.isConst()) {
          childrenConst = false;
        }
      }
      children.push_back(ri);
    }
    retNode = NodeManager::currentNM()->mkNode( r.getKind(), children );
    if (childrenConst) {
      retNode = Rewriter::rewrite(retNode);
      Assert(retNode.getKind() == kind::APPLY_UF || retNode.isConst());
    }
  }
  d_normalizedCache[r] = retNode;
  return retNode;
}
Example #10
0
Node ITESimplifier::createSimpContext(TNode c, Node& iteNode, Node& simpVar)
{
  NodeMap::iterator it;
  it = d_simpContextCache.find(c);
  if (it != d_simpContextCache.end()) {
    return (*it).second;
  }

  if (!containsTermITE(c)) {
    d_simpContextCache[c] = c;
    return c;
  }

  if (c.getKind() == kind::ITE && !c.getType().isBoolean()) {
    // Currently only support one ite node in a simp context
    // Return Null if more than one is found
    if (!iteNode.isNull()) {
      return Node();
    }
    simpVar = getSimpVar(c.getType());
    if (simpVar.isNull()) {
      return Node();
    }
    d_simpContextCache[c] = simpVar;
    iteNode = c;
    return simpVar;
  }

  NodeBuilder<> builder(c.getKind());
  if (c.getMetaKind() == kind::metakind::PARAMETERIZED) {
    builder << c.getOperator();
  }
  unsigned i = 0;
  for (; i < c.getNumChildren(); ++ i) {
    Node newChild = createSimpContext(c[i], iteNode, simpVar);
    if (newChild.isNull()) {
      return newChild;
    }
    builder << newChild;
  }
  // Mark the substitution and continue
  Node result = builder;
  d_simpContextCache[c] = result;
  return result;
}
Node TheoryBuiltinRewriter::blastChain(TNode in) {

  Assert(in.getKind() == kind::CHAIN);

  Kind chainedOp = in.getOperator().getConst<Chain>().getOperator();

  if(in.getNumChildren() == 2) {
    // if this is the case exactly 1 pair will be generated so the
    // AND is not required
    return NodeManager::currentNM()->mkNode(chainedOp, in[0], in[1]);
  } else {
    NodeBuilder<> conj(kind::AND);
    for(TNode::iterator i = in.begin(), j = i + 1; j != in.end(); ++i, ++j) {
      conj << NodeManager::currentNM()->mkNode(chainedOp, *i, *j);
    }
    return conj;
  }
}
Example #12
0
Node TheoryUF::ppRewrite(TNode node) {

  if (node.getKind() != kind::APPLY_UF) {
    return node;
  }

  // perform the callbacks requested by TheoryUF::registerPpRewrite()
  RegisterPpRewrites::iterator c = d_registeredPpRewrites.find(node.getOperator());
  if (c == d_registeredPpRewrites.end()) {
    return node;
  } else {
    Node res = c->second->ppRewrite(node);
    if (res != node) {
      return ppRewrite(res);
    } else {
      return res;
    }
  }
}
Example #13
0
Node RePairAssocCommutativeOperators::case_other(TNode n){
  if(n.isConst() || n.isVar()){
    return n;
  }

  NodeBuilder<> nb(n.getKind());

  if(n.getMetaKind() == kind::metakind::PARAMETERIZED) {
    nb << n.getOperator();
  }

  // Remove the ITEs from the children
  for(TNode::const_iterator i = n.begin(), end = n.end(); i != end; ++i) {
    Node newChild = rePairAssocCommutativeOperators(*i);
    nb << newChild;
  }

  Node result = (Node)nb;
  return result;
}
Example #14
0
Node AbstractionModule::getInterpretation(TNode node) {
  Assert (isAbstraction(node));
  TNode constant = node[0].getKind() == kind::CONST_BITVECTOR ? node[0] : node[1];
  TNode apply = node[0].getKind() == kind::APPLY_UF ? node[0] : node[1];
  Assert (constant.getKind() == kind::CONST_BITVECTOR &&
          apply.getKind() == kind::APPLY_UF);

  Node func = apply.getOperator(); 
  Assert (d_funcToSignature.find(func) != d_funcToSignature.end());
  
  Node sig = d_funcToSignature[func];
  
  // substitute arguments in signature
  TNodeTNodeMap seen;
  unsigned index = 0;
  Node result = substituteArguments(sig, apply, index, seen);
  Assert (result.getType().isBoolean()); 
  Assert (index == apply.getNumChildren());
  // Debug("bv-abstraction") << "AbstractionModule::getInterpretation " << node << "\n";
  // Debug("bv-abstraction") << "    => " << result << "\n";
  return result; 
}
Example #15
0
  Node removeToFPGeneric (TNode node) {
    Assert(node.getKind() == kind::FLOATINGPOINT_TO_FP_GENERIC);
    
    FloatingPointToFPGeneric info = node.getOperator().getConst<FloatingPointToFPGeneric>();
    
    size_t children = node.getNumChildren();
    
    Node op;
    
    if (children == 1) {
      op = NodeManager::currentNM()->mkConst(FloatingPointToFPIEEEBitVector(info.t.exponent(),
									    info.t.significand()));
      return NodeManager::currentNM()->mkNode(op, node[0]);
      
    } else {
      Assert(children == 2);
      Assert(node[0].getType().isRoundingMode());
      
      TypeNode t = node[1].getType();
      
      if (t.isFloatingPoint()) {
	op = NodeManager::currentNM()->mkConst(FloatingPointToFPFloatingPoint(info.t.exponent(),
									      info.t.significand()));
      } else if (t.isReal()) {
	op = NodeManager::currentNM()->mkConst(FloatingPointToFPReal(info.t.exponent(),
								     info.t.significand()));
      } else if (t.isBitVector()) {
	op = NodeManager::currentNM()->mkConst(FloatingPointToFPSignedBitVector(info.t.exponent(),
										info.t.significand()));
	
      } else {
	throw TypeCheckingExceptionPrivate(node, "cannot rewrite to_fp generic due to incorrect type of second argument");
      }
      
      return NodeManager::currentNM()->mkNode(op, node[0], node[1]);
    }
    
    Unreachable("to_fp generic not rewritten");
  }
Example #16
0
Node ITESimplifier::substitute(TNode e, TNodeMap& substTable, TNodeMap& cache)
{
  TNodeMap::iterator it = cache.find(e), iend = cache.end();
  if (it != iend) {
    return it->second;
  }

  // do substitution?
  it = substTable.find(e);
  iend = substTable.end();
  if (it != iend) {
    Node result = substitute(it->second, substTable, cache);
    cache[e] = result;
    return result;
  }

  size_t sz = e.getNumChildren();
  if (sz == 0) {
    cache[e] = e;
    return e;
  }

  NodeBuilder<> builder(e.getKind());
  if (e.getMetaKind() == kind::metakind::PARAMETERIZED) {
    builder << e.getOperator();
  }
  for (unsigned i = 0; i < e.getNumChildren(); ++ i) {
    builder << substitute(e[i], substTable, cache);
  }

  Node result = builder;
  // it = substTable.find(result);
  // if (it != iend) {
  //   result = substitute(it->second, substTable, cache);
  // }
  cache[e] = result;
  return result;
}
Example #17
0
bool AbstractionModule::isAbstraction(TNode node) {
  if (node.getKind() != kind::EQUAL)
    return false;
  if ((node[0].getKind() != kind::CONST_BITVECTOR ||
       node[1].getKind() != kind::APPLY_UF) &&
      (node[1].getKind() != kind::CONST_BITVECTOR ||
       node[0].getKind() != kind::APPLY_UF))
    return false;

  TNode constant = node[0].getKind() == kind::CONST_BITVECTOR ? node[0] : node[1];
  TNode func = node[0].getKind() == kind::APPLY_UF ? node[0] : node[1];
  Assert (constant.getKind() == kind::CONST_BITVECTOR &&
          func.getKind() == kind::APPLY_UF);
  if (utils::getSize(constant) != 1)
    return false;
  if (constant != utils::mkConst(1, 1u))
    return false;

  TNode func_symbol = func.getOperator(); 
  if (d_funcToSignature.find(func_symbol) == d_funcToSignature.end())
    return false;

  return true; 
}
Example #18
0
Node ITESimplifier::simpITE(TNode assertion)
{
  // Do a topological sort of the subexpressions and substitute them
  vector<preprocess_stack_element> toVisit;
  toVisit.push_back(assertion);

  while (!toVisit.empty())
  {
    // The current node we are processing
    preprocess_stack_element& stackHead = toVisit.back();
    TNode current = stackHead.node;

    // If node has no ITE's or already in the cache we're done, pop from the stack
    if (current.getNumChildren() == 0 ||
        (Theory::theoryOf(current) != THEORY_BOOL && !containsTermITE(current))) {
       d_simpITECache[current] = current;
       toVisit.pop_back();
       continue;
    }

    NodeMap::iterator find = d_simpITECache.find(current);
    if (find != d_simpITECache.end()) {
      toVisit.pop_back();
      continue;
    }

    // Not yet substituted, so process
    if (stackHead.children_added) {
      // Children have been processed, so substitute
      NodeBuilder<> builder(current.getKind());
      if (current.getMetaKind() == kind::metakind::PARAMETERIZED) {
        builder << current.getOperator();
      }
      for (unsigned i = 0; i < current.getNumChildren(); ++ i) {
        Assert(d_simpITECache.find(current[i]) != d_simpITECache.end());
        builder << d_simpITECache[current[i]];
      }
      // Mark the substitution and continue
      Node result = builder;

      // If this is an atom, we process it
      if (Theory::theoryOf(result) != THEORY_BOOL &&
          result.getType().isBoolean()) {
        result = simpITEAtom(result);
      }

      result = Rewriter::rewrite(result);
      d_simpITECache[current] = result;
      toVisit.pop_back();
    } else {
      // Mark that we have added the children if any
      if (current.getNumChildren() > 0) {
        stackHead.children_added = true;
        // We need to add the children
        for(TNode::iterator child_it = current.begin(); child_it != current.end(); ++ child_it) {
          TNode childNode = *child_it;
          NodeMap::iterator childFind = d_simpITECache.find(childNode);
          if (childFind == d_simpITECache.end()) {
            toVisit.push_back(childNode);
          }
        }
      } else {
        // No children, so we're done
        d_simpITECache[current] = current;
        toVisit.pop_back();
      }
    }
  }
  return d_simpITECache[assertion];
}
Example #19
0
Node RemoveITE::run(TNode node, std::vector<Node>& output,
                    IteSkolemMap& iteSkolemMap) {
  // Current node
  Debug("ite") << "removeITEs(" << node << ")" << endl;

  // The result may be cached already
  NodeManager *nodeManager = NodeManager::currentNM();
  ITECache::iterator i = d_iteCache.find(node);
  if(i != d_iteCache.end()) {
    Node cachedRewrite = (*i).second;
    Debug("ite") << "removeITEs: in-cache: " << cachedRewrite << endl;
    return cachedRewrite.isNull() ? Node(node) : cachedRewrite;
  }

  // If an ITE replace it
  if(node.getKind() == kind::ITE) {
    TypeNode nodeType = node.getType();
    if(!nodeType.isBoolean()) {
      // Make the skolem to represent the ITE
      Node skolem = nodeManager->mkSkolem("termITE_$$", nodeType, "a variable introduced due to term-level ITE removal");

      // The new assertion
      Node newAssertion =
        nodeManager->mkNode(kind::ITE, node[0], skolem.eqNode(node[1]),
                            skolem.eqNode(node[2]));
      Debug("ite") << "removeITEs(" << node << ") => " << newAssertion << endl;

      // Attach the skolem
      d_iteCache[node] = skolem;

      // Remove ITEs from the new assertion, rewrite it and push it to the output
      newAssertion = run(newAssertion, output, iteSkolemMap);
      iteSkolemMap[skolem] = output.size();
      output.push_back(newAssertion);

      // The representation is now the skolem
      return skolem;
    }
  }

  // If not an ITE, go deep
  if( node.getKind() != kind::FORALL &&
      node.getKind() != kind::EXISTS &&
      node.getKind() != kind::REWRITE_RULE ) {
    vector<Node> newChildren;
    bool somethingChanged = false;
    if(node.getMetaKind() == kind::metakind::PARAMETERIZED) {
      newChildren.push_back(node.getOperator());
    }
    // Remove the ITEs from the children
    for(TNode::const_iterator it = node.begin(), end = node.end(); it != end; ++it) {
      Node newChild = run(*it, output, iteSkolemMap);
      somethingChanged |= (newChild != *it);
      newChildren.push_back(newChild);
    }

    // If changes, we rewrite
    if(somethingChanged) {
      Node cachedRewrite = nodeManager->mkNode(node.getKind(), newChildren);
      d_iteCache[node] = cachedRewrite;
      return cachedRewrite;
    } else {
      d_iteCache[node] = Node::null();
      return node;
    }
  } else {
    d_iteCache[node] = Node::null();
    return node;
  }
}
Example #20
0
void AbstractionModule::skolemizeArguments(std::vector<Node>& assertions) {
  for (unsigned i = 0; i < assertions.size(); ++i) {
    TNode assertion = assertions[i];
    if (assertion.getKind() != kind::OR)
      continue;
    
    bool is_skolemizable = true;
    for (unsigned k = 0; k < assertion.getNumChildren(); ++k) {
      if (assertion[k].getKind() != kind::EQUAL ||
          assertion[k][0].getKind() != kind::APPLY_UF ||
          assertion[k][1].getKind() != kind::CONST_BITVECTOR ||
          assertion[k][1].getConst<BitVector>() != BitVector(1, 1u)) {
        is_skolemizable = false;
        break;
      }
    }

    if (!is_skolemizable)
      continue;

    ArgsTable assertion_table;

    // collect function symbols and their arguments
    for (unsigned j = 0; j < assertion.getNumChildren(); ++j) {
      TNode current = assertion[j];
      Assert (current.getKind() == kind::EQUAL &&
              current[0].getKind() == kind::APPLY_UF);
      TNode func = current[0];
      ArgsVec args;
      for (unsigned k = 0; k < func.getNumChildren(); ++k) {
        args.push_back(func[k]);
      }
      assertion_table.addEntry(func.getOperator(), args);
    }

    NodeBuilder<> assertion_builder (kind::OR);
    // construct skolemized assertion
    for (ArgsTable::iterator it = assertion_table.begin(); it != assertion_table.end(); ++it) {
      // for each function symbol
      ++(d_statistics.d_numArgsSkolemized);
      TNode func = it->first;
      ArgsTableEntry& args = it->second;
      NodeBuilder<> skolem_func (kind::APPLY_UF);
      skolem_func << func;
      std::vector<Node> skolem_args;
        
      for (unsigned j = 0; j < args.getArity(); ++j) {
        bool all_same = true;
        for (unsigned k = 1; k < args.getNumEntries(); ++k) {
          if ( args.getEntry(k)[j] != args.getEntry(0)[j])
            all_same = false; 
        }
        Node new_arg = all_same ? (Node)args.getEntry(0)[j] : utils::mkVar(utils::getSize(args.getEntry(0)[j])); 
        skolem_args.push_back(new_arg);
        skolem_func << new_arg; 
      }
      

      Node skolem_func_eq1 = utils::mkNode(kind::EQUAL, (Node)skolem_func, utils::mkConst(1, 1u)); 
      
      // enumerate arguments assignments
      std::vector<Node> or_assignments; 
      for (ArgsTableEntry::iterator it = args.begin(); it != args.end(); ++it) {
        NodeBuilder<> arg_assignment(kind::AND);
        ArgsVec& args =  *it;
        for (unsigned k = 0; k < args.size(); ++k) {
          Node eq = utils::mkNode(kind::EQUAL, args[k], skolem_args[k]);
          arg_assignment << eq; 
        }
        or_assignments.push_back(arg_assignment);
      }
      
      Node new_func_def = utils::mkNode(kind::AND, skolem_func_eq1, utils::mkNode(kind::OR, or_assignments));
      assertion_builder << new_func_def; 
    }
    Node new_assertion = assertion_builder;
    Debug("bv-abstraction-dbg") << "AbstractionModule::skolemizeArguments " << assertions[i] << " => \n";
    Debug("bv-abstraction-dbg") << "    " << new_assertion; 
    assertions[i] = new_assertion;
  }
}
Example #21
0
Node TheoryModel::getModelValue(TNode n, bool hasBoundVars) const
{
  Assert(n.getKind() != kind::FORALL && n.getKind() != kind::EXISTS);
  if(n.getKind() == kind::LAMBDA) {
    NodeManager* nm = NodeManager::currentNM();
    Node body = getModelValue(n[1], true);
    // This is a bit ugly, but cache inside simplifier can change, so can't be const
    // The ite simplifier is needed to get rid of artifacts created by Boolean terms
    body = const_cast<ITESimplifier*>(&d_iteSimp)->simpITE(body);
    body = Rewriter::rewrite(body);
    return nm->mkNode(kind::LAMBDA, n[0], body);
  }
  if(n.isConst() || (hasBoundVars && n.getKind() == kind::BOUND_VARIABLE)) {
    return n;
  }

  TypeNode t = n.getType();
  if (t.isFunction() || t.isPredicate()) {
    if (d_enableFuncModels) {
      std::map< Node, Node >::const_iterator it = d_uf_models.find(n);
      if (it != d_uf_models.end()) {
        // Existing function
        return it->second;
      }
      // Unknown function symbol: return LAMBDA x. c, where c is the first constant in the enumeration of the range type
      vector<TypeNode> argTypes = t.getArgTypes();
      vector<Node> args;
      NodeManager* nm = NodeManager::currentNM();
      for (unsigned i = 0; i < argTypes.size(); ++i) {
        args.push_back(nm->mkBoundVar(argTypes[i]));
      }
      Node boundVarList = nm->mkNode(kind::BOUND_VAR_LIST, args);
      TypeEnumerator te(t.getRangeType());
      return nm->mkNode(kind::LAMBDA, boundVarList, *te);
    }
    // TODO: if func models not enabled, throw an error?
    Unreachable();
  }

  if (n.getNumChildren() > 0) {
    std::vector<Node> children;
    if (n.getKind() == APPLY_UF) {
      Node op = getModelValue(n.getOperator(), hasBoundVars);
      children.push_back(op);
    }
    else if (n.getMetaKind() == kind::metakind::PARAMETERIZED) {
      children.push_back(n.getOperator());
    }
    //evaluate the children
    for (unsigned i = 0; i < n.getNumChildren(); ++i) {
      Node val = getModelValue(n[i], hasBoundVars);
      children.push_back(val);
    }
    Node val = Rewriter::rewrite(NodeManager::currentNM()->mkNode(n.getKind(), children));
    Assert(hasBoundVars || val.isConst());
    return val;
  }

  if (!d_equalityEngine.hasTerm(n)) {
    // Unknown term - return first enumerated value for this type
    TypeEnumerator te(n.getType());
    return *te;
  }
  Node val = d_equalityEngine.getRepresentative(n);
  Assert(d_reps.find(val) != d_reps.end());
  std::map< Node, Node >::const_iterator it = d_reps.find( val );
  if( it!=d_reps.end() ){
    return it->second;
  }else{
    return Node::null();
  }
}
Example #22
0
bool AbsMbqiBuilder::doCheck( FirstOrderModelAbs * m, TNode q, AbsDef & ad, TNode n ) {
  Assert( n.getKind()!=FORALL );
  if( n.getKind()==NOT && n[0].getKind()!=FORALL ){
    doCheck( m, q, ad, n[0] );
    ad.negate();
    return true;
  }else{
    std::map< unsigned, AbsDef > children;
    std::map< unsigned, int > bchildren;
    std::map< unsigned, int > vchildren;
    int varChCount = 0;
    for( unsigned i=0; i<n.getNumChildren(); i++ ){
      if( n[i].getKind()==FORALL ){
        bchildren[i] = AbsDef::val_unk;
      }else if( n[i].getKind() == BOUND_VARIABLE ){
        varChCount++;
        vchildren[i] = m->d_var_index[q][ m->getVariableId( q, n[i] ) ];
        //vchildren[i] = m->getVariableId( q, n[i] );
      }else if( m->hasTerm( n[i] ) ){
        bchildren[i] = m->getRepresentativeId( n[i] );
      }else{
        if( !doCheck( m, q, children[i], n[i] ) ){
          bchildren[i] = AbsDef::val_unk;
          children.erase( i );
        }
      }
    }
    //convert to pointers
    std::map< unsigned, AbsDef * > pchildren;
    for( std::map< unsigned, AbsDef >::iterator it = children.begin(); it != children.end(); ++it ){
      pchildren[it->first] = &it->second;
    }
    //construct the interpretation
    Trace("ambqi-check-debug") << "Compute Interpretation of " << n << " " << n.getKind() << std::endl;
    if( n.getKind() == APPLY_UF || n.getKind() == VARIABLE || n.getKind() == SKOLEM ){
      Node op;
      if( n.getKind() == APPLY_UF ){
        op = n.getOperator();
      }else{
        op = n;
      }
      //uninterpreted compose
      if( m->d_models_valid[op] ){
        ad.construct( m, q, n, m->d_models[op], pchildren, bchildren, vchildren, varChCount );
      }else{
        Trace("ambqi-check-debug") << "** Cannot produce interpretation for " << n << " (no function model)" << std::endl;
        return false;
      }
    }else if( !ad.construct( m, q, n, NULL, pchildren, bchildren, vchildren, varChCount ) ){
      Trace("ambqi-check-debug") << "** Cannot produce interpretation for " << n << " (variables are children of interpreted symbol)" << std::endl;
      return false;
    }
    Trace("ambqi-check-try") << "Interpretation for " << n << " is : " << std::endl;
    ad.debugPrint("ambqi-check-try", m, q[0] );
    ad.simplify( m, q, q[0] );
    Trace("ambqi-check-debug") << "(Simplified) Interpretation for " << n << " is : " << std::endl;
    ad.debugPrint("ambqi-check-debug", m, q[0] );
    Trace("ambqi-check-debug") << std::endl;
    return true;
  }
}
Example #23
0
Node SubstitutionEx::internalApply(TNode node) {
  if (d_substitutions.empty())
    return node;

  vector<SubstitutionStackElement> stack;
  stack.push_back(SubstitutionStackElement(node));

  while (!stack.empty()) {
    SubstitutionStackElement head = stack.back();
    stack.pop_back();
    
    TNode current = head.node;

    if (hasCache(current)) {
      continue;
    }

    // check if it has substitution
    Substitutions::const_iterator it = d_substitutions.find(current);
    if (it != d_substitutions.end()) {
      vector<Node> reasons;
      TNode to = it->second.to;
      reasons.push_back(it->second.reason);
      // check if the thing we subsituted to has substitutions
      TNode res = internalApply(to);
      // update reasons
      reasons.push_back(getReason(to));
      Node reason = mergeExplanations(reasons);
      storeCache(current, res, reason);
      continue;
    }

    // if no children then just continue
    if(current.getNumChildren() == 0) {
      storeCache(current, current, utils::mkTrue());
      continue;
    }
    
    // children already processed 
    if (head.childrenAdded) {
      NodeBuilder<> nb(current.getKind());
      std::vector<Node> reasons;
      
      if (current.getMetaKind() == kind::metakind::PARAMETERIZED) {
        TNode op = current.getOperator();
        Assert (hasCache(op));
        nb << getCache(op);
        reasons.push_back(getReason(op));
      }
      for (unsigned i = 0; i < current.getNumChildren(); ++i) {
        Assert (hasCache(current[i]));
        nb << getCache(current[i]);
        reasons.push_back(getReason(current[i]));
      }
      Node result = nb;
      // if the node is new apply substitutions to it
      Node subst_result = result;
      if (result != current) {
        subst_result = result!= current? internalApply(result) : result;
        reasons.push_back(getReason(result));
      }
      Node reason = mergeExplanations(reasons);
      storeCache(current, subst_result, reason);
      continue;
    } else {
      // add children to stack
      stack.push_back(SubstitutionStackElement(current, true));
      if (current.getMetaKind() == kind::metakind::PARAMETERIZED) {
        stack.push_back(SubstitutionStackElement(current.getOperator()));
      }
      for (unsigned i = 0; i < current.getNumChildren(); ++i) {
        stack.push_back(SubstitutionStackElement(current[i]));
      }
    }
  }

  Assert(hasCache(node));
  return getCache(node);
}