Branch data Line data Source code
1 : : /****************************************************************************** 2 : : * Top contributors (to current version): 3 : : * Andrew Reynolds, Hans-Joerg Schurr, Aina Niemetz 4 : : * 5 : : * This file is part of the cvc5 project. 6 : : * 7 : : * Copyright (c) 2009-2024 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 : : * Implementation of quantifiers proof checker. 14 : : */ 15 : : 16 : : #include "theory/quantifiers/proof_checker.h" 17 : : 18 : : #include "expr/node_algorithm.h" 19 : : #include "expr/skolem_manager.h" 20 : : #include "theory/builtin/proof_checker.h" 21 : : #include "theory/quantifiers/skolemize.h" 22 : : 23 : : using namespace cvc5::internal::kind; 24 : : 25 : : namespace cvc5::internal { 26 : : namespace theory { 27 : : namespace quantifiers { 28 : : 29 : 49691 : QuantifiersProofRuleChecker::QuantifiersProofRuleChecker(NodeManager* nm) 30 : 49691 : : ProofRuleChecker(nm) 31 : : { 32 : 49691 : } 33 : : 34 : 19195 : void QuantifiersProofRuleChecker::registerTo(ProofChecker* pc) 35 : : { 36 : : // add checkers 37 : 19195 : pc->registerChecker(ProofRule::SKOLEM_INTRO, this); 38 : 19195 : pc->registerChecker(ProofRule::SKOLEMIZE, this); 39 : 19195 : pc->registerChecker(ProofRule::INSTANTIATE, this); 40 : 19195 : pc->registerChecker(ProofRule::ALPHA_EQUIV, this); 41 : 19195 : pc->registerChecker(ProofRule::QUANT_VAR_REORDERING, this); 42 : 19195 : } 43 : : 44 : 26488 : Node QuantifiersProofRuleChecker::checkInternal( 45 : : ProofRule id, 46 : : const std::vector<Node>& children, 47 : : const std::vector<Node>& args) 48 : : { 49 [ + + ]: 26488 : if (id == ProofRule::SKOLEM_INTRO) 50 : : { 51 [ - + ][ - + ]: 19447 : Assert(children.empty()); [ - - ] 52 [ - + ][ - + ]: 19447 : Assert(args.size() == 1); [ - - ] 53 : 38894 : Node t = SkolemManager::getUnpurifiedForm(args[0]); 54 : 19447 : return args[0].eqNode(t); 55 : : } 56 [ + + ]: 7041 : else if (id == ProofRule::SKOLEMIZE) 57 : : { 58 [ - + ][ - + ]: 1036 : Assert(children.size() == 1); [ - - ] 59 [ - + ][ - + ]: 1036 : Assert(args.empty()); [ - - ] 60 : : // must use negated FORALL 61 : 1036 : if (children[0].getKind() != Kind::NOT 62 [ + - ][ - + ]: 2072 : || children[0][0].getKind() != Kind::FORALL) [ + - ][ - + ] [ - - ] 63 : : { 64 : 0 : return Node::null(); 65 : : } 66 : 2072 : Node q = children[0][0]; 67 : 3108 : std::vector<Node> vars(q[0].begin(), q[0].end()); 68 : 2072 : std::vector<Node> skolems = Skolemize::getSkolemConstants(q); 69 : : Node res = q[1].substitute( 70 : 2072 : vars.begin(), vars.end(), skolems.begin(), skolems.end()); 71 : 1036 : res = res.notNode(); 72 : 1036 : return res; 73 : : } 74 [ + + ]: 6005 : else if (id == ProofRule::INSTANTIATE) 75 : : { 76 [ - + ][ - + ]: 5864 : Assert(children.size() == 1); [ - - ] 77 : : // note we may have more arguments than just the term vector 78 [ + - ][ - + ]: 5864 : if (children[0].getKind() != Kind::FORALL || args.empty()) [ - + ] 79 : : { 80 : 0 : return Node::null(); 81 : : } 82 : 11728 : Node body = children[0][1]; 83 : 11728 : std::vector<Node> vars; 84 : 11728 : std::vector<Node> subs; 85 [ + + ]: 20737 : for (size_t i = 0, nc = children[0][0].getNumChildren(); i < nc; i++) 86 : : { 87 : 14873 : vars.push_back(children[0][0][i]); 88 : 14873 : subs.push_back(args[0][i]); 89 : : } 90 : : Node inst = 91 : 11728 : body.substitute(vars.begin(), vars.end(), subs.begin(), subs.end()); 92 : 5864 : return inst; 93 : : } 94 [ + + ]: 141 : else if (id == ProofRule::ALPHA_EQUIV) 95 : : { 96 [ - + ][ - + ]: 72 : Assert(children.empty()); [ - - ] 97 [ - + ][ - + ]: 72 : Assert(args.size() == 3); [ - - ] 98 : : // must be lists of the same length 99 [ + - ]: 144 : if (args[1].getKind() != Kind::SEXPR || args[2].getKind() != Kind::SEXPR 100 [ + - ][ - + ]: 144 : || args[1].getNumChildren() != args[2].getNumChildren()) [ - + ] 101 : : { 102 : 0 : return Node::null(); 103 : : } 104 : : // arguments must be lists of bound variables that are pairwise unique 105 [ + + ][ + + ]: 432 : std::unordered_set<Node> allVars[2]; [ - - ] 106 : 144 : std::vector<Node> vars; 107 : 144 : std::vector<Node> newVars; 108 [ + + ]: 184 : for (size_t i = 0, nargs = args[1].getNumChildren(); i < nargs; i++) 109 : : { 110 [ + + ]: 336 : for (size_t j = 1; j <= 2; j++) 111 : : { 112 : 224 : Node v = args[j][i]; 113 : 224 : std::unordered_set<Node>& av = allVars[j - 1]; 114 [ + - ][ - + ]: 224 : if (v.getKind() != Kind::BOUND_VARIABLE || av.find(v) != av.end()) [ - + ] 115 : : { 116 : 0 : return Node::null(); 117 : : } 118 : 224 : av.insert(v); 119 : : } 120 : 112 : vars.push_back(args[1][i]); 121 : 112 : newVars.push_back(args[2][i]); 122 : : } 123 : 72 : Node renamedBody = args[0].substitute( 124 : 144 : vars.begin(), vars.end(), newVars.begin(), newVars.end()); 125 : 72 : return args[0].eqNode(renamedBody); 126 : : } 127 [ + - ]: 69 : else if (id == ProofRule::QUANT_VAR_REORDERING) 128 : : { 129 [ - + ][ - + ]: 69 : Assert(children.empty()); [ - - ] 130 [ - + ][ - + ]: 69 : Assert(args.size() == 1); [ - - ] 131 : 138 : Node eq = args[0]; 132 [ + - ][ - + ]: 138 : if (eq.getKind() != Kind::EQUAL || eq[0].getKind() != Kind::FORALL [ - - ] 133 : 138 : || eq[1].getKind() != Kind::FORALL || eq[0][1] != eq[1][1]) 134 : : { 135 : 0 : return Node::null(); 136 : : } 137 : 207 : std::unordered_set<Node> varSet1(eq[0][0].begin(), eq[0][0].end()); 138 : 207 : std::unordered_set<Node> varSet2(eq[1][0].begin(), eq[1][0].end()); 139 : : // cannot have repetition 140 : 138 : if (varSet1.size() != eq[0][0].getNumChildren() 141 : 138 : || varSet2.size() != eq[1][0].getNumChildren()) 142 : : { 143 : 0 : return Node::null(); 144 : : } 145 [ - + ]: 69 : if (varSet1 != varSet2) 146 : : { 147 : 0 : return Node::null(); 148 : : } 149 : 69 : return eq; 150 : : } 151 : : 152 : : // no rule 153 : 0 : return Node::null(); 154 : : } 155 : : 156 : : } // namespace quantifiers 157 : : } // namespace theory 158 : : } // namespace cvc5::internal