コード例 #1
0
ファイル: substitutions.cpp プロジェクト: Awesomeclaw/CVC4
static bool check(TNode node, const SubstitutionMap::NodeMap& substitutions) {
  SubstitutionMap::NodeMap::const_iterator it = substitutions.begin();
  SubstitutionMap::NodeMap::const_iterator it_end = substitutions.end();
  Debug("substitution") << "checking " << node << endl;
  for (; it != it_end; ++ it) {
    Debug("substitution") << "-- hasSubterm( " << (*it).first << " ) ?" << endl;
    if (node.hasSubterm((*it).first)) {
      Debug("substitution") << "-- FAIL" << endl;
      return false;
    }
  }
  Debug("substitution") << "-- SUCCEED" << endl;
  return true;
}
コード例 #2
0
bool AlgebraicSolver::isSubstitutableIn(TNode node, TNode in) {
  if (node.getMetaKind() == kind::metakind::VARIABLE &&
      !in.hasSubterm(node))
    return true;
  return false; 
}
コード例 #3
0
bool AlgebraicSolver::solve(TNode fact, TNode reason, SubstitutionEx& subst) {
  if (fact.getKind() != kind::EQUAL) return false;

  TNode left = fact[0];
  TNode right = fact[1];

  
  if (left.isVar() && !right.hasSubterm(left)) {
    bool changed  = subst.addSubstitution(left, right, reason);
    return changed;
  }
  if (right.isVar() && !left.hasSubterm(right)) {
    bool changed = subst.addSubstitution(right, left, reason);
    return changed;
  }

  // xor simplification
  if (right.getKind() == kind::BITVECTOR_XOR &&
      left.getKind() == kind::BITVECTOR_XOR) {
    TNode var = left[0];
    if (var.getMetaKind() != kind::metakind::VARIABLE)
      return false; 

    // simplify xor with same variable on both sides
    if (right.hasSubterm(var)) {
      std::vector<Node> right_children;
      for (unsigned i = 0; i < right.getNumChildren(); ++i) {
        if (right[i] != var)
          right_children.push_back(right[i]); 
      }
      Assert (right_children.size());
      Node new_right = right_children.size() > 1 ? utils::mkNode(kind::BITVECTOR_XOR, right_children)
                                                 : right_children[0];
      std::vector<Node> left_children;
      for (unsigned i = 1; i < left.getNumChildren(); ++i) {
        left_children.push_back(left[i]);
      }
      Node new_left = left_children.size() > 1 ? utils::mkNode(kind::BITVECTOR_XOR, left_children)
                                               : left_children[0];
      Node new_fact = utils::mkNode(kind::EQUAL, new_left, new_right);
      bool changed = subst.addSubstitution(fact, new_fact, reason);
      return changed;
    }
    
    NodeBuilder<> nb(kind::BITVECTOR_XOR);
    for (unsigned i = 1; i < left.getNumChildren(); ++i) {
      nb << left[i];
    }
    Node inverse = left.getNumChildren() == 2? (Node)left[1] : (Node)nb;
    Node new_right = utils::mkNode(kind::BITVECTOR_XOR, right, inverse);
    bool changed = subst.addSubstitution(var, new_right, reason);

    if (Dump.isOn("bv-algebraic")) {
      Node query = utils::mkNot(utils::mkNode(kind::IFF, fact, utils::mkNode(kind::EQUAL, var, new_right)));
      Dump("bv-algebraic") << EchoCommand("ThoeryBV::AlgebraicSolver::substitution explanation"); 
      Dump("bv-algebraic") << PushCommand(); 
      Dump("bv-algebraic") << AssertCommand(query.toExpr());
      Dump("bv-algebraic") << CheckSatCommand();
      Dump("bv-algebraic") << PopCommand(); 
    }

    
    return changed;
  }

  // (a xor t = a) <=> (t = 0)
  if (left.getKind() == kind::BITVECTOR_XOR &&
      right.getMetaKind() == kind::metakind::VARIABLE &&
      left.hasSubterm(right)) {
    TNode var = right;
    Node new_left = utils::mkNode(kind::BITVECTOR_XOR, var, left);
    Node zero = utils::mkConst(utils::getSize(var), 0u);
    Node new_fact = utils::mkNode(kind::EQUAL, zero, new_left);
    bool changed = subst.addSubstitution(fact, new_fact, reason);
    return changed; 
  }
  
  if (right.getKind() == kind::BITVECTOR_XOR &&
      left.getMetaKind() == kind::metakind::VARIABLE &&
      right.hasSubterm(left)) {
    TNode var = left;
    Node new_right = utils::mkNode(kind::BITVECTOR_XOR, var, right);
    Node zero = utils::mkConst(utils::getSize(var), 0u);
    Node new_fact = utils::mkNode(kind::EQUAL, zero, new_right);
    bool changed = subst.addSubstitution(fact, new_fact, reason);
    return changed; 
  }

  // (a xor b = 0) <=> (a = b)
  if (left.getKind() == kind::BITVECTOR_XOR &&
      left.getNumChildren() == 2 &&
      right.getKind() == kind::CONST_BITVECTOR &&
      right.getConst<BitVector>() == BitVector(utils::getSize(left), 0u)) {
    Node new_fact = utils::mkNode(kind::EQUAL, left[0], left[1]);
    bool changed = subst.addSubstitution(fact, new_fact, reason);
    return changed; 
  }
  

  return false;
}