Branch data Line data Source code
1 : : /****************************************************************************** 2 : : * Top contributors (to current version): 3 : : * Andrew Reynolds, Mathias Preiner, Hans-Joerg Schurr 4 : : * 5 : : * This file is part of the cvc5 project. 6 : : * 7 : : * Copyright (c) 2009-2025 by the authors listed in the file AUTHORS 8 : : * in the top-level source directory and their institutional affiliations. 9 : : * All rights reserved. See the file COPYING in the top-level source 10 : : * directory for licensing information. 11 : : * **************************************************************************** 12 : : * 13 : : * The module for managing witness form conversion in proofs. 14 : : */ 15 : : 16 : : #include "smt/witness_form.h" 17 : : 18 : : #include "expr/skolem_manager.h" 19 : : #include "smt/env.h" 20 : : #include "theory/rewriter.h" 21 : : 22 : : namespace cvc5::internal { 23 : : namespace smt { 24 : : 25 : 20160 : WitnessFormGenerator::WitnessFormGenerator(Env& env) 26 : 40320 : : d_rewriter(env.getRewriter()), 27 : : d_tcpg(env, 28 : : nullptr, 29 : : TConvPolicy::FIXPOINT, 30 : : TConvCachePolicy::NEVER, 31 : : "WfGenerator::TConvProofGenerator", 32 : : nullptr, 33 : : true), 34 : : d_wintroPf(env, nullptr, nullptr, "WfGenerator::LazyCDProof"), 35 : 20160 : d_pskPf(env, nullptr, "WfGenerator::PurifySkolemProof") 36 : : { 37 : 20160 : } 38 : : 39 : 31272 : std::shared_ptr<ProofNode> WitnessFormGenerator::getProofFor(Node eq) 40 : : { 41 [ - + ]: 31272 : if (eq.getKind() != Kind::EQUAL) 42 : : { 43 : : // expecting an equality 44 : 0 : return nullptr; 45 : : } 46 : 62544 : Node lhs = eq[0]; 47 : 62544 : Node rhs = convertToWitnessForm(eq[0]); 48 [ - + ]: 31272 : if (rhs != eq[1]) 49 : : { 50 : : // expecting witness form 51 : 0 : return nullptr; 52 : : } 53 : 62544 : std::shared_ptr<ProofNode> pn = d_tcpg.getProofFor(eq); 54 [ - + ][ - + ]: 31272 : Assert(pn != nullptr); [ - - ] 55 : 31272 : return pn; 56 : : } 57 : : 58 : 0 : std::string WitnessFormGenerator::identify() const 59 : : { 60 : 0 : return "WitnessFormGenerator"; 61 : : } 62 : : 63 : 31272 : Node WitnessFormGenerator::convertToWitnessForm(Node t) 64 : : { 65 : 31272 : Node tw = SkolemManager::getOriginalForm(t); 66 [ - + ]: 31272 : if (t == tw) 67 : : { 68 : : // trivial case 69 : 0 : return tw; 70 : : } 71 : 31272 : std::unordered_set<Node>::iterator it; 72 : 62544 : std::vector<TNode> visit; 73 : 62544 : TNode cur; 74 : 62544 : TNode curw; 75 : 31272 : visit.push_back(t); 76 : 292252 : do 77 : : { 78 : 323524 : cur = visit.back(); 79 : 323524 : visit.pop_back(); 80 : 323524 : it = d_visited.find(cur); 81 [ + + ]: 323524 : if (it == d_visited.end()) 82 : : { 83 : 146951 : d_visited.insert(cur); 84 : 146951 : curw = SkolemManager::getOriginalForm(cur); 85 : : // if its original form is different 86 [ + + ]: 146951 : if (cur != curw) 87 : : { 88 [ + + ]: 106452 : if (cur.isVar()) 89 : : { 90 : 18762 : curw = SkolemManager::getUnpurifiedForm(cur); 91 : 37524 : Node eq = cur.eqNode(curw); 92 : : // equality between a variable and its unpurified form 93 : 18762 : d_eqs.insert(eq); 94 : : // ------- SKOLEM_INTRO 95 : : // k = t 96 : 37524 : d_wintroPf.addStep(eq, ProofRule::SKOLEM_INTRO, {}, {cur}); 97 : 18762 : d_tcpg.addRewriteStep( 98 : : cur, curw, &d_wintroPf, true, TrustId::NONE, true); 99 : : // recursively transform 100 : 18762 : visit.push_back(curw); 101 : : } 102 : : else 103 : : { 104 : : // A term whose original form is different from itself, recurse. 105 : : // It should be the case that cur has children, since the original 106 : : // form of constants are themselves. 107 [ - + ][ - + ]: 87690 : Assert(cur.getNumChildren() > 0); [ - - ] 108 [ + - ]: 87690 : if (cur.hasOperator()) 109 : : { 110 : 87690 : visit.push_back(cur.getOperator()); 111 : : } 112 : 87690 : visit.insert(visit.end(), cur.begin(), cur.end()); 113 : : } 114 : : } 115 : : } 116 [ + + ]: 323524 : } while (!visit.empty()); 117 : 31272 : return tw; 118 : : } 119 : : 120 : 212895 : bool WitnessFormGenerator::requiresWitnessFormTransform(Node t, Node s) const 121 : : { 122 : 212895 : return d_rewriter->rewrite(t) != d_rewriter->rewrite(s); 123 : : } 124 : : 125 : 59795 : bool WitnessFormGenerator::requiresWitnessFormIntro(Node t) const 126 : : { 127 : 59795 : Node tr = d_rewriter->rewrite(t); 128 [ + + ][ - + ]: 119590 : return !tr.isConst() || !tr.getConst<bool>(); 129 : : } 130 : : 131 : 0 : const std::unordered_set<Node>& WitnessFormGenerator::getWitnessFormEqs() const 132 : : { 133 : 0 : return d_eqs; 134 : : } 135 : : 136 : : } // namespace smt 137 : : } // namespace cvc5::internal