GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/theory/arrays/proof_checker.cpp Lines: 44 60 73.3 %
Date: 2021-09-16 Branches: 108 424 25.5 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Andrew Reynolds
4
 *
5
 * This file is part of the cvc5 project.
6
 *
7
 * Copyright (c) 2009-2021 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 {
24
namespace theory {
25
namespace arrays {
26
27
3796
void ArraysProofRuleChecker::registerTo(ProofChecker* pc)
28
{
29
3796
  pc->registerChecker(PfRule::ARRAYS_READ_OVER_WRITE, this);
30
3796
  pc->registerChecker(PfRule::ARRAYS_READ_OVER_WRITE_CONTRA, this);
31
3796
  pc->registerChecker(PfRule::ARRAYS_READ_OVER_WRITE_1, this);
32
3796
  pc->registerChecker(PfRule::ARRAYS_EXT, this);
33
3796
  pc->registerChecker(PfRule::ARRAYS_EQ_RANGE_EXPAND, this);
34
3796
}
35
36
486
Node ArraysProofRuleChecker::checkInternal(PfRule id,
37
                                           const std::vector<Node>& children,
38
                                           const std::vector<Node>& args)
39
{
40
486
  NodeManager* nm = NodeManager::currentNM();
41
486
  if (id == PfRule::ARRAYS_READ_OVER_WRITE)
42
  {
43
354
    Assert(children.size() == 1);
44
354
    Assert(args.size() == 1);
45
708
    Node ideq = children[0];
46
354
    if (ideq.getKind() != kind::NOT || ideq[0].getKind() != kind::EQUAL)
47
    {
48
      return Node::null();
49
    }
50
708
    Node lhs = args[0];
51
1062
    if (lhs.getKind() != kind::SELECT || lhs[0].getKind() != kind::STORE
52
1062
        || lhs[0][1] != ideq[0][0])
53
    {
54
      return Node::null();
55
    }
56
708
    Node rhs = nm->mkNode(kind::SELECT, lhs[0][0], ideq[0][1]);
57
354
    return lhs.eqNode(rhs);
58
  }
59
132
  else if (id == PfRule::ARRAYS_READ_OVER_WRITE_CONTRA)
60
  {
61
    Assert(children.size() == 1);
62
    Assert(args.empty());
63
    Node adeq = children[0];
64
    if (adeq.getKind() != kind::NOT || adeq[0].getKind() != kind::EQUAL)
65
    {
66
      return Node::null();
67
    }
68
    Node lhs = adeq[0][0];
69
    Node rhs = adeq[0][1];
70
    if (lhs.getKind() != kind::SELECT || lhs[0].getKind() != kind::STORE
71
        || rhs.getKind() != kind::SELECT || lhs[1] != rhs[1])
72
    {
73
      return Node::null();
74
    }
75
    return lhs[1].eqNode(lhs[0][1]);
76
  }
77
132
  if (id == PfRule::ARRAYS_READ_OVER_WRITE_1)
78
  {
79
115
    Assert(children.empty());
80
115
    Assert(args.size() == 1);
81
230
    Node lhs = args[0];
82
345
    if (lhs.getKind() != kind::SELECT || lhs[0].getKind() != kind::STORE
83
345
        || lhs[0][1] != lhs[1])
84
    {
85
      return Node::null();
86
    }
87
230
    Node rhs = lhs[0][2];
88
115
    return lhs.eqNode(rhs);
89
  }
90
17
  if (id == PfRule::ARRAYS_EXT)
91
  {
92
14
    Assert(children.size() == 1);
93
14
    Assert(args.empty());
94
28
    Node adeq = children[0];
95
42
    if (adeq.getKind() != kind::NOT || adeq[0].getKind() != kind::EQUAL
96
42
        || !adeq[0][0].getType().isArray())
97
    {
98
      return Node::null();
99
    }
100
28
    Node k = SkolemCache::getExtIndexSkolem(adeq);
101
28
    Node a = adeq[0][0];
102
28
    Node b = adeq[0][1];
103
28
    Node as = nm->mkNode(kind::SELECT, a, k);
104
28
    Node bs = nm->mkNode(kind::SELECT, b, k);
105
14
    return as.eqNode(bs).notNode();
106
  }
107
3
  if (id == PfRule::ARRAYS_EQ_RANGE_EXPAND)
108
  {
109
6
    Node expandedEqRange = TheoryArraysRewriter::expandEqRange(args[0]);
110
3
    return args[0].eqNode(expandedEqRange);
111
  }
112
  // no rule
113
  return Node::null();
114
}
115
116
}  // namespace arrays
117
}  // namespace theory
118
29577
}  // namespace cvc5