All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cvc5-cvc5-1.2.0.src.smt.witness_form.cpp Maven / Gradle / Ivy

The newest version!
/******************************************************************************
 * Top contributors (to current version):
 *   Andrew Reynolds, Mathias Preiner, Hans-Jörg Schurr
 *
 * This file is part of the cvc5 project.
 *
 * Copyright (c) 2009-2024 by the authors listed in the file AUTHORS
 * in the top-level source directory and their institutional affiliations.
 * All rights reserved.  See the file COPYING in the top-level source
 * directory for licensing information.
 * ****************************************************************************
 *
 * The module for managing witness form conversion in proofs.
 */

#include "smt/witness_form.h"

#include "expr/skolem_manager.h"
#include "smt/env.h"
#include "theory/rewriter.h"

namespace cvc5::internal {
namespace smt {

WitnessFormGenerator::WitnessFormGenerator(Env& env)
    : d_rewriter(env.getRewriter()),
      d_tcpg(env,
             nullptr,
             TConvPolicy::FIXPOINT,
             TConvCachePolicy::NEVER,
             "WfGenerator::TConvProofGenerator",
             nullptr,
             true),
      d_wintroPf(env, nullptr, nullptr, "WfGenerator::LazyCDProof"),
      d_pskPf(env, nullptr, "WfGenerator::PurifySkolemProof")
{
}

std::shared_ptr WitnessFormGenerator::getProofFor(Node eq)
{
  if (eq.getKind() != Kind::EQUAL)
  {
    // expecting an equality
    return nullptr;
  }
  Node lhs = eq[0];
  Node rhs = convertToWitnessForm(eq[0]);
  if (rhs != eq[1])
  {
    // expecting witness form
    return nullptr;
  }
  std::shared_ptr pn = d_tcpg.getProofFor(eq);
  Assert(pn != nullptr);
  return pn;
}

std::string WitnessFormGenerator::identify() const
{
  return "WitnessFormGenerator";
}

Node WitnessFormGenerator::convertToWitnessForm(Node t)
{
  Node tw = SkolemManager::getOriginalForm(t);
  if (t == tw)
  {
    // trivial case
    return tw;
  }
  std::unordered_set::iterator it;
  std::vector visit;
  TNode cur;
  TNode curw;
  visit.push_back(t);
  do
  {
    cur = visit.back();
    visit.pop_back();
    it = d_visited.find(cur);
    if (it == d_visited.end())
    {
      d_visited.insert(cur);
      curw = SkolemManager::getOriginalForm(cur);
      // if its original form is different
      if (cur != curw)
      {
        if (cur.isVar())
        {
          curw = SkolemManager::getUnpurifiedForm(cur);
          Node eq = cur.eqNode(curw);
          // equality between a variable and its unpurified form
          d_eqs.insert(eq);
          // ------- SKOLEM_INTRO
          // k = t
          d_wintroPf.addStep(eq, ProofRule::SKOLEM_INTRO, {}, {cur});
          d_tcpg.addRewriteStep(
              cur, curw, &d_wintroPf, true, TrustId::NONE, true);
          // recursively transform
          visit.push_back(curw);
        }
        else
        {
          // A term whose original form is different from itself, recurse.
          // It should be the case that cur has children, since the original
          // form of constants are themselves.
          Assert(cur.getNumChildren() > 0);
          if (cur.hasOperator())
          {
            visit.push_back(cur.getOperator());
          }
          visit.insert(visit.end(), cur.begin(), cur.end());
        }
      }
    }
  } while (!visit.empty());
  return tw;
}

bool WitnessFormGenerator::requiresWitnessFormTransform(Node t, Node s) const
{
  return d_rewriter->rewrite(t) != d_rewriter->rewrite(s);
}

bool WitnessFormGenerator::requiresWitnessFormIntro(Node t) const
{
  Node tr = d_rewriter->rewrite(t);
  return !tr.isConst() || !tr.getConst();
}

const std::unordered_set& WitnessFormGenerator::getWitnessFormEqs() const
{
  return d_eqs;
}

}  // namespace smt
}  // namespace cvc5::internal




© 2015 - 2024 Weber Informatics LLC | Privacy Policy