Branch data Line data Source code
1 : : /****************************************************************************** 2 : : * This file is part of the cvc5 project. 3 : : * 4 : : * Copyright (c) 2009-2026 by the authors listed in the file AUTHORS 5 : : * in the top-level source directory and their institutional affiliations. 6 : : * All rights reserved. See the file COPYING in the top-level source 7 : : * directory for licensing information. 8 : : * **************************************************************************** 9 : : * 10 : : * Implementation of witness elimination node conversion 11 : : */ 12 : : 13 : : #include "expr/elim_witness_converter.h" 14 : : 15 : : #include "expr/skolem_manager.h" 16 : : #include "proof/valid_witness_proof_generator.h" 17 : : #include "theory/quantifiers/quantifiers_attributes.h" 18 : : #include "util/rational.h" 19 : : 20 : : namespace cvc5::internal { 21 : : 22 : 765 : ElimWitnessNodeConverter::ElimWitnessNodeConverter(Env& env) 23 : 765 : : EnvObj(env), NodeConverter(nodeManager()) 24 : : { 25 : 765 : } 26 : : 27 : 12748 : Node ElimWitnessNodeConverter::postConvert(Node n) 28 : : { 29 [ + + ]: 12748 : if (n.getKind() == Kind::WITNESS) 30 : : { 31 [ + - ]: 781 : Trace("elim-witness") << "Eliminate " << n << std::endl; 32 : 781 : NodeManager* nm = nodeManager(); 33 : 781 : std::vector<Node> pats; 34 : 781 : Node k; 35 [ + + ]: 781 : if (n.getNumChildren() == 3) 36 : : { 37 : : // see if it has a proof specification marking, in which case we can 38 : : // introduce a skolem and axiom in the proper way 39 [ - + ][ - + ]: 14 : Assert(n[2].getKind() == Kind::INST_PATTERN_LIST); [ - - ] 40 : : ProofRule r; 41 : 14 : std::vector<Node> args; 42 [ + - ]: 14 : if (ValidWitnessProofGenerator::getProofSpec(n[2][0], r, args)) 43 : : { 44 : 14 : k = ValidWitnessProofGenerator::mkSkolem(nm, r, args); 45 : 14 : Node ax = ValidWitnessProofGenerator::mkAxiom(nm, k, r, args); 46 [ - + ][ - + ]: 14 : Assert(!ax.isNull()); [ - - ] 47 [ + - ]: 14 : if (!ax.isNull()) 48 : : { 49 : 14 : d_axioms.push_back(ax); 50 : : } 51 : 14 : } 52 : 14 : } 53 [ + + ]: 781 : if (k.isNull()) 54 : : { 55 : 767 : SkolemManager* skm = nm->getSkolemManager(); 56 : 767 : std::vector<Node> nchildren(n.begin(), n.end()); 57 : 767 : nchildren[1] = nchildren[1].notNode(); 58 : : // must mark that the quantified formula cannot be eliminated by 59 : : // rewriting, so that the form of the quantified formula is preserved for 60 : : // the introduction below. 61 : : Node psan = 62 : 767 : theory::quantifiers::QuantAttributes::mkAttrPreserveStructure(nm); 63 : 767 : Node ipl = nm->mkNode(Kind::INST_PATTERN_LIST, psan); 64 : 767 : nchildren.push_back(ipl); 65 : : // make the quantified formula 66 : 767 : Node q = nm->mkNode(Kind::FORALL, nchildren); 67 : 767 : Node qn = getNormalFormFor(q); 68 : : // should still be a FORALL due to above 69 [ - + ][ - + ]: 767 : Assert(qn.getKind() == Kind::FORALL); [ - - ] 70 [ + + ][ - - ]: 3835 : k = skm->mkSkolemFunction(SkolemId::QUANTIFIERS_SKOLEMIZE, 71 : 2301 : {qn, nm->mkConstInt(Rational(0))}); 72 : : // save the non-normalized version, which makes it easier to e.g. 73 : : // track proofs 74 : 767 : d_axioms.push_back(q.notNode()); 75 : 767 : } 76 : 781 : return k; 77 : 781 : } 78 : 11967 : return n; 79 : : } 80 : : 81 : 765 : const std::vector<Node>& ElimWitnessNodeConverter::getAxioms() const 82 : : { 83 : 765 : return d_axioms; 84 : : } 85 : : 86 : 0 : Node ElimWitnessNodeConverter::getNormalFormFor(const Node& q) { return q; } 87 : : 88 : : } // namespace cvc5::internal