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 arrays proof checker. 14 : : */ 15 : : 16 : : #include "theory/arrays/proof_checker.h" 17 : : 18 : : #include "expr/skolem_manager.h" 19 : : #include "theory/arrays/skolem_cache.h" 20 : : #include "theory/arrays/theory_arrays_rewriter.h" 21 : : #include "theory/rewriter.h" 22 : : 23 : : namespace cvc5::internal { 24 : : namespace theory { 25 : : namespace arrays { 26 : : 27 : 49839 : ArraysProofRuleChecker::ArraysProofRuleChecker(NodeManager* nm) 28 : 49839 : : ProofRuleChecker(nm) 29 : : { 30 : 49839 : } 31 : 19205 : void ArraysProofRuleChecker::registerTo(ProofChecker* pc) 32 : : { 33 : 19205 : pc->registerChecker(ProofRule::ARRAYS_READ_OVER_WRITE, this); 34 : 19205 : pc->registerChecker(ProofRule::ARRAYS_READ_OVER_WRITE_CONTRA, this); 35 : 19205 : pc->registerChecker(ProofRule::ARRAYS_READ_OVER_WRITE_1, this); 36 : 19205 : pc->registerChecker(ProofRule::ARRAYS_EXT, this); 37 : 19205 : } 38 : : 39 : 3109 : Node ArraysProofRuleChecker::checkInternal(ProofRule id, 40 : : const std::vector<Node>& children, 41 : : const std::vector<Node>& args) 42 : : { 43 : 3109 : NodeManager* nm = nodeManager(); 44 [ + + ]: 3109 : if (id == ProofRule::ARRAYS_READ_OVER_WRITE) 45 : : { 46 [ - + ][ - + ]: 1534 : Assert(children.size() == 1); [ - - ] 47 [ - + ][ - + ]: 1534 : Assert(args.size() == 1); [ - - ] 48 : 3068 : Node ideq = children[0]; 49 [ + - ][ - + ]: 1534 : if (ideq.getKind() != Kind::NOT || ideq[0].getKind() != Kind::EQUAL) [ + - ][ - + ] [ - - ] 50 : : { 51 : 0 : return Node::null(); 52 : : } 53 : 3068 : Node lhs = args[0]; 54 [ + - ][ - + ]: 3068 : if (lhs.getKind() != Kind::SELECT || lhs[0].getKind() != Kind::STORE [ - - ] 55 : 3068 : || lhs[0][1] != ideq[0][0]) 56 : : { 57 : 0 : return Node::null(); 58 : : } 59 : 4602 : Node rhs = nm->mkNode(Kind::SELECT, lhs[0][0], ideq[0][1]); 60 : 1534 : return lhs.eqNode(rhs); 61 : : } 62 [ - + ]: 1575 : else if (id == ProofRule::ARRAYS_READ_OVER_WRITE_CONTRA) 63 : : { 64 : 0 : Assert(children.size() == 1); 65 : 0 : Assert(args.empty()); 66 : 0 : Node adeq = children[0]; 67 : 0 : if (adeq.getKind() != Kind::NOT || adeq[0].getKind() != Kind::EQUAL) 68 : : { 69 : 0 : return Node::null(); 70 : : } 71 : 0 : Node lhs = adeq[0][0]; 72 : 0 : Node rhs = adeq[0][1]; 73 : 0 : if (lhs.getKind() != Kind::SELECT || lhs[0].getKind() != Kind::STORE 74 : 0 : || rhs.getKind() != Kind::SELECT || lhs[1] != rhs[1]) 75 : : { 76 : 0 : return Node::null(); 77 : : } 78 : 0 : return lhs[1].eqNode(lhs[0][1]); 79 : : } 80 [ + + ]: 1575 : if (id == ProofRule::ARRAYS_READ_OVER_WRITE_1) 81 : : { 82 [ - + ][ - + ]: 875 : Assert(children.empty()); [ - - ] 83 [ - + ][ - + ]: 875 : Assert(args.size() == 1); [ - - ] 84 : 1750 : Node lhs = args[0]; 85 [ + - ][ - + ]: 1750 : if (lhs.getKind() != Kind::SELECT || lhs[0].getKind() != Kind::STORE [ - - ] 86 : 1750 : || lhs[0][1] != lhs[1]) 87 : : { 88 : 0 : return Node::null(); 89 : : } 90 : 1750 : Node rhs = lhs[0][2]; 91 : 875 : return lhs.eqNode(rhs); 92 : : } 93 [ + - ]: 700 : if (id == ProofRule::ARRAYS_EXT) 94 : : { 95 [ - + ][ - + ]: 700 : Assert(children.size() == 1); [ - - ] 96 [ - + ][ - + ]: 700 : Assert(args.empty()); [ - - ] 97 : 1400 : Node adeq = children[0]; 98 [ + - ][ - + ]: 1400 : if (adeq.getKind() != Kind::NOT || adeq[0].getKind() != Kind::EQUAL [ - - ] 99 : 1400 : || !adeq[0][0].getType().isArray()) 100 : : { 101 : 0 : return Node::null(); 102 : : } 103 : 1400 : Node k = SkolemCache::getExtIndexSkolem(nm, adeq); 104 : 1400 : Node a = adeq[0][0]; 105 : 1400 : Node b = adeq[0][1]; 106 : 2100 : Node as = nm->mkNode(Kind::SELECT, a, k); 107 : 1400 : Node bs = nm->mkNode(Kind::SELECT, b, k); 108 : 1400 : return as.eqNode(bs).notNode(); 109 : : } 110 : : // no rule 111 : 0 : return Node::null(); 112 : : } 113 : : 114 : : } // namespace arrays 115 : : } // namespace theory 116 : : } // namespace cvc5::internal